mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Bug fixes Part 2
- If the internal v4l2 grabber is switched off, it will now be de-initialized (Issue: #542) - Extended error detection in MJPEG decompress method - Default instance capture activation if it is missing in the configuration (https://hyperion-project.org/goto/post?id=13656#post-13656) - Fixed some small (think)mistakes (https://hyperion-project.org/threads/hdmi-grabber.3302/page-2#post-14887)
This commit is contained in:
		
				
					committed by
					
						
						Paulchen-Panther
					
				
			
			
				
	
			
			
			
						parent
						
							0a8af60726
						
					
				
				
					commit
					c6de5173ec
				
			@@ -17,6 +17,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_JPEG
 | 
			
		||||
	#include <QImage>
 | 
			
		||||
	#include <QColor>
 | 
			
		||||
	#include <jpeglib.h>
 | 
			
		||||
	#include <csetjmp>
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -924,7 +924,28 @@ void V4L2Grabber::process_image(const uint8_t * data, int size)
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		jpeg_start_decompress(_decompress);
 | 
			
		||||
		_decompress->scale_num = 1;
 | 
			
		||||
		_decompress->scale_denom = 1;
 | 
			
		||||
		_decompress->out_color_space = JCS_RGB;
 | 
			
		||||
		_decompress->dct_method = JDCT_IFAST;
 | 
			
		||||
 | 
			
		||||
		if (!jpeg_start_decompress(_decompress))
 | 
			
		||||
		{
 | 
			
		||||
			jpeg_abort_decompress(_decompress);
 | 
			
		||||
			jpeg_destroy_decompress(_decompress);
 | 
			
		||||
			delete _decompress;
 | 
			
		||||
			delete _error;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (_decompress->out_color_components != 3)
 | 
			
		||||
		{
 | 
			
		||||
			jpeg_abort_decompress(_decompress);
 | 
			
		||||
			jpeg_destroy_decompress(_decompress);
 | 
			
		||||
			delete _decompress;
 | 
			
		||||
			delete _error;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		QImage imageFrame = QImage(_decompress->output_width, _decompress->output_height, QImage::Format_RGB888);
 | 
			
		||||
 | 
			
		||||
@@ -948,20 +969,18 @@ void V4L2Grabber::process_image(const uint8_t * data, int size)
 | 
			
		||||
		imageFrame = imageFrame.copy(rect);
 | 
			
		||||
		imageFrame = imageFrame.scaled(imageFrame.width() / _pixelDecimation, imageFrame.height() / _pixelDecimation,Qt::KeepAspectRatio);
 | 
			
		||||
 | 
			
		||||
		if ((image.width() != unsigned(imageFrame.width())) && (image.height() != unsigned(imageFrame.height())))
 | 
			
		||||
		if ((image.width() != unsigned(imageFrame.width())) || (image.height() != unsigned(imageFrame.height())))
 | 
			
		||||
			image.resize(imageFrame.width(), imageFrame.height());
 | 
			
		||||
 | 
			
		||||
		for (int y=0; y<imageFrame.height(); ++y)
 | 
			
		||||
		{
 | 
			
		||||
			for (int x=0; x<imageFrame.width(); ++x)
 | 
			
		||||
			{
 | 
			
		||||
				const QRgb inPixel = imageFrame.pixel(x,y);
 | 
			
		||||
				QColor inPixel(imageFrame.pixel(x,y));
 | 
			
		||||
				ColorRgb & outPixel = image(x,y);
 | 
			
		||||
				outPixel.red   = (inPixel & 0xff0000) >> 16;
 | 
			
		||||
				outPixel.green = (inPixel & 0xff00) >>  8;
 | 
			
		||||
				outPixel.blue  = (inPixel & 0xff);
 | 
			
		||||
				outPixel.red   = inPixel.red();
 | 
			
		||||
				outPixel.green = inPixel.green();
 | 
			
		||||
				outPixel.blue  = inPixel.blue();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1045,7 +1064,7 @@ void V4L2Grabber::throw_errno_exception(const QString & error)
 | 
			
		||||
 | 
			
		||||
void V4L2Grabber::setSignalDetectionEnable(bool enable)
 | 
			
		||||
{
 | 
			
		||||
	if(_signalDetectionEnabled != enable)
 | 
			
		||||
	if (_signalDetectionEnabled != enable)
 | 
			
		||||
	{
 | 
			
		||||
		_signalDetectionEnabled = enable;
 | 
			
		||||
		Info(_log, "Signal detection is now %s", enable ? "enabled" : "disabled");
 | 
			
		||||
@@ -1059,7 +1078,7 @@ bool V4L2Grabber::getSignalDetectionEnabled()
 | 
			
		||||
 | 
			
		||||
void V4L2Grabber::setPixelDecimation(int pixelDecimation)
 | 
			
		||||
{
 | 
			
		||||
	if(_pixelDecimation != pixelDecimation)
 | 
			
		||||
	if (_pixelDecimation != pixelDecimation)
 | 
			
		||||
	{
 | 
			
		||||
		_pixelDecimation = pixelDecimation;
 | 
			
		||||
		_imageResampler.setHorizontalPixelDecimation(pixelDecimation);
 | 
			
		||||
@@ -1069,7 +1088,7 @@ void V4L2Grabber::setPixelDecimation(int pixelDecimation)
 | 
			
		||||
 | 
			
		||||
void V4L2Grabber::setDeviceVideoStandard(QString device, VideoStandard videoStandard)
 | 
			
		||||
{
 | 
			
		||||
	if(_deviceName != device || _videoStandard != videoStandard)
 | 
			
		||||
	if (_deviceName != device || _videoStandard != videoStandard)
 | 
			
		||||
	{
 | 
			
		||||
		// extract input of device
 | 
			
		||||
		QChar input = device.at(device.size() - 1);
 | 
			
		||||
@@ -1079,9 +1098,9 @@ void V4L2Grabber::setDeviceVideoStandard(QString device, VideoStandard videoStan
 | 
			
		||||
		_deviceName = device;
 | 
			
		||||
		_videoStandard = videoStandard;
 | 
			
		||||
 | 
			
		||||
		// start if init is a success
 | 
			
		||||
		if(init())
 | 
			
		||||
			start();
 | 
			
		||||
// 		// start if init is a success
 | 
			
		||||
// 		if(init())
 | 
			
		||||
// 			start();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1092,11 +1111,9 @@ void V4L2Grabber::componentStateChanged(const hyperion::Components component, bo
 | 
			
		||||
		if (_initialized != enable)
 | 
			
		||||
		{
 | 
			
		||||
			if (enable)
 | 
			
		||||
			{
 | 
			
		||||
				if(init()) start();
 | 
			
		||||
			}
 | 
			
		||||
				start();
 | 
			
		||||
			else
 | 
			
		||||
				uninit();
 | 
			
		||||
				stop();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -82,6 +82,7 @@ void CaptureCont::setSystemCaptureEnable(const bool& enable)
 | 
			
		||||
		}
 | 
			
		||||
		_systemCaptEnabled = enable;
 | 
			
		||||
		_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_GRABBER, enable);
 | 
			
		||||
		_hyperion->setComponentState(hyperion::COMP_GRABBER, enable);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -103,6 +104,7 @@ void CaptureCont::setV4LCaptureEnable(const bool& enable)
 | 
			
		||||
		}
 | 
			
		||||
		_v4lCaptEnabled = enable;
 | 
			
		||||
		_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_V4L, enable);
 | 
			
		||||
		_hyperion->setComponentState(hyperion::COMP_V4L, enable);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -104,11 +104,7 @@ void GrabberWrapper::handleSettingsUpdate(const settings::type& type, const QJso
 | 
			
		||||
	if(type == settings::V4L2 || type == settings::SYSTEMCAPTURE)
 | 
			
		||||
	{
 | 
			
		||||
		// extract settings
 | 
			
		||||
		QJsonObject obj;
 | 
			
		||||
		if(config.isArray() && !config.isEmpty())
 | 
			
		||||
			obj = config.array().at(0).toObject();
 | 
			
		||||
		else
 | 
			
		||||
			obj = config.object();
 | 
			
		||||
		const QJsonObject& obj = config.object();
 | 
			
		||||
 | 
			
		||||
		if(type == settings::SYSTEMCAPTURE  && !_grabberName.startsWith("V4L"))
 | 
			
		||||
		{
 | 
			
		||||
@@ -172,5 +168,4 @@ void GrabberWrapper::handleSettingsUpdate(const settings::type& type, const QJso
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,14 +26,6 @@
 | 
			
		||||
 | 
			
		||||
using namespace commandline;
 | 
			
		||||
 | 
			
		||||
// save the image as screenshot
 | 
			
		||||
void saveScreenshot(QString filename, const Image<ColorRgb> & image)
 | 
			
		||||
{
 | 
			
		||||
	// store as PNG
 | 
			
		||||
	QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
 | 
			
		||||
	pngImage.save(filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
	Logger *log = Logger::getInstance("V4L2GRABBER");
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje
 | 
			
		||||
	, _webserver(nullptr)
 | 
			
		||||
	, _jsonServer(nullptr)
 | 
			
		||||
	, _udpListener(nullptr)
 | 
			
		||||
	, _v4l2Grabbers(nullptr)
 | 
			
		||||
	, _v4l2Grabber(nullptr)
 | 
			
		||||
	, _dispmanx(nullptr)
 | 
			
		||||
	, _x11Grabber(nullptr)
 | 
			
		||||
	, _amlGrabber(nullptr)
 | 
			
		||||
@@ -83,10 +83,10 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje
 | 
			
		||||
 | 
			
		||||
	// set inital log lvl if the loglvl wasn't overwritten by arg
 | 
			
		||||
	if(!logLvlOverwrite)
 | 
			
		||||
		handleSettingsUpdate(settings::LOGGER, _settingsManager->getSetting(settings::LOGGER));
 | 
			
		||||
		handleSettingsUpdate(settings::LOGGER, getSetting(settings::LOGGER));
 | 
			
		||||
 | 
			
		||||
	// init EffectFileHandler
 | 
			
		||||
	EffectFileHandler* efh = new EffectFileHandler(rootPath, _settingsManager->getSetting(settings::EFFECTS), this);
 | 
			
		||||
	EffectFileHandler* efh = new EffectFileHandler(rootPath, getSetting(settings::EFFECTS), this);
 | 
			
		||||
	connect(this, &HyperionDaemon::settingsChanged, efh, &EffectFileHandler::handleSettingsUpdate);
 | 
			
		||||
 | 
			
		||||
	// spawn all Hyperion instances before network services
 | 
			
		||||
@@ -94,7 +94,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje
 | 
			
		||||
 | 
			
		||||
	Info(_log, "Hyperion initialized");
 | 
			
		||||
 | 
			
		||||
	//connect(_hyperion,SIGNAL(closing()),this,SLOT(freeObjects())); for app restart refactor required
 | 
			
		||||
	//connect(_hyperion,SIGNAL(closing()),this,SLOT(freeObjects())); // TODO for app restart, refactor required
 | 
			
		||||
 | 
			
		||||
	// listen for setting changes
 | 
			
		||||
	connect(_hyperion, &Hyperion::settingsChanged, this, &HyperionDaemon::settingsChanged);
 | 
			
		||||
@@ -111,10 +111,17 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje
 | 
			
		||||
		Warning(_log, "No platform capture can be instantiated, because all grabbers have been left out from the build");
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	// init system capture (framegrabber)
 | 
			
		||||
	// get power state of system/v4l2 capture
 | 
			
		||||
	const QJsonObject & grabberConfig = getSetting(settings::INSTCAPTURE).object();
 | 
			
		||||
 | 
			
		||||
	// init system capture (framegrabber) and update power state
 | 
			
		||||
	handleSettingsUpdate(settings::SYSTEMCAPTURE, getSetting(settings::SYSTEMCAPTURE));
 | 
			
		||||
	// init v4l2 capture
 | 
			
		||||
	_hyperion->setComponentState(hyperion::COMP_GRABBER, grabberConfig["systemEnable"].toBool(true));
 | 
			
		||||
 | 
			
		||||
	// init v4l2 capture  and update power state
 | 
			
		||||
	handleSettingsUpdate(settings::V4L2, getSetting(settings::V4L2));
 | 
			
		||||
	_hyperion->setComponentState(hyperion::COMP_V4L, grabberConfig["v4lEnable"].toBool(true));
 | 
			
		||||
 | 
			
		||||
	// ---- network services -----
 | 
			
		||||
	startNetworkServices();
 | 
			
		||||
}
 | 
			
		||||
@@ -162,10 +169,10 @@ void HyperionDaemon::freeObjects()
 | 
			
		||||
	delete _fbGrabber;
 | 
			
		||||
	delete _osxGrabber;
 | 
			
		||||
	delete _qtGrabber;
 | 
			
		||||
	delete _v4l2Grabbers;
 | 
			
		||||
	delete _v4l2Grabber;
 | 
			
		||||
	delete _stats;
 | 
			
		||||
 | 
			
		||||
	_v4l2Grabbers          = nullptr;
 | 
			
		||||
	_v4l2Grabber           = nullptr;
 | 
			
		||||
	_bonjourBrowserWrapper = nullptr;
 | 
			
		||||
	_amlGrabber            = nullptr;
 | 
			
		||||
	_dispmanx              = nullptr;
 | 
			
		||||
@@ -384,24 +391,27 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJso
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
#ifdef ENABLE_V4L2
 | 
			
		||||
			if(_v4l2Grabber != nullptr)
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			const QJsonObject & grabberConfig = config.object();
 | 
			
		||||
 | 
			
		||||
			V4L2Wrapper* grabber = new V4L2Wrapper(
 | 
			
		||||
			_v4l2Grabber = new V4L2Wrapper(
 | 
			
		||||
				grabberConfig["device"].toString("auto"),
 | 
			
		||||
				parseVideoStandard(grabberConfig["standard"].toString("no-change")),
 | 
			
		||||
				parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")),
 | 
			
		||||
				grabberConfig["sizeDecimation"].toInt(8) );
 | 
			
		||||
			grabber->setSignalThreshold(
 | 
			
		||||
			_v4l2Grabber->setSignalThreshold(
 | 
			
		||||
				grabberConfig["redSignalThreshold"].toDouble(0.0)/100.0,
 | 
			
		||||
				grabberConfig["greenSignalThreshold"].toDouble(0.0)/100.0,
 | 
			
		||||
				grabberConfig["blueSignalThreshold"].toDouble(0.0)/100.0);
 | 
			
		||||
			grabber->setCropping(
 | 
			
		||||
			_v4l2Grabber->setCropping(
 | 
			
		||||
				grabberConfig["cropLeft"].toInt(0),
 | 
			
		||||
				grabberConfig["cropRight"].toInt(0),
 | 
			
		||||
				grabberConfig["cropTop"].toInt(0),
 | 
			
		||||
				grabberConfig["cropBottom"].toInt(0));
 | 
			
		||||
			grabber->setSignalDetectionEnable(grabberConfig["signalDetection"].toBool(true));
 | 
			
		||||
			grabber->setSignalDetectionOffset(
 | 
			
		||||
			_v4l2Grabber->setSignalDetectionEnable(grabberConfig["signalDetection"].toBool(true));
 | 
			
		||||
			_v4l2Grabber->setSignalDetectionOffset(
 | 
			
		||||
				grabberConfig["sDHOffsetMin"].toDouble(0.25),
 | 
			
		||||
				grabberConfig["sDVOffsetMin"].toDouble(0.25),
 | 
			
		||||
				grabberConfig["sDHOffsetMax"].toDouble(0.75),
 | 
			
		||||
@@ -409,8 +419,8 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJso
 | 
			
		||||
			Debug(_log, "V4L2 grabber created");
 | 
			
		||||
 | 
			
		||||
			// connect to HyperionDaemon signal
 | 
			
		||||
			connect(this, &HyperionDaemon::videoMode, grabber, &V4L2Wrapper::setVideoMode);
 | 
			
		||||
			connect(this, &HyperionDaemon::settingsChanged, grabber, &V4L2Wrapper::handleSettingsUpdate);
 | 
			
		||||
			connect(this, &HyperionDaemon::videoMode, _v4l2Grabber, &V4L2Wrapper::setVideoMode);
 | 
			
		||||
			connect(this, &HyperionDaemon::settingsChanged, _v4l2Grabber, &V4L2Wrapper::handleSettingsUpdate);
 | 
			
		||||
#else
 | 
			
		||||
		Error(_log, "The v4l2 grabber can not be instantiated, because it has been left out from the build");
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ private:
 | 
			
		||||
	WebServer*                 _webserver;
 | 
			
		||||
	JsonServer*                _jsonServer;
 | 
			
		||||
	UDPListener*               _udpListener;
 | 
			
		||||
	V4L2Wrapper*               _v4l2Grabbers;
 | 
			
		||||
	V4L2Wrapper*               _v4l2Grabber;
 | 
			
		||||
	DispmanxWrapper*           _dispmanx;
 | 
			
		||||
	X11Wrapper*                _x11Grabber;
 | 
			
		||||
	AmlogicWrapper*            _amlGrabber;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user