mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Merge remote-tracking branch 'hyperion-project/master' into userauthapi
This commit is contained in:
@@ -19,7 +19,9 @@
|
||||
"type" : "bool"
|
||||
},
|
||||
"interval": {
|
||||
"type" : "integer"
|
||||
"type" : "integer",
|
||||
"required" : false,
|
||||
"minimum": 50
|
||||
}
|
||||
},
|
||||
|
||||
|
@@ -12,17 +12,16 @@
|
||||
#include <QImage>
|
||||
#include <QBuffer>
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
#include <QHostInfo>
|
||||
#include <QMutexLocker>
|
||||
#include <QTimer>
|
||||
|
||||
// hyperion includes
|
||||
#include <utils/jsonschema/QJsonFactory.h>
|
||||
#include <utils/SysInfo.h>
|
||||
#include <HyperionConfig.h>
|
||||
#include <utils/ColorSys.h>
|
||||
#include <leddevice/LedDeviceWrapper.h>
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
#include <utils/jsonschema/QJsonFactory.h>
|
||||
#include <utils/jsonschema/QJsonSchemaChecker.h>
|
||||
#include <HyperionConfig.h>
|
||||
#include <utils/SysInfo.h>
|
||||
#include <utils/ColorSys.h>
|
||||
#include <utils/Process.h>
|
||||
#include <utils/JsonUtils.h>
|
||||
|
||||
@@ -53,8 +52,8 @@ JsonAPI::JsonAPI(QString peerAddress, Logger* log, const bool& localConnection,
|
||||
, _hyperion(nullptr)
|
||||
, _jsonCB(new JsonCB(this))
|
||||
, _streaming_logging_activated(false)
|
||||
, _image_stream_timeout(0)
|
||||
, _led_stream_timeout(0)
|
||||
, _imageStreamTimer(new QTimer(this))
|
||||
, _ledStreamTimer(new QTimer(this))
|
||||
{
|
||||
Q_INIT_RESOURCE(JSONRPC_schemas);
|
||||
|
||||
@@ -1024,28 +1023,68 @@ void JsonAPI::handleLedColorsCommand(const QJsonObject& message, const QString &
|
||||
// create result
|
||||
QString subcommand = message["subcommand"].toString("");
|
||||
|
||||
// max 20 Hz (50ms) interval for streaming (default: 10 Hz (100ms))
|
||||
qint64 streaming_interval = qMax(message["interval"].toInt(100), 50);
|
||||
|
||||
if (subcommand == "ledstream-start")
|
||||
{
|
||||
_streaming_leds_reply["success"] = true;
|
||||
_streaming_leds_reply["command"] = command+"-ledstream-update";
|
||||
_streaming_leds_reply["tan"] = tan;
|
||||
connect(_hyperion, &Hyperion::rawLedColors, this, &JsonAPI::streamLedcolorsUpdate, Qt::UniqueConnection);
|
||||
|
||||
connect(_hyperion, &Hyperion::rawLedColors, this, [=](const std::vector<ColorRgb>& ledValues)
|
||||
{
|
||||
_currentLedValues = ledValues;
|
||||
|
||||
// necessary because Qt::UniqueConnection for lambdas does not work until 5.9
|
||||
// see: https://bugreports.qt.io/browse/QTBUG-52438
|
||||
if (!_ledStreamConnection)
|
||||
_ledStreamConnection = connect(_ledStreamTimer, &QTimer::timeout, this, [=]()
|
||||
{
|
||||
emit streamLedcolorsUpdate(_currentLedValues);
|
||||
}, Qt::UniqueConnection);
|
||||
|
||||
// start the timer
|
||||
if (!_ledStreamTimer->isActive() || _ledStreamTimer->interval() != streaming_interval)
|
||||
_ledStreamTimer->start(streaming_interval);
|
||||
}, Qt::UniqueConnection);
|
||||
}
|
||||
else if (subcommand == "ledstream-stop")
|
||||
{
|
||||
disconnect(_hyperion, &Hyperion::rawLedColors, this, &JsonAPI::streamLedcolorsUpdate);
|
||||
disconnect(_hyperion, &Hyperion::rawLedColors, this, 0);
|
||||
_ledStreamTimer->stop();
|
||||
disconnect(_ledStreamConnection);
|
||||
}
|
||||
else if (subcommand == "imagestream-start")
|
||||
{
|
||||
_streaming_image_reply["success"] = true;
|
||||
_streaming_image_reply["command"] = command+"-imagestream-update";
|
||||
_streaming_image_reply["tan"] = tan;
|
||||
connect(_hyperion, &Hyperion::currentImage, this, &JsonAPI::setImage, Qt::UniqueConnection);
|
||||
|
||||
connect(_hyperion, &Hyperion::currentImage, this, [=](const Image<ColorRgb>& image)
|
||||
{
|
||||
_currentImage = image;
|
||||
|
||||
// necessary because Qt::UniqueConnection for lambdas does not work until 5.9
|
||||
// see: https://bugreports.qt.io/browse/QTBUG-52438
|
||||
if (!_imageStreamConnection)
|
||||
_imageStreamConnection = connect(_imageStreamTimer, &QTimer::timeout, this, [=]()
|
||||
{
|
||||
emit setImage(_currentImage);
|
||||
}, Qt::UniqueConnection);
|
||||
|
||||
// start timer
|
||||
if (!_imageStreamTimer->isActive() || _imageStreamTimer->interval() != streaming_interval)
|
||||
_imageStreamTimer->start(streaming_interval);
|
||||
}, Qt::UniqueConnection);
|
||||
|
||||
_hyperion->update();
|
||||
}
|
||||
else if (subcommand == "imagestream-stop")
|
||||
{
|
||||
disconnect(_hyperion, &Hyperion::currentImage, this, &JsonAPI::setImage);
|
||||
disconnect(_hyperion, &Hyperion::currentImage, this, 0);
|
||||
_imageStreamTimer->stop();
|
||||
disconnect(_imageStreamConnection);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1485,52 +1524,35 @@ void JsonAPI::sendErrorReply(const QString &error, const QString &command, const
|
||||
emit callbackMessage(reply);
|
||||
}
|
||||
|
||||
|
||||
void JsonAPI::streamLedcolorsUpdate(const std::vector<ColorRgb>& ledColors)
|
||||
{
|
||||
QMutexLocker lock(&_led_stream_mutex);
|
||||
if ( (_led_stream_timeout+100) < QDateTime::currentMSecsSinceEpoch() )
|
||||
QJsonObject result;
|
||||
QJsonArray leds;
|
||||
|
||||
for(const auto & color : ledColors)
|
||||
{
|
||||
_led_stream_timeout = QDateTime::currentMSecsSinceEpoch();
|
||||
QJsonObject result;
|
||||
QJsonArray leds;
|
||||
|
||||
for(auto color = ledColors.begin(); color != ledColors.end(); ++color)
|
||||
{
|
||||
QJsonObject item;
|
||||
item["index"] = int(color - ledColors.begin());
|
||||
item["red"] = color->red;
|
||||
item["green"] = color->green;
|
||||
item["blue"] = color->blue;
|
||||
leds.append(item);
|
||||
}
|
||||
|
||||
result["leds"] = leds;
|
||||
_streaming_leds_reply["result"] = result;
|
||||
|
||||
// send the result
|
||||
emit callbackMessage(_streaming_leds_reply);
|
||||
leds << QJsonValue(color.red) << QJsonValue(color.green) << QJsonValue(color.blue);
|
||||
}
|
||||
|
||||
result["leds"] = leds;
|
||||
_streaming_leds_reply["result"] = result;
|
||||
|
||||
// send the result
|
||||
emit callbackMessage(_streaming_leds_reply);
|
||||
}
|
||||
|
||||
void JsonAPI::setImage(const Image<ColorRgb> & image)
|
||||
{
|
||||
QMutexLocker lock(&_image_stream_mutex);
|
||||
if ( (_image_stream_timeout+100) < QDateTime::currentMSecsSinceEpoch() )
|
||||
{
|
||||
_image_stream_timeout = QDateTime::currentMSecsSinceEpoch();
|
||||
QImage jpgImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
jpgImage.save(&buffer, "jpg");
|
||||
|
||||
QImage jpgImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
jpgImage.save(&buffer, "jpg");
|
||||
|
||||
QJsonObject result;
|
||||
result["image"] = "data:image/jpg;base64,"+QString(ba.toBase64());
|
||||
_streaming_image_reply["result"] = result;
|
||||
emit callbackMessage(_streaming_image_reply);
|
||||
}
|
||||
QJsonObject result;
|
||||
result["image"] = "data:image/jpg;base64,"+QString(ba.toBase64());
|
||||
_streaming_image_reply["result"] = result;
|
||||
emit callbackMessage(_streaming_image_reply);
|
||||
}
|
||||
|
||||
void JsonAPI::incommingLogMessage(const Logger::T_LOG_MESSAGE &msg)
|
||||
|
@@ -617,8 +617,16 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input)
|
||||
}
|
||||
|
||||
// set the settings
|
||||
fmt.fmt.pix.width = max_width;
|
||||
fmt.fmt.pix.height = max_height;
|
||||
if (max_width != 0 || max_height != 0)
|
||||
{
|
||||
fmt.fmt.pix.width = max_width;
|
||||
fmt.fmt.pix.height = max_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt.fmt.pix.width = _width;
|
||||
fmt.fmt.pix.height = _height;
|
||||
}
|
||||
|
||||
if (-1 == xioctl(VIDIOC_S_FMT, &fmt))
|
||||
{
|
||||
|
@@ -46,7 +46,6 @@ Hyperion::Hyperion(const quint8& instance)
|
||||
, _settingsManager(new SettingsManager(instance, this))
|
||||
, _componentRegister(this)
|
||||
, _ledString(hyperion::createLedString(getSetting(settings::LEDS).array(), hyperion::createColorOrder(getSetting(settings::DEVICE).object())))
|
||||
, _ledStringClone(hyperion::createLedStringClone(getSetting(settings::LEDS).array(), hyperion::createColorOrder(getSetting(settings::DEVICE).object())))
|
||||
, _imageProcessor(new ImageProcessor(_ledString, this))
|
||||
, _muxer(_ledString.leds().size())
|
||||
, _raw2ledAdjustment(hyperion::createLedColorsAdjustment(_ledString.leds().size(), getSetting(settings::COLOR).object()))
|
||||
@@ -87,10 +86,6 @@ void Hyperion::start()
|
||||
{
|
||||
_ledStringColorOrder.push_back(led.colorOrder);
|
||||
}
|
||||
for (Led& led : _ledStringClone.leds())
|
||||
{
|
||||
_ledStringColorOrder.insert(_ledStringColorOrder.begin() + led.index, led.colorOrder);
|
||||
}
|
||||
|
||||
// connect Hyperion::update with Muxer visible priority changes as muxer updates independent
|
||||
connect(&_muxer, &PriorityMuxer::visiblePriorityChanged, this, &Hyperion::update);
|
||||
@@ -202,9 +197,8 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
|
||||
// stop and cache all running effects, as effects depend heavily on ledlayout
|
||||
_effectEngine->cacheRunningEffects();
|
||||
|
||||
// ledstring, clone, img processor, muxer, ledGridSize (eff engine image based effects), _ledBuffer and ByteOrder of ledstring
|
||||
// ledstring, img processor, muxer, ledGridSize (eff engine image based effects), _ledBuffer and ByteOrder of ledstring
|
||||
_ledString = hyperion::createLedString(leds, hyperion::createColorOrder(getSetting(settings::DEVICE).object()));
|
||||
_ledStringClone = hyperion::createLedStringClone(leds, hyperion::createColorOrder(getSetting(settings::DEVICE).object()));
|
||||
_imageProcessor->setLedString(_ledString);
|
||||
_muxer.updateLedColorsLength(_ledString.leds().size());
|
||||
_ledGridSize = hyperion::getLedLayoutGridSize(leds);
|
||||
@@ -217,10 +211,6 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
|
||||
{
|
||||
_ledStringColorOrder.push_back(led.colorOrder);
|
||||
}
|
||||
for (Led& led : _ledStringClone.leds())
|
||||
{
|
||||
_ledStringColorOrder.insert(_ledStringColorOrder.begin() + led.index, led.colorOrder);
|
||||
}
|
||||
|
||||
// handle hwLedCount update
|
||||
_hwLedCount = qMax(unsigned(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount())), getLedCount());
|
||||
@@ -244,7 +234,6 @@ void Hyperion::handleSettingsUpdate(const settings::type& type, const QJsonDocum
|
||||
if(_ledDeviceWrapper->getColorOrder() != dev["colorOrder"].toString("rgb"))
|
||||
{
|
||||
_ledString = hyperion::createLedString(getSetting(settings::LEDS).array(), hyperion::createColorOrder(dev));
|
||||
_ledStringClone = hyperion::createLedStringClone(getSetting(settings::LEDS).array(), hyperion::createColorOrder(dev));
|
||||
_imageProcessor->setLedString(_ledString);
|
||||
}
|
||||
|
||||
@@ -368,6 +357,9 @@ void Hyperion::setColor(const int priority, const ColorRgb &color, const int tim
|
||||
// create led vector from single color
|
||||
std::vector<ColorRgb> ledColors(_ledString.leds().size(), color);
|
||||
|
||||
if (getPriorityInfo(priority).componentId != hyperion::COMP_COLOR)
|
||||
clear(priority);
|
||||
|
||||
// register color
|
||||
registerInput(priority, hyperion::COMP_COLOR, origin);
|
||||
|
||||
@@ -539,12 +531,6 @@ void Hyperion::update()
|
||||
|
||||
_raw2ledAdjustment->applyAdjustment(_ledBuffer);
|
||||
|
||||
// insert cloned leds into buffer
|
||||
for (Led& led : _ledStringClone.leds())
|
||||
{
|
||||
_ledBuffer.insert(_ledBuffer.begin() + led.index, _ledBuffer.at(led.clone));
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (ColorRgb& color : _ledBuffer)
|
||||
{
|
||||
|
@@ -72,7 +72,7 @@ int LinearColorSmoothing::write(const std::vector<ColorRgb> &ledValues)
|
||||
|
||||
_previousTime = QDateTime::currentMSecsSinceEpoch();
|
||||
_previousValues = ledValues;
|
||||
_timer->start();
|
||||
QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -182,7 +182,7 @@ void LinearColorSmoothing::setEnable(bool enable)
|
||||
{
|
||||
if (!enable)
|
||||
{
|
||||
_timer->stop();
|
||||
QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
|
||||
_previousValues.clear();
|
||||
}
|
||||
// update comp register
|
||||
@@ -218,10 +218,9 @@ bool LinearColorSmoothing::selectConfig(unsigned cfg, const bool& force)
|
||||
|
||||
if (_cfgList[cfg].updateInterval != _updateInterval)
|
||||
{
|
||||
_timer->stop();
|
||||
QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
|
||||
_updateInterval = _cfgList[cfg].updateInterval;
|
||||
_timer->setInterval(_updateInterval);
|
||||
_timer->start();
|
||||
QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval));
|
||||
}
|
||||
_currentConfigId = cfg;
|
||||
//DebugIf( enabled() && !_pause, _log, "set smoothing cfg: %d, interval: %d ms, settlingTime: %d ms, updateDelay: %d frames", _currentConfigId, _updateInterval, _settlingTime, _outputDelay );
|
||||
|
@@ -185,6 +185,7 @@ bool PriorityMuxer::setInput(const int priority, const std::vector<ColorRgb>& le
|
||||
// update input
|
||||
input.timeoutTime_ms = timeout_ms;
|
||||
input.ledColors = ledColors;
|
||||
input.image.clear();
|
||||
|
||||
// emit active change
|
||||
if(activeChange)
|
||||
@@ -224,6 +225,7 @@ bool PriorityMuxer::setInputImage(const int priority, const Image<ColorRgb>& ima
|
||||
// update input
|
||||
input.timeoutTime_ms = timeout_ms;
|
||||
input.image = image;
|
||||
input.ledColors.clear();
|
||||
|
||||
// emit active change
|
||||
if(activeChange)
|
||||
|
@@ -8,23 +8,13 @@
|
||||
"required" : true,
|
||||
"properties":
|
||||
{
|
||||
"index":
|
||||
{
|
||||
"type":"integer",
|
||||
"required":true,
|
||||
"default" : 0
|
||||
},
|
||||
"clone":
|
||||
{
|
||||
"type":"integer"
|
||||
},
|
||||
"hscan":
|
||||
"h":
|
||||
{
|
||||
"type":"object",
|
||||
"required" : true,
|
||||
"properties":
|
||||
{
|
||||
"minimum":
|
||||
"min":
|
||||
{
|
||||
"type":"number",
|
||||
"minimum" : 0,
|
||||
@@ -32,7 +22,7 @@
|
||||
"required":true,
|
||||
"default" : 0
|
||||
},
|
||||
"maximum":
|
||||
"max":
|
||||
{
|
||||
"type":"number",
|
||||
"minimum" : 0,
|
||||
@@ -43,13 +33,13 @@
|
||||
},
|
||||
"additionalProperties" : false
|
||||
},
|
||||
"vscan":
|
||||
"v":
|
||||
{
|
||||
"type":"object",
|
||||
"required" : true,
|
||||
"properties":
|
||||
{
|
||||
"minimum":
|
||||
"min":
|
||||
{
|
||||
"type":"number",
|
||||
"minimum" : 0,
|
||||
@@ -57,7 +47,7 @@
|
||||
"required":true,
|
||||
"default" : 0
|
||||
},
|
||||
"maximum":
|
||||
"max":
|
||||
{
|
||||
"type":"number",
|
||||
"minimum" : 0,
|
||||
|
Reference in New Issue
Block a user