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:
Paulchen-Panther 2019-05-03 17:54:43 +02:00 committed by Paulchen-Panther
parent 0a8af60726
commit c6de5173ec
No known key found for this signature in database
GPG Key ID: 84E3B692456B6840
7 changed files with 65 additions and 48 deletions

View File

@ -17,6 +17,7 @@
#ifdef HAVE_JPEG #ifdef HAVE_JPEG
#include <QImage> #include <QImage>
#include <QColor>
#include <jpeglib.h> #include <jpeglib.h>
#include <csetjmp> #include <csetjmp>
#endif #endif

View File

@ -924,7 +924,28 @@ void V4L2Grabber::process_image(const uint8_t * data, int size)
return; 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); 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.copy(rect);
imageFrame = imageFrame.scaled(imageFrame.width() / _pixelDecimation, imageFrame.height() / _pixelDecimation,Qt::KeepAspectRatio); 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()); image.resize(imageFrame.width(), imageFrame.height());
for (int y=0; y<imageFrame.height(); ++y) for (int y=0; y<imageFrame.height(); ++y)
{
for (int x=0; x<imageFrame.width(); ++x) 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); ColorRgb & outPixel = image(x,y);
outPixel.red = (inPixel & 0xff0000) >> 16; outPixel.red = inPixel.red();
outPixel.green = (inPixel & 0xff00) >> 8; outPixel.green = inPixel.green();
outPixel.blue = (inPixel & 0xff); outPixel.blue = inPixel.blue();
} }
}
} }
else else
#endif #endif
@ -1045,7 +1064,7 @@ void V4L2Grabber::throw_errno_exception(const QString & error)
void V4L2Grabber::setSignalDetectionEnable(bool enable) void V4L2Grabber::setSignalDetectionEnable(bool enable)
{ {
if(_signalDetectionEnabled != enable) if (_signalDetectionEnabled != enable)
{ {
_signalDetectionEnabled = enable; _signalDetectionEnabled = enable;
Info(_log, "Signal detection is now %s", enable ? "enabled" : "disabled"); Info(_log, "Signal detection is now %s", enable ? "enabled" : "disabled");
@ -1059,7 +1078,7 @@ bool V4L2Grabber::getSignalDetectionEnabled()
void V4L2Grabber::setPixelDecimation(int pixelDecimation) void V4L2Grabber::setPixelDecimation(int pixelDecimation)
{ {
if(_pixelDecimation != pixelDecimation) if (_pixelDecimation != pixelDecimation)
{ {
_pixelDecimation = pixelDecimation; _pixelDecimation = pixelDecimation;
_imageResampler.setHorizontalPixelDecimation(pixelDecimation); _imageResampler.setHorizontalPixelDecimation(pixelDecimation);
@ -1069,7 +1088,7 @@ void V4L2Grabber::setPixelDecimation(int pixelDecimation)
void V4L2Grabber::setDeviceVideoStandard(QString device, VideoStandard videoStandard) void V4L2Grabber::setDeviceVideoStandard(QString device, VideoStandard videoStandard)
{ {
if(_deviceName != device || _videoStandard != videoStandard) if (_deviceName != device || _videoStandard != videoStandard)
{ {
// extract input of device // extract input of device
QChar input = device.at(device.size() - 1); QChar input = device.at(device.size() - 1);
@ -1079,9 +1098,9 @@ void V4L2Grabber::setDeviceVideoStandard(QString device, VideoStandard videoStan
_deviceName = device; _deviceName = device;
_videoStandard = videoStandard; _videoStandard = videoStandard;
// start if init is a success // // start if init is a success
if(init()) // if(init())
start(); // start();
} }
} }
@ -1092,11 +1111,9 @@ void V4L2Grabber::componentStateChanged(const hyperion::Components component, bo
if (_initialized != enable) if (_initialized != enable)
{ {
if (enable) if (enable)
{ start();
if(init()) start();
}
else else
uninit(); stop();
} }
} }
} }

View File

@ -82,6 +82,7 @@ void CaptureCont::setSystemCaptureEnable(const bool& enable)
} }
_systemCaptEnabled = enable; _systemCaptEnabled = enable;
_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_GRABBER, 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; _v4lCaptEnabled = enable;
_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_V4L, enable); _hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_V4L, enable);
_hyperion->setComponentState(hyperion::COMP_V4L, enable);
} }
} }

