Smoothing Fixes, Optimizations (#1295)

* Fix #1098, Removed Continuous Output as being obsolete

* Pause output processing when no input source is available

* Only show configurable options for Linear smoothing
This commit is contained in:
LordGrey 2021-08-31 10:56:06 +02:00 committed by GitHub
parent f0bd38d473
commit 1ef3a106f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 134 additions and 148 deletions

View File

@ -58,8 +58,7 @@
"outputRate" : 25.0000, "outputRate" : 25.0000,
"decay" : 1, "decay" : 1,
"dithering" : false, "dithering" : false,
"updateDelay" : 0, "updateDelay" : 0
"continuousOutput" : true
}, },
"grabberV4L2" : "grabberV4L2" :

View File

@ -476,8 +476,11 @@ private slots:
/// ///
void handleNewVideoMode(VideoMode mode) { _currVideoMode = mode; } void handleNewVideoMode(VideoMode mode) { _currVideoMode = mode; }
///
void handlePriorityChangedLedDevice(const quint8& priority); /// @brief Handle the scenario when no/an input source is available
/// @param priority Current priority
///
void handleSourceAvailability(const quint8& priority);
private: private:
friend class HyperionDaemon; friend class HyperionDaemon;

View File

@ -93,7 +93,7 @@ void Hyperion::start()
// connect Hyperion::update with Muxer visible priority changes as muxer updates independent // connect Hyperion::update with Muxer visible priority changes as muxer updates independent
connect(&_muxer, &PriorityMuxer::visiblePriorityChanged, this, &Hyperion::update); connect(&_muxer, &PriorityMuxer::visiblePriorityChanged, this, &Hyperion::update);
connect(&_muxer, &PriorityMuxer::visiblePriorityChanged, this, &Hyperion::handlePriorityChangedLedDevice); connect(&_muxer, &PriorityMuxer::visiblePriorityChanged, this, &Hyperion::handleSourceAvailability);
connect(&_muxer, &PriorityMuxer::visibleComponentChanged, this, &Hyperion::handleVisibleComponentChanged); connect(&_muxer, &PriorityMuxer::visibleComponentChanged, this, &Hyperion::handleVisibleComponentChanged);
// listens for ComponentRegister changes of COMP_ALL to perform core enable/disable actions // listens for ComponentRegister changes of COMP_ALL to perform core enable/disable actions
@ -552,22 +552,23 @@ void Hyperion::handleVisibleComponentChanged(hyperion::Components comp)
_raw2ledAdjustment->setBacklightEnabled((comp != hyperion::COMP_COLOR && comp != hyperion::COMP_EFFECT)); _raw2ledAdjustment->setBacklightEnabled((comp != hyperion::COMP_COLOR && comp != hyperion::COMP_EFFECT));
} }
void Hyperion::handlePriorityChangedLedDevice(const quint8& priority) void Hyperion::handleSourceAvailability(const quint8& priority)
{ { int previousPriority = _muxer.getPreviousPriority();
int previousPriority = _muxer.getPreviousPriority();
Debug(_log,"priority[%d], previousPriority[%d]", priority, previousPriority); Debug(_log,"priority[%d], previousPriority[%d]", priority, previousPriority);
if ( priority == PriorityMuxer::LOWEST_PRIORITY) if ( priority == PriorityMuxer::LOWEST_PRIORITY)
{ {
Debug(_log,"No source left -> switch LED-Device off"); Debug(_log,"No source left -> Pause output processing and switch LED-Device off");
emit _ledDeviceWrapper->switchOff(); emit _ledDeviceWrapper->switchOff();
emit _deviceSmooth->setPause(true);
} }
else else
{ {
if ( previousPriority == PriorityMuxer::LOWEST_PRIORITY ) if ( previousPriority == PriorityMuxer::LOWEST_PRIORITY )
{ {
Debug(_log,"new source available -> switch LED-Device on"); Debug(_log,"new source available -> Resume output processing and switch LED-Device on");
emit _ledDeviceWrapper->switchOn(); emit _ledDeviceWrapper->switchOn();
emit _deviceSmooth->setPause(false);
} }
} }
} }

View File

