Media Foundation/V4L2 grabber ... (#1119)

* - New Media Foundation grabber
- JsonAPI available grabber fix
- commented json config removed

* Added libjpeg-turbo to dependencies

* Fix OSX build
Removed Azure Pipelines from build scripts

* Remove Platform from Dashboard

* Correct Grabber Namings

* Grabber UI improvements, generic JSONEditor Selection Update

* Active grabber fix

* Stop Framebuffer grabber on failure

* - Image format NV12 and I420 added
- Flip mode
- Scaling factor for MJPEG
- VSCode (compile before run)
- CI (push) dependency libjpeg-turbo added

* Refactor MediaFoundation (Part 1)

* Remove QDebug output

* Added image flipping ability to MF Grabber

* fix issue 1160

* -Reload MF Grabber only once per WebUI update
- Cleanup

* Improvements

* - Set 'Software Frame Decimation' begin to 0
- Removed grabber specific device name from Log
- Keep pixel format when switching resolution
- Display 'Flip mode' correct in Log
- BGR24 images always flipped

* Refactor MediaFoundation (Part 2)

* Refactor V4L2 grabber (part 1) (#62)

* Media Foundation grabber adapted to V4L2 change

* Enable Media Foundation grabber on windows

* Have fps as int, fix height typo

* Added video standards to JsonAPI output

* Error handling in source reader improved

* Fix "Frame to small" error

* Discovery VideoSources and Dynamically Update Editor

* Hide all element when no video grabber discovered, upate naming

* Do not show unsupported grabbers

* Copy Log to Clipboard

* Update Grabber schema and Defaults

* Update access levels and validate crop ranges

* Height and width in Qt grabber corrected

* Correct formatting

* Untabify

* Global component states across instances

* Components divided on the dashboard

* refactor

* Fix Merge-issues

* Database migration aligning with updated grabber model

* Align Grabber.js with new utility functions

* Allow editor-validation for enum-lists

* Handle "Show Explainations scenario" correctly

* Grabber - Ensure save is only possible on valid content

* Dashboard update + fix GlobalSignal connection

* Ensure default database is populated with current release

* Correct grabber4L2 access level

* Display Signal detection area in preview

* Write Hyperion version into default config on compiling.

* Create defaultconfig.json dynamically

* WebUI changes

* Correct grabber config look-ups

* Refactor i18n language loading

* Fix en.json

* Split global capture from instance capture config

* Update grabber default values

* Standalone grabber: Add --debug switch

* Enhance showInputOptionsForKey for multiple keys

* Add grabber instance link to system grabber config

* Only show signal detection area, if grabber is enabled

* Always show Active element on grabber page

* Remote control - Only display gabber status, if global grabber is enabled

* WebUI optimization (thx to @mkcologne)
Start Grabber only when global settings are enabled
Fixed an issue in the WebUI preview

* V4L2/MF changes

* Jsoneditor, Correct translation for default values

* Refactor LED-Device handling in UI and make element naming consistent

* MF Discovery extended

* Fix LGTM finding

* Support Grabber Bri, Hue, Sat and Con in UI, plus their defaults

* Concider Access level for item filtering

* Concider Access level for item filtering

* Revert "Concider Access level for item filtering"

This reverts commit 5b0ce3c0f2.

* Disable fpsSoftwareDecimation for framegrabber, as not supported yet

* JSON-Editor- Add updated schema for validation on dynamic elements

* added V4L2 color IDs

* LGTM findings fix

* destroy SR callback only on exit

* Grabber.js - Hide elements not supported by platform

* Fixed freezing start effect

* Grabber UI - Hardware controls - Show current values and allow to reset to defaults

* Grabber - Discovery - Add current values to properties

* Small things

* Clean-up Effects and have ENDLESS consistently defined

* Fix on/off/on priority during startup, by initializing _prevVisComp in line with background priority

* Add missing translation mappings

* DirectX Grabber reactivated/ QT Grabber size decimation fixed

* typo in push-master workflow

* Use PreciseTimer for Grabber to ensure stable FPS timing

* Set default Screencapture rate consistently

* Fix libjpeg-turbo download

* Remove Zero character from file

* docker-compile Add PLATFORM parameter, only copy output file after successful compile

* Framebuffer, Dispmanx, OSX, AML Grabber discovery, various clean-up and consistencies across grabbers

* Fix merge problem - on docker-compile Add PLATFORM parameter, only copy output file after successful compile

* Fix definition

* OSXFRameGrabber - Revert cast

* Clean-ups nach Feedback

* Disable certain libraries when building armlogic via standard stretch image as developer

* Add CEC availability to ServerInfo to have it platform independent

* Grabber UI - Fix problem that crop values are not populated when refining editor rage

* Preserve value when updating json-editor range

* LEDVisualisation - Clear image when source changes

* Fix - Preserve value when updating json-editor range

* LEDVisualisation - Clear image when no component is active

* Allow to have password handled by Password-Manager (#1263)

* Update default signal detection area to green assuming rainbow grabber

* LED Visualisation - Handle empty priority update

* Fix yuv420 in v4l2 grabber

* V4L2-Grabber discovery - Only report grabbers with valid video input information

* Grabber - Update static variables to have them working in release build

* LED Visualisation - ClearImage when no priorities

* LED Visualisation - Fix Logo resizing issue

* LED Visualisation - Have nearly black background and negative logo

Co-authored-by: LordGrey <lordgrey.emmel@gmail.com>
Co-authored-by: LordGrey <48840279+Lord-Grey@users.noreply.github.com>
This commit is contained in:
Markus
2021-07-14 20:48:33 +02:00
committed by GitHub
parent b0e1510a78
commit c135d91986
163 changed files with 10756 additions and 5953 deletions

View File

@@ -1,3 +1,12 @@
# Find the BCM-package (VC control)
IF ( "${PLATFORM}" MATCHES rpi)
find_package(BCM REQUIRED)
include_directories(${BCM_INCLUDE_DIRS})
ELSE()
SET(BCM_INCLUDE_DIRS "")
SET(BCM_LIBRARIES "")
ENDIF()
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/api)
@@ -12,6 +21,11 @@ add_library(hyperion-api
${Api_RESOURCES}
)
if(ENABLE_DX)
include_directories(${DIRECTX9_INCLUDE_DIRS})
target_link_libraries(hyperion-api ${DIRECTX9_LIBRARIES})
endif(ENABLE_DX)
target_link_libraries(hyperion-api
hyperion
hyperion-utils

View File

@@ -0,0 +1,28 @@
{
"type":"object",
"required":true,
"properties": {
"command": {
"type": "string",
"required": true,
"enum": [ "inputsource" ]
},
"tan": {
"type": "integer"
},
"subcommand": {
"type": "string",
"required": true,
"enum": [ "discover", "getProperties" ]
},
"sourceType": {
"type": "string",
"required": true
},
"params": {
"type": "object",
"required": false
}
},
"additionalProperties": false
}

View File

@@ -5,7 +5,7 @@
"command": {
"type" : "string",
"required" : true,
"enum" : ["color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "leddevice", "transform", "correction" , "temperature"]
"enum": [ "color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "leddevice", "inputsource", "transform", "correction", "temperature" ]
}
}
}

View File

@@ -20,7 +20,8 @@
<file alias="schema-videomode">JSONRPC_schema/schema-videomode.json</file>
<file alias="schema-authorize">JSONRPC_schema/schema-authorize.json</file>
<file alias="schema-instance">JSONRPC_schema/schema-instance.json</file>
<file alias="schema-leddevice">JSONRPC_schema/schema-leddevice.json</file>
<file alias="schema-leddevice">JSONRPC_schema/schema-leddevice.json</file>
<file alias="schema-inputsource">JSONRPC_schema/schema-inputsource.json</file>
<!-- The following schemas are derecated but used to ensure backward compatibility with hyperion Classic remote control-->
<file alias="schema-transform">JSONRPC_schema/schema-hyperion-classic.json</file>
<file alias="schema-correction">JSONRPC_schema/schema-hyperion-classic.json</file>

View File

@@ -16,7 +16,45 @@
#include <leddevice/LedDevice.h>
#include <leddevice/LedDeviceFactory.h>
#include <HyperionConfig.h> // Required to determine the cmake options
#include <hyperion/GrabberWrapper.h>
#include <grabber/QtGrabber.h>
#if defined(ENABLE_MF)
#include <grabber/MFGrabber.h>
#elif defined(ENABLE_V4L2)
#include <grabber/V4L2Grabber.h>
#endif
#if defined(ENABLE_X11)
#include <grabber/X11Grabber.h>
#endif
#if defined(ENABLE_XCB)
#include <grabber/XcbGrabber.h>
#endif
#if defined(ENABLE_DX)
#include <grabber/DirectXGrabber.h>
#endif
#if defined(ENABLE_FB)
#include <grabber/FramebufferFrameGrabber.h>
#endif
#if defined(ENABLE_DISPMANX)
#include <grabber/DispmanxFrameGrabber.h>
#endif
#if defined(ENABLE_AMLOGIC)
#include <grabber/AmlogicGrabber.h>
#endif
#if defined(ENABLE_OSX)
#include <grabber/OsxFrameGrabber.h>
#endif
#include <utils/jsonschema/QJsonFactory.h>
#include <utils/jsonschema/QJsonSchemaChecker.h>
#include <HyperionConfig.h>
@@ -41,7 +79,10 @@
using namespace hyperion;
JsonAPI::JsonAPI(QString peerAddress, Logger* log, bool localConnection, QObject* parent, bool noListener)
// Constants
namespace { const bool verbose = false; }
JsonAPI::JsonAPI(QString peerAddress, Logger *log, bool localConnection, QObject *parent, bool noListener)
: API(log, localConnection, parent)
{
_noListener = noListener;
@@ -86,7 +127,7 @@ bool JsonAPI::handleInstanceSwitch(quint8 inst, bool forced)
return false;
}
void JsonAPI::handleMessage(const QString& messageString, const QString& httpAuthHeader)
void JsonAPI::handleMessage(const QString &messageString, const QString &httpAuthHeader)
{
const QString ident = "JsonRpc@" + _peerAddress;
QJsonObject message;
@@ -174,6 +215,8 @@ proceed:
handleInstanceCommand(message, command, tan);
else if (command == "leddevice")
handleLedDeviceCommand(message, command, tan);
else if (command == "inputsource")
handleInputSourceCommand(message, command, tan);
// BEGIN | The following commands are deprecated but used to ensure backward compatibility with hyperion Classic remote control
else if (command == "clearall")
@@ -187,17 +230,17 @@ proceed:
handleNotImplemented(command, tan);
}
void JsonAPI::handleColorCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleColorCommand(const QJsonObject &message, const QString &command, int tan)
{
emit forwardJsonMessage(message);
int priority = message["priority"].toInt();
int duration = message["duration"].toInt(-1);
const QString origin = message["origin"].toString("JsonRpc") + "@" + _peerAddress;
const QJsonArray& jsonColor = message["color"].toArray();
const QJsonArray &jsonColor = message["color"].toArray();
std::vector<uint8_t> colors;
// TODO faster copy
for (const auto& entry : jsonColor)
for (const auto &entry : jsonColor)
{
colors.emplace_back(uint8_t(entry.toInt()));
}
@@ -206,7 +249,7 @@ void JsonAPI::handleColorCommand(const QJsonObject& message, const QString& comm
sendSuccessReply(command, tan);
}
void JsonAPI::handleImageCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleImageCommand(const QJsonObject &message, const QString &command, int tan)
{
emit forwardJsonMessage(message);
@@ -230,7 +273,7 @@ void JsonAPI::handleImageCommand(const QJsonObject& message, const QString& comm
sendSuccessReply(command, tan);
}
void JsonAPI::handleEffectCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleEffectCommand(const QJsonObject &message, const QString &command, int tan)
{
emit forwardJsonMessage(message);
@@ -249,19 +292,19 @@ void JsonAPI::handleEffectCommand(const QJsonObject& message, const QString& com
sendErrorReply("Effect '" + dat.effectName + "' not found", command, tan);
}
void JsonAPI::handleCreateEffectCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleCreateEffectCommand(const QJsonObject &message, const QString &command, int tan)
{
const QString resultMsg = API::saveEffect(message);
resultMsg.isEmpty() ? sendSuccessReply(command, tan) : sendErrorReply(resultMsg, command, tan);
}
void JsonAPI::handleDeleteEffectCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleDeleteEffectCommand(const QJsonObject &message, const QString &command, int tan)
{
const QString res = API::deleteEffect(message["name"].toString());
res.isEmpty() ? sendSuccessReply(command, tan) : sendErrorReply(res, command, tan);
}
void JsonAPI::handleSysInfoCommand(const QJsonObject&, const QString& command, int tan)
void JsonAPI::handleSysInfoCommand(const QJsonObject &, const QString &command, int tan)
{
// create result
QJsonObject result;
@@ -304,7 +347,7 @@ void JsonAPI::handleSysInfoCommand(const QJsonObject&, const QString& command, i
emit callbackMessage(result);
}
void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString &command, int tan)
{
QJsonObject info;
@@ -315,9 +358,9 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
activePriorities.removeAll(255);
int currentPriority = _hyperion->getCurrentPriority();
for (int priority : activePriorities)
for(int priority : activePriorities)
{
const Hyperion::InputInfo& priorityInfo = _hyperion->getPriorityInfo(priority);
const Hyperion::InputInfo &priorityInfo = _hyperion->getPriorityInfo(priority);
QJsonObject item;
item["priority"] = priority;
if (priorityInfo.timeoutTime_ms > 0)
@@ -349,9 +392,9 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
// add HSL Value to Array
QJsonArray HSLValue;
ColorSys::rgb2hsl(priorityInfo.ledColors.begin()->red,
priorityInfo.ledColors.begin()->green,
priorityInfo.ledColors.begin()->blue,
Hue, Saturation, Luminace);
priorityInfo.ledColors.begin()->green,
priorityInfo.ledColors.begin()->blue,
Hue, Saturation, Luminace);
HSLValue.append(Hue);
HSLValue.append(Saturation);
@@ -362,8 +405,8 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
}
(priority == currentPriority)
? priorities.prepend(item)
: priorities.append(item);
? priorities.prepend(item)
: priorities.append(item);
}
info["priorities"] = priorities;
@@ -371,9 +414,9 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
// collect adjustment information
QJsonArray adjustmentArray;
for (const QString& adjustmentId : _hyperion->getAdjustmentIds())
for (const QString &adjustmentId : _hyperion->getAdjustmentIds())
{
const ColorAdjustment* colorAdjustment = _hyperion->getAdjustment(adjustmentId);
const ColorAdjustment *colorAdjustment = _hyperion->getAdjustment(adjustmentId);
if (colorAdjustment == nullptr)
{
Error(_log, "Incorrect color adjustment id: %s", QSTRING_CSTR(adjustmentId));
@@ -440,8 +483,8 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
// collect effect info
QJsonArray effects;
const std::list<EffectDefinition>& effectsDefinitions = _hyperion->getEffects();
for (const EffectDefinition& effectDefinition : effectsDefinitions)
const std::list<EffectDefinition> &effectsDefinitions = _hyperion->getEffects();
for (const EffectDefinition &effectDefinition : effectsDefinitions)
{
QJsonObject effect;
effect["name"] = effectDefinition.name;
@@ -467,11 +510,18 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
QJsonObject grabbers;
QJsonArray availableGrabbers;
#if defined(ENABLE_DISPMANX) || defined(ENABLE_V4L2) || defined(ENABLE_FB) || defined(ENABLE_AMLOGIC) || defined(ENABLE_OSX) || defined(ENABLE_X11) || defined(ENABLE_XCB) || defined(ENABLE_QT)
#if defined(ENABLE_DISPMANX) || defined(ENABLE_V4L2) || defined(ENABLE_MF) || defined(ENABLE_FB) || defined(ENABLE_AMLOGIC) || defined(ENABLE_OSX) || defined(ENABLE_X11) || defined(ENABLE_XCB) || defined(ENABLE_QT)
if (GrabberWrapper::getInstance() != nullptr)
if ( GrabberWrapper::getInstance() != nullptr )
{
grabbers["active"] = GrabberWrapper::getInstance()->getActive();
QStringList activeGrabbers = GrabberWrapper::getInstance()->getActive(_hyperion->getInstanceIndex());
QJsonArray activeGrabberNames;
for (auto grabberName : activeGrabbers)
{
activeGrabberNames.append(grabberName);
}
grabbers["active"] = activeGrabberNames;
}
// get available grabbers
@@ -480,55 +530,20 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
availableGrabbers.append(grabber);
}
#endif
#if defined(ENABLE_V4L2)
QJsonArray availableV4L2devices;
for (const auto& devicePath : GrabberWrapper::getInstance()->getV4L2devices())
{
QJsonObject device;
device["device"] = devicePath;
device["name"] = GrabberWrapper::getInstance()->getV4L2deviceName(devicePath);
QJsonArray availableInputs;
QMultiMap<QString, int> inputs = GrabberWrapper::getInstance()->getV4L2deviceInputs(devicePath);
for (auto input = inputs.begin(); input != inputs.end(); input++)
{
QJsonObject availableInput;
availableInput["inputName"] = input.key();
availableInput["inputIndex"] = input.value();
availableInputs.append(availableInput);
}
device.insert("inputs", availableInputs);
QJsonArray availableResolutions;
QStringList resolutions = GrabberWrapper::getInstance()->getResolutions(devicePath);
for (auto resolution : resolutions)
{
availableResolutions.append(resolution);
}
device.insert("resolutions", availableResolutions);
QJsonArray availableFramerates;
QStringList framerates = GrabberWrapper::getInstance()->getFramerates(devicePath);
for (auto framerate : framerates)
{
availableFramerates.append(framerate);
}
device.insert("framerates", availableFramerates);
availableV4L2devices.append(device);
}
grabbers["v4l2_properties"] = availableV4L2devices;
#endif
grabbers["available"] = availableGrabbers;
info["videomode"] = QString(videoMode2String(_hyperion->getCurrentVideoMode()));
info["grabbers"] = grabbers;
QJsonObject cecInfo;
#if defined(ENABLE_CEC)
cecInfo["enabled"] = true;
#else
cecInfo["enabled"] = false;
#endif
info["cec"] = cecInfo;
// get available components
QJsonArray component;
std::map<hyperion::Components, bool> components = _hyperion->getComponentRegister().getRegister();
@@ -547,7 +562,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
// add sessions
QJsonArray sessions;
#ifdef ENABLE_AVAHI
for (auto session : BonjourBrowserWrapper::getInstance()->getAllServices())
for (auto session: BonjourBrowserWrapper::getInstance()->getAllServices())
{
if (session.port < 0)
continue;
@@ -564,7 +579,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
#endif
// add instance info
QJsonArray instanceInfo;
for (const auto& entry : API::getAllInstanceData())
for (const auto &entry : API::getAllInstanceData())
{
QJsonObject obj;
obj.insert("friendly_name", entry["friendly_name"].toString());
@@ -586,7 +601,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
// TRANSFORM INFORMATION (DEFAULT VALUES)
QJsonArray transformArray;
for (const QString& transformId : _hyperion->getAdjustmentIds())
for (const QString &transformId : _hyperion->getAdjustmentIds())
{
QJsonObject transform;
QJsonArray blacklevel, whitelevel, gamma, threshold;
@@ -617,7 +632,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
// ACTIVE EFFECT INFO
QJsonArray activeEffects;
for (const ActiveEffectDefinition& activeEffectDefinition : _hyperion->getActiveEffects())
for (const ActiveEffectDefinition &activeEffectDefinition : _hyperion->getActiveEffects())
{
if (activeEffectDefinition.priority != PriorityMuxer::LOWEST_PRIORITY - 1)
{
@@ -634,15 +649,15 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
// ACTIVE STATIC LED COLOR
QJsonArray activeLedColors;
const Hyperion::InputInfo& priorityInfo = _hyperion->getPriorityInfo(_hyperion->getCurrentPriority());
const Hyperion::InputInfo &priorityInfo = _hyperion->getPriorityInfo(_hyperion->getCurrentPriority());
if (priorityInfo.componentId == hyperion::COMP_COLOR && !priorityInfo.ledColors.empty())
{
QJsonObject LEDcolor;
// check if LED Color not Black (0,0,0)
if ((priorityInfo.ledColors.begin()->red +
priorityInfo.ledColors.begin()->green +
priorityInfo.ledColors.begin()->blue !=
0))
priorityInfo.ledColors.begin()->green +
priorityInfo.ledColors.begin()->blue !=
0))
{
QJsonObject LEDcolor;
@@ -659,9 +674,9 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
// add HSL Value to Array
QJsonArray HSLValue;
ColorSys::rgb2hsl(priorityInfo.ledColors.begin()->red,
priorityInfo.ledColors.begin()->green,
priorityInfo.ledColors.begin()->blue,
Hue, Saturation, Luminace);
priorityInfo.ledColors.begin()->green,
priorityInfo.ledColors.begin()->blue,
Hue, Saturation, Luminace);
HSLValue.append(Hue);
HSLValue.append(Saturation);
@@ -706,7 +721,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject& message, const QString&
}
}
void JsonAPI::handleClearCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleClearCommand(const QJsonObject &message, const QString &command, int tan)
{
emit forwardJsonMessage(message);
int priority = message["priority"].toInt();
@@ -720,7 +735,7 @@ void JsonAPI::handleClearCommand(const QJsonObject& message, const QString& comm
sendSuccessReply(command, tan);
}
void JsonAPI::handleClearallCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleClearallCommand(const QJsonObject &message, const QString &command, int tan)
{
emit forwardJsonMessage(message);
QString replyMsg;
@@ -728,12 +743,12 @@ void JsonAPI::handleClearallCommand(const QJsonObject& message, const QString& c
sendSuccessReply(command, tan);
}
void JsonAPI::handleAdjustmentCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleAdjustmentCommand(const QJsonObject &message, const QString &command, int tan)
{
const QJsonObject& adjustment = message["adjustment"].toObject();
const QJsonObject &adjustment = message["adjustment"].toObject();
const QString adjustmentId = adjustment["id"].toString(_hyperion->getAdjustmentIds().first());
ColorAdjustment* colorAdjustment = _hyperion->getAdjustment(adjustmentId);
ColorAdjustment *colorAdjustment = _hyperion->getAdjustment(adjustmentId);
if (colorAdjustment == nullptr)
{
Warning(_log, "Incorrect adjustment identifier: %s", adjustmentId.toStdString().c_str());
@@ -742,39 +757,39 @@ void JsonAPI::handleAdjustmentCommand(const QJsonObject& message, const QString&
if (adjustment.contains("red"))
{
const QJsonArray& values = adjustment["red"].toArray();
const QJsonArray &values = adjustment["red"].toArray();
colorAdjustment->_rgbRedAdjustment.setAdjustment(values[0u].toInt(), values[1u].toInt(), values[2u].toInt());
}
if (adjustment.contains("green"))
{
const QJsonArray& values = adjustment["green"].toArray();
const QJsonArray &values = adjustment["green"].toArray();
colorAdjustment->_rgbGreenAdjustment.setAdjustment(values[0u].toInt(), values[1u].toInt(), values[2u].toInt());
}
if (adjustment.contains("blue"))
{
const QJsonArray& values = adjustment["blue"].toArray();
const QJsonArray &values = adjustment["blue"].toArray();
colorAdjustment->_rgbBlueAdjustment.setAdjustment(values[0u].toInt(), values[1u].toInt(), values[2u].toInt());
}
if (adjustment.contains("cyan"))
{
const QJsonArray& values = adjustment["cyan"].toArray();
const QJsonArray &values = adjustment["cyan"].toArray();
colorAdjustment->_rgbCyanAdjustment.setAdjustment(values[0u].toInt(), values[1u].toInt(), values[2u].toInt());
}
if (adjustment.contains("magenta"))
{
const QJsonArray& values = adjustment["magenta"].toArray();
const QJsonArray &values = adjustment["magenta"].toArray();
colorAdjustment->_rgbMagentaAdjustment.setAdjustment(values[0u].toInt(), values[1u].toInt(), values[2u].toInt());
}
if (adjustment.contains("yellow"))
{
const QJsonArray& values = adjustment["yellow"].toArray();
const QJsonArray &values = adjustment["yellow"].toArray();
colorAdjustment->_rgbYellowAdjustment.setAdjustment(values[0u].toInt(), values[1u].toInt(), values[2u].toInt());
}
if (adjustment.contains("white"))
{
const QJsonArray& values = adjustment["white"].toArray();
const QJsonArray &values = adjustment["white"].toArray();
colorAdjustment->_rgbWhiteAdjustment.setAdjustment(values[0u].toInt(), values[1u].toInt(), values[2u].toInt());
}
@@ -814,7 +829,7 @@ void JsonAPI::handleAdjustmentCommand(const QJsonObject& message, const QString&
sendSuccessReply(command, tan);
}
void JsonAPI::handleSourceSelectCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleSourceSelectCommand(const QJsonObject &message, const QString &command, int tan)
{
if (message.contains("auto"))
{
@@ -832,7 +847,7 @@ void JsonAPI::handleSourceSelectCommand(const QJsonObject& message, const QStrin
sendSuccessReply(command, tan);
}
void JsonAPI::handleConfigCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleConfigCommand(const QJsonObject &message, const QString &command, int tan)
{
QString subcommand = message["subcommand"].toString("");
QString full_command = command + "-" + subcommand;
@@ -876,14 +891,14 @@ void JsonAPI::handleConfigCommand(const QJsonObject& message, const QString& com
}
}
void JsonAPI::handleConfigSetCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleConfigSetCommand(const QJsonObject &message, const QString &command, int tan)
{
if (message.contains("config"))
{
QJsonObject config = message["config"].toObject();
if (API::isHyperionEnabled())
{
if (API::saveSettings(config))
if ( API::saveSettings(config) )
{
sendSuccessReply(command, tan);
}
@@ -897,7 +912,7 @@ void JsonAPI::handleConfigSetCommand(const QJsonObject& message, const QString&
}
}
void JsonAPI::handleSchemaGetCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleSchemaGetCommand(const QJsonObject &message, const QString &command, int tan)
{
// create result
QJsonObject schemaJson, alldevices, properties;
@@ -912,7 +927,7 @@ void JsonAPI::handleSchemaGetCommand(const QJsonObject& message, const QString&
{
schemaJson = QJsonFactory::readSchema(schemaFile);
}
catch (const std::runtime_error& error)
catch (const std::runtime_error &error)
{
throw std::runtime_error(error.what());
}
@@ -949,9 +964,9 @@ void JsonAPI::handleSchemaGetCommand(const QJsonObject& message, const QString&
sendSuccessDataReply(QJsonDocument(schemaJson), command, tan);
}
void JsonAPI::handleComponentStateCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleComponentStateCommand(const QJsonObject &message, const QString &command, int tan)
{
const QJsonObject& componentState = message["componentstate"].toObject();
const QJsonObject &componentState = message["componentstate"].toObject();
QString comp = componentState["component"].toString("invalid");
bool compState = componentState["state"].toBool(true);
QString replyMsg;
@@ -964,7 +979,7 @@ void JsonAPI::handleComponentStateCommand(const QJsonObject& message, const QStr
sendSuccessReply(command, tan);
}
void JsonAPI::handleLedColorsCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleLedColorsCommand(const QJsonObject &message, const QString &command, int tan)
{
// create result
QString subcommand = message["subcommand"].toString("");
@@ -978,22 +993,22 @@ void JsonAPI::handleLedColorsCommand(const QJsonObject& message, const QString&
_streaming_leds_reply["command"] = command + "-ledstream-update";
_streaming_leds_reply["tan"] = tan;
connect(_hyperion, &Hyperion::rawLedColors, this, [=](const std::vector<ColorRgb>& ledValues) {
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);
emit streamLedcolorsUpdate(_currentLedValues);
},
Qt::UniqueConnection);
// start the timer
if (!_ledStreamTimer->isActive() || _ledStreamTimer->interval() != streaming_interval)
_ledStreamTimer->start(streaming_interval);
},
Qt::UniqueConnection);
},
Qt::UniqueConnection);
// push once
_hyperion->update();
}
@@ -1023,7 +1038,7 @@ void JsonAPI::handleLedColorsCommand(const QJsonObject& message, const QString&
sendSuccessReply(command + "-" + subcommand, tan);
}
void JsonAPI::handleLoggingCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleLoggingCommand(const QJsonObject &message, const QString &command, int tan)
{
// create result
QString subcommand = message["subcommand"].toString("");
@@ -1065,25 +1080,25 @@ void JsonAPI::handleLoggingCommand(const QJsonObject& message, const QString& co
}
}
void JsonAPI::handleProcessingCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleProcessingCommand(const QJsonObject &message, const QString &command, int tan)
{
API::setLedMappingType(ImageProcessor::mappingTypeToInt(message["mappingType"].toString("multicolor_mean")));
sendSuccessReply(command, tan);
}
void JsonAPI::handleVideoModeCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleVideoModeCommand(const QJsonObject &message, const QString &command, int tan)
{
API::setVideoMode(parse3DMode(message["videoMode"].toString("2D")));
sendSuccessReply(command, tan);
}
void JsonAPI::handleAuthorizeCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleAuthorizeCommand(const QJsonObject &message, const QString &command, int tan)
{
const QString& subc = message["subcommand"].toString().trimmed();
const QString& id = message["id"].toString().trimmed();
const QString& password = message["password"].toString().trimmed();
const QString& newPassword = message["newPassword"].toString().trimmed();
const QString& comment = message["comment"].toString().trimmed();
const QString &subc = message["subcommand"].toString().trimmed();
const QString &id = message["id"].toString().trimmed();
const QString &password = message["password"].toString().trimmed();
const QString &newPassword = message["newPassword"].toString().trimmed();
const QString &comment = message["comment"].toString().trimmed();
// catch test if auth is required
if (subc == "tokenRequired")
@@ -1194,8 +1209,8 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject& message, const QString&
if (subc == "requestToken")
{
// use id/comment
const QString& comment = message["comment"].toString().trimmed();
const bool& acc = message["accept"].toBool(true);
const QString &comment = message["comment"].toString().trimmed();
const bool &acc = message["accept"].toBool(true);
if (acc)
API::setNewTokenRequest(comment, id, tan);
else
@@ -1211,7 +1226,7 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject& message, const QString&
if (API::getPendingTokenRequests(vec))
{
QJsonArray arr;
for (const auto& entry : vec)
for (const auto &entry : vec)
{
QJsonObject obj;
obj["comment"] = entry.comment;
@@ -1233,7 +1248,7 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject& message, const QString&
if (subc == "answerRequest")
{
// use id
const bool& accept = message["accept"].toBool(false);
const bool &accept = message["accept"].toBool(false);
if (!API::handlePendingTokenRequest(id, accept))
sendErrorReply("No Authorization", command + "-" + subc, tan);
return;
@@ -1246,7 +1261,7 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject& message, const QString&
if (API::getTokenList(defVect))
{
QJsonArray tArr;
for (const auto& entry : defVect)
for (const auto &entry : defVect)
{
QJsonObject subO;
subO["comment"] = entry.comment;
@@ -1265,7 +1280,7 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject& message, const QString&
// login
if (subc == "login")
{
const QString& token = message["token"].toString().trimmed();
const QString &token = message["token"].toString().trimmed();
// catch token
if (!token.isEmpty())
@@ -1313,11 +1328,11 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject& message, const QString&
}
}
void JsonAPI::handleInstanceCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleInstanceCommand(const QJsonObject &message, const QString &command, int tan)
{
const QString& subc = message["subcommand"].toString();
const quint8& inst = message["instance"].toInt();
const QString& name = message["name"].toString();
const QString &subc = message["subcommand"].toString();
const quint8 &inst = message["instance"].toInt();
const QString &name = message["name"].toString();
if (subc == "switchTo")
{
@@ -1334,7 +1349,7 @@ void JsonAPI::handleInstanceCommand(const QJsonObject& message, const QString& c
if (subc == "startInstance")
{
connect(this, &API::onStartInstanceResponse, [=](const int& tan) { sendSuccessReply(command + "-" + subc, tan); });
connect(this, &API::onStartInstanceResponse, [=] (const int &tan) { sendSuccessReply(command + "-" + subc, tan); });
if (!API::startInstance(inst, tan))
sendErrorReply("Can't start Hyperion instance index " + QString::number(inst), command + "-" + subc, tan);
@@ -1384,12 +1399,12 @@ void JsonAPI::handleInstanceCommand(const QJsonObject& message, const QString& c
}
}
void JsonAPI::handleLedDeviceCommand(const QJsonObject& message, const QString& command, int tan)
void JsonAPI::handleLedDeviceCommand(const QJsonObject &message, const QString &command, int tan)
{
Debug(_log, "message: [%s]", QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toUtf8().constData());
Debug(_log, "message: [%s]", QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toUtf8().constData() );
const QString& subc = message["subcommand"].toString().trimmed();
const QString& devType = message["ledDeviceType"].toString().trimmed();
const QString &subc = message["subcommand"].toString().trimmed();
const QString &devType = message["ledDeviceType"].toString().trimmed();
QString full_command = command + "-" + subc;
@@ -1399,7 +1414,7 @@ void JsonAPI::handleLedDeviceCommand(const QJsonObject& message, const QString&
sendErrorReply("Unknown device", full_command, tan);
}
else
*/ {
*/ {
QJsonObject config;
config.insert("type", devType);
LedDevice* ledDevice = nullptr;
@@ -1407,27 +1422,27 @@ void JsonAPI::handleLedDeviceCommand(const QJsonObject& message, const QString&
if (subc == "discover")
{
ledDevice = LedDeviceFactory::construct(config);
const QJsonObject& params = message["params"].toObject();
const QJsonObject &params = message["params"].toObject();
const QJsonObject devicesDiscovered = ledDevice->discover(params);
Debug(_log, "response: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
Debug(_log, "response: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData() );
sendSuccessDataReply(QJsonDocument(devicesDiscovered), full_command, tan);
}
else if (subc == "getProperties")
{
ledDevice = LedDeviceFactory::construct(config);
const QJsonObject& params = message["params"].toObject();
const QJsonObject &params = message["params"].toObject();
const QJsonObject deviceProperties = ledDevice->getProperties(params);
Debug(_log, "response: [%s]", QString(QJsonDocument(deviceProperties).toJson(QJsonDocument::Compact)).toUtf8().constData());
Debug(_log, "response: [%s]", QString(QJsonDocument(deviceProperties).toJson(QJsonDocument::Compact)).toUtf8().constData() );
sendSuccessDataReply(QJsonDocument(deviceProperties), full_command, tan);
}
else if (subc == "identify")
{
ledDevice = LedDeviceFactory::construct(config);
const QJsonObject& params = message["params"].toObject();
const QJsonObject &params = message["params"].toObject();
ledDevice->identify(params);
sendSuccessReply(full_command, tan);
@@ -1441,12 +1456,152 @@ void JsonAPI::handleLedDeviceCommand(const QJsonObject& message, const QString&
}
}
void JsonAPI::handleNotImplemented(const QString& command, int tan)
void JsonAPI::handleInputSourceCommand(const QJsonObject& message, const QString& command, int tan)
{
DebugIf(verbose, _log, "message: [%s]", QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toUtf8().constData());
const QString& subc = message["subcommand"].toString().trimmed();
const QString& sourceType = message["sourceType"].toString().trimmed();
QString full_command = command + "-" + subc;
// TODO: Validate that source type is a valid one
/* if ( ! valid type )
{
sendErrorReply("Unknown device", full_command, tan);
}
else
*/ {
if (subc == "discover")
{
QJsonObject inputSourcesDiscovered;
inputSourcesDiscovered.insert("sourceType", sourceType);
QJsonArray videoInputs;
#if defined(ENABLE_V4L2) || defined(ENABLE_MF)
if (sourceType == "video" )
{
#if defined(ENABLE_MF)
MFGrabber* grabber = new MFGrabber();
#elif defined(ENABLE_V4L2)
V4L2Grabber* grabber = new V4L2Grabber();
#endif
QJsonObject params;
videoInputs = grabber->discover(params);
delete grabber;
}
else
#endif
{
DebugIf(verbose, _log, "sourceType: [%s]", QSTRING_CSTR(sourceType));
if (sourceType == "screen")
{
QJsonObject params;
QJsonObject device;
#ifdef ENABLE_QT
QtGrabber* qtgrabber = new QtGrabber();
device = qtgrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete qtgrabber;
#endif
#ifdef ENABLE_DX
DirectXGrabber* dxgrabber = new DirectXGrabber();
device = dxgrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete dxgrabber;
#endif
#ifdef ENABLE_X11
X11Grabber* x11Grabber = new X11Grabber();
device = x11Grabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete x11Grabber;
#endif
#ifdef ENABLE_XCB
XcbGrabber* xcbGrabber = new XcbGrabber();
device = xcbGrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete xcbGrabber;
#endif
#ifdef ENABLE_FB
FramebufferFrameGrabber* fbGrabber = new FramebufferFrameGrabber();
device = fbGrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete fbGrabber;
#endif
#if defined(ENABLE_DISPMANX)
DispmanxFrameGrabber* dispmanx = new DispmanxFrameGrabber();
device = dispmanx->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete dispmanx;
#endif
#if defined(ENABLE_AMLOGIC)
AmlogicGrabber* amlGrabber = new AmlogicGrabber();
device = amlGrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete amlGrabber;
#endif
#if defined(ENABLE_OSX)
OsxFrameGrabber* osxGrabber = new OsxFrameGrabber();
device = osxGrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete osxGrabber;
#endif
}
}
inputSourcesDiscovered["video_sources"] = videoInputs;
DebugIf(verbose, _log, "response: [%s]", QString(QJsonDocument(inputSourcesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
sendSuccessDataReply(QJsonDocument(inputSourcesDiscovered), full_command, tan);
}
else
{
sendErrorReply("Unknown or missing subcommand", full_command, tan);
}
}
}
void JsonAPI::handleNotImplemented(const QString &command, int tan)
{
sendErrorReply("Command not implemented", command, tan);
}
void JsonAPI::sendSuccessReply(const QString& command, int tan)
void JsonAPI::sendSuccessReply(const QString &command, int tan)
{
// create reply
QJsonObject reply;
@@ -1458,7 +1613,7 @@ void JsonAPI::sendSuccessReply(const QString& command, int tan)
emit callbackMessage(reply);
}
void JsonAPI::sendSuccessDataReply(const QJsonDocument& doc, const QString& command, int tan)
void JsonAPI::sendSuccessDataReply(const QJsonDocument &doc, const QString &command, int tan)
{
QJsonObject reply;
reply["success"] = true;
@@ -1472,7 +1627,7 @@ void JsonAPI::sendSuccessDataReply(const QJsonDocument& doc, const QString& comm
emit callbackMessage(reply);
}
void JsonAPI::sendErrorReply(const QString& error, const QString& command, int tan)
void JsonAPI::sendErrorReply(const QString &error, const QString &command, int tan)
{
// create reply
QJsonObject reply;
@@ -1485,12 +1640,12 @@ void JsonAPI::sendErrorReply(const QString& error, const QString& command, int t
emit callbackMessage(reply);
}
void JsonAPI::streamLedcolorsUpdate(const std::vector<ColorRgb>& ledColors)
void JsonAPI::streamLedcolorsUpdate(const std::vector<ColorRgb> &ledColors)
{
QJsonObject result;
QJsonArray leds;
for (const auto& color : ledColors)
for (const auto &color : ledColors)
{
leds << QJsonValue(color.red) << QJsonValue(color.green) << QJsonValue(color.blue);
}
@@ -1502,9 +1657,9 @@ void JsonAPI::streamLedcolorsUpdate(const std::vector<ColorRgb>& ledColors)
emit callbackMessage(_streaming_leds_reply);
}
void JsonAPI::setImage(const Image<ColorRgb>& image)
void JsonAPI::setImage(const Image<ColorRgb> &image)
{
QImage jpgImage((const uint8_t*)image.memptr(), image.width(), image.height(), 3 * image.width(), QImage::Format_RGB888);
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);
@@ -1516,7 +1671,7 @@ void JsonAPI::setImage(const Image<ColorRgb>& image)
emit callbackMessage(_streaming_image_reply);
}
void JsonAPI::incommingLogMessage(const Logger::T_LOG_MESSAGE& msg)
void JsonAPI::incommingLogMessage(const Logger::T_LOG_MESSAGE &msg)
{
QJsonObject result, message;
QJsonArray messageArray;
@@ -1524,7 +1679,7 @@ void JsonAPI::incommingLogMessage(const Logger::T_LOG_MESSAGE& msg)
if (!_streaming_logging_activated)
{
_streaming_logging_activated = true;
const QList<Logger::T_LOG_MESSAGE>* logBuffer = LoggerManager::getInstance()->getLogMessageBuffer();
const QList<Logger::T_LOG_MESSAGE> *logBuffer = LoggerManager::getInstance()->getLogMessageBuffer();
for (int i = 0; i < logBuffer->length(); i++)
{
message["appName"] = logBuffer->at(i).appName;
@@ -1560,7 +1715,7 @@ void JsonAPI::incommingLogMessage(const Logger::T_LOG_MESSAGE& msg)
emit callbackMessage(_streaming_logging_reply);
}
void JsonAPI::newPendingTokenRequest(const QString& id, const QString& comment)
void JsonAPI::newPendingTokenRequest(const QString &id, const QString &comment)
{
QJsonObject obj;
obj["comment"] = comment;
@@ -1570,7 +1725,7 @@ void JsonAPI::newPendingTokenRequest(const QString& id, const QString& comment)
sendSuccessDataReply(QJsonDocument(obj), "authorize-tokenRequest", 1);
}
void JsonAPI::handleTokenResponse(bool success, const QString& token, const QString& comment, const QString& id, const int& tan)
void JsonAPI::handleTokenResponse(bool success, const QString &token, const QString &comment, const QString &id, const int &tan)
{
const QString cmd = "authorize-requestToken";
QJsonObject result;
@@ -1584,7 +1739,7 @@ void JsonAPI::handleTokenResponse(bool success, const QString& token, const QStr
sendErrorReply("Token request timeout or denied", cmd, tan);
}
void JsonAPI::handleInstanceStateChange(InstanceState state, quint8 instance, const QString& name)
void JsonAPI::handleInstanceStateChange(InstanceState state, quint8 instance, const QString &name)
{
switch (state)
{