mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
implement optional color correction for V4L only (#267)
* remove color temperatire, its the same as color adjustment * remove temperature from schema * implement most part of v4l only colro settings, now hyperion update knows from which component the colors come * update configs * fix webui config write * reomve correction and temperature from hyperion-remote
This commit is contained in:
@@ -165,7 +165,7 @@ void BoblightClientConnection::handleMessage(const QString & message)
|
||||
// send current color values to hyperion if this is the last led assuming leds values are send in order of id
|
||||
if ((ledIndex == _ledColors.size() -1) && _priority < 255)
|
||||
{
|
||||
_hyperion->setColors(_priority, _ledColors, -1);
|
||||
_hyperion->setColors(_priority, _ledColors, -1, hyperion::COMP_BOBLIGHTSERVER);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -203,7 +203,7 @@ void BoblightClientConnection::handleMessage(const QString & message)
|
||||
// send current color values to hyperion
|
||||
if (_priority < 255)
|
||||
{
|
||||
_hyperion->setColors(_priority, _ledColors, -1);
|
||||
_hyperion->setColors(_priority, _ledColors, -1, hyperion::COMP_BOBLIGHTSERVER);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@@ -261,7 +261,7 @@ PyObject* Effect::wrapSetColor(PyObject *self, PyObject *args)
|
||||
if (PyArg_ParseTuple(args, "bbb", &color.red, &color.green, &color.blue))
|
||||
{
|
||||
std::fill(effect->_colors.begin(), effect->_colors.end(), color);
|
||||
effect->setColors(effect->_priority, effect->_colors, timeout, false);
|
||||
effect->setColors(effect->_priority, effect->_colors, timeout, false, hyperion::COMP_EFFECT);
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
else
|
||||
@@ -282,7 +282,7 @@ PyObject* Effect::wrapSetColor(PyObject *self, PyObject *args)
|
||||
{
|
||||
char * data = PyByteArray_AS_STRING(bytearray);
|
||||
memcpy(effect->_colors.data(), data, length);
|
||||
effect->setColors(effect->_priority, effect->_colors, timeout, false);
|
||||
effect->setColors(effect->_priority, effect->_colors, timeout, false, hyperion::COMP_EFFECT);
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
else
|
||||
@@ -352,7 +352,7 @@ PyObject* Effect::wrapSetImage(PyObject *self, PyObject *args)
|
||||
memcpy(image.memptr(), data, length);
|
||||
|
||||
effect->_imageProcessor->process(image, effect->_colors);
|
||||
effect->setColors(effect->_priority, effect->_colors, timeout, false);
|
||||
effect->setColors(effect->_priority, effect->_colors, timeout, false, hyperion::COMP_EFFECT);
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
else
|
||||
@@ -428,7 +428,7 @@ PyObject* Effect::wrapImageShow(PyObject *self, PyObject *args)
|
||||
|
||||
memcpy(image.memptr(), binaryImage.data(), binaryImage.size());
|
||||
effect->_imageProcessor->process(image, effect->_colors);
|
||||
effect->setColors(effect->_priority, effect->_colors, timeout, false);
|
||||
effect->setColors(effect->_priority, effect->_colors, timeout, false, hyperion::COMP_EFFECT);
|
||||
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
#include <utils/Components.h>
|
||||
|
||||
class Effect : public QThread
|
||||
{
|
||||
@@ -42,7 +43,7 @@ public slots:
|
||||
signals:
|
||||
void effectFinished(Effect * effect);
|
||||
|
||||
void setColors(int priority, const std::vector<ColorRgb> &ledColors, const int timeout_ms, bool clearEffects);
|
||||
void setColors(int priority, const std::vector<ColorRgb> &ledColors, const int timeout_ms, bool clearEffects, hyperion::Components component);
|
||||
|
||||
private slots:
|
||||
void effectFinished();
|
||||
|
@@ -13,6 +13,7 @@
|
||||
// hyperion util includes
|
||||
#include <utils/jsonschema/QJsonSchemaChecker.h>
|
||||
#include <utils/FileUtils.h>
|
||||
#include <utils/Components.h>
|
||||
|
||||
// effect engine includes
|
||||
#include <effectengine/EffectEngine.h>
|
||||
@@ -28,6 +29,7 @@ EffectEngine::EffectEngine(Hyperion * hyperion, const QJsonObject & jsonEffectCo
|
||||
{
|
||||
Q_INIT_RESOURCE(EffectEngine);
|
||||
qRegisterMetaType<std::vector<ColorRgb>>("std::vector<ColorRgb>");
|
||||
qRegisterMetaType<hyperion::Components>("hyperion::Components");
|
||||
|
||||
// connect the Hyperion channel clear feedback
|
||||
connect(_hyperion, SIGNAL(channelCleared(int)), this, SLOT(channelCleared(int)));
|
||||
@@ -272,7 +274,7 @@ int EffectEngine::runEffectScript(const QString &script, const QString &name, co
|
||||
|
||||
// create the effect
|
||||
Effect * effect = new Effect(_mainThreadState, priority, timeout, script, name, args);
|
||||
connect(effect, SIGNAL(setColors(int,std::vector<ColorRgb>,int,bool)), _hyperion, SLOT(setColors(int,std::vector<ColorRgb>,int,bool)), Qt::QueuedConnection);
|
||||
connect(effect, SIGNAL(setColors(int,std::vector<ColorRgb>,int,bool,hyperion::Components)), _hyperion, SLOT(setColors(int,std::vector<ColorRgb>,int,bool,hyperion::Components)), Qt::QueuedConnection);
|
||||
connect(effect, SIGNAL(effectFinished(Effect*)), this, SLOT(effectFinished(Effect*)));
|
||||
_activeEffects.push_back(effect);
|
||||
|
||||
|
@@ -47,7 +47,7 @@ void AmlogicWrapper::action()
|
||||
}
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
_hyperion->setColors(_priority, _ledColors, _timeout_ms);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
void AmlogicWrapper::setVideoMode(const VideoMode mode)
|
||||
|
@@ -43,7 +43,7 @@ void DispmanxWrapper::action()
|
||||
}
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
_hyperion->setColors(_priority, _ledColors, _timeout_ms);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
void DispmanxWrapper::kodiPlay()
|
||||
|
@@ -37,7 +37,7 @@ void FramebufferWrapper::action()
|
||||
}
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
_hyperion->setColors(_priority, _ledColors, _timeout_ms);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
void FramebufferWrapper::setVideoMode(const VideoMode mode)
|
||||
|
@@ -37,7 +37,7 @@ void OsxWrapper::action()
|
||||
}
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
_hyperion->setColors(_priority, _ledColors, _timeout_ms);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -35,6 +35,7 @@ V4L2Wrapper::V4L2Wrapper(const std::string &device,
|
||||
// register the image type
|
||||
qRegisterMetaType<Image<ColorRgb>>("Image<ColorRgb>");
|
||||
qRegisterMetaType<std::vector<ColorRgb>>("std::vector<ColorRgb>");
|
||||
qRegisterMetaType<hyperion::Components>("hyperion::Components");
|
||||
|
||||
// Handle the image in the captured thread using a direct connection
|
||||
QObject::connect(&_grabber, SIGNAL(newFrame(Image<ColorRgb>)), this, SLOT(newFrame(Image<ColorRgb>)), Qt::DirectConnection);
|
||||
@@ -88,7 +89,7 @@ void V4L2Wrapper::newFrame(const Image<ColorRgb> &image)
|
||||
|
||||
// process the new image
|
||||
_processor->process(image, _ledColors);
|
||||
_hyperion->setColors(_priority, _ledColors, _timeout_ms);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
void V4L2Wrapper::readError(const char* err)
|
||||
|
@@ -70,7 +70,7 @@ void X11Wrapper::action()
|
||||
}
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
_hyperion->setColors(_priority, _ledColors, _timeout_ms);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -20,7 +20,6 @@ SET(Hyperion_HEADERS
|
||||
${CURRENT_HEADER_DIR}/PriorityMuxer.h
|
||||
|
||||
${CURRENT_SOURCE_DIR}/MultiColorTransform.h
|
||||
${CURRENT_SOURCE_DIR}/MultiColorCorrection.h
|
||||
${CURRENT_SOURCE_DIR}/MultiColorAdjustment.h
|
||||
${CURRENT_HEADER_DIR}/MessageForwarder.h
|
||||
)
|
||||
@@ -34,7 +33,6 @@ SET(Hyperion_SOURCES
|
||||
|
||||
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
|
||||
${CURRENT_SOURCE_DIR}/MultiColorTransform.cpp
|
||||
${CURRENT_SOURCE_DIR}/MultiColorCorrection.cpp
|
||||
${CURRENT_SOURCE_DIR}/MultiColorAdjustment.cpp
|
||||
${CURRENT_SOURCE_DIR}/LinearColorSmoothing.cpp
|
||||
${CURRENT_SOURCE_DIR}/MessageForwarder.cpp
|
||||
|
@@ -18,9 +18,10 @@ GrabberWrapper::GrabberWrapper(std::string grabberName, const int priority, hype
|
||||
|
||||
_forward = _hyperion->getForwarder()->protoForwardingEnabled();
|
||||
_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_BLACKBORDER, _processor->blackBorderDetectorEnabled());
|
||||
qRegisterMetaType<hyperion::Components>("hyperion::Components");
|
||||
|
||||
connect(_hyperion, SIGNAL(componentStateChanged(hyperion::Components,bool)), this, SLOT(componentStateChanged(hyperion::Components,bool)));
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(action()));
|
||||
|
||||
}
|
||||
|
||||
GrabberWrapper::~GrabberWrapper()
|
||||
@@ -116,3 +117,8 @@ void GrabberWrapper::setGrabbingMode(const GrabbingMode mode)
|
||||
}
|
||||
}
|
||||
|
||||
void GrabberWrapper::setColors(const std::vector<ColorRgb> &ledColors, const int timeout_ms)
|
||||
{
|
||||
_hyperion->setColors(_priority, ledColors, timeout_ms, true, _grabberComponentId);
|
||||
}
|
||||
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ColorTransform.h>
|
||||
#include <hyperion/ColorCorrection.h>
|
||||
#include <hyperion/ColorAdjustment.h>
|
||||
|
||||
// Leddevice includes
|
||||
@@ -28,7 +27,6 @@
|
||||
#include <leddevice/LedDeviceFactory.h>
|
||||
|
||||
#include "MultiColorTransform.h"
|
||||
#include "MultiColorCorrection.h"
|
||||
#include "MultiColorAdjustment.h"
|
||||
#include "LinearColorSmoothing.h"
|
||||
|
||||
@@ -90,23 +88,6 @@ ColorTransform * Hyperion::createColorTransform(const QJsonObject & transformCon
|
||||
}
|
||||
|
||||
|
||||
ColorCorrection * Hyperion::createColorCorrection(const QJsonObject & correctionConfig)
|
||||
{
|
||||
const std::string id = correctionConfig["id"].toString("default").toStdString();
|
||||
|
||||
RgbChannelAdjustment * rgbCorrection = createRgbChannelCorrection(correctionConfig["correctionValues"].toObject());
|
||||
|
||||
ColorCorrection * correction = new ColorCorrection();
|
||||
correction->_id = id;
|
||||
correction->_rgbCorrection = *rgbCorrection;
|
||||
|
||||
// Cleanup the allocated individual transforms
|
||||
delete rgbCorrection;
|
||||
|
||||
return correction;
|
||||
}
|
||||
|
||||
|
||||
ColorAdjustment * Hyperion::createColorAdjustment(const QJsonObject & adjustmentConfig)
|
||||
{
|
||||
const std::string id = adjustmentConfig["id"].toString("default").toStdString();
|
||||
@@ -205,83 +186,6 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt,
|
||||
return transform;
|
||||
}
|
||||
|
||||
MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCnt, const QJsonObject & colorConfig)
|
||||
{
|
||||
// Create the result, the corrections are added to this
|
||||
MultiColorCorrection * correction = new MultiColorCorrection(ledCnt);
|
||||
Logger * log = Logger::getInstance("Core");
|
||||
|
||||
const QString jsonKey = colorConfig.contains("temperature") ? "temperature" : "correction";
|
||||
const QJsonValue correctionConfig = colorConfig[jsonKey];
|
||||
if (correctionConfig.isNull())
|
||||
{
|
||||
// Old style color correction config (just one for all leds)
|
||||
ColorCorrection * colorCorrection = createColorCorrection(colorConfig);
|
||||
correction->addCorrection(colorCorrection);
|
||||
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
|
||||
}
|
||||
else if (correctionConfig.isObject())
|
||||
{
|
||||
ColorCorrection * colorCorrection = createColorCorrection(correctionConfig.toObject());
|
||||
correction->addCorrection(colorCorrection);
|
||||
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
|
||||
}
|
||||
else if (correctionConfig.isArray())
|
||||
{
|
||||
const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
|
||||
|
||||
const QJsonArray & correctionConfigArray = correctionConfig.toArray();
|
||||
for (signed i = 0; i < correctionConfigArray.size(); ++i)
|
||||
{
|
||||
const QJsonObject & config = correctionConfigArray.at(i).toObject();
|
||||
ColorCorrection * colorCorrection = createColorCorrection(config);
|
||||
correction->addCorrection(colorCorrection);
|
||||
|
||||
const QString ledIndicesStr = config["leds"].toString("").trimmed();
|
||||
if (ledIndicesStr.compare("*") == 0)
|
||||
{
|
||||
// Special case for indices '*' => all leds
|
||||
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
|
||||
Info(log, "ColorTemperature '%s' => [0; %d]", colorCorrection->_id.c_str(), ledCnt-1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!overallExp.exactMatch(ledIndicesStr))
|
||||
{
|
||||
Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
const QStringList ledIndexList = ledIndicesStr.split(",");
|
||||
for (int i=0; i<ledIndexList.size(); ++i) {
|
||||
if (i > 0)
|
||||
{
|
||||
ss << ", ";
|
||||
}
|
||||
if (ledIndexList[i].contains("-"))
|
||||
{
|
||||
QStringList ledIndices = ledIndexList[i].split("-");
|
||||
int startInd = ledIndices[0].toInt();
|
||||
int endInd = ledIndices[1].toInt();
|
||||
|
||||
correction->setCorrectionForLed(colorCorrection->_id, startInd, endInd);
|
||||
ss << startInd << "-" << endInd;
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = ledIndexList[i].toInt();
|
||||
correction->setCorrectionForLed(colorCorrection->_id, index, index);
|
||||
ss << index;
|
||||
}
|
||||
}
|
||||
Info(log, "ColorTemperature '%s' => [%s]", colorCorrection->_id.c_str(), ss.str().c_str());
|
||||
}
|
||||
}
|
||||
return correction;
|
||||
}
|
||||
|
||||
|
||||
MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt, const QJsonObject & colorConfig)
|
||||
{
|
||||
// Create the result, the transforms are added to this
|
||||
@@ -385,16 +289,6 @@ RgbChannelTransform* Hyperion::createRgbChannelTransform(const QJsonObject& colo
|
||||
return transform;
|
||||
}
|
||||
|
||||
RgbChannelAdjustment* Hyperion::createRgbChannelCorrection(const QJsonObject& colorConfig)
|
||||
{
|
||||
const int varR = colorConfig["red"].toInt(255);
|
||||
const int varG = colorConfig["green"].toInt(255);
|
||||
const int varB = colorConfig["blue"].toInt(255);
|
||||
|
||||
RgbChannelAdjustment* correction = new RgbChannelAdjustment(varR, varG, varB);
|
||||
return correction;
|
||||
}
|
||||
|
||||
RgbChannelAdjustment* Hyperion::createRgbChannelAdjustment(const QJsonObject& colorConfig, const RgbChannel color)
|
||||
{
|
||||
int varR=0, varG=0, varB=0;
|
||||
@@ -628,7 +522,6 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const QJsonObject &qjsonConfig
|
||||
, _ledStringClone(createLedStringClone(qjsonConfig["leds"], createColorOrder(qjsonConfig["device"].toObject())))
|
||||
, _muxer(_ledString.leds().size())
|
||||
, _raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), qjsonConfig["color"].toObject()))
|
||||
, _raw2ledTemperature(createLedColorsTemperature(_ledString.leds().size(), qjsonConfig["color"].toObject()))
|
||||
, _raw2ledAdjustment(createLedColorsAdjustment(_ledString.leds().size(), qjsonConfig["color"].toObject()))
|
||||
, _effectEngine(nullptr)
|
||||
, _messageForwarder(createMessageForwarder(qjsonConfig["forwarder"].toObject()))
|
||||
@@ -638,6 +531,8 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const QJsonObject &qjsonConfig
|
||||
, _timer()
|
||||
, _log(Logger::getInstance("Core"))
|
||||
, _hwLedCount(_ledString.leds().size())
|
||||
, _colorAdjustmentV4Lonly(false)
|
||||
, _colorTransformV4Lonly(false)
|
||||
, _sourceAutoSelectEnabled(true)
|
||||
, _configHash()
|
||||
, _ledGridSize(getLedLayoutGridSize(qjsonConfig["leds"]))
|
||||
@@ -648,10 +543,6 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const QJsonObject &qjsonConfig
|
||||
{
|
||||
throw std::runtime_error("Color adjustment incorrectly set");
|
||||
}
|
||||
if (!_raw2ledTemperature->verifyCorrections())
|
||||
{
|
||||
throw std::runtime_error("Color temperature incorrectly set");
|
||||
}
|
||||
if (!_raw2ledTransform->verifyTransforms())
|
||||
{
|
||||
throw std::runtime_error("Color transformation incorrectly set");
|
||||
@@ -660,11 +551,15 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const QJsonObject &qjsonConfig
|
||||
const QJsonObject& color = qjsonConfig["color"].toObject();
|
||||
_transformEnabled = color["transform_enable"].toBool(true);
|
||||
_adjustmentEnabled = color["channelAdjustment_enable"].toBool(true);
|
||||
_temperatureEnabled = color["temperature_enable"].toBool(true);
|
||||
|
||||
_colorTransformV4Lonly = color["transform_v4l_only"].toBool(false);
|
||||
_colorAdjustmentV4Lonly = color["channelAdjustment_v4l_only"].toBool(false);
|
||||
|
||||
InfoIf(!_transformEnabled , _log, "Color transformation disabled" );
|
||||
InfoIf(!_adjustmentEnabled , _log, "Color adjustment disabled" );
|
||||
InfoIf(!_temperatureEnabled, _log, "Color temperature disabled" );
|
||||
|
||||
InfoIf(_colorTransformV4Lonly , _log, "Color transformation for v4l inputs only" );
|
||||
InfoIf(_colorAdjustmentV4Lonly , _log, "Color adjustment for v4l inputs only" );
|
||||
|
||||
// initialize the image processor factory
|
||||
ImageProcessorFactory::getInstance().init(
|
||||
@@ -709,7 +604,6 @@ Hyperion::~Hyperion()
|
||||
delete _effectEngine;
|
||||
delete _device;
|
||||
delete _raw2ledTransform;
|
||||
delete _raw2ledTemperature;
|
||||
delete _raw2ledAdjustment;
|
||||
delete _messageForwarder;
|
||||
}
|
||||
@@ -807,10 +701,10 @@ void Hyperion::setColor(int priority, const ColorRgb &color, const int timeout_m
|
||||
std::vector<ColorRgb> ledColors(_ledString.leds().size(), color);
|
||||
|
||||
// set colors
|
||||
setColors(priority, ledColors, timeout_ms, clearEffects);
|
||||
setColors(priority, ledColors, timeout_ms, clearEffects, hyperion::COMP_COLOR);
|
||||
}
|
||||
|
||||
void Hyperion::setColors(int priority, const std::vector<ColorRgb>& ledColors, const int timeout_ms, bool clearEffects)
|
||||
void Hyperion::setColors(int priority, const std::vector<ColorRgb>& ledColors, const int timeout_ms, bool clearEffects, hyperion::Components component)
|
||||
{
|
||||
// clear effects if this call does not come from an effect
|
||||
if (clearEffects)
|
||||
@@ -821,11 +715,11 @@ void Hyperion::setColors(int priority, const std::vector<ColorRgb>& ledColors, c
|
||||
if (timeout_ms > 0)
|
||||
{
|
||||
const uint64_t timeoutTime = QDateTime::currentMSecsSinceEpoch() + timeout_ms;
|
||||
_muxer.setInput(priority, ledColors, timeoutTime);
|
||||
_muxer.setInput(priority, ledColors, timeoutTime, component);
|
||||
}
|
||||
else
|
||||
{
|
||||
_muxer.setInput(priority, ledColors);
|
||||
_muxer.setInput(priority, ledColors, -1, component);
|
||||
}
|
||||
|
||||
if (! _sourceAutoSelectEnabled || priority == _muxer.getCurrentPriority())
|
||||
@@ -839,11 +733,6 @@ const std::vector<std::string> & Hyperion::getTransformIds() const
|
||||
return _raw2ledTransform->getTransformIds();
|
||||
}
|
||||
|
||||
const std::vector<std::string> & Hyperion::getTemperatureIds() const
|
||||
{
|
||||
return _raw2ledTemperature->getCorrectionIds();
|
||||
}
|
||||
|
||||
const std::vector<std::string> & Hyperion::getAdjustmentIds() const
|
||||
{
|
||||
return _raw2ledAdjustment->getAdjustmentIds();
|
||||
@@ -854,11 +743,6 @@ ColorTransform * Hyperion::getTransform(const std::string& id)
|
||||
return _raw2ledTransform->getTransform(id);
|
||||
}
|
||||
|
||||
ColorCorrection * Hyperion::getTemperature(const std::string& id)
|
||||
{
|
||||
return _raw2ledTemperature->getCorrection(id);
|
||||
}
|
||||
|
||||
ColorAdjustment * Hyperion::getAdjustment(const std::string& id)
|
||||
{
|
||||
return _raw2ledAdjustment->getAdjustment(id);
|
||||
@@ -869,16 +753,6 @@ void Hyperion::transformsUpdated()
|
||||
update();
|
||||
}
|
||||
|
||||
void Hyperion::correctionsUpdated()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void Hyperion::temperaturesUpdated()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void Hyperion::adjustmentsUpdated()
|
||||
{
|
||||
update();
|
||||
@@ -962,11 +836,14 @@ void Hyperion::update()
|
||||
_ledBuffer.reserve(_hwLedCount);
|
||||
_ledBuffer = priorityInfo.ledColors;
|
||||
|
||||
// Apply the correction and the transform to each led and color-channel
|
||||
// Avoid applying correction, the same task is performed by adjustment
|
||||
if (_transformEnabled) _raw2ledTransform->applyTransform(_ledBuffer);
|
||||
if (_adjustmentEnabled) _raw2ledAdjustment->applyAdjustment(_ledBuffer);
|
||||
if (_temperatureEnabled) _raw2ledTemperature->applyCorrection(_ledBuffer);
|
||||
if ( _transformEnabled && (!_colorTransformV4Lonly || priorityInfo.componentId == hyperion::COMP_V4L) )
|
||||
{
|
||||
_raw2ledTransform->applyTransform(_ledBuffer);
|
||||
}
|
||||
if ( _adjustmentEnabled && (!_colorAdjustmentV4Lonly || priorityInfo.componentId == hyperion::COMP_V4L) )
|
||||
{
|
||||
_raw2ledAdjustment->applyAdjustment(_ledBuffer);
|
||||
}
|
||||
|
||||
// init colororder vector, if empty
|
||||
if (_ledStringColorOrder.empty())
|
||||
|
@@ -1,92 +0,0 @@
|
||||
|
||||
// STL includes
|
||||
#include <cassert>
|
||||
|
||||
// Hyperion includes
|
||||
#include <utils/Logger.h>
|
||||
#include "MultiColorCorrection.h"
|
||||
|
||||
MultiColorCorrection::MultiColorCorrection(const unsigned ledCnt) :
|
||||
_ledCorrections(ledCnt, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
MultiColorCorrection::~MultiColorCorrection()
|
||||
{
|
||||
// Clean up all the correctinos
|
||||
for (ColorCorrection * correction : _correction)
|
||||
{
|
||||
delete correction;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiColorCorrection::addCorrection(ColorCorrection * correction)
|
||||
{
|
||||
_correctionIds.push_back(correction->_id);
|
||||
_correction.push_back(correction);
|
||||
}
|
||||
|
||||
void MultiColorCorrection::setCorrectionForLed(const std::string& id, const unsigned startLed, const unsigned endLed)
|
||||
{
|
||||
assert(startLed <= endLed);
|
||||
assert(endLed < _ledCorrections.size());
|
||||
|
||||
// Get the identified correction (don't care if is nullptr)
|
||||
ColorCorrection * correction = getCorrection(id);
|
||||
for (unsigned iLed=startLed; iLed<=endLed; ++iLed)
|
||||
{
|
||||
_ledCorrections[iLed] = correction;
|
||||
}
|
||||
}
|
||||
|
||||
bool MultiColorCorrection::verifyCorrections() const
|
||||
{
|
||||
for (unsigned iLed=0; iLed<_ledCorrections.size(); ++iLed)
|
||||
{
|
||||
if (_ledCorrections[iLed] == nullptr)
|
||||
{
|
||||
Warning(Logger::getInstance("ColorCorrect"), "No adjustment set for %d", iLed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::vector<std::string> & MultiColorCorrection::getCorrectionIds()
|
||||
{
|
||||
return _correctionIds;
|
||||
}
|
||||
|
||||
ColorCorrection* MultiColorCorrection::getCorrection(const std::string& id)
|
||||
{
|
||||
// Iterate through the unique corrections until we find the one with the given id
|
||||
for (ColorCorrection * correction : _correction)
|
||||
{
|
||||
if (correction->_id == id)
|
||||
{
|
||||
return correction;
|
||||
}
|
||||
}
|
||||
|
||||
// The ColorCorrection was not found
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MultiColorCorrection::applyCorrection(std::vector<ColorRgb>& ledColors)
|
||||
{
|
||||
const size_t itCnt = std::min(_ledCorrections.size(), ledColors.size());
|
||||
for (size_t i=0; i<itCnt; ++i)
|
||||
{
|
||||
ColorCorrection * correction = _ledCorrections[i];
|
||||
if (correction == nullptr)
|
||||
{
|
||||
// No correction set for this led (do nothing)
|
||||
continue;
|
||||
}
|
||||
ColorRgb& color = ledColors[i];
|
||||
|
||||
color.red = correction->_rgbCorrection.adjustmentR(color.red);
|
||||
color.green = correction->_rgbCorrection.adjustmentG(color.green);
|
||||
color.blue = correction->_rgbCorrection.adjustmentB(color.blue);
|
||||
}
|
||||
}
|
@@ -1,64 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// STL includes
|
||||
#include <vector>
|
||||
|
||||
// Utils includes
|
||||
#include <utils/ColorRgb.h>
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/ColorCorrection.h>
|
||||
|
||||
///
|
||||
/// The LedColorCorrection is responsible for performing color correction from 'raw' colors
|
||||
/// received as input to colors mapped to match the color-properties of the leds.
|
||||
///
|
||||
class MultiColorCorrection
|
||||
{
|
||||
public:
|
||||
MultiColorCorrection(const unsigned ledCnt);
|
||||
~MultiColorCorrection();
|
||||
|
||||
/**
|
||||
* Adds a new ColorCorrection to this MultiColorCorrection
|
||||
*
|
||||
* @param Correction The new ColorCorrection (ownership is transfered)
|
||||
*/
|
||||
void addCorrection(ColorCorrection * correction);
|
||||
|
||||
void setCorrectionForLed(const std::string& id, const unsigned startLed, const unsigned endLed);
|
||||
|
||||
bool verifyCorrections() const;
|
||||
|
||||
///
|
||||
/// Returns the identifier of all the unique ColorCorrection
|
||||
///
|
||||
/// @return The list with unique id's of the ColorCorrections
|
||||
const std::vector<std::string> & getCorrectionIds();
|
||||
|
||||
///
|
||||
/// Returns the pointer to the ColorCorrection with the given id
|
||||
///
|
||||
/// @param id The identifier of the ColorCorrection
|
||||
///
|
||||
/// @return The ColorCorrection with the given id (or nullptr if it does not exist)
|
||||
///
|
||||
ColorCorrection* getCorrection(const std::string& id);
|
||||
|
||||
///
|
||||
/// Performs the color transoformation from raw-color to led-color
|
||||
///
|
||||
/// @param ledColors The list with led colors
|
||||
///
|
||||
void applyCorrection(std::vector<ColorRgb>& ledColors);
|
||||
|
||||
private:
|
||||
/// List with Correction ids
|
||||
std::vector<std::string> _correctionIds;
|
||||
|
||||
/// List with unique ColorCorrections
|
||||
std::vector<ColorCorrection*> _correction;
|
||||
|
||||
/// List with a pointer to the ColorCorrection for each individual led
|
||||
std::vector<ColorCorrection*> _ledCorrections;
|
||||
};
|
@@ -48,13 +48,13 @@ const PriorityMuxer::InputInfo& PriorityMuxer::getInputInfo(const int priority)
|
||||
return elemIt.value();
|
||||
}
|
||||
|
||||
void PriorityMuxer::setInput(const int priority, const std::vector<ColorRgb>& ledColors, const int64_t timeoutTime_ms)
|
||||
void PriorityMuxer::setInput(const int priority, const std::vector<ColorRgb>& ledColors, const int64_t timeoutTime_ms, hyperion::Components component)
|
||||
{
|
||||
InputInfo& input = _activeInputs[priority];
|
||||
input.priority = priority;
|
||||
input.timeoutTime_ms = timeoutTime_ms;
|
||||
input.ledColors = ledColors;
|
||||
|
||||
input.componentId = component;
|
||||
_currentPriority = std::min(_currentPriority, priority);
|
||||
}
|
||||
|
||||
|
@@ -67,13 +67,20 @@
|
||||
"channelAdjustment_enable" :
|
||||
{
|
||||
"type" : "boolean",
|
||||
"default" : true,
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"channelAdjustment_v4l_only" :
|
||||
{
|
||||
"type" : "boolean",
|
||||
"default" : false,
|
||||
"propertyOrder" : 2
|
||||
},
|
||||
"channelAdjustment" :
|
||||
{
|
||||
"type" : "array",
|
||||
"required" : true,
|
||||
"propertyOrder" : 2,
|
||||
"propertyOrder" : 3,
|
||||
"items" :
|
||||
{
|
||||
"type" : "object",
|
||||
@@ -184,74 +191,23 @@
|
||||
"additionalProperties" : false
|
||||
}
|
||||
},
|
||||
"temperature_enable" :
|
||||
{
|
||||
"type" : "boolean"
|
||||
},
|
||||
"temperature" :
|
||||
{
|
||||
"type" : "array",
|
||||
"required" : true,
|
||||
"items" :
|
||||
{
|
||||
"type" : "object",
|
||||
"required" : true,
|
||||
"properties" :
|
||||
{
|
||||
"id" :
|
||||
{
|
||||
"type" : "string",
|
||||
"required" : true
|
||||
},
|
||||
"leds" :
|
||||
{
|
||||
"type" : "string",
|
||||
"required" : true
|
||||
},
|
||||
"correctionValues" :
|
||||
{
|
||||
"type":"object",
|
||||
"required" : true,
|
||||
"properties":
|
||||
{
|
||||
"red" :
|
||||
{
|
||||
"type": "integer",
|
||||
"required" : true,
|
||||
"minimum": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
"green" :
|
||||
{
|
||||
"type": "integer",
|
||||
"required" : true,
|
||||
"minimum": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
"blue" :
|
||||
{
|
||||
"type": "integer",
|
||||
"required" : true,
|
||||
"minimum": 0,
|
||||
"maximum": 255
|
||||
}
|
||||
},
|
||||
"additionalProperties" : false
|
||||
}
|
||||
},
|
||||
"additionalProperties" : false
|
||||
}
|
||||
},
|
||||
"transform_enable" :
|
||||
{
|
||||
"type" : "boolean",
|
||||
"propertyOrder" : 3
|
||||
"default" : true,
|
||||
"propertyOrder" : 4
|
||||
},
|
||||
"transform_v4l_only" :
|
||||
{
|
||||
"type" : "boolean",
|
||||
"default" : false,
|
||||
"propertyOrder" : 5
|
||||
},
|
||||
"transform" :
|
||||
{
|
||||
"type" : "array",
|
||||
"required" : true,
|
||||
"propertyOrder" : 4,
|
||||
"propertyOrder" : 6,
|
||||
"items" :
|
||||
{
|
||||
"type" : "object",
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
#include <hyperion/MessageForwarder.h>
|
||||
#include <hyperion/ColorTransform.h>
|
||||
#include <hyperion/ColorCorrection.h>
|
||||
#include <hyperion/ColorAdjustment.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <leddevice/LedDevice.h>
|
||||
@@ -291,8 +290,6 @@ void JsonClientConnection::handleMessage(const QString& messageString)
|
||||
handleClearallCommand(message, command, tan);
|
||||
else if (command == "transform")
|
||||
handleTransformCommand(message, command, tan);
|
||||
else if (command == "temperature")
|
||||
handleTemperatureCommand(message, command, tan);
|
||||
else if (command == "adjustment")
|
||||
handleAdjustmentCommand(message, command, tan);
|
||||
else if (command == "sourceselect")
|
||||
@@ -492,34 +489,9 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt
|
||||
item["owner"] = QString::fromStdString(entry.first);
|
||||
priorities.append(item);
|
||||
}
|
||||
|
||||
|
||||
info["priorities"] = priorities;
|
||||
|
||||
// collect temperature correction information
|
||||
QJsonArray temperatureArray;
|
||||
for (const std::string& tempId : _hyperion->getTemperatureIds())
|
||||
{
|
||||
const ColorCorrection * colorTemp = _hyperion->getTemperature(tempId);
|
||||
if (colorTemp == nullptr)
|
||||
{
|
||||
Error(_log, "Incorrect color temperature correction id: %s", tempId.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
QJsonObject temperature;
|
||||
temperature["id"] = QString::fromStdString(tempId);
|
||||
|
||||
QJsonArray tempValues;
|
||||
tempValues.append(colorTemp->_rgbCorrection.getAdjustmentR());
|
||||
tempValues.append(colorTemp->_rgbCorrection.getAdjustmentG());
|
||||
tempValues.append(colorTemp->_rgbCorrection.getAdjustmentB());
|
||||
temperature.insert("correctionValues", tempValues);
|
||||
temperatureArray.append(temperature);
|
||||
}
|
||||
|
||||
info["temperature"] = temperatureArray;
|
||||
|
||||
|
||||
// collect transform information
|
||||
QJsonArray transformArray;
|
||||
for (const std::string& transformId : _hyperion->getTransformIds())
|
||||
@@ -849,32 +821,6 @@ void JsonClientConnection::handleTransformCommand(const QJsonObject& message, co
|
||||
}
|
||||
|
||||
|
||||
void JsonClientConnection::handleTemperatureCommand(const QJsonObject& message, const QString& command, const int tan)
|
||||
{
|
||||
const QJsonObject & temperature = message["temperature"].toObject();
|
||||
|
||||
const QString tempId = temperature["id"].toString(QString::fromStdString(_hyperion->getTemperatureIds().front()));
|
||||
ColorCorrection * colorTemperature = _hyperion->getTemperature(tempId.toStdString());
|
||||
if (colorTemperature == nullptr)
|
||||
{
|
||||
Warning(_log, "Incorrect temperature identifier: %s", tempId.toStdString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (temperature.contains("correctionValues"))
|
||||
{
|
||||
const QJsonArray & values = temperature["correctionValues"].toArray();
|
||||
colorTemperature->_rgbCorrection.setAdjustmentR(values[0u].toInt());
|
||||
colorTemperature->_rgbCorrection.setAdjustmentG(values[1u].toInt());
|
||||
colorTemperature->_rgbCorrection.setAdjustmentB(values[2u].toInt());
|
||||
}
|
||||
|
||||
// commit the changes
|
||||
_hyperion->temperaturesUpdated();
|
||||
|
||||
sendSuccessReply(command, tan);
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleAdjustmentCommand(const QJsonObject& message, const QString& command, const int tan)
|
||||
{
|
||||
const QJsonObject & adjustment = message["adjustment"].toObject();
|
||||
|
@@ -116,14 +116,7 @@ private:
|
||||
/// @param message the incoming message
|
||||
///
|
||||
void handleTransformCommand(const QJsonObject & message, const QString &command, const int tan);
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON Temperature message
|
||||
///
|
||||
/// @param message the incoming message
|
||||
///
|
||||
void handleTemperatureCommand(const QJsonObject & message, const QString &command, const int tan);
|
||||
|
||||
|
||||
///
|
||||
/// Handle an incoming JSON Adjustment message
|
||||
///
|
||||
|
@@ -130,6 +130,6 @@ void UDPListener::processTheDatagram(const QByteArray * datagram)
|
||||
rgb.blue = datagram->at(ledIndex*3+2);
|
||||
}
|
||||
|
||||
_hyperion->setColors(_priority, _ledColors, _timeout, -1);
|
||||
_hyperion->setColors(_priority, _ledColors, _timeout, -1, hyperion::COMP_UDPLISTENER);
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user