View File

@ -104,11 +104,7 @@ void GrabberWrapper::handleSettingsUpdate(const settings::type& type, const QJso
if(type == settings::V4L2 || type == settings::SYSTEMCAPTURE) if(type == settings::V4L2 || type == settings::SYSTEMCAPTURE)
{ {
// extract settings // extract settings
QJsonObject obj; const QJsonObject& obj = config.object();
if(config.isArray() && !config.isEmpty())
obj = config.array().at(0).toObject();
else
obj = config.object();
if(type == settings::SYSTEMCAPTURE && !_grabberName.startsWith("V4L")) if(type == settings::SYSTEMCAPTURE && !_grabberName.startsWith("V4L"))
{ {
@ -172,5 +168,4 @@ void GrabberWrapper::handleSettingsUpdate(const settings::type& type, const QJso
} }
} }
} }

View File

@ -26,14 +26,6 @@
using namespace commandline; 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) int main(int argc, char** argv)
{ {
Logger *log = Logger::getInstance("V4L2GRABBER"); Logger *log = Logger::getInstance("V4L2GRABBER");

View File

@ -57,7 +57,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje
, _webserver(nullptr) , _webserver(nullptr)
, _jsonServer(nullptr) , _jsonServer(nullptr)
, _udpListener(nullptr) , _udpListener(nullptr)
, _v4l2Grabbers(nullptr) , _v4l2Grabber(nullptr)
, _dispmanx(nullptr) , _dispmanx(nullptr)
, _x11Grabber(nullptr) , _x11Grabber(nullptr)
, _amlGrabber(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 // set inital log lvl if the loglvl wasn't overwritten by arg
if(!logLvlOverwrite) if(!logLvlOverwrite)
handleSettingsUpdate(settings::LOGGER, _settingsManager->getSetting(settings::LOGGER)); handleSettingsUpdate(settings::LOGGER, getSetting(settings::LOGGER));
// init EffectFileHandler // 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); connect(this, &HyperionDaemon::settingsChanged, efh, &EffectFileHandler::handleSettingsUpdate);
// spawn all Hyperion instances before network services // spawn all Hyperion instances before network services
@ -94,7 +94,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, const QString rootPath, QObje
Info(_log, "Hyperion initialized"); 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 // listen for setting changes
connect(_hyperion, &Hyperion::settingsChanged, this, &HyperionDaemon::settingsChanged); 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"); Warning(_log, "No platform capture can be instantiated, because all grabbers have been left out from the build");
#endif #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)); 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)); handleSettingsUpdate(settings::V4L2, getSetting(settings::V4L2));
_hyperion->setComponentState(hyperion::COMP_V4L, grabberConfig["v4lEnable"].toBool(true));
// ---- network services ----- // ---- network services -----
startNetworkServices(); startNetworkServices();
} }
@ -162,10 +169,10 @@ void HyperionDaemon::freeObjects()
delete _fbGrabber; delete _fbGrabber;
delete _osxGrabber; delete _osxGrabber;
delete _qtGrabber; delete _qtGrabber;
delete _v4l2Grabbers; delete _v4l2Grabber;
delete _stats; delete _stats;
_v4l2Grabbers = nullptr; _v4l2Grabber = nullptr;
_bonjourBrowserWrapper = nullptr; _bonjourBrowserWrapper = nullptr;
_amlGrabber = nullptr; _amlGrabber = nullptr;
_dispmanx = nullptr; _dispmanx = nullptr;
@ -384,24 +391,27 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJso
{ {
#ifdef ENABLE_V4L2 #ifdef ENABLE_V4L2
if(_v4l2Grabber != nullptr)
return;
const QJsonObject & grabberConfig = config.object(); const QJsonObject & grabberConfig = config.object();
V4L2Wrapper* grabber = new V4L2Wrapper( _v4l2Grabber = new V4L2Wrapper(
grabberConfig["device"].toString("auto"), grabberConfig["device"].toString("auto"),
parseVideoStandard(grabberConfig["standard"].toString("no-change")), parseVideoStandard(grabberConfig["standard"].toString("no-change")),
parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")), parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")),
grabberConfig["sizeDecimation"].toInt(8) ); grabberConfig["sizeDecimation"].toInt(8) );
grabber->setSignalThreshold( _v4l2Grabber->setSignalThreshold(
grabberConfig["redSignalThreshold"].toDouble(0.0)/100.0, grabberConfig["redSignalThreshold"].toDouble(0.0)/100.0,
grabberConfig["greenSignalThreshold"].toDouble(0.0)/100.0, grabberConfig["greenSignalThreshold"].toDouble(0.0)/100.0,
grabberConfig["blueSignalThreshold"].toDouble(0.0)/100.0); grabberConfig["blueSignalThreshold"].toDouble(0.0)/100.0);
grabber->setCropping( _v4l2Grabber->setCropping(
grabberConfig["cropLeft"].toInt(0), grabberConfig["cropLeft"].toInt(0),
grabberConfig["cropRight"].toInt(0), grabberConfig["cropRight"].toInt(0),
grabberConfig["cropTop"].toInt(0), grabberConfig["cropTop"].toInt(0),
grabberConfig["cropBottom"].toInt(0)); grabberConfig["cropBottom"].toInt(0));
grabber->setSignalDetectionEnable(grabberConfig["signalDetection"].toBool(true)); _v4l2Grabber->setSignalDetectionEnable(grabberConfig["signalDetection"].toBool(true));
grabber->setSignalDetectionOffset( _v4l2Grabber->setSignalDetectionOffset(
grabberConfig["sDHOffsetMin"].toDouble(0.25), grabberConfig["sDHOffsetMin"].toDouble(0.25),
grabberConfig["sDVOffsetMin"].toDouble(0.25), grabberConfig["sDVOffsetMin"].toDouble(0.25),
grabberConfig["sDHOffsetMax"].toDouble(0.75), grabberConfig["sDHOffsetMax"].toDouble(0.75),
@ -409,8 +419,8 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJso
Debug(_log, "V4L2 grabber created"); Debug(_log, "V4L2 grabber created");
// connect to HyperionDaemon signal // connect to HyperionDaemon signal
connect(this, &HyperionDaemon::videoMode, grabber, &V4L2Wrapper::setVideoMode); connect(this, &HyperionDaemon::videoMode, _v4l2Grabber, &V4L2Wrapper::setVideoMode);
connect(this, &HyperionDaemon::settingsChanged, grabber, &V4L2Wrapper::handleSettingsUpdate); connect(this, &HyperionDaemon::settingsChanged, _v4l2Grabber, &V4L2Wrapper::handleSettingsUpdate);
#else #else
Error(_log, "The v4l2 grabber can not be instantiated, because it has been left out from the build"); Error(_log, "The v4l2 grabber can not be instantiated, because it has been left out from the build");
#endif #endif

View File

@ -137,7 +137,7 @@ private:
WebServer* _webserver; WebServer* _webserver;
JsonServer* _jsonServer; JsonServer* _jsonServer;
UDPListener* _udpListener; UDPListener* _udpListener;
V4L2Wrapper* _v4l2Grabbers; V4L2Wrapper* _v4l2Grabber;
DispmanxWrapper* _dispmanx; DispmanxWrapper* _dispmanx;
X11Wrapper* _x11Grabber; X11Wrapper* _x11Grabber;
AmlogicWrapper* _amlGrabber; AmlogicWrapper* _amlGrabber;