Various Cleanups (#1075)

* LedDevice - Address clang findings

* Fix Windows Warnings

* Ensure newInput is initialised

* Clean-up unused elements for Plaform Capture

* Fix initialization problem and spellings

* Address clang findings and spelling corrections

* LedDevice clean-ups

* Cleanups

* Align that getLedCount is int

* Have "display" as default for Grabbers

* Fix config during start-up for missing elements

* Framegrabber Clean-up - Remove non supported grabbers from selection, filter valid options

* Typo

* Framegrabber.json - Fix property numbering

* Preselect active Grabbertype

* Sort Grabbernames

* Align options with selected element

* Fix deletion of pointer to incomplete type 'BonjourBrowserWrapper'

* Address macOS compile warnings

* Have default layout = 1 LED only to avoid errors as in #673

* Address lgtm findings

* Address finding that params passed to LedDevice discovery were not considered

* Cleanups after merging with latest master

* Update Changelog

* Address lgtm findings

* Fix comment

* Test Fix

* Fix Python Warning

* Handle Dummy Device assignment correctly

* Address delete called on non-final 'commandline::Option' that has virtual functions but non-virtual destructor

* Correct that QTimer.start accepts only int

* Have Release Python GIL & reset threat state chnage downward compatible

* Correct format specifier

* LedDevice - add assertions

* Readonly DB - Fix merge issue

* Smoothing - Fix wrong defaults

* LedDevice - correct assertion

* Show smoothing config set# in debug and related values.

* Suppress error on windows, if default file is "/dev/null"

* CMAKE - Allow to define QT_BASE_DIR dynamically via environment-variable

* Ignore Visual Studio specific files

Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com>
This commit is contained in:
LordGrey
2020-11-14 17:58:56 +01:00
committed by GitHub
parent d28540a7fe
commit efc2046ab5
93 changed files with 1140 additions and 1172 deletions

View File

@@ -7,14 +7,14 @@ using namespace hyperion;
ComponentRegister::ComponentRegister(Hyperion* hyperion)
: _hyperion(hyperion)
, _log(Logger::getInstance("COMPONENTREG"))
, _log(Logger::getInstance("COMPONENTREG"))
{
// init all comps to false
QVector<hyperion::Components> vect;
vect << COMP_ALL << COMP_SMOOTHING << COMP_BLACKBORDER << COMP_FORWARDER << COMP_BOBLIGHTSERVER << COMP_GRABBER << COMP_V4L << COMP_LEDDEVICE;
for(auto e : vect)
{
_componentStates.emplace(e, ((e == COMP_ALL) ? true : false));
_componentStates.emplace(e, (e == COMP_ALL));
}
connect(_hyperion, &Hyperion::compStateChangeRequest, this, &ComponentRegister::handleCompStateChangeRequest);
@@ -36,7 +36,7 @@ void ComponentRegister::setNewComponentState(hyperion::Components comp, bool act
Debug( _log, "%s: %s", componentToString(comp), (activated? "enabled" : "disabled"));
_componentStates[comp] = activated;
// emit component has changed state
emit updatedComponentState(comp, activated);
emit updatedComponentState(comp, activated);
}
}
@@ -48,28 +48,34 @@ void ComponentRegister::handleCompStateChangeRequest(hyperion::Components comps,
if(!activated && _prevComponentStates.empty())
{
Debug(_log,"Disable Hyperion, store current component states");
for(const auto comp : _componentStates)
for(const auto &comp : _componentStates)
{
// save state
_prevComponentStates.emplace(comp.first, comp.second);
// disable if enabled
if(comp.second)
{
emit _hyperion->compStateChangeRequest(comp.first, false);
}
}
setNewComponentState(COMP_ALL, false);
}
else if(activated && !_prevComponentStates.empty())
else
{
Debug(_log,"Enable Hyperion, recover previous component states");
for(const auto comp : _prevComponentStates)
if(activated && !_prevComponentStates.empty())
{
// if comp was enabled, enable again
if(comp.second)
emit _hyperion->compStateChangeRequest(comp.first, true);
Debug(_log,"Enable Hyperion, recover previous component states");
for(const auto &comp : _prevComponentStates)
{
// if comp was enabled, enable again
if(comp.second)
{
emit _hyperion->compStateChangeRequest(comp.first, true);
}
}
_prevComponentStates.clear();
setNewComponentState(COMP_ALL, true);
}
_prevComponentStates.clear();
setNewComponentState(COMP_ALL, true);
}
_inProgress = false;
}

View File

@@ -18,7 +18,7 @@
#include <utils/GlobalSignals.h>
#include <utils/Logger.h>
// Leddevice includes
// LedDevice includes
#include <leddevice/LedDeviceWrapper.h>
#include <hyperion/MultiColorAdjustment.h>
@@ -46,14 +46,19 @@ Hyperion::Hyperion(quint8 instance, bool readonlyMode)
, _componentRegister(this)
, _ledString(hyperion::createLedString(getSetting(settings::LEDS).array(), hyperion::createColorOrder(getSetting(settings::DEVICE).object())))
, _imageProcessor(new ImageProcessor(_ledString, this))
, _muxer(_ledString.leds().size(), this)
, _raw2ledAdjustment(hyperion::createLedColorsAdjustment(_ledString.leds().size(), getSetting(settings::COLOR).object()))
, _muxer(static_cast<int>(_ledString.leds().size()), this)
, _raw2ledAdjustment(hyperion::createLedColorsAdjustment(static_cast<int>(_ledString.leds().size()), getSetting(settings::COLOR).object()))
, _ledDeviceWrapper(nullptr)
, _deviceSmooth(nullptr)
, _effectEngine(nullptr)
, _messageForwarder(nullptr)
, _log(Logger::getInstance("HYPERION"))
, _hwLedCount()
, _ledGridSize(hyperion::getLedLayoutGridSize(getSetting(settings::LEDS).array()))
, _BGEffectHandler(nullptr)
,_captureCont(nullptr)
, _ledBuffer(_ledString.leds().size(), ColorRgb::BLACK)
, _boblightServer(nullptr)
, _readOnlyMode(readonlyMode)
{
@@ -78,9 +83,9 @@ void Hyperion::start()
}
// handle hwLedCount
_hwLedCount = qMax(unsigned(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount())), getLedCount());
_hwLedCount = qMax(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount()), getLedCount());
// init colororder vector
// Initialize colororder vector
for (const Led& led : _ledString.leds())
{
_ledStringColorOrder.push_back(led.colorOrder);
@@ -97,12 +102,14 @@ void Hyperion::start()
// listen for settings updates of this instance (LEDS & COLOR)
connect(_settingsManager, &SettingsManager::settingsChanged, this, &Hyperion::handleSettingsUpdate);
#if 0
// set color correction activity state
const QJsonObject color = getSetting(settings::COLOR).object();
#endif
// initialize leddevices
// initialize LED-devices
QJsonObject ledDevice = getSetting(settings::DEVICE).object();
ledDevice["currentLedCount"] = int(_hwLedCount); // Inject led count info
ledDevice["currentLedCount"] = _hwLedCount; // Inject led count info
_ledDeviceWrapper = new LedDeviceWrapper(this);
connect(this, &Hyperion::compStateChangeRequest, _ledDeviceWrapper, &LedDeviceWrapper::handleComponentState);
@@ -115,7 +122,9 @@ void Hyperion::start()
// create the message forwarder only on main instance
if (_instIndex == 0)
{
_messageForwarder = new MessageForwarder(this);
}
// create the effect engine; needs to be initialized after smoothing!
_effectEngine = new EffectEngine(this);
@@ -136,14 +145,14 @@ void Hyperion::start()
connect(GlobalSignals::getInstance(), &GlobalSignals::setGlobalColor, this, &Hyperion::setColor);
connect(GlobalSignals::getInstance(), &GlobalSignals::setGlobalImage, this, &Hyperion::setInputImage);
// if there is no startup / background eff and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a prioritiy change)
// if there is no startup / background effect and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a priority change)
update();
// boblight, can't live in global scope as it depends on layout
_boblightServer = new BoblightServer(this, getSetting(settings::BOBLSERVER));
connect(this, &Hyperion::settingsChanged, _boblightServer, &BoblightServer::handleSettingsUpdate);
// instance inited, enter thread event loop
// instance initiated, enter thread event loop
emit started();
}
@@ -178,7 +187,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
const QJsonObject obj = config.object();
// change in color recreate ledAdjustments
delete _raw2ledAdjustment;
_raw2ledAdjustment = hyperion::createLedColorsAdjustment(_ledString.leds().size(), obj);
_raw2ledAdjustment = hyperion::createLedColorsAdjustment(static_cast<int>(_ledString.leds().size()), obj);
if (!_raw2ledAdjustment->verifyAdjustments())
{
@@ -189,13 +198,13 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
{
const QJsonArray leds = config.array();
// stop and cache all running effects, as effects depend heavily on ledlayout
// stop and cache all running effects, as effects depend heavily on LED-layout
_effectEngine->cacheRunningEffects();
// ledstring, img processor, muxer, ledGridSize (eff engine image based effects), _ledBuffer and ByteOrder of ledstring
// ledstring, img processor, muxer, ledGridSize (effect-engine image based effects), _ledBuffer and ByteOrder of ledstring
_ledString = hyperion::createLedString(leds, hyperion::createColorOrder(getSetting(settings::DEVICE).object()));
_imageProcessor->setLedString(_ledString);
_muxer.updateLedColorsLength(_ledString.leds().size());
_muxer.updateLedColorsLength(static_cast<int>(_ledString.leds().size()));
_ledGridSize = hyperion::getLedLayoutGridSize(leds);
std::vector<ColorRgb> color(_ledString.leds().size(), ColorRgb{0,0,0});
@@ -208,11 +217,11 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
}
// handle hwLedCount update
_hwLedCount = qMax(unsigned(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount())), getLedCount());
_hwLedCount = qMax(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount()), getLedCount());
// change in leds are also reflected in adjustment
delete _raw2ledAdjustment;
_raw2ledAdjustment = hyperion::createLedColorsAdjustment(_ledString.leds().size(), getSetting(settings::COLOR).object());
_raw2ledAdjustment = hyperion::createLedColorsAdjustment(static_cast<int>(_ledString.leds().size()), getSetting(settings::COLOR).object());
// start cached effects
_effectEngine->startCachedEffects();
@@ -222,7 +231,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
QJsonObject dev = config.object();
// handle hwLedCount update
_hwLedCount = qMax(unsigned(dev["hardwareLedCount"].toInt(getLedCount())), getLedCount());
_hwLedCount = qMax(dev["hardwareLedCount"].toInt(getLedCount()), getLedCount());
// force ledString update, if device ByteOrder changed
if(_ledDeviceWrapper->getColorOrder() != dev["colorOrder"].toString("rgb"))
@@ -238,7 +247,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
}
// do always reinit until the led devices can handle dynamic changes
dev["currentLedCount"] = int(_hwLedCount); // Inject led count info
dev["currentLedCount"] = _hwLedCount; // Inject led count info
_ledDeviceWrapper->createLedDevice(dev);
// TODO: Check, if framegrabber frequency is lower than latchtime..., if yes, stop
@@ -277,9 +286,9 @@ unsigned Hyperion::updateSmoothingConfig(unsigned id, int settlingTime_ms, doubl
return _deviceSmooth->updateConfig(id, settlingTime_ms, ledUpdateFrequency_hz, updateDelay);
}
unsigned Hyperion::getLedCount() const
int Hyperion::getLedCount() const
{
return _ledString.leds().size();
return static_cast<int>(_ledString.leds().size());
}
void Hyperion::setSourceAutoSelect(bool state)
@@ -323,7 +332,9 @@ bool Hyperion::setInput(int priority, const std::vector<ColorRgb>& ledColors, in
{
// clear effect if this call does not come from an effect
if(clearEffect)
{
_effectEngine->channelCleared(priority);
}
// if this priority is visible, update immediately
if(priority == _muxer.getCurrentPriority())
@@ -348,7 +359,9 @@ bool Hyperion::setInputImage(int priority, const Image<ColorRgb>& image, int64_t
{
// clear effect if this call does not come from an effect
if(clearEffect)
{
_effectEngine->channelCleared(priority);
}
// if this priority is visible, update immediately
if(priority == _muxer.getCurrentPriority())
@@ -370,7 +383,9 @@ void Hyperion::setColor(int priority, const std::vector<ColorRgb> &ledColors, in
{
// clear effect if this call does not come from an effect
if (clearEffects)
{
_effectEngine->channelCleared(priority);
}
// create full led vector from single/multiple colors
size_t size = _ledString.leds().size();
@@ -381,13 +396,17 @@ void Hyperion::setColor(int priority, const std::vector<ColorRgb> &ledColors, in
{
newLedColors.emplace_back(entry);
if (newLedColors.size() == size)
{
goto end;
}
}
}
end:
if (getPriorityInfo(priority).componentId != hyperion::COMP_COLOR)
{
clear(priority);
}
// register color
registerInput(priority, hyperion::COMP_COLOR, origin);
@@ -414,13 +433,14 @@ void Hyperion::adjustmentsUpdated()
bool Hyperion::clear(int priority, bool forceClearAll)
{
bool isCleared = false;
if (priority < 0)
{
_muxer.clearAll(forceClearAll);
// send clearall signal to the effect engine
_effectEngine->allChannelsCleared();
return true;
isCleared = true;
}
else
{
@@ -429,9 +449,11 @@ bool Hyperion::clear(int priority, bool forceClearAll)
_effectEngine->channelCleared(priority);
if (_muxer.clearInput(priority))
return true;
{
isCleared = true;
}
}
return false;
return isCleared;
}
int Hyperion::getCurrentPriority() const
@@ -532,9 +554,9 @@ void Hyperion::handleVisibleComponentChanged(hyperion::Components comp)
void Hyperion::handlePriorityChangedLedDevice(const quint8& priority)
{
quint8 previousPriority = _muxer.getPreviousPriority();
int previousPriority = _muxer.getPreviousPriority();
Debug(_log,"priority[%u], previousPriority[%u]", priority, previousPriority);
Debug(_log,"priority[%d], previousPriority[%d]", priority, previousPriority);
if ( priority == PriorityMuxer::LOWEST_PRIORITY)
{
Debug(_log,"No source left -> switch LED-Device off");
@@ -604,8 +626,8 @@ void Hyperion::update()
i++;
}
// fill additional hw leds with black
if ( _hwLedCount > _ledBuffer.size() )
// fill additional hardware LEDs with black
if ( _hwLedCount > static_cast<int>(_ledBuffer.size()) )
{
_ledBuffer.resize(_hwLedCount, ColorRgb::BLACK);
}
@@ -623,16 +645,18 @@ void Hyperion::update()
{
_deviceSmooth->selectConfig(priorityInfo.smooth_cfg);
// feed smoothing in pause mode to maintain a smooth transistion back to smooth mode
// feed smoothing in pause mode to maintain a smooth transition back to smooth mode
if (_deviceSmooth->enabled() || _deviceSmooth->pause())
{
_deviceSmooth->updateLedValues(_ledBuffer);
}
}
}
//else
//{
// /LEDDevice is disabled
// Debug(_log, "LEDDevice is disabled - no update required");
//}
#if 0
else
{
//LEDDevice is disabled
Debug(_log, "LEDDevice is disabled - no update required");
}
#endif
}

View File

@@ -5,16 +5,6 @@
// hyperion includes
#include <hyperion/LedString.h>
LedString::LedString()
{
// empty
}
LedString::~LedString()
{
// empty
}
std::vector<Led>& LedString::leds()
{
return mLeds;

View File

@@ -22,7 +22,7 @@ const int64_t MS_PER_MICRO = 1000;
/// Clamps the rounded values to the byte-interval of [0, 255].
ALWAYS_INLINE long clampRounded(const floatT x) {
return std::min(255l, std::max(0l, std::lroundf(x)));
return std::min(255L, std::max(0L, std::lroundf(x)));
}
/// The number of bits that are used for shifting the fixed point values
@@ -43,15 +43,16 @@ const char* SETTINGS_KEY_DECAY = "decay";
using namespace hyperion;
const int64_t DEFAUL_SETTLINGTIME = 200; // settlingtime in ms
const double DEFAUL_UPDATEFREQUENCY = 25; // updatefrequncy in hz
const int64_t DEFAUL_UPDATEINTERVALL = static_cast<int64_t>(1000 / DEFAUL_UPDATEFREQUENCY); // updateintervall in ms
const int DEFAUL_UPDATEFREQUENCY = 25; // updatefrequncy in hz
constexpr std::chrono::milliseconds DEFAUL_UPDATEINTERVALL{1000/ DEFAUL_UPDATEFREQUENCY};
const unsigned DEFAUL_OUTPUTDEPLAY = 0; // outputdelay in ms
LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument &config, Hyperion *hyperion)
: QObject(hyperion)
, _log(Logger::getInstance("SMOOTHING"))
, _hyperion(hyperion)
, _updateInterval(DEFAUL_UPDATEINTERVALL)
, _updateInterval(DEFAUL_UPDATEINTERVALL.count())
, _settlingTime(DEFAUL_SETTLINGTIME)
, _timer(new QTimer(this))
, _outputDelay(DEFAUL_OUTPUTDEPLAY)
@@ -61,7 +62,7 @@ LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument &config, Hyperion
, _pause(false)
, _currentConfigId(0)
, _enabled(false)
, tempValues(std::vector<uint64_t>(0, 0l))
, tempValues(std::vector<uint64_t>(0, 0L))
{
// init cfg 0 (default)
addConfig(DEFAUL_SETTLINGTIME, DEFAUL_UPDATEFREQUENCY, DEFAUL_OUTPUTDEPLAY);
@@ -69,7 +70,7 @@ LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument &config, Hyperion
selectConfig(0, true);
// add pause on cfg 1
SMOOTHING_CFG cfg = {SmoothingType::Linear, 0, 0, 0, 0, 0, false};
SMOOTHING_CFG cfg = {SmoothingType::Linear, false, 0, 0, 0, 0, 0, false, 1};
_cfgList.append(cfg);
// listen for comp changes
@@ -77,7 +78,7 @@ LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument &config, Hyperion
// timer
connect(_timer, &QTimer::timeout, this, &LinearColorSmoothing::updateLeds);
Info(_log, "LinearColorSmoothing sizeof floatT == %d", (sizeof(floatT)));
//Debug(_log, "LinearColorSmoothing sizeof floatT == %d", (sizeof(floatT)));
}
void LinearColorSmoothing::handleSettingsUpdate(settings::type type, const QJsonDocument &config)
@@ -89,7 +90,9 @@ void LinearColorSmoothing::handleSettingsUpdate(settings::type type, const QJson
QJsonObject obj = config.object();
if (enabled() != obj["enable"].toBool(true))
{
setEnable(obj["enable"].toBool(true));
}
_continuousOutput = obj["continuousOutput"].toBool(true);
@@ -105,7 +108,7 @@ void LinearColorSmoothing::handleSettingsUpdate(settings::type type, const QJson
cfg.pause = false;
cfg.settlingTime = static_cast<int64_t>(obj["time_ms"].toInt(DEFAUL_SETTLINGTIME));
cfg.updateInterval = static_cast<int64_t>(1000.0 / obj["updateFrequency"].toDouble(DEFAUL_UPDATEFREQUENCY));
cfg.updateInterval = static_cast<int>(1000.0 / obj["updateFrequency"].toDouble(DEFAUL_UPDATEFREQUENCY));
cfg.outputRate = obj[SETTINGS_KEY_OUTPUT_RATE].toDouble(DEFAUL_UPDATEFREQUENCY);
cfg.interpolationRate = obj[SETTINGS_KEY_INTERPOLATION_RATE].toDouble(DEFAUL_UPDATEFREQUENCY);
cfg.outputDelay = static_cast<unsigned>(obj["updateDelay"].toInt(DEFAUL_OUTPUTDEPLAY));
@@ -155,7 +158,7 @@ int LinearColorSmoothing::updateLedValues(const std::vector<ColorRgb> &ledValues
int retval = 0;
if (!_enabled)
{
return -1;
retval = -1;
}
else
{
@@ -173,13 +176,13 @@ void LinearColorSmoothing::intitializeComponentVectors(const size_t ledCount)
const size_t len = 3 * ledCount;
meanValues = std::vector<floatT>(len, 0.0f);
residualErrors = std::vector<floatT>(len, 0.0f);
tempValues = std::vector<uint64_t>(len, 0l);
meanValues = std::vector<floatT>(len, 0.0F);
residualErrors = std::vector<floatT>(len, 0.0F);
tempValues = std::vector<uint64_t>(len, 0L);
}
// Zero the temp vector
std::fill(tempValues.begin(), tempValues.end(), 0l);
std::fill(tempValues.begin(), tempValues.end(), 0L);
}
void LinearColorSmoothing::writeDirect()
@@ -232,9 +235,9 @@ void LinearColorSmoothing::assembleAndDitherFrame()
// Update the colors
ColorRgb &prev = _previousValues[i];
prev.red = (uint8_t)ir;
prev.green = (uint8_t)ig;
prev.blue = (uint8_t)ib;
prev.red = static_cast<uint8_t>(ir);
prev.green = static_cast<uint8_t>(ig);
prev.blue = static_cast<uint8_t>(ib);
// Determine the component errors
residualErrors[3 * i + 0] = fr - ir;
@@ -262,15 +265,15 @@ void LinearColorSmoothing::assembleFrame()
// Update the colors
ColorRgb &prev = _previousValues[i];
prev.red = (uint8_t)ir;
prev.green = (uint8_t)ig;
prev.blue = (uint8_t)ib;
prev.red = static_cast<uint8_t>(ir);
prev.green = static_cast<uint8_t>(ig);
prev.blue = static_cast<uint8_t>(ib);
}
}
ALWAYS_INLINE void LinearColorSmoothing::aggregateComponents(const std::vector<ColorRgb>& colors, std::vector<uint64_t>& weighted, const floatT weight) {
// Determine the integer-scale by converting the weight to fixed point
const uint64_t scale = (1l<<FPShift) * static_cast<double>(weight);
const uint64_t scale = (static_cast<uint64_t>(1L)<<FPShift) * static_cast<double>(weight);
const size_t N = colors.size();
@@ -309,7 +312,7 @@ void LinearColorSmoothing::interpolateFrame()
const int64_t windowStart = now - (MS_PER_MICRO * _settlingTime);
/// The total weight of the frames that were included in our window; sum of the individual weights
floatT fs = 0.0f;
floatT fs = 0.0F;
// To calculate the mean component we iterate over all relevant frames;
// from the most recent to the oldest frame that still clips our moving-average window given by time (now)
@@ -331,7 +334,7 @@ void LinearColorSmoothing::interpolateFrame()
}
/// The inverse scaling factor for the color components, clamped to (0, 1.0]; 1.0 for fs < 1, 1 : fs otherwise
const floatT inv_fs = ((fs < 1.0f) ? 1.0f : 1.0f / fs) / (1 << SmallShiftBis);
const floatT inv_fs = ((fs < 1.0F) ? 1.0F : 1.0F / fs) / (1 << SmallShiftBis);
// Normalize the mean component values for the window (fs)
for (size_t i = 0; i < 3 * N; ++i)
@@ -385,8 +388,8 @@ void LinearColorSmoothing::performDecay(const int64_t now) {
if(_updateInterval <= 0 && !(interpolatePending || writePending)) {
const int64_t nextActionExpected = std::min(interpolationTarget, writeTarget);
const int64_t microsTillNextAction = nextActionExpected - now;
const int64_t SLEEP_MAX_MICROS = 1000l; // We want to use usleep for up to 1ms
const int64_t SLEEP_RES_MICROS = 100l; // Expected resolution is >= 100µs on stock linux
const int64_t SLEEP_MAX_MICROS = 1000L; // We want to use usleep for up to 1ms
const int64_t SLEEP_RES_MICROS = 100L; // Expected resolution is >= 100µs on stock linux
if(microsTillNextAction > SLEEP_RES_MICROS) {
const int64_t wait = std::min(microsTillNextAction - SLEEP_RES_MICROS, SLEEP_MAX_MICROS);
@@ -398,12 +401,12 @@ void LinearColorSmoothing::performDecay(const int64_t now) {
// Write stats every 30 sec
if ((now > (_renderedStatTime + 30 * 1000000)) && (_renderedCounter > _renderedStatCounter))
{
Info(_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
, (1.0f * (_renderedCounter - _renderedStatCounter) / ((now - _renderedStatTime) / 1000000.0f))
, (1.0F * (_renderedCounter - _renderedStatCounter) / ((now - _renderedStatTime) / 1000000.0F))
, _interpolationCounter - _interpolationStatCounter
, (1.0f * (_interpolationCounter - _interpolationStatCounter) / ((now - _renderedStatTime) / 1000000.0f))
, (now - _renderedStatTime) / 1000.0f
, (1.0F * (_interpolationCounter - _interpolationStatCounter) / ((now - _renderedStatTime) / 1000000.0F))
, (now - _renderedStatTime) / 1000.0F
);
_renderedStatTime = now;
_renderedStatCounter = _renderedCounter;
@@ -413,7 +416,7 @@ void LinearColorSmoothing::performDecay(const int64_t now) {
void LinearColorSmoothing::performLinear(const int64_t now) {
const int64_t deltaTime = _targetTime - now;
const float k = 1.0f - 1.0f * deltaTime / (_targetTime - _previousWriteTime);
const float k = 1.0F - 1.0F * deltaTime / (_targetTime - _previousWriteTime);
const size_t N = _previousValues.size();
for (size_t i = 0; i < N; ++i)
@@ -461,7 +464,7 @@ void LinearColorSmoothing::updateLeds()
void LinearColorSmoothing::rememberFrame(const std::vector<ColorRgb> &ledColors)
{
//Info(_log, "rememberFrame - before _frameQueue.size() [%d]", _frameQueue.size());
//Debug(_log, "rememberFrame - before _frameQueue.size() [%d]", _frameQueue.size());
const int64_t now = micros();
@@ -478,7 +481,7 @@ void LinearColorSmoothing::rememberFrame(const std::vector<ColorRgb> &ledColors)
if (p > 0)
{
//Info(_log, "rememberFrame - erasing %d frames", p);
//Debug(_log, "rememberFrame - erasing %d frames", p);
_frameQueue.erase(_frameQueue.begin(), _frameQueue.begin() + p);
}
@@ -486,7 +489,7 @@ void LinearColorSmoothing::rememberFrame(const std::vector<ColorRgb> &ledColors)
const REMEMBERED_FRAME frame = REMEMBERED_FRAME(now, ledColors);
_frameQueue.push_back(frame);
//Info(_log, "rememberFrame - after _frameQueue.size() [%d]", _frameQueue.size());
//Debug(_log, "rememberFrame - after _frameQueue.size() [%d]", _frameQueue.size());
}
@@ -518,10 +521,12 @@ void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> &ledColors)
{
// Push new colors in the delay-buffer
if (_writeToLedsEnable)
{
_outputQueue.push_back(ledColors);
}
// If the delay-buffer is filled pop the front and write to device
if (_outputQueue.size() > 0)
if (!_outputQueue.empty())
{
if (_outputQueue.size() > _outputDelay || !_writeToLedsEnable)
{
@@ -581,7 +586,7 @@ unsigned LinearColorSmoothing::addConfig(int settlingTime_ms, double ledUpdateFr
SmoothingType::Linear,
false,
settlingTime_ms,
int64_t(1000.0 / ledUpdateFrequency_hz),
static_cast<int>(1000.0 / ledUpdateFrequency_hz),
ledUpdateFrequency_hz,
ledUpdateFrequency_hz,
updateDelay,
@@ -603,7 +608,7 @@ unsigned LinearColorSmoothing::updateConfig(unsigned cfgID, int settlingTime_ms,
SmoothingType::Linear,
false,
settlingTime_ms,
int64_t(1000.0 / ledUpdateFrequency_hz),
static_cast<int>(1000.0 / ledUpdateFrequency_hz),
ledUpdateFrequency_hz,
ledUpdateFrequency_hz,
updateDelay,
@@ -630,7 +635,7 @@ bool LinearColorSmoothing::selectConfig(unsigned cfg, bool force)
}
//Debug( _log, "selectConfig FORCED - _currentConfigId [%u], force [%d]", cfg, force);
if (cfg < (unsigned)_cfgList.count())
if (cfg < static_cast<uint>(_cfgList.count()) )
{
_smoothingType = _cfgList[cfg].smoothingType;
_settlingTime = _cfgList[cfg].settlingTime;
@@ -642,14 +647,14 @@ bool LinearColorSmoothing::selectConfig(unsigned cfg, bool force)
_interpolationIntervalMicros = int64_t(1000000.0 / _interpolationRate);
_dithering = _cfgList[cfg].dithering;
_decay = _cfgList[cfg].decay;
_invWindow = 1.0f / (MS_PER_MICRO * _settlingTime);
_invWindow = 1.0F / (MS_PER_MICRO * _settlingTime);
// Set _weightFrame based on the given decay
const float decay = _decay;
const floatT inv_window = _invWindow;
// For decay != 1 use power-based approach for calculating the moving average values
if(std::abs(decay - 1.0f) > std::numeric_limits<float>::epsilon()) {
if(std::abs(decay - 1.0F) > std::numeric_limits<float>::epsilon()) {
// Exponential Decay
_weightFrame = [inv_window,decay](const int64_t fs, const int64_t fe, const int64_t ws) {
const floatT s = (fs - ws) * inv_window;
@@ -660,7 +665,7 @@ bool LinearColorSmoothing::selectConfig(unsigned cfg, bool force)
} else {
// For decay == 1 use linear interpolation of the moving average values
// Linear Decay
_weightFrame = [inv_window](const int64_t fs, const int64_t fe, const int64_t ws) {
_weightFrame = [inv_window](const int64_t fs, const int64_t fe, const int64_t /*ws*/) {
// Linear weighting = (end - start) * scale
return static_cast<floatT>((fe - fs) * inv_window);
};
@@ -693,7 +698,7 @@ bool LinearColorSmoothing::selectConfig(unsigned cfg, bool force)
// DebugIf( _pause, _log, "set smoothing cfg: %d, pause", _currentConfigId );
const float thalf = (1.0-std::pow(1.0/2, 1.0/_decay))*_settlingTime;
Info( _log, "%s - Time: %d ms, outputRate %f Hz, interpolationRate: %f Hz, timer: %d ms, Dithering: %d, Decay: %f -> HalfTime: %f ms", _smoothingType == SmoothingType::Decay ? "decay" : "linear", _settlingTime, _outputRate, _interpolationRate, _updateInterval, _dithering ? 1 : 0, _decay, thalf);
Debug( _log, "cfg [%d]: Type: %s - Time: %d ms, outputRate %f Hz, interpolationRate: %f Hz, timer: %d ms, Dithering: %d, Decay: %f -> HalfTime: %f ms", cfg, _smoothingType == SmoothingType::Decay ? "decay" : "linear", _settlingTime, _outputRate, _interpolationRate, _updateInterval, _dithering ? 1 : 0, _decay, thalf);
return true;
}

View File

@@ -7,7 +7,7 @@
// Qt includes
#include <QVector>
// hyperion incluse
// hyperion includes
#include <leddevice/LedDevice.h>
#include <utils/Components.h>
@@ -30,7 +30,7 @@ enum SmoothingType {
Decay,
};
/// Linear Smooting class
/// Linear Smoothing class
///
/// This class processes the requested led values and forwards them to the device after applying
/// a smoothing effect to LED colors. This class can be handled as a generic LedDevice.
@@ -94,12 +94,12 @@ public:
bool enabled() const { return _enabled && !_pause; }
///
/// @brief Add a new smoothing cfg which can be used with selectConfig()
/// @brief Add a new smoothing configuration which can be used with selectConfig()
/// @param settlingTime_ms The buffer time
/// @param ledUpdateFrequency_hz The frequency of update
/// @param updateDelay The delay
///
/// @return The index of the cfg which can be passed to selectConfig()
/// @return The index of the configuration, which can be passed to selectConfig()
///
unsigned addConfig(int settlingTime_ms, double ledUpdateFrequency_hz = 25.0, unsigned updateDelay = 0);
@@ -112,12 +112,12 @@ public:
/// @param ledUpdateFrequency_hz The frequency of update
/// @param updateDelay The delay
///
/// @return The index of the cfg which can be passed to selectConfig()
/// @return The index of the configuration, which can be passed to selectConfig()
///
unsigned updateConfig(unsigned cfgID, int settlingTime_ms, double ledUpdateFrequency_hz = 25.0, unsigned updateDelay = 0);
///
/// @brief select a smoothing cfg given by cfg index from addConfig()
/// @brief select a smoothing configuration given by cfg index from addConfig()
/// @param cfg The index to use
/// @param force Overwrite in any case the current values (used for cfg 0 settings update)
///
@@ -128,7 +128,7 @@ public:
public slots:
///
/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
/// @param type settingyType from enum
/// @param type settingType from enum
/// @param config configuration object
///
void handleSettingsUpdate(settings::type type, const QJsonDocument &config);
@@ -167,7 +167,7 @@ private:
Hyperion *_hyperion;
/// The interval at which to update the leds (msec)
int64_t _updateInterval;
int _updateInterval;
/// The time after which the updated led values have been fully applied (msec)
int64_t _settlingTime;
@@ -243,7 +243,7 @@ private:
/// The interval time in microseconds for interpolation of LED Frames.
int64_t _interpolationIntervalMicros;
/// Whether to apply temproral dithering to diffuse rounding errors when downsampling to 8-bit RGB colors.
/// Whether to apply temporal dithering to diffuse rounding errors when downsampling to 8-bit RGB colors.
bool _dithering;
/// The decay power > 0. A value of exactly 1 is linear decay, higher numbers indicate a faster decay rate.
@@ -263,8 +263,8 @@ private:
/// The time of the smoothing window.
int64_t settlingTime;
/// The interval time in millisecons of the timer used for scheduling LED update operations. A value of 0 indicates sub-millisecond timing.
int64_t updateInterval;
/// The interval time in milliseconds of the timer used for scheduling LED update operations. A value of 0 indicates sub-millisecond timing.
int updateInterval;
// The rate at which color frames should be written to LED device.
double outputRate;
@@ -275,13 +275,13 @@ private:
/// The number of frames the output is delayed
unsigned outputDelay;
/// Whether to apply temproral dithering to diffuse rounding errors when downsampling to 8-bit RGB colors. Improves color accuracy.
/// Whether to apply temporal dithering to diffuse rounding errors when downsampling to 8-bit RGB colors. Improves color accuracy.
bool dithering;
/// The decay power > 0. A value of exactly 1 is linear decay, higher numbers indicate a faster decay rate.
double decay;
};
/// smooth config list
/// smooth configuration list
QVector<SMOOTHING_CFG> _cfgList;
unsigned _currentConfigId;
@@ -329,7 +329,7 @@ private:
/// Prepares a frame of LED colors by interpolating using the current smoothing window
void interpolateFrame();
/// Performes a decay-based smoothing effect. The frames are interpolated based on their age and a given decay-power.
/// Performs a decay-based smoothing effect. The frames are interpolated based on their age and a given decay-power.
///
/// The ingress frames that were received during the current smoothing window are reduced using a weighted moving average
/// by applying the weighting-function to the color components of each frame.

View File

@@ -2,7 +2,7 @@
#include <utils/Logger.h>
#include <hyperion/MultiColorAdjustment.h>
MultiColorAdjustment::MultiColorAdjustment(unsigned ledCnt)
MultiColorAdjustment::MultiColorAdjustment(int ledCnt)
: _ledAdjustments(ledCnt, nullptr)
, _log(Logger::getInstance("ADJUSTMENT"))
{
@@ -25,7 +25,7 @@ void MultiColorAdjustment::addAdjustment(ColorAdjustment * adjustment)
_adjustment.push_back(adjustment);
}
void MultiColorAdjustment::setAdjustmentForLed(const QString& id, unsigned startLed, unsigned endLed)
void MultiColorAdjustment::setAdjustmentForLed(const QString& id, int startLed, int endLed)
{
// abort
if(startLed > endLed)
@@ -34,19 +34,19 @@ void MultiColorAdjustment::setAdjustmentForLed(const QString& id, unsigned start
return;
}
// catch wrong values
if(endLed > _ledAdjustments.size()-1)
if(endLed > static_cast<int>(_ledAdjustments.size()-1))
{
Warning(_log,"The color calibration 'LED index' field has leds specified which aren't part of your led layout");
endLed = _ledAdjustments.size()-1;
Warning(_log,"The color calibration 'LED index' field has LEDs specified which aren't part of your led layout");
endLed = static_cast<int>(_ledAdjustments.size()-1);
}
// Get the identified adjustment (don't care if is nullptr)
ColorAdjustment * adjustment = getAdjustment(id);
//Debug(_log,"ColorAdjustment Profile [%s], startLed[%u], endLed[%u]", QSTRING_CSTR(id), startLed, endLed);
for (unsigned iLed=startLed; iLed<=endLed; ++iLed)
//Debug(_log,"ColorAdjustment Profile [%s], startLed[%d], endLed[%d]", QSTRING_CSTR(id), startLed, endLed);
for (int iLed=startLed; iLed<=endLed; ++iLed)
{
//Debug(_log,"_ledAdjustments [%u] -> [%p]", iLed, adjustment);
//Debug(_log,"_ledAdjustments [%d] -> [%p]", iLed, adjustment);
_ledAdjustments[iLed] = adjustment;
}
}

View File

@@ -84,7 +84,7 @@ bool PriorityMuxer::setSourceAutoSelectEnabled(bool enable, bool update)
return false;
}
bool PriorityMuxer::setPriority(uint8_t priority)
bool PriorityMuxer::setPriority(int priority)
{
if(_activeInputs.contains(priority))
{
@@ -141,7 +141,8 @@ hyperion::Components PriorityMuxer::getComponentOfPriority(int priority) const
void PriorityMuxer::registerInput(int priority, hyperion::Components component, const QString& origin, const QString& owner, unsigned smooth_cfg)
{
// detect new registers
bool newInput = false, reusedInput = false;
bool newInput = false;
bool reusedInput = false;
if (!_activeInputs.contains(priority))
newInput = true;
else if(_prevVisComp == component || _activeInputs[priority].componentId == component)
@@ -165,7 +166,9 @@ void PriorityMuxer::registerInput(int priority, hyperion::Components component,
}
if (reusedInput)
{
emit timeRunner();
}
}
bool PriorityMuxer::setInput(int priority, const std::vector<ColorRgb>& ledColors, int64_t timeout_ms)
@@ -203,7 +206,9 @@ bool PriorityMuxer::setInput(int priority, const std::vector<ColorRgb>& ledColor
{
Debug(_log, "Priority %d is now %s", priority, active ? "active" : "inactive");
if (_currentPriority < priority)
{
emit prioritiesChanged();
}
setCurrentTime();
}
@@ -218,7 +223,7 @@ bool PriorityMuxer::setInputImage(int priority, const Image<ColorRgb>& image, in
return false;
}
// calc final timeout
// calculate final timeout
if(timeout_ms > 0)
timeout_ms = QDateTime::currentMSecsSinceEpoch() + timeout_ms;
@@ -252,13 +257,13 @@ bool PriorityMuxer::setInputImage(int priority, const Image<ColorRgb>& image, in
return true;
}
bool PriorityMuxer::setInputInactive(quint8 priority)
bool PriorityMuxer::setInputInactive(int priority)
{
Image<ColorRgb> image;
return setInputImage(priority, image, -100);
}
bool PriorityMuxer::clearInput(uint8_t priority)
bool PriorityMuxer::clearInput(int priority)
{
if (priority < PriorityMuxer::LOWEST_PRIORITY && _activeInputs.remove(priority))
{
@@ -288,7 +293,9 @@ void PriorityMuxer::clearAll(bool forceClearAll)
{
const InputInfo info = getInputInfo(key);
if ((info.componentId == hyperion::COMP_COLOR || info.componentId == hyperion::COMP_EFFECT || info.componentId == hyperion::COMP_IMAGE) && key < PriorityMuxer::LOWEST_PRIORITY-1)
{
clearInput(key);
}
}
}
}
@@ -303,7 +310,7 @@ void PriorityMuxer::setCurrentTime()
{
if (infoIt->timeoutTime_ms > 0 && infoIt->timeoutTime_ms <= now)
{
quint8 tPrio = infoIt->priority;
int tPrio = infoIt->priority;
infoIt = _activeInputs.erase(infoIt);
Debug(_log,"Timeout clear for priority %d",tPrio);
emit prioritiesChanged();
@@ -321,7 +328,7 @@ void PriorityMuxer::setCurrentTime()
++infoIt;
}
}
// eval if manual selected prio is still available
// evaluate, if manual selected priority is still available
if(!_sourceAutoSelectEnabled)
{
if(_activeInputs.contains(_manualSelectedPriority))

View File

@@ -11,6 +11,7 @@
"options":
{
"enum_titles": ["edt_conf_enum_automatic","AMLogic","DispmanX","DirectX9","Framebuffer","OSX","QT","X11","XCB"]
},
"default" : "auto",
"propertyOrder" : 1

View File

@@ -8,22 +8,22 @@
"top": {
"type": "integer",
"minimum": 0,
"default": 8
"default": 1
},
"bottom": {
"type": "integer",
"minimum": 0,
"default": 8
"default": 0
},
"left": {
"type": "integer",
"minimum": 0,
"default": 5
"default": 0
},
"right": {
"type": "integer",
"minimum": 0,
"default": 5
"default": 0
},
"glength": {
"type": "integer",

View File

@@ -47,7 +47,7 @@
"title" : "edt_conf_smooth_interpolationRate_title",
"minimum" : 1.0,
"maximum": 1000.0,
"default" : 0,
"default" : 1.0,
"append" : "edt_append_hz",
"propertyOrder" : 5
},
@@ -57,7 +57,7 @@
"title" : "edt_conf_smooth_outputRate_title",
"minimum" : 1.0,
"maximum": 1000.0,
"default" : 0,
"default" : 1.0,
"append" : "edt_append_hz",
"propertyOrder" : 6
},