enable components at runtime + grabber refactoring (#160)

* implement enable/disable on runtime for:
- smoothing
- kodi
- udplistener
- boblight

* implement enable/disable for forwarder
refactor component

* - implement grabber enable/disable at runtime
- big grabber refactoring. now with common base class for all grabbers

* implement enable/disable at runtime for bb detector

* osx fix

* try to fix cutted travis output for osx build
This commit is contained in:
redPanther 2016-08-11 07:13:55 +02:00 committed by GitHub
parent 0d3f6c7ba1
commit f1cc82b8c7
36 changed files with 471 additions and 495 deletions

View File

@ -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

View File

@ -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

View File

@ -10,6 +10,7 @@
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <utils/Logger.h>
#include <utils/Components.h>
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);

View File

@ -1,15 +1,12 @@
#pragma once
// QT includes
#include <QObject>
#include <QTimer>
// Utils includes
#include <utils/Image.h>
#include <utils/ColorBgr.h>
#include <utils/ColorRgb.h>
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
#include <hyperion/GrabberWrapper.h>
// 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<ColorRgb> & 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<ColorBgr> _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<ColorRgb> _ledColors;
/// Pointer to Hyperion for writing led values
Hyperion * _hyperion;
// forwarding enabled
bool _forward;
};

View File

@ -1,19 +1,15 @@
#pragma once
// QT includes
#include <QObject>
#include <QTimer>
// Utils includes
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/ColorRgba.h>
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
#include <hyperion/GrabberWrapper.h>
// 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<ColorRgb> & 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<ColorRgba> _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<ColorRgb> _ledColors;
/// Pointer to Hyperion for writing led values
Hyperion * _hyperion;
// forwarding enabled
bool _forward;
};

View File

@ -1,18 +1,14 @@
#pragma once
// QT includes
#include <QObject>
#include <QTimer>
// Utils includes
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
#include <hyperion/GrabberWrapper.h>
// 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<ColorRgb> & 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<ColorRgb> _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<ColorRgb> _ledColors;
/// Pointer to Hyperion for writing led values
Hyperion * _hyperion;
};

View File

@ -1,19 +1,15 @@
#pragma once
// QT includes
#include <QObject>
#include <QTimer>
// Utils includes
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/ColorRgba.h>
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
#include <hyperion/GrabberWrapper.h>
// 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<ColorRgb> & 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<ColorRgb> _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<ColorRgb> _ledColors;
/// Pointer to Hyperion for writing led values
Hyperion * _hyperion;
};

View File

@ -1,16 +1,14 @@
#pragma once
// Qt includes
#include <QTimer>
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <hyperion/ImageProcessor.h>
#include <hyperion/GrabberWrapper.h>
// Grabber includes
#include <grabber/V4L2Grabber.h>
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<ColorRgb> &ledColors, const int timeout_ms);
void emitImage(int priority, const Image<ColorRgb> & image, const int timeout_ms);
// signals:
// void emitColors(int priority, const std::vector<ColorRgb> &ledColors, const int timeout_ms);
private slots:
void newFrame(const Image<ColorRgb> & 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<ColorRgb> _ledColors;
/// Timer which tests if a higher priority source is active
QTimer _timer;
};

View File

@ -1,18 +1,14 @@
#pragma once
// QT includes
#include <QObject>
#include <QTimer>
// Utils includes
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
#include <hyperion/GrabberWrapper.h>
// 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<ColorRgb> & 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<ColorRgb> _image;
/// The actual grabber
X11Grabber * _grabber;
/// The processor for transforming images to led colors
ImageProcessor * _processor;
/// The list with computed led colors
std::vector<ColorRgb> _ledColors;
/// Pointer to Hyperion for writing led values
Hyperion * _hyperion;
bool _init;
bool _x11SetupSuccess;
};

View File

@ -0,0 +1,52 @@
#pragma once
#include <QObject>
#include <QTimer>
#include <string>
#include <utils/Logger.h>
#include <utils/Components.h>
#include <hyperion/Hyperion.h>
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<ColorRgb> & 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;
};

