Add Stream Reader Thread
This commit is contained in:
@@ -34,6 +34,7 @@ add_executable( FaultFinder
|
||||
ImageManager.cpp
|
||||
ConfigManager.cpp
|
||||
FaultManager.cpp
|
||||
StreamReader.cpp
|
||||
${prog_SRCS}
|
||||
)
|
||||
|
||||
|
||||
@@ -1,18 +1,213 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
#include "StreamManager.hpp"
|
||||
#include "ImageManager.hpp"
|
||||
|
||||
StreamManager::StreamManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
QTimer *timer = new QTimer(this);
|
||||
connect(timer, &QTimer::timeout, this, QOverload<>::of(&StreamManager::Process));
|
||||
timer->start(1000);
|
||||
// Listen for New Emissivity Signal
|
||||
//connect(&config_mgr, &ConfigManager::NewEmissivity, this, &StreamManager::SetEmissivity);
|
||||
PvResult res;
|
||||
|
||||
res = FindDevice();
|
||||
|
||||
if (res.IsFailure())
|
||||
exit(res.GetCode());
|
||||
|
||||
res = ConnectToDevice();
|
||||
|
||||
if (res.IsFailure())
|
||||
exit(res.GetCode());
|
||||
|
||||
res = OpenStream();
|
||||
|
||||
if (res.IsFailure())
|
||||
exit(res.GetCode());
|
||||
|
||||
ConfigureStream();
|
||||
|
||||
CreatePipeline();
|
||||
|
||||
StartStream();
|
||||
|
||||
ImageThread = new StreamReader(Device, Stream, Pipeline);
|
||||
|
||||
ImageThread->start(QThread::TimeCriticalPriority);
|
||||
}
|
||||
|
||||
void StreamManager::Process()
|
||||
StreamManager::~StreamManager()
|
||||
{
|
||||
qInfo() << "TICK";
|
||||
ImageThread->requestInterruption();
|
||||
ImageThread->wait();
|
||||
StopStream();
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
void StreamManager::SetEmissivity(double emissivity)
|
||||
{
|
||||
if (lDeviceParams)
|
||||
lDeviceParams->SetFloatValue("ObjectEmissivity", emissivity);
|
||||
}
|
||||
|
||||
PvResult StreamManager::FindDevice()
|
||||
{
|
||||
PvResult lResult = PvResult();
|
||||
const PvDeviceInfo *lSelectedDI = NULL;
|
||||
PvSystem lSystem;
|
||||
|
||||
lSystem.Find();
|
||||
|
||||
// Detect, select device.
|
||||
std::vector<const PvDeviceInfo *> lDIVector;
|
||||
for (uint32_t i = 0; i < lSystem.GetInterfaceCount(); i++)
|
||||
{
|
||||
const PvInterface *lInterface = dynamic_cast<const PvInterface *>(lSystem.GetInterface(i));
|
||||
if (lInterface != NULL)
|
||||
{
|
||||
for (uint32_t j = 0; j < lInterface->GetDeviceCount(); j++)
|
||||
{
|
||||
const PvDeviceInfo *lDI = dynamic_cast<const PvDeviceInfo *>(lInterface->GetDeviceInfo(j));
|
||||
if (lDI != NULL)
|
||||
{
|
||||
lDIVector.push_back(lDI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lDIVector.size() == 0)
|
||||
{
|
||||
qCritical() << "Device not found!";
|
||||
lResult.SetCode(PV_NOT_FOUND);
|
||||
return lResult;
|
||||
}
|
||||
|
||||
lSelectedDI = lDIVector.front();
|
||||
|
||||
ConnectionID = lSelectedDI->GetConnectionID();
|
||||
|
||||
lResult.SetCode(PV_OK);
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
PvResult StreamManager::ConnectToDevice()
|
||||
{
|
||||
PvResult lResult;
|
||||
|
||||
// Connect to the GigE Vision or USB3 Vision device
|
||||
qInfo() << "Connecting to device.";
|
||||
Device = PvDevice::CreateAndConnect(ConnectionID, &lResult);
|
||||
if (Device == NULL)
|
||||
{
|
||||
qCritical() << "Unable to connect to device.";
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
PvResult StreamManager::OpenStream()
|
||||
{
|
||||
PvResult lResult;
|
||||
|
||||
// Open stream to the GigE Vision or USB3 Vision device
|
||||
qInfo() << "Opening stream from device.";
|
||||
Stream = PvStream::CreateAndOpen(ConnectionID, &lResult);
|
||||
|
||||
if (Stream != NULL)
|
||||
{
|
||||
// If this is a GigE Vision device, configure GigE Vision specific streaming parameters
|
||||
PvDeviceGEV* lDeviceGEV = dynamic_cast<PvDeviceGEV *>(Device);
|
||||
if ( lDeviceGEV != NULL )
|
||||
{
|
||||
PvStreamGEV *lStreamGEV = static_cast<PvStreamGEV *>(Stream);
|
||||
|
||||
// Negotiate packet size
|
||||
lDeviceGEV->NegotiatePacketSize();
|
||||
|
||||
// Configure device streaming destination
|
||||
lDeviceGEV->SetStreamDestination( lStreamGEV->GetLocalIPAddress(), lStreamGEV->GetLocalPort() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qCritical() << "Unable to stream from device.";
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
void StreamManager::ConfigureStream()
|
||||
{
|
||||
// Get device parameters need to control streaming
|
||||
lDeviceParams = Device->GetParameters();
|
||||
|
||||
// Use Temperature Format Instead of Raw Counts
|
||||
lDeviceParams->SetEnumValue("IRFormat", 1);
|
||||
|
||||
SetEmissivity(0.95);
|
||||
}
|
||||
|
||||
void StreamManager::CreatePipeline()
|
||||
{
|
||||
// Create the PvPipeline object
|
||||
Pipeline = new PvPipeline( Stream );
|
||||
|
||||
if ( Pipeline != NULL )
|
||||
{
|
||||
// Reading payload size from device
|
||||
uint32_t lSize = Device->GetPayloadSize();
|
||||
|
||||
// Set the Buffer count and the Buffer size
|
||||
Pipeline->SetBufferCount( BUFFER_COUNT );
|
||||
Pipeline->SetBufferSize( lSize );
|
||||
}
|
||||
}
|
||||
|
||||
void StreamManager::StartStream()
|
||||
{
|
||||
// Map the GenICam AcquisitionStart and AcquisitionStop commands
|
||||
PvGenCommand *lStart = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStart"));
|
||||
|
||||
qInfo() << "Starting pipeline";
|
||||
Pipeline->Start();
|
||||
|
||||
// Get stream parameters
|
||||
PvGenParameterArray *lStreamParams = Stream->GetParameters();
|
||||
|
||||
// Map a few GenICam stream stats counters
|
||||
PvGenFloat *lFrameRate = dynamic_cast<PvGenFloat *>(lStreamParams->Get("AcquisitionRate"));
|
||||
PvGenFloat *lBandwidth = dynamic_cast<PvGenFloat *>(lStreamParams->Get("Bandwidth"));
|
||||
|
||||
// Enable streaming and send the AcquisitionStart command
|
||||
qInfo() << "Enabling streaming and sending AcquisitionStart command.";
|
||||
Device->StreamEnable();
|
||||
lStart->Execute();
|
||||
}
|
||||
|
||||
void StreamManager::StopStream()
|
||||
{
|
||||
// Tell the device to stop sending images.
|
||||
qInfo() << "Sending AcquisitionStop command to the device";
|
||||
PvGenCommand *lStop = dynamic_cast<PvGenCommand *>(lDeviceParams->Get("AcquisitionStop"));
|
||||
lStop->Execute();
|
||||
|
||||
// Disable streaming on the device
|
||||
qInfo() << "Disable streaming on the controller.";;
|
||||
Device->StreamDisable();
|
||||
|
||||
// Stop the pipeline
|
||||
qInfo() << "Stop pipeline";
|
||||
Pipeline->Stop();
|
||||
}
|
||||
|
||||
void StreamManager::Disconnect()
|
||||
{
|
||||
if (Stream != NULL)
|
||||
{
|
||||
Stream->Close();
|
||||
PvStream::Free(Stream);
|
||||
}
|
||||
if (Device != NULL)
|
||||
{
|
||||
Device->Disconnect();
|
||||
PvDevice::Free(Device);
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,47 @@
|
||||
#define STREAM_MANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
#include <PvSystem.h>
|
||||
#include <PvDevice.h>
|
||||
#include <PvStream.h>
|
||||
#include <PvPipeline.h>
|
||||
#include <PvDeviceGEV.h>
|
||||
#include <PvStreamGEV.h>
|
||||
|
||||
#include "StreamReader.hpp"
|
||||
|
||||
#define BUFFER_COUNT (32)
|
||||
|
||||
class StreamManager : public QObject
|
||||
{
|
||||
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
|
||||
StreamManager(QObject *parent);
|
||||
void Process();
|
||||
virtual ~StreamManager();
|
||||
|
||||
public slots:
|
||||
void SetEmissivity(double emissivity);
|
||||
|
||||
private:
|
||||
PvResult FindDevice();
|
||||
PvResult ConnectToDevice();
|
||||
PvResult OpenStream();
|
||||
void ConfigureStream();
|
||||
void StartStream();
|
||||
void StopStream();
|
||||
void CreatePipeline();
|
||||
void AcquireImages();
|
||||
void Disconnect();
|
||||
|
||||
PvString ConnectionID;
|
||||
PvDevice *Device = NULL;
|
||||
PvStream *Stream = NULL;
|
||||
PvGenParameterArray *lDeviceParams = NULL;
|
||||
PvPipeline *Pipeline = NULL;
|
||||
StreamReader *ImageThread;
|
||||
};
|
||||
|
||||
#endif
|
||||
60
StreamReader.cpp
Normal file
60
StreamReader.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "StreamReader.hpp"
|
||||
|
||||
StreamReader::StreamReader(PvDevice *Device, PvStream *Stream, PvPipeline *Pipeline)
|
||||
{
|
||||
this->Device = Device;
|
||||
this->Stream = Stream;
|
||||
this->Pipeline = Pipeline;
|
||||
}
|
||||
|
||||
void StreamReader::run()
|
||||
{
|
||||
while (!isInterruptionRequested())
|
||||
{
|
||||
PvBuffer *lBuffer = NULL;
|
||||
PvResult lOperationResult;
|
||||
|
||||
// wait for this to unblock before called in event loop
|
||||
// Retrieve next buffer
|
||||
PvResult lResult = Stream->RetrieveBuffer(&lBuffer, &lOperationResult, 1000);
|
||||
if (lResult.IsOK())
|
||||
{
|
||||
if (lOperationResult.IsOK())
|
||||
{
|
||||
PvPayloadType lType;
|
||||
|
||||
// If the buffer contains an image, display width and height.
|
||||
uint32_t lWidth = 0, lHeight = 0;
|
||||
lType = lBuffer->GetPayloadType();
|
||||
|
||||
if (lType == PvPayloadTypeImage)
|
||||
{
|
||||
// Get image specific buffer interface.
|
||||
PvImage *lImage = lBuffer->GetImage();
|
||||
|
||||
// Read width, height.
|
||||
lWidth = lImage->GetWidth();
|
||||
lHeight = lImage->GetHeight();
|
||||
|
||||
NewImage(lWidth, lHeight, lImage->GetDataPointer());
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << " (buffer does not contain image)";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qInfo() << lOperationResult.GetCodeString().GetAscii() << "\r";
|
||||
}
|
||||
|
||||
// Re-queue the buffer in the stream object
|
||||
Stream->QueueBuffer(lBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Retrieve buffer failure
|
||||
qCritical() << lResult.GetCodeString().GetAscii() << "\r";
|
||||
}
|
||||
}
|
||||
}
|
||||
28
StreamReader.hpp
Normal file
28
StreamReader.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef STREAM_READER_H
|
||||
#define STREAM_READER_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
#include <PvDevice.h>
|
||||
#include <PvStream.h>
|
||||
#include <PvPipeline.h>
|
||||
|
||||
class StreamReader : public QThread
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
void run();
|
||||
|
||||
public:
|
||||
StreamReader(PvDevice *Device, PvStream *Stream, PvPipeline *Pipeline);
|
||||
|
||||
signals:
|
||||
void NewImage(uint32_t width, uint32_t height, uint8_t *imgPointer);
|
||||
|
||||
private:
|
||||
PvDevice *Device = NULL;
|
||||
PvStream *Stream = NULL;
|
||||
PvPipeline *Pipeline = NULL;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user