Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
frameobserver.cpp 2.66 KiB
#include "frameobserver.h"
#include "cam.h"
#include "frameprocessor.h"
#include "qnamespace.h"

#include <VmbCPP/SharedPointerDefines.h>
#include <VmbCPP/Camera.h>

#include <QDebug>
#include <QThread>
#include <QObject>


using namespace VmbCPP;

FrameObserver::FrameObserver( CamPtr cam ) : IFrameObserver( cam->getCameraPtr() ),
	_cam(cam)
{
}

FrameObserver::~FrameObserver()
{
	qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
}


/* Frame callback notifies about incoming frames
	process data afap
	some functions are prohibited within this callback!
	Do not apply image processing within this callback ( performance )
	-> create frame processor to handle frame processing asynchronously
	- when the frame has been processed , requeue it
	- frameprocessing is done in a separate thread
*/
void FrameObserver::FrameReceived ( const FramePtr pframe )
{
	// qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";

	VmbFrameStatusType status;
	pframe->GetReceiveStatus(status);
	switch( status )
	{
		case VmbFrameStatusIncomplete:
			_cam->_nframes_incomplete++;
			queueFrame(pframe);
			return;
		case VmbFrameStatusTooSmall:
			_cam->_nframes_toosmall++;
			queueFrame(pframe);
			return;
		case VmbFrameStatusInvalid:
			_cam->_nframes_invalid++;
			queueFrame(pframe);
			return;
		default:
			_cam->_nframes_unknown++;
			return;
		case VmbFrameStatusComplete:
			_cam->_nframes_complete++;
			break;
	}

	FrameProcessor* processor = new FrameProcessor(pframe,_cam->outDir());
	QThread *thread = new QThread;
	processor->moveToThread(thread);

	connect(thread, &QThread::started, processor, &FrameProcessor::processFrame);
	connect(processor, &FrameProcessor::frameProcessed, this, &FrameObserver::queueFrame); //call **before** thread is deleted!
	connect(processor, &FrameProcessor::frameProcessed, processor, &FrameProcessor::deleteLater);
	connect(processor, &FrameProcessor::frameProcessed, thread, &QThread::quit, Qt::DirectConnection); // direct!
	connect(thread, &QThread::finished, thread, &QThread::deleteLater);

	// Optional: Connect to custom debug slots to monitor creation/deletion
	// static int count=0;
	// count++;
	// connect(processor, &QObject::destroyed, this, []() { qDebug() << "Processor destroyed: #" << count; });
	// connect(thread, &QObject::destroyed, this, []() { qDebug() << "Thread destroyed: #" << count; });
	// connect(thread, &QThread::started, this, []() { qDebug() << "Thread started: #" << count; });
	// connect(thread, &QThread::finished, this, []() { qDebug() << "Thread finished: #" << count; });

	thread->start();
}

void FrameObserver::queueFrame(FramePtr pframe)
{
	_cam->getCameraPtr()->QueueFrame(pframe); // Queue the frame back to the camera
}