View File

@ -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

View File

@ -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);

View File

@ -18,6 +18,7 @@
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
#include <utils/Logger.h>
#include <utils/Components.h>
///
/// 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);

View File

@ -52,6 +52,7 @@ public:
public slots:
void sendImageToProtoSlaves(int priority, const Image<ColorRgb> & 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<ProtoConnection*> _proxy_connections;
/// Logger instance
Logger * _log;
/// flag if forwarder is enabled
bool _forwarder_enabled;
};

View File

@ -11,6 +11,7 @@
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <utils/Logger.h>
#include <utils/Components.h>
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);

View File

@ -1,30 +1,50 @@
#pragma once
#include <QString>
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 "";
}
}
}
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;
}
}

View File

@ -5,6 +5,8 @@
#include <boblightserver/BoblightServer.h>
#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
{

View File

@ -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);
}

View File

@ -11,46 +11,29 @@
#include <grabber/DispmanxFrameGrabber.h>
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);
}

View File

@ -7,57 +7,38 @@
#include <grabber/FramebufferWrapper.h>
#include <grabber/FramebufferFrameGrabber.h>
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);
}

View File

@ -7,57 +7,38 @@
#include <grabber/OsxWrapper.h>
#include <grabber/OsxFrameGrabber.h>
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);
}

View File

@ -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<ColorRgb>,int)),
_hyperion, SLOT(setColors(int,std::vector<ColorRgb>,int)),
Qt::QueuedConnection);
// QObject::connect(
// this, SIGNAL(emitColors(int,std::vector<ColorRgb>,int)),
// _hyperion, SLOT(setColors(int,std::vector<ColorRgb>,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<ColorRgb> &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();
}

View File

@ -8,34 +8,24 @@
#include <grabber/X11Grabber.h>
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)
{

View File

@ -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

View File

@ -0,0 +1,62 @@
// Hyperion includes
#include <hyperion/ImageProcessorFactory.h>
#include <hyperion/ImageProcessor.h>
#include <hyperion/GrabberWrapper.h>
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") );
}
}

View File

@ -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)

View File

@ -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())

View File

@ -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<ColorRgb> &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<ColorRgb> & 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") );
}
}

View File

@ -9,6 +9,7 @@
// hyperion incluse
#include <leddevice/LedDevice.h>
#include <utils/Components.h>
/// 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;
};

View File

@ -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<MessageForwarder::JsonSlaveAddress> list = _hyperion->getForwarder()->getJsonSlaves();
for ( int i=0; i<list.size(); i++ )
if (_forwarder_enabled)
{
client.connectToHost(list.at(i).addr, list.at(i).port);
if ( client.waitForConnected(500) )
QTcpSocket client;
QList<MessageForwarder::JsonSlaveAddress> list = _hyperion->getForwarder()->getJsonSlaves();
for ( int i=0; i<list.size(); i++ )
{
sendMessage(message,&client);
client.close();
client.connectToHost(list.at(i).addr, list.at(i).port);
if ( client.waitForConnected(500) )
{
sendMessage(message,&client);
client.close();
}
}
}
}
@ -830,24 +845,17 @@ void JsonClientConnection::handleConfigGetCommand(const Json::Value &)
void JsonClientConnection::handleComponentStateCommand(const Json::Value& message)
{
const Json::Value & componentState = message["componentstate"];
QString component = QString::fromStdString(componentState.get("component", "").asString()).toUpper();
Components component = stringToComponent(QString::fromStdString(componentState.get("component", "invalid").asString()));
if (component == "SMOOTHING")
_hyperion->setComponentState((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()

View File

@ -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;
};

View File

@ -5,6 +5,7 @@
#include <kodivideochecker/KODIVideoChecker.h>
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;

View File

@ -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<ColorRgb> & 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)

View File

@ -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);

View File

@ -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");
}
}

View File

@ -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