@ -50,19 +50,17 @@ const unsigned DEFAUL_OUTPUTDEPLAY = 0; // outputdelay in ms
LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument &config, Hyperion *hyperion) LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument &config, Hyperion *hyperion)
: QObject(hyperion) : QObject(hyperion)
, _log(Logger::getInstance("SMOOTHING")) , _log(Logger::getInstance("SMOOTHING"))
, _hyperion(hyperion) , _hyperion(hyperion)
, _updateInterval(DEFAUL_UPDATEINTERVALL.count()) , _updateInterval(DEFAUL_UPDATEINTERVALL.count())
, _settlingTime(DEFAUL_SETTLINGTIME) , _settlingTime(DEFAUL_SETTLINGTIME)
, _timer(new QTimer(this)) , _timer(new QTimer(this))
, _outputDelay(DEFAUL_OUTPUTDEPLAY) , _outputDelay(DEFAUL_OUTPUTDEPLAY)
, _smoothingType(SmoothingType::Linear) , _smoothingType(SmoothingType::Linear)
, _writeToLedsEnable(false) , _pause(false)
, _continuousOutput(false) , _currentConfigId(0)
, _pause(false) , _enabled(false)
, _currentConfigId(0) , tempValues(std::vector<uint64_t>(0, 0L))
, _enabled(false)
, tempValues(std::vector<uint64_t>(0, 0L))
{ {
// init cfg 0 (default) // init cfg 0 (default)
addConfig(DEFAUL_SETTLINGTIME, DEFAUL_UPDATEFREQUENCY, DEFAUL_OUTPUTDEPLAY); addConfig(DEFAUL_SETTLINGTIME, DEFAUL_UPDATEFREQUENCY, DEFAUL_OUTPUTDEPLAY);
@ -94,8 +92,6 @@ void LinearColorSmoothing::handleSettingsUpdate(settings::type type, const QJson
setEnable(obj["enable"].toBool(true)); setEnable(obj["enable"].toBool(true));
} }
_continuousOutput = obj["continuousOutput"].toBool(true);
SMOOTHING_CFG cfg = {SmoothingType::Linear,true, 0, 0, 0, 0, 0, false, 1}; SMOOTHING_CFG cfg = {SmoothingType::Linear,true, 0, 0, 0, 0, 0, false, 1};
const QString typeString = obj[SETTINGS_KEY_SMOOTHING_TYPE].toString(); const QString typeString = obj[SETTINGS_KEY_SMOOTHING_TYPE].toString();
@ -192,7 +188,6 @@ void LinearColorSmoothing::writeDirect()
_previousWriteTime = now; _previousWriteTime = now;
queueColors(_previousValues); queueColors(_previousValues);
_writeToLedsEnable = _continuousOutput;
} }
@ -201,7 +196,6 @@ void LinearColorSmoothing::writeFrame()
const int64_t now = micros(); const int64_t now = micros();
_previousWriteTime = now; _previousWriteTime = now;
queueColors(_previousValues); queueColors(_previousValues);
_writeToLedsEnable = _continuousOutput;
} }
@ -402,12 +396,12 @@ void LinearColorSmoothing::performDecay(const int64_t now) {
if ((now > (_renderedStatTime + 30 * 1000000)) && (_renderedCounter > _renderedStatCounter)) if ((now > (_renderedStatTime + 30 * 1000000)) && (_renderedCounter > _renderedStatCounter))
{ {
Debug(_log, "decay - rendered frames [%d] (%f/s), interpolated frames [%d] (%f/s) in [%f ms]" Debug(_log, "decay - rendered frames [%d] (%f/s), interpolated frames [%d] (%f/s) in [%f ms]"
, _renderedCounter - _renderedStatCounter , _renderedCounter - _renderedStatCounter
, (1.0F * (_renderedCounter - _renderedStatCounter) / ((now - _renderedStatTime) / 1000000.0F)) , (1.0F * (_renderedCounter - _renderedStatCounter) / ((now - _renderedStatTime) / 1000000.0F))
, _interpolationCounter - _interpolationStatCounter , _interpolationCounter - _interpolationStatCounter
, (1.0F * (_interpolationCounter - _interpolationStatCounter) / ((now - _renderedStatTime) / 1000000.0F)) , (1.0F * (_interpolationCounter - _interpolationStatCounter) / ((now - _renderedStatTime) / 1000000.0F))
, (now - _renderedStatTime) / 1000.0F , (now - _renderedStatTime) / 1000.0F
); );
_renderedStatTime = now; _renderedStatTime = now;
_renderedStatCounter = _renderedCounter; _renderedStatCounter = _renderedCounter;
_interpolationStatCounter = _interpolationCounter; _interpolationStatCounter = _interpolationCounter;
@ -505,30 +499,23 @@ void LinearColorSmoothing::clearRememberedFrames()
void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> &ledColors) void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> &ledColors)
{ {
//Debug(_log, "queueColors - _outputDelay[%d] _outputQueue.size() [%d], _writeToLedsEnable[%d]", _outputDelay, _outputQueue.size(), _writeToLedsEnable);
if (_outputDelay == 0) if (_outputDelay == 0)
{ {
// No output delay => immediate write // No output delay => immediate write
if (_writeToLedsEnable && !_pause) if (!_pause)
{ {
// if ( ledColors.size() == 0 )
// qFatal ("No LedValues! - in LinearColorSmoothing::queueColors() - _outputDelay == 0");
// else
emit _hyperion->ledDeviceData(ledColors); emit _hyperion->ledDeviceData(ledColors);
} }
} }
else else
{ {
// Push new colors in the delay-buffer // Push new colors in the delay-buffer
if (_writeToLedsEnable) _outputQueue.push_back(ledColors);
{
_outputQueue.push_back(ledColors);
}
// If the delay-buffer is filled pop the front and write to device // If the delay-buffer is filled pop the front and write to device
if (!_outputQueue.empty()) if (!_outputQueue.empty())
{ {
if (_outputQueue.size() > _outputDelay || !_writeToLedsEnable) if (_outputQueue.size() > _outputDelay)
{ {
if (!_pause) if (!_pause)
{ {
@ -552,7 +539,6 @@ void LinearColorSmoothing::clearQueuedColors()
void LinearColorSmoothing::componentStateChange(hyperion::Components component, bool state) void LinearColorSmoothing::componentStateChange(hyperion::Components component, bool state)
{ {
_writeToLedsEnable = state;
if (component == hyperion::COMP_LEDDEVICE) if (component == hyperion::COMP_LEDDEVICE)
{ {
clearQueuedColors(); clearQueuedColors();
@ -682,7 +668,7 @@ bool LinearColorSmoothing::selectConfig(unsigned cfg, bool force)
QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection); QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
_updateInterval = _cfgList[cfg].updateInterval; _updateInterval = _cfgList[cfg].updateInterval;
if (this->enabled() && this->_writeToLedsEnable) if (this->enabled())
{ {
//Debug( _log, "_cfgList[cfg].updateInterval != _updateInterval - Restart timer - _updateInterval [%d]", _updateInterval); //Debug( _log, "_cfgList[cfg].updateInterval != _updateInterval - Restart timer - _updateInterval [%d]", _updateInterval);
QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval)); QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval));

View File

@ -222,12 +222,6 @@ private:
/// The queue of temporarily remembered frames /// The queue of temporarily remembered frames
std::deque<REMEMBERED_FRAME> _frameQueue; std::deque<REMEMBERED_FRAME> _frameQueue;
/// Prevent sending data to device when no intput data is sent
bool _writeToLedsEnable;
/// Flag for dis/enable continuous output to led device regardless there is new data or not
bool _continuousOutput;
/// Flag for pausing /// Flag for pausing
bool _pause; bool _pause;

View File

@ -1,99 +1,102 @@
{ {
"type" : "object", "type": "object",
"title" : "edt_conf_smooth_heading_title", "title": "edt_conf_smooth_heading_title",
"properties" : "properties": {
{ "enable": {
"enable" : "type": "boolean",
{ "title": "edt_conf_general_enable_title",
"type" : "boolean", "default": true,
"title" : "edt_conf_general_enable_title", "propertyOrder": 1
"default" : true, },
"propertyOrder" : 1 "type": {
}, "type": "string",
"type" : "title": "edt_conf_smooth_type_title",
{ "enum": [ "linear", "decay" ],
"type" : "string", "default": "linear",
"title" : "edt_conf_smooth_type_title", "options": {
"enum" : ["linear", "decay"], "enum_titles": [ "edt_conf_enum_linear", "edt_conf_enum_decay" ]
"default" : "linear", },
"options" : { "propertyOrder": 2
"enum_titles" : ["edt_conf_enum_linear", "edt_conf_enum_decay"] },
}, "time_ms": {
"propertyOrder" : 2 "type": "integer",
}, "title": "edt_conf_smooth_time_ms_title",
"time_ms" : "minimum": 25,
{ "maximum": 5000,
"type" : "integer", "default": 200,
"title" : "edt_conf_smooth_time_ms_title", "append": "edt_append_ms",
"minimum" : 25, "propertyOrder": 3
"maximum": 5000, },
"default" : 200, "updateFrequency": {
"append" : "edt_append_ms", "type": "number",
"propertyOrder" : 3 "title": "edt_conf_smooth_updateFrequency_title",
}, "minimum": 1.0,
"updateFrequency" : "maximum": 2000.0,
{ "default": 25.0,
"type" : "number", "append": "edt_append_hz",
"title" : "edt_conf_smooth_updateFrequency_title", "propertyOrder": 4
"minimum" : 1.0, },
"maximum" : 2000.0, "interpolationRate": {
"default" : 25.0, "type": "number",
"append" : "edt_append_hz", "title": "edt_conf_smooth_interpolationRate_title",
"propertyOrder" : 4 "minimum": 1.0,
}, "maximum": 1000.0,
"interpolationRate" : "default": 1.0,
{ "append": "edt_append_hz",
"type" : "number", "propertyOrder": 5,
"title" : "edt_conf_smooth_interpolationRate_title", "options": {
"minimum" : 1.0, "dependencies": {
"maximum": 1000.0, "type": "decay"
"default" : 1.0, }
"append" : "edt_append_hz", }
"propertyOrder" : 5 },
}, "outputRate": {
"outputRate" : "type": "number",
{ "title": "edt_conf_smooth_outputRate_title",
"type" : "number", "minimum": 1.0,
"title" : "edt_conf_smooth_outputRate_title", "maximum": 1000.0,
"minimum" : 1.0, "default": 1.0,
"maximum": 1000.0, "append": "edt_append_hz",
"default" : 1.0, "propertyOrder": 6,
"append" : "edt_append_hz", "options": {
"propertyOrder" : 6 "dependencies": {
}, "type": "decay"
"decay" : }
{ }
"type" : "number", },
"title" : "edt_conf_smooth_decay_title", "decay": {
"default" : 1.0, "type": "number",
"minimum" : 1.0, "title": "edt_conf_smooth_decay_title",
"maximum": 20.0, "default": 1.0,
"propertyOrder" : 7 "minimum": 1.0,
}, "maximum": 20.0,
"dithering" : "propertyOrder": 7,
{ "options": {
"type" : "boolean", "dependencies": {
"title" : "edt_conf_smooth_dithering_title", "type": "decay"
"default" : true, }
"propertyOrder" : 8 }
}, },
"updateDelay" : "dithering": {
{ "type": "boolean",
"type" : "integer", "title": "edt_conf_smooth_dithering_title",
"title" : "edt_conf_smooth_updateDelay_title", "default": true,
"minimum" : 0, "propertyOrder": 8,
"maximum": 2048, "options": {
"default" : 0, "dependencies": {
"append" : "edt_append_ms", "type": "decay"
"propertyOrder" : 9 }
}, }
"continuousOutput" : },
{ "updateDelay": {
"type" : "boolean", "type": "integer",
"title" : "edt_conf_smooth_continuousOutput_title", "title": "edt_conf_smooth_updateDelay_title",
"default" : true, "minimum": 0,
"propertyOrder" : 10 "maximum": 2048,
} "default": 0,
}, "append": "edt_append_ms",
"additionalProperties" : false "propertyOrder": 9
}
},
"additionalProperties": false
} }