diff --git a/.travis/travis_build.sh b/.travis/travis_build.sh index 0f1a4d6b..e5f514eb 100755 --- a/.travis/travis_build.sh +++ b/.travis/travis_build.sh @@ -10,8 +10,8 @@ # compile hyperion on osx if [[ $TRAVIS_OS_NAME == 'osx' ]] then - procs=$(sysctl -n hw.ncpu | xargs) - echo "Processes: $procs" + procs=$(sysctl -n hw.ncpu | xargs) + echo "Processes: $procs" mkdir build || exit 1 cd build diff --git a/PULL_REQUEST_TEMPLATE b/PULL_REQUEST_TEMPLATE index a8e72756..5eb1f655 100644 --- a/PULL_REQUEST_TEMPLATE +++ b/PULL_REQUEST_TEMPLATE @@ -3,7 +3,7 @@ **2.** If this changes affect the .conf file. Please provide the changed section -**3.** Reference a issue (optional) +**3.** Reference an issue (optional) Note: For further discussions use our forum: forum.hyperion-project.org diff --git a/include/boblightserver/BoblightServer.h b/include/boblightserver/BoblightServer.h index 9e6ff9e1..647f889f 100644 --- a/include/boblightserver/BoblightServer.h +++ b/include/boblightserver/BoblightServer.h @@ -10,6 +10,7 @@ // Hyperion includes #include #include +#include class BoblightClientConnection; @@ -37,7 +38,8 @@ public: /// @return true if server is active (bind to a port) /// bool active() { return _isActive; }; - + bool componentState() { return active(); }; + public slots: /// /// bind server to network @@ -49,6 +51,8 @@ public slots: /// void stop(); + void componentStateChanged(const hyperion::Components component, bool enable); + signals: void statusChanged(bool isActive); diff --git a/include/grabber/AmlogicWrapper.h b/include/grabber/AmlogicWrapper.h index da10a5f0..56821604 100644 --- a/include/grabber/AmlogicWrapper.h +++ b/include/grabber/AmlogicWrapper.h @@ -1,15 +1,12 @@ #pragma once -// QT includes -#include -#include - // Utils includes #include #include #include #include #include +#include // Forward class declaration class AmlogicGrabber; @@ -21,7 +18,7 @@ class ImageProcessor; /// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the /// attached Hyperion. /// -class AmlogicWrapper : public QObject +class AmlogicWrapper : public GrabberWrapper { Q_OBJECT public: @@ -41,20 +38,10 @@ public: virtual ~AmlogicWrapper(); public slots: - /// - /// Starts the grabber wich produces led values with the specified update rate - /// - void start(); - /// /// Performs a single frame grab and computes the led-colors /// - void action(); - - /// - /// Stops the grabber - /// - void stop(); + virtual void action(); /// /// Set the grabbing mode @@ -68,33 +55,17 @@ public slots: /// void setVideoMode(const VideoMode videoMode); -signals: - void emitImage(int priority, const Image & image, const int timeout_ms); - private: /// The update rate [Hz] const int _updateInterval_ms; /// The timeout of the led colors [ms] const int _timeout_ms; - /// The priority of the led colors - const int _priority; - - /// The timer for generating events with the specified update rate - QTimer _timer; /// The image used for grabbing frames Image _image; /// The actual grabber - AmlogicGrabber * _frameGrabber; - /// The processor for transforming images to led colors - ImageProcessor * _processor; + AmlogicGrabber * _grabber; /// The list with computed led colors std::vector _ledColors; - - /// Pointer to Hyperion for writing led values - Hyperion * _hyperion; - - // forwarding enabled - bool _forward; }; diff --git a/include/grabber/DispmanxWrapper.h b/include/grabber/DispmanxWrapper.h index 75dbcd24..329f35b6 100644 --- a/include/grabber/DispmanxWrapper.h +++ b/include/grabber/DispmanxWrapper.h @@ -1,19 +1,15 @@ #pragma once -// QT includes -#include -#include - // Utils includes #include #include #include #include #include +#include // Forward class declaration class DispmanxFrameGrabber; -class Hyperion; class ImageProcessor; /// @@ -21,7 +17,7 @@ class ImageProcessor; /// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the /// attached Hyperion. /// -class DispmanxWrapper: public QObject +class DispmanxWrapper: public GrabberWrapper { Q_OBJECT public: @@ -41,20 +37,10 @@ public: virtual ~DispmanxWrapper(); public slots: - /// - /// Starts the grabber wich produces led values with the specified update rate - /// - void start(); - /// /// Performs a single frame grab and computes the led-colors /// - void action(); - - /// - /// Stops the grabber - /// - void stop(); + virtual void action(); void setCropping(const unsigned cropLeft, const unsigned cropRight, const unsigned cropTop, const unsigned cropBottom); @@ -71,9 +57,6 @@ public slots: /// void setVideoMode(const VideoMode videoMode); -signals: - void emitImage(int priority, const Image & image, const int timeout_ms); - private: /// The update rate [Hz] const int _updateInterval_ms; @@ -82,22 +65,11 @@ private: /// The priority of the led colors const int _priority; - /// The timer for generating events with the specified update rate - QTimer _timer; - /// The image used for grabbing frames Image _image; /// The actual grabber - DispmanxFrameGrabber * _frameGrabber; - /// The processor for transforming images to led colors - ImageProcessor * _processor; + DispmanxFrameGrabber * _grabber; /// The list with computed led colors std::vector _ledColors; - - /// Pointer to Hyperion for writing led values - Hyperion * _hyperion; - - // forwarding enabled - bool _forward; }; diff --git a/include/grabber/FramebufferWrapper.h b/include/grabber/FramebufferWrapper.h index 3faeb521..0e388d09 100644 --- a/include/grabber/FramebufferWrapper.h +++ b/include/grabber/FramebufferWrapper.h @@ -1,18 +1,14 @@ #pragma once -// QT includes -#include -#include - // Utils includes #include #include #include #include +#include // Forward class declaration class FramebufferFrameGrabber; -class Hyperion; class ImageProcessor; /// @@ -20,7 +16,7 @@ class ImageProcessor; /// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the /// attached Hyperion. /// -class FramebufferWrapper: public QObject +class FramebufferWrapper: public GrabberWrapper { Q_OBJECT public: @@ -40,20 +36,10 @@ public: virtual ~FramebufferWrapper(); public slots: - /// - /// Starts the grabber wich produces led values with the specified update rate - /// - void start(); - /// /// Performs a single frame grab and computes the led-colors /// - void action(); - - /// - /// Stops the grabber - /// - void stop(); + virtual void action(); /// /// Set the grabbing mode @@ -67,30 +53,17 @@ public slots: /// void setVideoMode(const VideoMode videoMode); -signals: - void emitImage(int priority, const Image & image, const int timeout_ms); - private: /// The update rate [Hz] const int _updateInterval_ms; /// The timeout of the led colors [ms] const int _timeout_ms; - /// The priority of the led colors - const int _priority; - - /// The timer for generating events with the specified update rate - QTimer _timer; /// The image used for grabbing frames Image _image; /// The actual grabber - FramebufferFrameGrabber * _frameGrabber; - /// The processor for transforming images to led colors - ImageProcessor * _processor; + FramebufferFrameGrabber * _grabber; /// The list with computed led colors std::vector _ledColors; - - /// Pointer to Hyperion for writing led values - Hyperion * _hyperion; }; diff --git a/include/grabber/OsxWrapper.h b/include/grabber/OsxWrapper.h index bb902abd..007a8579 100644 --- a/include/grabber/OsxWrapper.h +++ b/include/grabber/OsxWrapper.h @@ -1,19 +1,15 @@ #pragma once -// QT includes -#include -#include - // Utils includes #include #include #include #include #include +#include // Forward class declaration class OsxFrameGrabber; -class Hyperion; class ImageProcessor; /// @@ -21,7 +17,7 @@ class ImageProcessor; /// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the /// attached Hyperion. /// -class OsxWrapper: public QObject +class OsxWrapper: public GrabberWrapper { Q_OBJECT public: @@ -42,20 +38,10 @@ public: virtual ~OsxWrapper(); public slots: - /// - /// Starts the grabber wich produces led values with the specified update rate - /// - void start(); - /// /// Performs a single frame grab and computes the led-colors /// - void action(); - - /// - /// Stops the grabber - /// - void stop(); + virtual void action(); /// /// Set the grabbing mode @@ -69,30 +55,17 @@ public slots: /// void setVideoMode(const VideoMode videoMode); -signals: - void emitImage(int priority, const Image & image, const int timeout_ms); - private: /// The update rate [Hz] const int _updateInterval_ms; /// The timeout of the led colors [ms] const int _timeout_ms; - /// The priority of the led colors - const int _priority; - - /// The timer for generating events with the specified update rate - QTimer _timer; /// The image used for grabbing frames Image _image; /// The actual grabber - OsxFrameGrabber * _frameGrabber; - /// The processor for transforming images to led colors - ImageProcessor * _processor; + OsxFrameGrabber * _grabber; /// The list with computed led colors std::vector _ledColors; - - /// Pointer to Hyperion for writing led values - Hyperion * _hyperion; }; diff --git a/include/grabber/V4L2Wrapper.h b/include/grabber/V4L2Wrapper.h index 9911ceab..dde90edd 100644 --- a/include/grabber/V4L2Wrapper.h +++ b/include/grabber/V4L2Wrapper.h @@ -1,16 +1,14 @@ #pragma once -// Qt includes -#include - // Hyperion includes #include #include +#include // Grabber includes #include -class V4L2Wrapper : public QObject +class V4L2Wrapper : public GrabberWrapper { Q_OBJECT @@ -26,7 +24,7 @@ public: double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, - int hyperionPriority); + const int priority); virtual ~V4L2Wrapper(); public slots: @@ -41,34 +39,22 @@ public slots: void set3D(VideoMode mode); -signals: - void emitColors(int priority, const std::vector &ledColors, const int timeout_ms); - void emitImage(int priority, const Image & image, const int timeout_ms); +// signals: +// void emitColors(int priority, const std::vector &ledColors, const int timeout_ms); private slots: void newFrame(const Image & image); + virtual void action(); void checkSources(); private: /// The timeout of the led colors [ms] const int _timeout_ms; - /// The priority of the led colors - const int _priority; - /// The V4L2 grabber V4L2Grabber _grabber; - /// The processor for transforming images to led colors - ImageProcessor * _processor; - - /// The Hyperion instance - Hyperion * _hyperion; - /// The list with computed led colors std::vector _ledColors; - - /// Timer which tests if a higher priority source is active - QTimer _timer; }; diff --git a/include/grabber/X11Wrapper.h b/include/grabber/X11Wrapper.h index fcc52da3..9120712e 100644 --- a/include/grabber/X11Wrapper.h +++ b/include/grabber/X11Wrapper.h @@ -1,18 +1,14 @@ #pragma once -// QT includes -#include -#include - // Utils includes #include #include #include #include +#include // Forward class declaration class X11Grabber; -class Hyperion; class ImageProcessor; /// @@ -20,7 +16,7 @@ class ImageProcessor; /// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the /// attached Hyperion. /// -class X11Wrapper: public QObject +class X11Wrapper: public GrabberWrapper { Q_OBJECT public: @@ -43,17 +39,12 @@ public slots: /// /// Starts the grabber wich produces led values with the specified update rate /// - void start(); + bool start(); /// /// Performs a single frame grab and computes the led-colors /// - void action(); - - /// - /// Stops the grabber - /// - void stop(); + virtual void action(); /// /// Set the grabbing mode @@ -67,33 +58,22 @@ public slots: /// void setVideoMode(const VideoMode videoMode); -signals: - void emitImage(int priority, const Image & image, const int timeout_ms); - private: /// The update rate [Hz] const int _updateInterval_ms; /// The timeout of the led colors [ms] const int _timeout_ms; - /// The priority of the led colors - const int _priority; - - /// The timer for generating events with the specified update rate - QTimer _timer; /// The image used for grabbing frames Image _image; + /// The actual grabber X11Grabber * _grabber; - /// The processor for transforming images to led colors - ImageProcessor * _processor; /// The list with computed led colors std::vector _ledColors; - /// Pointer to Hyperion for writing led values - Hyperion * _hyperion; - + bool _init; bool _x11SetupSuccess; }; diff --git a/include/hyperion/GrabberWrapper.h b/include/hyperion/GrabberWrapper.h new file mode 100644 index 00000000..463047a8 --- /dev/null +++ b/include/hyperion/GrabberWrapper.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include + +class ImageProcessor; + +class GrabberWrapper : public QObject +{ + Q_OBJECT +public: + GrabberWrapper(std::string grabberName, const int priority); + + virtual ~GrabberWrapper(); + + virtual bool start(); + virtual void stop(); + +public slots: + void componentStateChanged(const hyperion::Components component, bool enable); + virtual void action() = 0; + +signals: + void emitImage(int priority, const Image & image, const int timeout_ms); + +protected: + std::string _grabberName; + + /// Pointer to Hyperion for writing led values + Hyperion * _hyperion; + + /// The priority of the led colors + const int _priority; + + /// The timer for generating events with the specified update rate + QTimer _timer; + + /// The Logger instance + Logger * _log; + + // forwarding enabled + bool _forward; + + /// The processor for transforming images to led colors + ImageProcessor * _processor; + +}; diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h index 53c013ce..8dcfbf7f 100644 --- a/include/hyperion/Hyperion.h +++ b/include/hyperion/Hyperion.h @@ -156,7 +156,7 @@ public: /// @param component The component [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER] /// @param state The state of the component [true | false] /// - void setComponentState(const Components component, const bool state); + void setComponentState(const hyperion::Components component, const bool state); public slots: /// /// Writes a single color to all the leds for the given time and priority @@ -294,6 +294,8 @@ signals: /// This signal will not be emitted when a priority channel time out void allChannelsCleared(); + void componentStateChanged(const hyperion::Components component, bool enabled); + private slots: /// /// Updates the priority muxer with the current time and (re)writes the led color with applied diff --git a/include/hyperion/ImageProcessor.h b/include/hyperion/ImageProcessor.h index 102f806f..f5b709f1 100644 --- a/include/hyperion/ImageProcessor.h +++ b/include/hyperion/ImageProcessor.h @@ -41,6 +41,9 @@ public: /// Enable or disable the black border detector void enableBlackBorderDetector(bool enable); + /// Returns starte of black border detector + bool blackBorderDetectorEnabled(); + /// /// Processes the image to a list of led colors. This will update the size of the buffer-image /// if required and call the image-to-leds mapping to determine the mean color per led. @@ -104,7 +107,6 @@ private: /// given led-string specification /// /// @param[in] ledString The led-string specification - /// @param[in] enableBlackBorderDetector Flag indicating if the blacborder detector should be enabled /// @param[in] blackborderThreshold The threshold which the blackborder detector should use /// ImageProcessor(const LedString &ledString, const Json::Value &blackborderConfig); diff --git a/include/kodivideochecker/KODIVideoChecker.h b/include/kodivideochecker/KODIVideoChecker.h index 72f54e90..c8ef8d38 100644 --- a/include/kodivideochecker/KODIVideoChecker.h +++ b/include/kodivideochecker/KODIVideoChecker.h @@ -18,6 +18,7 @@ #include #include #include +#include /// /// This class will check if KODI is playing something. When it does not, this class will send all black data to Hyperion. @@ -36,6 +37,8 @@ public: ~KODIVideoChecker(); void setConfig(const QString & address, uint16_t port, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu, bool grabPause, bool grabScreensaver, bool enable3DDetection); + bool componentState() { return _active; } + public slots: /// /// Start polling KODI @@ -47,6 +50,8 @@ public slots: /// void stop(); + void componentStateChanged(const hyperion::Components component, bool enable); + signals: /// Signal emitted when the grabbing mode changes void grabbingMode(GrabbingMode grabbingMode); diff --git a/include/protoserver/ProtoServer.h b/include/protoserver/ProtoServer.h index c6b35968..e17244b3 100644 --- a/include/protoserver/ProtoServer.h +++ b/include/protoserver/ProtoServer.h @@ -52,6 +52,7 @@ public: public slots: void sendImageToProtoSlaves(int priority, const Image & image, int duration_ms); + void componentStateChanged(const hyperion::Components component, bool enable); signals: /// @@ -87,6 +88,10 @@ private: /// Hyperion proto connection object for forwarding QList _proxy_connections; - + + /// Logger instance Logger * _log; + + /// flag if forwarder is enabled + bool _forwarder_enabled; }; diff --git a/include/udplistener/UDPListener.h b/include/udplistener/UDPListener.h index 8d061dca..6fdec310 100644 --- a/include/udplistener/UDPListener.h +++ b/include/udplistener/UDPListener.h @@ -11,6 +11,7 @@ // Hyperion includes #include #include +#include class UDPClientConnection; @@ -39,6 +40,7 @@ public: /// @return true if server is active (bind to a port) /// bool active() { return _isActive; }; + bool componentState() { return active(); }; public slots: /// @@ -51,6 +53,8 @@ public slots: /// void stop(); + void componentStateChanged(const hyperion::Components component, bool enable); + signals: void statusChanged(bool isActive); diff --git a/include/utils/Components.h b/include/utils/Components.h index 900b971a..b865d249 100644 --- a/include/utils/Components.h +++ b/include/utils/Components.h @@ -1,30 +1,50 @@ #pragma once +#include +namespace hyperion +{ /** * Enumeration of components in Hyperion. */ enum Components { - SMOOTHING, - BLACKBORDER, - KODICHECKER, - FORWARDER, - UDPLISTENER, - BOBLIGHTSERVER, - GRABBER + COMP_INVALID, + COMP_SMOOTHING, + COMP_BLACKBORDER, + COMP_KODICHECKER, + COMP_FORWARDER, + COMP_UDPLISTENER, + COMP_BOBLIGHTSERVER, + COMP_GRABBER }; inline const char* componentToString(Components c) { switch (c) { - case SMOOTHING: return "Smoothing option"; - case BLACKBORDER: return "Blackborder detector"; - case KODICHECKER: return "KodiVideoChecker"; - case FORWARDER: return "Json/Proto forwarder"; - case UDPLISTENER: return "UDP listener"; - case BOBLIGHTSERVER: return "Boblight server"; - case GRABBER: return "Framegrabber"; - default: return ""; + case COMP_SMOOTHING: return "Smoothing"; + case COMP_BLACKBORDER: return "Blackborder detector"; + case COMP_KODICHECKER: return "KodiVideoChecker"; + case COMP_FORWARDER: return "Json/Proto forwarder"; + case COMP_UDPLISTENER: return "UDP listener"; + case COMP_BOBLIGHTSERVER:return "Boblight server"; + case COMP_GRABBER: return "Framegrabber"; + default: return ""; } -} \ No newline at end of file +} + +inline Components stringToComponent(QString component) +{ + component = component.toUpper(); + if (component == "SMOOTHING") return COMP_SMOOTHING; + if (component == "BLACKBORDER") return COMP_BLACKBORDER; + if (component == "KODICHECKER") return COMP_KODICHECKER; + if (component == "FORWARDER") return COMP_FORWARDER; + if (component == "UDPLISTENER") return COMP_UDPLISTENER; + if (component == "BOBLIGHTSERVER")return COMP_BOBLIGHTSERVER; + if (component == "GRABBER") return COMP_GRABBER; + + return COMP_INVALID; +} + +} diff --git a/libsrc/boblightserver/BoblightServer.cpp b/libsrc/boblightserver/BoblightServer.cpp index a8176bf2..e6b81d94 100644 --- a/libsrc/boblightserver/BoblightServer.cpp +++ b/libsrc/boblightserver/BoblightServer.cpp @@ -5,6 +5,8 @@ #include #include "BoblightClientConnection.h" +using namespace hyperion; + BoblightServer::BoblightServer(const int priority, uint16_t port) : QObject() , _hyperion(Hyperion::getInstance()) @@ -50,6 +52,7 @@ void BoblightServer::stop() foreach (BoblightClientConnection * connection, _openConnections) { delete connection; } + _server.close(); _isActive = false; emit statusChanged(_isActive); @@ -57,6 +60,15 @@ void BoblightServer::stop() } +void BoblightServer::componentStateChanged(const hyperion::Components component, bool enable) +{ + if (component == COMP_BOBLIGHTSERVER && _isActive != enable) + { + if (enable) start(); + else stop(); + Info(_log, "change state to %s", (enable ? "enabled" : "disabled") ); + } +} uint16_t BoblightServer::getPort() const { diff --git a/libsrc/grabber/amlogic/AmlogicWrapper.cpp b/libsrc/grabber/amlogic/AmlogicWrapper.cpp index 9c000c40..1ab0c256 100644 --- a/libsrc/grabber/amlogic/AmlogicWrapper.cpp +++ b/libsrc/grabber/amlogic/AmlogicWrapper.cpp @@ -12,45 +12,28 @@ AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority) - : _updateInterval_ms(1000/updateRate_Hz) + : GrabberWrapper("AmLogic", priority) + , _updateInterval_ms(1000/updateRate_Hz) , _timeout_ms(2 * _updateInterval_ms) - , _priority(priority) - , _timer() , _image(grabWidth, grabHeight) - , _frameGrabber(new AmlogicGrabber(grabWidth, grabHeight)) - , _processor(ImageProcessorFactory::getInstance().newImageProcessor()) + , _grabber(new AmlogicGrabber(grabWidth, grabHeight)) , _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0}) - , _hyperion(Hyperion::getInstance()) { // Configure the timer to generate events every n milliseconds _timer.setInterval(_updateInterval_ms); - _timer.setSingleShot(false); - _forward = _hyperion->getForwarder()->protoForwardingEnabled(); _processor->setSize(grabWidth, grabHeight); - - // Connect the QTimer to this - QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(action())); } AmlogicWrapper::~AmlogicWrapper() { - // Cleanup used resources (ImageProcessor and FrameGrabber) - delete _processor; - delete _frameGrabber; -} - -void AmlogicWrapper::start() -{ - // Start the timer with the pre configured interval - _timer.start(); - _hyperion->registerPriority("Amlogic Grabber",_priority); + delete _grabber; } void AmlogicWrapper::action() { // Grab frame into the allocated image - if (_frameGrabber->grabFrame(_image) < 0) + if (_grabber->grabFrame(_image) < 0) { // Frame grab failed, maybe nothing playing or .... return; @@ -67,21 +50,13 @@ void AmlogicWrapper::action() _hyperion->setColors(_priority, _ledColors, _timeout_ms); } -void AmlogicWrapper::stop() -{ - // Stop the timer, effectivly stopping the process - _timer.stop(); - _hyperion->unRegisterPriority("Amlogic Grabber"); - -} - void AmlogicWrapper::setGrabbingMode(const GrabbingMode mode) { switch (mode) { case GRABBINGMODE_VIDEO: case GRABBINGMODE_PAUSE: -// _frameGrabber->setFlags(DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL); +// _grabber->setFlags(DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL); start(); break; case GRABBINGMODE_AUDIO: @@ -89,7 +64,7 @@ void AmlogicWrapper::setGrabbingMode(const GrabbingMode mode) case GRABBINGMODE_MENU: case GRABBINGMODE_SCREENSAVER: case GRABBINGMODE_INVALID: -// _frameGrabber->setFlags(0); +// _grabber->setFlags(0); start(); break; case GRABBINGMODE_OFF: @@ -100,5 +75,5 @@ void AmlogicWrapper::setGrabbingMode(const GrabbingMode mode) void AmlogicWrapper::setVideoMode(const VideoMode mode) { - _frameGrabber->setVideoMode(mode); + _grabber->setVideoMode(mode); } diff --git a/libsrc/grabber/dispmanx/DispmanxWrapper.cpp b/libsrc/grabber/dispmanx/DispmanxWrapper.cpp index 5ab45534..65583ab7 100644 --- a/libsrc/grabber/dispmanx/DispmanxWrapper.cpp +++ b/libsrc/grabber/dispmanx/DispmanxWrapper.cpp @@ -11,46 +11,29 @@ #include -DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority) : - _updateInterval_ms(1000/updateRate_Hz), - _timeout_ms(2 * _updateInterval_ms), - _priority(priority), - _timer(), - _image(grabWidth, grabHeight), - _frameGrabber(new DispmanxFrameGrabber(grabWidth, grabHeight)), - _processor(ImageProcessorFactory::getInstance().newImageProcessor()), - _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0}), - _hyperion(Hyperion::getInstance()) +DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority) + : GrabberWrapper("Dispmanx", priority) + , _updateInterval_ms(1000/updateRate_Hz) + , _timeout_ms(2 * _updateInterval_ms) + , _image(grabWidth, grabHeight) + , _grabber(new DispmanxFrameGrabber(grabWidth, grabHeight)) + , _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0}) { // Configure the timer to generate events every n milliseconds _timer.setInterval(_updateInterval_ms); - _timer.setSingleShot(false); _processor->setSize(grabWidth, grabHeight); - _forward = _hyperion->getForwarder()->protoForwardingEnabled(); - - // Connect the QTimer to this - QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(action())); } DispmanxWrapper::~DispmanxWrapper() { - // Cleanup used resources (ImageProcessor and FrameGrabber) - delete _processor; - delete _frameGrabber; -} - -void DispmanxWrapper::start() -{ - // Start the timer with the pre configured interval - _timer.start(); - _hyperion->registerPriority("Dispmanx Grabber", _priority); + delete _grabber; } void DispmanxWrapper::action() { // Grab frame into the allocated image - _frameGrabber->grabFrame(_image); + _grabber->grabFrame(_image); if ( _forward ) { @@ -63,20 +46,13 @@ void DispmanxWrapper::action() _hyperion->setColors(_priority, _ledColors, _timeout_ms); } -void DispmanxWrapper::stop() -{ - // Stop the timer, effectivly stopping the process - _timer.stop(); - _hyperion->unRegisterPriority("Dispmanx Grabber"); -} - void DispmanxWrapper::setGrabbingMode(const GrabbingMode mode) { switch (mode) { case GRABBINGMODE_VIDEO: case GRABBINGMODE_PAUSE: - _frameGrabber->setFlags(DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL); + _grabber->setFlags(DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL); start(); break; case GRABBINGMODE_AUDIO: @@ -84,7 +60,7 @@ void DispmanxWrapper::setGrabbingMode(const GrabbingMode mode) case GRABBINGMODE_MENU: case GRABBINGMODE_SCREENSAVER: case GRABBINGMODE_INVALID: - _frameGrabber->setFlags(0); + _grabber->setFlags(0); start(); break; case GRABBINGMODE_OFF: @@ -95,11 +71,11 @@ void DispmanxWrapper::setGrabbingMode(const GrabbingMode mode) void DispmanxWrapper::setVideoMode(const VideoMode mode) { - _frameGrabber->setVideoMode(mode); + _grabber->setVideoMode(mode); } void DispmanxWrapper::setCropping(const unsigned cropLeft, const unsigned cropRight, const unsigned cropTop, const unsigned cropBottom) { - _frameGrabber->setCropping(cropLeft, cropRight, cropTop, cropBottom); + _grabber->setCropping(cropLeft, cropRight, cropTop, cropBottom); } diff --git a/libsrc/grabber/framebuffer/FramebufferWrapper.cpp b/libsrc/grabber/framebuffer/FramebufferWrapper.cpp index c64fe9bf..1de8d586 100644 --- a/libsrc/grabber/framebuffer/FramebufferWrapper.cpp +++ b/libsrc/grabber/framebuffer/FramebufferWrapper.cpp @@ -7,57 +7,38 @@ #include #include -FramebufferWrapper::FramebufferWrapper(const std::string & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority) : - _updateInterval_ms(1000/updateRate_Hz), - _timeout_ms(2 * _updateInterval_ms), - _priority(priority), - _timer(), - _image(grabWidth, grabHeight), - _frameGrabber(new FramebufferFrameGrabber(device, grabWidth, grabHeight)), - _processor(ImageProcessorFactory::getInstance().newImageProcessor()), - _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0}), - _hyperion(Hyperion::getInstance()) +FramebufferWrapper::FramebufferWrapper(const std::string & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority) + : GrabberWrapper("FrameBuffer", priority) + , _updateInterval_ms(1000/updateRate_Hz) + , _timeout_ms(2 * _updateInterval_ms) + , _image(grabWidth, grabHeight) + , _grabber(new FramebufferFrameGrabber(device, grabWidth, grabHeight)) + , _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0}) { // Configure the timer to generate events every n milliseconds _timer.setInterval(_updateInterval_ms); - _timer.setSingleShot(false); _processor->setSize(grabWidth, grabHeight); - - // Connect the QTimer to this - QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(action())); } FramebufferWrapper::~FramebufferWrapper() { - // Cleanup used resources (ImageProcessor and FrameGrabber) - delete _processor; - delete _frameGrabber; -} - -void FramebufferWrapper::start() -{ - // Start the timer with the pre configured interval - _timer.start(); - _hyperion->registerPriority("FrameBuffer Grabber", _priority); + delete _grabber; } void FramebufferWrapper::action() { // Grab frame into the allocated image - _frameGrabber->grabFrame(_image); - - emit emitImage(_priority, _image, _timeout_ms); + _grabber->grabFrame(_image); + if ( _forward ) + { + emit emitImage(_priority, _image, _timeout_ms); + } + _processor->process(_image, _ledColors); _hyperion->setColors(_priority, _ledColors, _timeout_ms); } -void FramebufferWrapper::stop() -{ - // Stop the timer, effectivly stopping the process - _timer.stop(); - _hyperion->unRegisterPriority("FrameBuffer Grabber"); -} void FramebufferWrapper::setGrabbingMode(const GrabbingMode mode) { @@ -80,5 +61,5 @@ void FramebufferWrapper::setGrabbingMode(const GrabbingMode mode) void FramebufferWrapper::setVideoMode(const VideoMode mode) { - _frameGrabber->setVideoMode(mode); + _grabber->setVideoMode(mode); } diff --git a/libsrc/grabber/osx/OsxWrapper.cpp b/libsrc/grabber/osx/OsxWrapper.cpp index 3654209b..9e94fa08 100644 --- a/libsrc/grabber/osx/OsxWrapper.cpp +++ b/libsrc/grabber/osx/OsxWrapper.cpp @@ -7,57 +7,38 @@ #include #include -OsxWrapper::OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority) : - _updateInterval_ms(1000/updateRate_Hz), - _timeout_ms(2 * _updateInterval_ms), - _priority(priority), - _timer(), - _image(grabWidth, grabHeight), - _frameGrabber(new OsxFrameGrabber(display, grabWidth, grabHeight)), - _processor(ImageProcessorFactory::getInstance().newImageProcessor()), - _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0}), - _hyperion(Hyperion::getInstance()) +OsxWrapper::OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority) + : GrabberWrapper("OSX FrameGrabber", priority) + , _updateInterval_ms(1000/updateRate_Hz) + , _timeout_ms(2 * _updateInterval_ms) + , _image(grabWidth, grabHeight) + , _grabber(new OsxFrameGrabber(display, grabWidth, grabHeight)) + , _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0}) { // Configure the timer to generate events every n milliseconds _timer.setInterval(_updateInterval_ms); - _timer.setSingleShot(false); _processor->setSize(grabWidth, grabHeight); - - // Connect the QTimer to this - QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(action())); } OsxWrapper::~OsxWrapper() { - // Cleanup used resources (ImageProcessor and FrameGrabber) - delete _processor; - delete _frameGrabber; -} - -void OsxWrapper::start() -{ - // Start the timer with the pre configured interval - _timer.start(); - _hyperion->registerPriority("OsxFrameGrabber", _priority); + delete _grabber; } void OsxWrapper::action() { // Grab frame into the allocated image - _frameGrabber->grabFrame(_image); + _grabber->grabFrame(_image); - emit emitImage(_priority, _image, _timeout_ms); + if ( _forward ) + { + emit emitImage(_priority, _image, _timeout_ms); + } _processor->process(_image, _ledColors); _hyperion->setColors(_priority, _ledColors, _timeout_ms); } -void OsxWrapper::stop() -{ - // Stop the timer, effectivly stopping the process - _timer.stop(); - _hyperion->unRegisterPriority("OsxFrameGrabber"); -} void OsxWrapper::setGrabbingMode(const GrabbingMode mode) { @@ -80,5 +61,5 @@ void OsxWrapper::setGrabbingMode(const GrabbingMode mode) void OsxWrapper::setVideoMode(const VideoMode mode) { - _frameGrabber->setVideoMode(mode); + _grabber->setVideoMode(mode); } diff --git a/libsrc/grabber/v4l2/V4L2Wrapper.cpp b/libsrc/grabber/v4l2/V4L2Wrapper.cpp index bf1eb9cb..e67847ac 100644 --- a/libsrc/grabber/v4l2/V4L2Wrapper.cpp +++ b/libsrc/grabber/v4l2/V4L2Wrapper.cpp @@ -15,9 +15,9 @@ V4L2Wrapper::V4L2Wrapper(const std::string &device, double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, - int hyperionPriority) - : _timeout_ms(1000) - , _priority(hyperionPriority) + const int priority) + : GrabberWrapper("V4L2", priority) + , _timeout_ms(1000) , _grabber(device, input, videoStandard, @@ -27,10 +27,7 @@ V4L2Wrapper::V4L2Wrapper(const std::string &device, frameDecimation, pixelDecimation, pixelDecimation) - , _processor(ImageProcessorFactory::getInstance().newImageProcessor()) - , _hyperion(Hyperion::getInstance()) , _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0}) - , _timer() { // set the signal detection threshold of the grabber _grabber.setSignalThreshold( redSignalThreshold, greenSignalThreshold, blueSignalThreshold, 50); @@ -46,44 +43,30 @@ V4L2Wrapper::V4L2Wrapper(const std::string &device, Qt::DirectConnection); // send color data to Hyperion using a queued connection to handle the data over to the main event loop - QObject::connect( - this, SIGNAL(emitColors(int,std::vector,int)), - _hyperion, SLOT(setColors(int,std::vector,int)), - Qt::QueuedConnection); +// QObject::connect( +// this, SIGNAL(emitColors(int,std::vector,int)), +// _hyperion, SLOT(setColors(int,std::vector,int)), +// Qt::QueuedConnection); // setup the higher prio source checker - // this will disable the v4l2 grabber when a source with hisher priority is active + // this will disable the v4l2 grabber when a source with higher priority is active _timer.setInterval(500); - _timer.setSingleShot(false); - QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(checkSources())); } V4L2Wrapper::~V4L2Wrapper() { - delete _processor; } bool V4L2Wrapper::start() { - _timer.start(); - bool grabber_started = _grabber.start(); - if ( ! grabber_started ) - { - _timer.stop(); - } - else - { - _hyperion->registerPriority("V4L2", _priority); - } - - return grabber_started; + return ( _grabber.start() && GrabberWrapper::start()); } void V4L2Wrapper::stop() { _grabber.stop(); - _hyperion->unRegisterPriority("V4L2"); + GrabberWrapper::stop(); } void V4L2Wrapper::setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom) @@ -98,14 +81,15 @@ void V4L2Wrapper::set3D(VideoMode mode) void V4L2Wrapper::newFrame(const Image &image) { + // forward to other hyperions + if ( _forward ) + { + emit emitImage(_priority, image, _timeout_ms); + } + // process the new image _processor->process(image, _ledColors); - - // forward to other hyperions - emit emitImage(_priority, image, _timeout_ms); - - // send colors to Hyperion - emit emitColors(_priority, _ledColors, _timeout_ms); + _hyperion->setColors(_priority, _ledColors, _timeout_ms); } void V4L2Wrapper::checkSources() @@ -125,3 +109,8 @@ void V4L2Wrapper::checkSources() // no higher priority source was found: grabber should be enabled _grabber.start(); } + +void V4L2Wrapper::action() +{ + checkSources(); +} diff --git a/libsrc/grabber/x11/X11Wrapper.cpp b/libsrc/grabber/x11/X11Wrapper.cpp index a0d3f45c..915562c1 100644 --- a/libsrc/grabber/x11/X11Wrapper.cpp +++ b/libsrc/grabber/x11/X11Wrapper.cpp @@ -8,34 +8,24 @@ #include X11Wrapper::X11Wrapper(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation, const unsigned updateRate_Hz, const int priority) - : _updateInterval_ms(1000/updateRate_Hz) + : GrabberWrapper("X11", priority) + , _updateInterval_ms(1000/updateRate_Hz) , _timeout_ms(2 * _updateInterval_ms) - , _priority(priority) - , _timer() -// , _image(grabWidth, grabHeight) , _grabber(new X11Grabber(useXGetImage, cropLeft, cropRight, cropTop, cropBottom, horizontalPixelDecimation, verticalPixelDecimation)) - , _processor(ImageProcessorFactory::getInstance().newImageProcessor()) , _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0}) - , _hyperion(Hyperion::getInstance()) , _init(false) , _x11SetupSuccess(false) { // Configure the timer to generate events every n milliseconds _timer.setInterval(_updateInterval_ms); - _timer.setSingleShot(false); - - // Connect the QTimer to this - QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(action())); } X11Wrapper::~X11Wrapper() { - // Cleanup used resources (ImageProcessor and FrameGrabber) - delete _processor; delete _grabber; } -void X11Wrapper::start() +bool X11Wrapper::start() { if (! _init ) { @@ -51,11 +41,11 @@ void X11Wrapper::start() // Start the timer with the pre configured interval if ( _x11SetupSuccess ) { - _timer.start(); - _hyperion->registerPriority("X11 Grabber", _priority); + GrabberWrapper::start(); } - ErrorIf( ! _x11SetupSuccess, Logger::getInstance("X11"), "X11 Grabber start failed"); + ErrorIf( ! _x11SetupSuccess, _log, "X11 Grabber start failed"); + return _x11SetupSuccess; } @@ -74,17 +64,14 @@ void X11Wrapper::action() // Grab frame into the allocated image _grabber->grabFrame(_image); - emit emitImage(_priority, _image, _timeout_ms); + if ( _forward ) + { + emit emitImage(_priority, _image, _timeout_ms); + } _processor->process(_image, _ledColors); _hyperion->setColors(_priority, _ledColors, _timeout_ms); } -void X11Wrapper::stop() -{ - // Stop the timer, effectivly stopping the process - _timer.stop(); - _hyperion->unRegisterPriority("X11 Grabber"); -} void X11Wrapper::setGrabbingMode(const GrabbingMode mode) { diff --git a/libsrc/hyperion/CMakeLists.txt b/libsrc/hyperion/CMakeLists.txt index 3b3d9cde..dc70fc8d 100644 --- a/libsrc/hyperion/CMakeLists.txt +++ b/libsrc/hyperion/CMakeLists.txt @@ -8,6 +8,7 @@ SET(Hyperion_QT_HEADERS ${CURRENT_HEADER_DIR}/Hyperion.h ${CURRENT_SOURCE_DIR}/LinearColorSmoothing.h + ${CURRENT_HEADER_DIR}/GrabberWrapper.h ) SET(Hyperion_HEADERS @@ -36,6 +37,7 @@ SET(Hyperion_SOURCES ${CURRENT_SOURCE_DIR}/MultiColorAdjustment.cpp ${CURRENT_SOURCE_DIR}/LinearColorSmoothing.cpp ${CURRENT_SOURCE_DIR}/MessageForwarder.cpp + ${CURRENT_SOURCE_DIR}/GrabberWrapper.cpp ) SET(Hyperion_RESOURCES diff --git a/libsrc/hyperion/GrabberWrapper.cpp b/libsrc/hyperion/GrabberWrapper.cpp new file mode 100644 index 00000000..753c70ac --- /dev/null +++ b/libsrc/hyperion/GrabberWrapper.cpp @@ -0,0 +1,62 @@ +// Hyperion includes +#include +#include +#include + + +GrabberWrapper::GrabberWrapper(std::string grabberName, const int priority) + : _grabberName(grabberName) + , _hyperion(Hyperion::getInstance()) + , _priority(priority) + , _timer() + , _log(Logger::getInstance(grabberName.c_str())) + , _forward(true) + , _processor(ImageProcessorFactory::getInstance().newImageProcessor()) +{ + _timer.setSingleShot(false); + + _forward = _hyperion->getForwarder()->protoForwardingEnabled(); + connect(_hyperion, SIGNAL(componentStateChanged(hyperion::Components,bool)), this, SLOT(componentStateChanged(hyperion::Components,bool))); + connect(&_timer, SIGNAL(timeout()), this, SLOT(action())); + +} + +GrabberWrapper::~GrabberWrapper() +{ + delete _processor; +} + +bool GrabberWrapper::start() +{ + // Start the timer with the pre configured interval + _timer.start(); + _hyperion->registerPriority(_grabberName,_priority); + return _timer.isActive(); + +} + +void GrabberWrapper::stop() +{ + // Stop the timer, effectivly stopping the process + _timer.stop(); + _hyperion->unRegisterPriority(_grabberName); +} + +void GrabberWrapper::componentStateChanged(const hyperion::Components component, bool enable) +{ + if (component == hyperion::COMP_GRABBER && _timer.isActive() != enable) + { + if (enable) start(); + else stop(); + + _forward = _hyperion->getForwarder()->protoForwardingEnabled(); + + Info(_log, "grabber change state to %s", (enable ? "enabled" : "disabled") ); + } + + if (component == hyperion::COMP_BLACKBORDER && _processor->blackBorderDetectorEnabled() != enable) + { + _processor->enableBlackBorderDetector(enable); + Info(_log, "bb detector change state to %s", (_processor->blackBorderDetectorEnabled() ? "enabled" : "disabled") ); + } +} diff --git a/libsrc/hyperion/Hyperion.cpp b/libsrc/hyperion/Hyperion.cpp index a33fef71..aa4cae2a 100644 --- a/libsrc/hyperion/Hyperion.cpp +++ b/libsrc/hyperion/Hyperion.cpp @@ -498,7 +498,7 @@ LedString Hyperion::createLedStringClone(const Json::Value& ledsConfig, const Co } LedDevice * Hyperion::createColorSmoothing(const Json::Value & smoothingConfig, LedDevice * ledDevice) -{ +{ Logger * log = Logger::getInstance("Core"); std::string type = smoothingConfig.get("type", "linear").asString(); std::transform(type.begin(), type.end(), type.begin(), ::tolower); @@ -507,7 +507,7 @@ LedDevice * Hyperion::createColorSmoothing(const Json::Value & smoothingConfig, if ( ! smoothingConfig.get("enable", true).asBool() ) { Info(log,"Smoothing disabled"); - return ledDevice; + return nullptr; } if (type == "linear") @@ -523,7 +523,7 @@ LedDevice * Hyperion::createColorSmoothing(const Json::Value & smoothingConfig, } Error(log, "Smoothing disabled, because of unknown type '%s'.", type.c_str()); - return ledDevice; + return nullptr; } MessageForwarder * Hyperion::createMessageForwarder(const Json::Value & forwarderConfig) @@ -605,8 +605,12 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile) ); // initialize the color smoothing filter - _device = createColorSmoothing(jsonConfig["smoothing"], _device); - + LedDevice* smoothing = createColorSmoothing(jsonConfig["smoothing"], _device); + if ( smoothing != nullptr ) + { + _device = smoothing; + connect(this, SIGNAL(componentStateChanged(hyperion::Components,bool)), (LinearColorSmoothing*)_device, SLOT(componentStateChanged(hyperion::Components,bool))); + } // setup the timer _timer.setSingleShot(true); @@ -689,33 +693,9 @@ bool Hyperion::setCurrentSourcePriority(int priority ) return priorityValid; } -void Hyperion::setComponentState(const Components component, const bool state) +void Hyperion::setComponentState(const hyperion::Components component, const bool state) { - switch(component) - { - case SMOOTHING: - break; - case BLACKBORDER: - break; - case KODICHECKER: - { - KODIVideoChecker* kodiVideoChecker = KODIVideoChecker::getInstance(); - if (kodiVideoChecker != nullptr) - state ? kodiVideoChecker->start() : kodiVideoChecker->stop(); - else - Debug(_log, "Can't get instance from: '%s'", componentToString(component)); - break; - } - case FORWARDER: - //_messageForwarder - break; - case UDPLISTENER: - break; - case BOBLIGHTSERVER: - break; - case GRABBER: - break; - } + emit componentStateChanged(component, state); } void Hyperion::setColor(int priority, const ColorRgb &color, const int timeout_ms, bool clearEffects) diff --git a/libsrc/hyperion/ImageProcessor.cpp b/libsrc/hyperion/ImageProcessor.cpp index 71b13a59..5294245a 100644 --- a/libsrc/hyperion/ImageProcessor.cpp +++ b/libsrc/hyperion/ImageProcessor.cpp @@ -48,6 +48,11 @@ void ImageProcessor::enableBlackBorderDetector(bool enable) _borderProcessor->setEnabled(enable); } +bool ImageProcessor::blackBorderDetectorEnabled() +{ + return _borderProcessor->enabled(); +} + bool ImageProcessor::getScanParameters(size_t led, double &hscanBegin, double &hscanEnd, double &vscanBegin, double &vscanEnd) const { if (led < _ledString.leds().size()) diff --git a/libsrc/hyperion/LinearColorSmoothing.cpp b/libsrc/hyperion/LinearColorSmoothing.cpp index b6efe06d..e475b7f2 100644 --- a/libsrc/hyperion/LinearColorSmoothing.cpp +++ b/libsrc/hyperion/LinearColorSmoothing.cpp @@ -3,6 +3,8 @@ #include "LinearColorSmoothing.h" +using namespace hyperion; + LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, double ledUpdateFrequency_hz, int settlingTime_ms, unsigned updateDelay, bool continuousOutput) : QObject() , LedDevice() @@ -13,15 +15,16 @@ LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, double ledUpd , _outputDelay(updateDelay) , _writeToLedsEnable(true) , _continuousOutput(continuousOutput) + , _bypass(false) { + _log = Logger::getInstance("Smoothing"); _timer.setSingleShot(false); _timer.setInterval(_updateInterval); connect(&_timer, SIGNAL(timeout()), this, SLOT(updateLeds())); - Info(Logger::getInstance("Smoothing"), - "Created linear-smoothing with interval: %d ms, settlingTime: %d ms, updateDelay: %d frames", - _updateInterval, settlingTime_ms, _outputDelay ); + Info( _log, "Created linear-smoothing with interval: %d ms, settlingTime: %d ms, updateDelay: %d frames", + _updateInterval, settlingTime_ms, _outputDelay ); } LinearColorSmoothing::~LinearColorSmoothing() @@ -33,21 +36,28 @@ LinearColorSmoothing::~LinearColorSmoothing() int LinearColorSmoothing::write(const std::vector &ledValues) { - // received a new target color - if (_previousValues.empty()) + if (_bypass) { - // not initialized yet - _targetTime = QDateTime::currentMSecsSinceEpoch() + _settlingTime; - _targetValues = ledValues; - - _previousTime = QDateTime::currentMSecsSinceEpoch(); - _previousValues = ledValues; - _timer.start(); + _ledDevice->write(ledValues); } else { - _targetTime = QDateTime::currentMSecsSinceEpoch() + _settlingTime; - memcpy(_targetValues.data(), ledValues.data(), ledValues.size() * sizeof(ColorRgb)); + // received a new target color + if (_previousValues.empty()) + { + // not initialized yet + _targetTime = QDateTime::currentMSecsSinceEpoch() + _settlingTime; + _targetValues = ledValues; + + _previousTime = QDateTime::currentMSecsSinceEpoch(); + _previousValues = ledValues; + _timer.start(); + } + else + { + _targetTime = QDateTime::currentMSecsSinceEpoch() + _settlingTime; + memcpy(_targetValues.data(), ledValues.data(), ledValues.size() * sizeof(ColorRgb)); + } } return 0; @@ -129,3 +139,13 @@ void LinearColorSmoothing::queueColors(const std::vector & ledColors) } } } + +void LinearColorSmoothing::componentStateChanged(const hyperion::Components component, bool enable) +{ + if (component == COMP_SMOOTHING && _bypass == enable) + { + _bypass = !enable; + Info(_log, "change state to %s", (enable ? "enabled" : "disabled") ); + } +} + diff --git a/libsrc/hyperion/LinearColorSmoothing.h b/libsrc/hyperion/LinearColorSmoothing.h index 6897289d..bba78d23 100644 --- a/libsrc/hyperion/LinearColorSmoothing.h +++ b/libsrc/hyperion/LinearColorSmoothing.h @@ -9,6 +9,7 @@ // hyperion incluse #include +#include /// Linear Smooting class /// @@ -39,10 +40,14 @@ public: /// Switch the leds off virtual int switchOff(); + bool componentState() { return _bypass; } + private slots: /// Timer callback which writes updated led values to the led device void updateLeds(); + void componentStateChanged(const hyperion::Components component, bool enable); + private: /** * Pushes the colors into the output queue and popping the head to the led-device @@ -85,4 +90,6 @@ private: /// Flag for dis/enable continuous output to led device regardless there is new data or not bool _continuousOutput; + + bool _bypass; }; diff --git a/libsrc/jsonserver/JsonClientConnection.cpp b/libsrc/jsonserver/JsonClientConnection.cpp index 4849cbb7..843c61bb 100644 --- a/libsrc/jsonserver/JsonClientConnection.cpp +++ b/libsrc/jsonserver/JsonClientConnection.cpp @@ -28,6 +28,8 @@ // project includes #include "JsonClientConnection.h" +using namespace hyperion; + JsonClientConnection::JsonClientConnection(QTcpSocket *socket) : QObject() , _socket(socket) @@ -36,10 +38,12 @@ JsonClientConnection::JsonClientConnection(QTcpSocket *socket) , _receiveBuffer() , _webSocketHandshakeDone(false) , _log(Logger::getInstance("JSONCLIENTCONNECTION")) + , _forwarder_enabled(true) { // connect internal signals and slots connect(_socket, SIGNAL(disconnected()), this, SLOT(socketClosed())); connect(_socket, SIGNAL(readyRead()), this, SLOT(readData())); + connect( _hyperion, SIGNAL(componentStateChanged(hyperion::Components,bool)), this, SLOT(componentStateChanged(hyperion::Components,bool))); } @@ -276,19 +280,30 @@ void JsonClientConnection::handleMessage(const std::string &messageString) } +void JsonClientConnection::componentStateChanged(const hyperion::Components component, bool enable) +{ + if (component == COMP_FORWARDER && _forwarder_enabled != enable) + { + _forwarder_enabled = enable; + Info(_log, "forwarder change state to %s", (enable ? "enabled" : "disabled") ); + } +} void JsonClientConnection::forwardJsonMessage(const Json::Value & message) { - QTcpSocket client; - QList list = _hyperion->getForwarder()->getJsonSlaves(); - - for ( int i=0; i list = _hyperion->getForwarder()->getJsonSlaves(); + + for ( int i=0; isetComponentState((Components)0, componentState.get("state", true).asBool()); - else if (component == "BLACKBORDER") - _hyperion->setComponentState((Components)1, componentState.get("state", true).asBool()); - else if (component == "KODICHECKER") - _hyperion->setComponentState((Components)2, componentState.get("state", true).asBool()); - else if (component == "FORWARDER") - _hyperion->setComponentState((Components)3, componentState.get("state", true).asBool()); - else if (component == "UDPLISTENER") - _hyperion->setComponentState((Components)4, componentState.get("state", true).asBool()); - else if (component == "BOBLIGHTSERVER") - _hyperion->setComponentState((Components)5, componentState.get("state", true).asBool()); - else if (component == "GRABBER") - _hyperion->setComponentState((Components)6, componentState.get("state", true).asBool()); - - sendSuccessReply(); + if (component != COMP_INVALID) + { + _hyperion->setComponentState(component, componentState.get("state", true).asBool()); + sendSuccessReply(); + } + else + { + sendErrorReply("invalid component name"); + } } void JsonClientConnection::handleNotImplemented() diff --git a/libsrc/jsonserver/JsonClientConnection.h b/libsrc/jsonserver/JsonClientConnection.h index 102b4112..0362e94c 100644 --- a/libsrc/jsonserver/JsonClientConnection.h +++ b/libsrc/jsonserver/JsonClientConnection.h @@ -40,6 +40,9 @@ public: /// ~JsonClientConnection(); +public slots: + void componentStateChanged(const hyperion::Components component, bool enable); + signals: /// /// Signal which is emitted when the connection is being closed @@ -217,6 +220,9 @@ private: /// used for WebSocket detection and connection handling bool _webSocketHandshakeDone; - /// the logger instance + /// The logger instance Logger * _log; + + /// Flag if forwarder is enabled + bool _forwarder_enabled; }; diff --git a/libsrc/kodivideochecker/KODIVideoChecker.cpp b/libsrc/kodivideochecker/KODIVideoChecker.cpp index 143715c2..99aeb23b 100644 --- a/libsrc/kodivideochecker/KODIVideoChecker.cpp +++ b/libsrc/kodivideochecker/KODIVideoChecker.cpp @@ -5,6 +5,7 @@ #include +using namespace hyperion; KODIVideoChecker* KODIVideoChecker::_kodichecker = nullptr; @@ -116,6 +117,17 @@ void KODIVideoChecker::stop() _socket.close(); } +void KODIVideoChecker::componentStateChanged(const hyperion::Components component, bool enable) +{ + if (component == COMP_KODICHECKER && _active != enable) + { + if (enable) start(); + else stop(); + Info(_log, "change state to %s", (enable ? "enabled" : "disabled") ); + } +} + + void KODIVideoChecker::receiveReply() { QJsonParseError error; diff --git a/libsrc/protoserver/ProtoServer.cpp b/libsrc/protoserver/ProtoServer.cpp index b3b0a654..9de9cbb7 100644 --- a/libsrc/protoserver/ProtoServer.cpp +++ b/libsrc/protoserver/ProtoServer.cpp @@ -13,6 +13,7 @@ ProtoServer::ProtoServer(uint16_t port) , _server() , _openConnections() , _log(Logger::getInstance("PROTOSERVER")) + , _forwarder_enabled(true) { MessageForwarder * forwarder = _hyperion->getForwarder(); @@ -35,6 +36,8 @@ ProtoServer::ProtoServer(uint16_t port) // Set trigger for incoming connections connect(&_server, SIGNAL(newConnection()), this, SLOT(newConnection())); + connect( _hyperion, SIGNAL(componentStateChanged(hyperion::Components,bool)), this, SLOT(componentStateChanged(hyperion::Components,bool))); + } ProtoServer::~ProtoServer() @@ -81,8 +84,20 @@ void ProtoServer::newMessage(const proto::HyperionRequest * message) void ProtoServer::sendImageToProtoSlaves(int priority, const Image & image, int duration_ms) { - for (int i = 0; i < _proxy_connections.size(); ++i) - _proxy_connections.at(i)->setImage(image, priority, duration_ms); + if ( _forwarder_enabled ) + { + for (int i = 0; i < _proxy_connections.size(); ++i) + _proxy_connections.at(i)->setImage(image, priority, duration_ms); + } +} + +void ProtoServer::componentStateChanged(const hyperion::Components component, bool enable) +{ + if (component == hyperion::COMP_FORWARDER && _forwarder_enabled != enable) + { + _forwarder_enabled = enable; + Info(_log, "forwarder change state to %s", (enable ? "enabled" : "disabled") ); + } } void ProtoServer::closedConnection(ProtoClientConnection *connection) diff --git a/libsrc/udplistener/UDPListener.cpp b/libsrc/udplistener/UDPListener.cpp index 8898ad9c..eaf0fbc9 100644 --- a/libsrc/udplistener/UDPListener.cpp +++ b/libsrc/udplistener/UDPListener.cpp @@ -10,6 +10,8 @@ #include "utils/ColorRgb.h" #include "HyperionConfig.h" +using namespace hyperion; + UDPListener::UDPListener(const int priority, const int timeout, const QString& address, quint16 listenPort, bool shared) : QObject(), _hyperion(Hyperion::getInstance()), @@ -80,6 +82,15 @@ void UDPListener::stop() emit statusChanged(_isActive); } +void UDPListener::componentStateChanged(const hyperion::Components component, bool enable) +{ + if (component == COMP_UDPLISTENER && _isActive != enable) + { + if (enable) start(); + else stop(); + Info(_log, "change state to %s", (enable ? "enabled" : "disabled") ); + } +} uint16_t UDPListener::getPort() const { @@ -95,8 +106,7 @@ void UDPListener::readPendingDatagrams() QHostAddress sender; quint16 senderPort; - _server->readDatagram(datagram.data(), datagram.size(), - &sender, &senderPort); + _server->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); processTheDatagram(&datagram); diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index dba8ff2f..0abf8f3e 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -265,6 +265,7 @@ void HyperionDaemon::createKODIVideoChecker() { _kodiVideoChecker->start(); } + connect( Hyperion::getInstance(), SIGNAL(componentStateChanged(hyperion::Components,bool)), _kodiVideoChecker, SLOT(componentStateChanged(hyperion::Components,bool))); } void HyperionDaemon::startNetworkServices() @@ -301,39 +302,37 @@ void HyperionDaemon::startNetworkServices() Info(_log, "Proto server created and started on port %d", _protoServer->getPort()); // Create Boblight server if configuration is present - if (_qconfig.contains("boblightServer")) - { - const QJsonObject & boblightServerConfig = _qconfig["boblightServer"].toObject(); - _boblightServer = new BoblightServer( - boblightServerConfig["priority"].toInt(710), - boblightServerConfig["port"].toInt() - ); - Debug(_log, "Boblight server created"); + bool boblightConfigured = _qconfig.contains("boblightServer"); - if ( boblightServerConfig["enable"].toBool(true)) - { - _boblightServer->start(); - } + const QJsonObject & boblightServerConfig = _qconfig["boblightServer"].toObject(); + _boblightServer = new BoblightServer( + boblightServerConfig["priority"].toInt(710), + boblightServerConfig["port"].toInt(19333) ); + Debug(_log, "Boblight server created"); + + if ( boblightConfigured && boblightServerConfig["enable"].toBool(true)) + { + _boblightServer->start(); } + connect( Hyperion::getInstance(), SIGNAL(componentStateChanged(hyperion::Components,bool)), _boblightServer, SLOT(componentStateChanged(hyperion::Components,bool))); // Create UDP listener if configuration is present - if (_qconfig.contains("udpListener")) + bool udpListenerConfigured = _qconfig.contains("udpListener"); + const QJsonObject & udpListenerConfig = _qconfig["udpListener"].toObject(); + _udpListener = new UDPListener( + udpListenerConfig["priority"].toInt(700), + udpListenerConfig["timeout"].toInt(10000), + udpListenerConfig["address"].toString(""), + udpListenerConfig["port"].toInt(2801), + udpListenerConfig["shared"].toBool(false)); + + Debug(_log, "UDP listener created"); + + if ( udpListenerConfigured && udpListenerConfig["enable"].toBool(true)) { - const QJsonObject & udpListenerConfig = _qconfig["udpListener"].toObject(); - _udpListener = new UDPListener( - udpListenerConfig["priority"].toInt(700), - udpListenerConfig["timeout"].toInt(10000), - udpListenerConfig["address"].toString(""), - udpListenerConfig["port"].toInt(2801), - udpListenerConfig["shared"].toBool(false)); - - Debug(_log, "UDP listener created"); - - if ( udpListenerConfig["enable"].toBool(true)) - { - _udpListener->start(); - } + _udpListener->start(); } + connect( Hyperion::getInstance(), SIGNAL(componentStateChanged(hyperion::Components,bool)), _udpListener, SLOT(componentStateChanged(hyperion::Components,bool))); // zeroconf description - $leddevicename@$hostname const QJsonObject & deviceConfig = _qconfig["device"].toObject(); @@ -422,7 +421,7 @@ void HyperionDaemon::createSystemFrameGrabber() { type = "framebuffer"; } - Info( _log, "set screen capture device to '%s'", type.constData()); + Info( _log, "set screen capture device to '%s'", type.toUtf8().constData()); } if (type == "framebuffer") createGrabberFramebuffer(grabberConfig); @@ -430,7 +429,7 @@ void HyperionDaemon::createSystemFrameGrabber() else if (type == "amlogic") { createGrabberAmlogic(); createGrabberFramebuffer(grabberConfig); } else if (type == "osx") createGrabberOsx(grabberConfig); else if (type == "x11") createGrabberX11(grabberConfig); - else WarningIf( type != "", _log, "unknown framegrabber type '%s'", type.constData()); + else WarningIf( type != "", _log, "unknown framegrabber type '%s'", type.toUtf8().constData()); InfoIf( type == "", _log, "screen capture device disabled"); } } diff --git a/test/testrunner.sh b/test/testrunner.sh index 0cfb45cd..8c1afa3f 100644 --- a/test/testrunner.sh +++ b/test/testrunner.sh @@ -44,7 +44,7 @@ echo " total: $STATS_TOTAL" echo " success: $STATS_SUCCESS" echo " failed: $STATS_FAILED" +sleep 2 + [ $STATS_FAILED -gt 0 ] && exit 200 exit 0 - -