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

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