diff --git a/CHANGELOG.md b/CHANGELOG.md index 2975135d..fdcab2b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Decrease compile time (#886) - Fix some data synchronization error (#890) - Fix Qt screenhot crash (#889) +- Fix crash on startup if no X server available (#892) - Fix RPC restart of Hyperion (#894) ### Removed diff --git a/include/grabber/V4L2Wrapper.h b/include/grabber/V4L2Wrapper.h index 8089ff3c..ff3f5f90 100644 --- a/include/grabber/V4L2Wrapper.h +++ b/include/grabber/V4L2Wrapper.h @@ -32,6 +32,7 @@ public slots: void setCecDetectionEnable(bool enable); void setDeviceVideoStandard(QString device, VideoStandard videoStandard); void handleCecEvent(CECEvent event); + void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) override; private slots: void newFrame(const Image & image); diff --git a/include/hyperion/GrabberWrapper.h b/include/hyperion/GrabberWrapper.h index aea9e135..d190a997 100644 --- a/include/hyperion/GrabberWrapper.h +++ b/include/hyperion/GrabberWrapper.h @@ -51,6 +51,11 @@ public: /// virtual void stop(); + /// + /// Check if grabber is active + /// + virtual bool isActive() const; + /// /// @brief Get a list of all available V4L devices /// @return List of all available V4L devices on success else empty List @@ -146,6 +151,12 @@ private slots: /// Will start and stop grabber based on active listeners count void handleSourceRequest(const hyperion::Components& component, const int hyperionInd, const bool listen); + /// + /// @brief Update Update capture rate + /// @param type interval between frames in millisecons + /// + void updateTimer(int interval); + protected: QString _grabberName; diff --git a/libsrc/grabber/v4l2/V4L2Wrapper.cpp b/libsrc/grabber/v4l2/V4L2Wrapper.cpp index db0e24b5..730e44c3 100644 --- a/libsrc/grabber/v4l2/V4L2Wrapper.cpp +++ b/libsrc/grabber/v4l2/V4L2Wrapper.cpp @@ -109,3 +109,48 @@ void V4L2Wrapper::handleCecEvent(CECEvent event) { _grabber.handleCecEvent(event); } + +void V4L2Wrapper::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) +{ + if(type == settings::V4L2 && _grabberName.startsWith("V4L")) + { + // extract settings + const QJsonObject& obj = config.object(); + + // pixel decimation for v4l + _grabber.setPixelDecimation(obj["sizeDecimation"].toInt(8)); + + // crop for v4l + _grabber.setCropping( + obj["cropLeft"].toInt(0), + obj["cropRight"].toInt(0), + obj["cropTop"].toInt(0), + obj["cropBottom"].toInt(0)); + + // device input + _grabber.setInput(obj["input"].toInt(-1)); + + // device resolution + _grabber.setWidthHeight(obj["width"].toInt(0), obj["height"].toInt(0)); + + // device framerate + _grabber.setFramerate(obj["fps"].toInt(15)); + + // CEC Standby + _grabber.setCecDetectionEnable(obj["cecDetection"].toBool(true)); + + _grabber.setSignalDetectionEnable(obj["signalDetection"].toBool(true)); + _grabber.setSignalDetectionOffset( + obj["sDHOffsetMin"].toDouble(0.25), + obj["sDVOffsetMin"].toDouble(0.25), + obj["sDHOffsetMax"].toDouble(0.75), + obj["sDVOffsetMax"].toDouble(0.75)); + _grabber.setSignalThreshold( + obj["redSignalThreshold"].toDouble(0.0)/100.0, + obj["greenSignalThreshold"].toDouble(0.0)/100.0, + obj["blueSignalThreshold"].toDouble(0.0)/100.0); + _grabber.setDeviceVideoStandard( + obj["device"].toString("auto"), + parseVideoStandard(obj["standard"].toString("no-change"))); + } +} diff --git a/libsrc/grabber/x11/X11Wrapper.cpp b/libsrc/grabber/x11/X11Wrapper.cpp index 91f2f8f7..eb89b358 100644 --- a/libsrc/grabber/x11/X11Wrapper.cpp +++ b/libsrc/grabber/x11/X11Wrapper.cpp @@ -25,8 +25,11 @@ void X11Wrapper::action() } } - if (_grabber.updateScreenDimensions() >= 0 ) + if (isActive()) { - transferFrame(_grabber); + if (_grabber.updateScreenDimensions() >= 0 ) + { + transferFrame(_grabber); + } } } diff --git a/libsrc/hyperion/GrabberWrapper.cpp b/libsrc/hyperion/GrabberWrapper.cpp index fb7f2a43..aa1bd106 100644 --- a/libsrc/hyperion/GrabberWrapper.cpp +++ b/libsrc/hyperion/GrabberWrapper.cpp @@ -61,6 +61,11 @@ void GrabberWrapper::stop() } } +bool GrabberWrapper::isActive() const +{ + return _timer->isActive(); +} + QStringList GrabberWrapper::availableGrabbers() { QStringList grabbers; @@ -110,85 +115,49 @@ void GrabberWrapper::setCropping(unsigned cropLeft, unsigned cropRight, unsigned _ggrabber->setCropping(cropLeft, cropRight, cropTop, cropBottom); } +void GrabberWrapper::updateTimer(int interval) +{ + if(_updateInterval_ms != interval) + { + _updateInterval_ms = interval; + + const bool& timerWasActive = _timer->isActive(); + _timer->stop(); + _timer->setInterval(_updateInterval_ms); + + if(timerWasActive) + _timer->start(); + } +} + void GrabberWrapper::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) { - if(type == settings::V4L2 || type == settings::SYSTEMCAPTURE) + if(type == settings::SYSTEMCAPTURE && !_grabberName.startsWith("V4L")) { // extract settings const QJsonObject& obj = config.object(); - if(type == settings::SYSTEMCAPTURE && !_grabberName.startsWith("V4L")) - { - // width/height - _ggrabber->setWidthHeight(obj["width"].toInt(96), obj["height"].toInt(96)); + // width/height + _ggrabber->setWidthHeight(obj["width"].toInt(96), obj["height"].toInt(96)); - // display index for MAC - _ggrabber->setDisplayIndex(obj["display"].toInt(0)); + // display index for MAC + _ggrabber->setDisplayIndex(obj["display"].toInt(0)); - // device path for Framebuffer - _ggrabber->setDevicePath(obj["device"].toString("/dev/fb0")); + // device path for Framebuffer + _ggrabber->setDevicePath(obj["device"].toString("/dev/fb0")); - // pixel decimation for x11 - _ggrabber->setPixelDecimation(obj["pixelDecimation"].toInt(8)); + // pixel decimation for x11 + _ggrabber->setPixelDecimation(obj["pixelDecimation"].toInt(8)); - // crop for system capture - _ggrabber->setCropping( - obj["cropLeft"].toInt(0), - obj["cropRight"].toInt(0), - obj["cropTop"].toInt(0), - obj["cropBottom"].toInt(0)); + // crop for system capture + _ggrabber->setCropping( + obj["cropLeft"].toInt(0), + obj["cropRight"].toInt(0), + obj["cropTop"].toInt(0), + obj["cropBottom"].toInt(0)); - // eval new update timer (not for v4l) - if(_updateInterval_ms != 1000/obj["frequency_Hz"].toInt(10)) - { - _updateInterval_ms = 1000/obj["frequency_Hz"].toInt(10); - const bool& timerWasActive = _timer->isActive(); - _timer->stop(); - _timer->setInterval(_updateInterval_ms); - if(timerWasActive) - _timer->start(); - } - } - - // v4l instances only! - if(type == settings::V4L2 && _grabberName.startsWith("V4L")) - { - // pixel decimation for v4l - _ggrabber->setPixelDecimation(obj["sizeDecimation"].toInt(8)); - - // crop for v4l - _ggrabber->setCropping( - obj["cropLeft"].toInt(0), - obj["cropRight"].toInt(0), - obj["cropTop"].toInt(0), - obj["cropBottom"].toInt(0)); - - // device input - _ggrabber->setInput(obj["input"].toInt(-1)); - - // device resolution - _ggrabber->setWidthHeight(obj["width"].toInt(0), obj["height"].toInt(0)); - - // device framerate - _ggrabber->setFramerate(obj["fps"].toInt(15)); - - // CEC Standby - _ggrabber->setCecDetectionEnable(obj["cecDetection"].toBool(true)); - - _ggrabber->setSignalDetectionEnable(obj["signalDetection"].toBool(true)); - _ggrabber->setSignalDetectionOffset( - obj["sDHOffsetMin"].toDouble(0.25), - obj["sDVOffsetMin"].toDouble(0.25), - obj["sDHOffsetMax"].toDouble(0.75), - obj["sDVOffsetMax"].toDouble(0.75)); - _ggrabber->setSignalThreshold( - obj["redSignalThreshold"].toDouble(0.0)/100.0, - obj["greenSignalThreshold"].toDouble(0.0)/100.0, - obj["blueSignalThreshold"].toDouble(0.0)/100.0); - _ggrabber->setDeviceVideoStandard( - obj["device"].toString("auto"), - parseVideoStandard(obj["standard"].toString("no-change"))); - } + // eval new update time + updateTimer(1000/obj["frequency_Hz"].toInt(10)); } } diff --git a/libsrc/utils/Logger.cpp b/libsrc/utils/Logger.cpp index ef3d5507..013a4b39 100644 --- a/libsrc/utils/Logger.cpp +++ b/libsrc/utils/Logger.cpp @@ -128,12 +128,13 @@ Logger::Logger (const QString & name, LogLevel minLevel) { qRegisterMetaType(); - int count = LoggerCount.fetchAndAddOrdered(1); - - if (_syslogEnabled && count == 1) + if (LoggerCount.fetchAndAddOrdered(1) == 1) { #ifndef _WIN32 - openlog (_appname.toLocal8Bit(), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0); + if (_syslogEnabled) + { + openlog (_appname.toLocal8Bit(), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0); + } #endif } } @@ -142,11 +143,16 @@ Logger::~Logger() { //Debug(this, "logger '%s' destroyed", QSTRING_CSTR(_name) ); - int count = LoggerCount.fetchAndSubOrdered(1); + + if (LoggerCount.fetchAndSubOrdered(1) == 0) + { #ifndef _WIN32 - if (_syslogEnabled && count == 0) - closelog(); + if (_syslogEnabled) + { + closelog(); + } #endif + } } void Logger::write(const Logger::T_LOG_MESSAGE & message) const