diff --git a/assets/webconfig/i18n/de.json b/assets/webconfig/i18n/de.json
index 45b65f4b..469a5e21 100644
--- a/assets/webconfig/i18n/de.json
+++ b/assets/webconfig/i18n/de.json
@@ -416,6 +416,7 @@
"edt_conf_enum_PAL" : "PAL",
"edt_conf_enum_NTSC" : "NTSC",
"edt_conf_enum_SECAM" : "SECAM",
+ "edt_conf_enum_NO_CHANGE" : "Auto",
"edt_conf_enum_logsilent" : "Stille",
"edt_conf_enum_logwarn" : "Warnung",
"edt_conf_enum_logverbose" : "Ausführlich",
@@ -486,14 +487,8 @@
"edt_conf_v4l2_input_expl" : "Der Eingang des Pfades.",
"edt_conf_v4l2_standard_title" : "Videoformat",
"edt_conf_v4l2_standard_expl" : "Wähle das passende Videoformat deiner Region.",
- "edt_conf_v4l2_width_title" : "Breite",
- "edt_conf_v4l2_width_expl" : "Die Breite des Bildes. (-1 = Automatische Breitenbestimmung)",
- "edt_conf_v4l2_height_title" : "Höhe",
- "edt_conf_v4l2_height_expl" : "Die Höhes des Bildes. (-1 = Automatische Höhenbestimmung)",
- "edt_conf_v4l2_frameDecimation_title" : "Bildverkleinerung",
- "edt_conf_v4l2_frameDecimation_expl" : "Der Faktor der Bildverkleinerung",
- "edt_conf_v4l2_sizeDecimation_title" : "Größenänderung",
- "edt_conf_v4l2_sizeDecimation_expl" : "Der Faktor der Größenänderung",
+ "edt_conf_v4l2_sizeDecimation_title" : "Bildverkleinerung Faktor",
+ "edt_conf_v4l2_sizeDecimation_expl" : "Der Faktor der Bildverkleinerung ausgehend der von der ursprünglichen Größe, 1 bedeutet keine Änderung (originales Bild).",
"edt_conf_v4l2_cropLeft_title" : "Entferne links",
"edt_conf_v4l2_cropLeft_expl" : "Anzahl der Pixel auf der linken Seite die vom Bild entfernt werden.",
"edt_conf_v4l2_cropRight_title" : "Entferne rechts",
@@ -503,7 +498,7 @@
"edt_conf_v4l2_cropBottom_title" : "Entferne unten",
"edt_conf_v4l2_cropBottom_expl" : "Anzahl der Pixel auf der unteren Seite die vom Bild entfernt werden.",
"edt_conf_v4l2_signalDetection_title" : "Signal Erkennung",
- "edt_conf_v4l2_signalDetection_expl" : "Wenn aktiviert, wird die USB Aufnahme temporär bei \"kein Signal\" abgeschalten. Das Bild muss dazu 4 Sekunden lang unter die Schwellwerte fallen.",
+ "edt_conf_v4l2_signalDetection_expl" : "Wenn aktiviert, wird die USB Aufnahme temporär bei \"kein Signal\" abgeschalten.",
"edt_conf_v4l2_redSignalThreshold_title" : "Rote Signalschwelle",
"edt_conf_v4l2_redSignalThreshold_expl" : "Je höher die rote Schwelle je eher wird abgeschalten bei entsprechendem rot-Anteil.",
"edt_conf_v4l2_greenSignalThreshold_title" : "Grüne Signalschwelle",
@@ -523,16 +518,12 @@
"edt_conf_fg_type_expl" : "Art der Plattform Aufnahme, standard ist 'auto'",
"edt_conf_fg_frequency_Hz_title" : "Aufnahmefrequenz",
"edt_conf_fg_frequency_Hz_expl" : "Wie schnell neue Bilder aufgenommen werden.",
- "edt_conf_fg_horizontalPixelDecimation_title" : "Horizontale Pixelreduzierung",
- "edt_conf_fg_horizontalPixelDecimation_expl" : "Horizontale Pixelreduzierung (Faktor)",
- "edt_conf_fg_useXGetImage_title" : "Nutze XGetImage",
- "edt_conf_fg_useXGetImage_expl" : "XGetImage für aktuelle X11 desktops",
"edt_conf_fg_width_title" : "Breite",
"edt_conf_fg_width_expl" : "Verkleinere Bild auf dieser Breite, da das Rohmaterial viel Leistung benötigen würde.",
"edt_conf_fg_height_title" : "Höhe",
"edt_conf_fg_height_expl" : "Verkleinere Bild auf dieser Höhe, da das Rohmaterial viel Leistung benötigen würde.",
- "edt_conf_fg_verticalPixelDecimation_title" : "Vertikale Pixelreduzierung",
- "edt_conf_fg_verticalPixelDecimation_expl" : "Vertikale Pixelreduzierung (Faktor)",
+ "edt_conf_fg_pixelDecimation_title" : "Bildverkleinerung Faktor",
+ "edt_conf_fg_pixelDecimation_expl" : "Bildverkleinerung (Faktor) ausgehend von der original Größe. 1 für unveränderte/originale Größe.",
"edt_conf_fg_device_title" : "Device",
"edt_conf_fg_display_title" : "Display",
"edt_conf_fg_display_expl" : "Gebe an von welchem Desktop aufgenommen werden soll. (Multi Monitor Setup)",
diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json
index 5431fd04..5c2ae968 100644
--- a/assets/webconfig/i18n/en.json
+++ b/assets/webconfig/i18n/en.json
@@ -417,6 +417,7 @@
"edt_conf_enum_PAL" : "PAL",
"edt_conf_enum_NTSC" : "NTSC",
"edt_conf_enum_SECAM" : "SECAM",
+ "edt_conf_enum_NO_CHANGE" : "Auto",
"edt_conf_enum_logsilent" : "Silent",
"edt_conf_enum_logwarn" : "Warning",
"edt_conf_enum_logverbose" : "Verbose",
@@ -504,7 +505,7 @@
"edt_conf_v4l2_cropBottom_title" : "Crop bottom",
"edt_conf_v4l2_cropBottom_expl" : "Count of pixels on the bottom side that are removed from the picture.",
"edt_conf_v4l2_signalDetection_title" : "Signal detection",
- "edt_conf_v4l2_signalDetection_expl" : "If enabled, usb capture will be temporarily disabled when no signal was found. This will happen when the picture fall below the threshold value for a period of 4 seconds.",
+ "edt_conf_v4l2_signalDetection_expl" : "If enabled, usb capture will be temporarily disabled when no signal was found.",
"edt_conf_v4l2_redSignalThreshold_title" : "Red signal threshold",
"edt_conf_v4l2_redSignalThreshold_expl" : "Darkens low red values (recognized as black)",
"edt_conf_v4l2_greenSignalThreshold_title" : "Green signal threshold",
@@ -524,16 +525,12 @@
"edt_conf_fg_type_expl" : "Type of platform capture, default is 'auto'",
"edt_conf_fg_frequency_Hz_title" : "Capture frequency",
"edt_conf_fg_frequency_Hz_expl" : "How fast new pictures are captured",
- "edt_conf_fg_horizontalPixelDecimation_title" : "Horizontal pixel decimation",
- "edt_conf_fg_horizontalPixelDecimation_expl" : "Horizontal pixel decimation (factor)",
"edt_conf_fg_width_title" : "Width",
"edt_conf_fg_width_expl" : "Shrink picture to this width, as raw picture needs a lot of cpu time.",
"edt_conf_fg_height_title" : "Height",
"edt_conf_fg_height_expl" : "Shrink picture to this height, as raw picture needs a lot of cpu time.",
- "edt_conf_fg_useXGetImage_title" : "Use XGetImage",
- "edt_conf_fg_useXGetImage_expl" : "XGetImage for newer X11 desktops",
- "edt_conf_fg_verticalPixelDecimation_title" : "Vertical pixel decimation",
- "edt_conf_fg_verticalPixelDecimation_expl" : "Vertical pixel decimation (factor)",
+ "edt_conf_fg_pixelDecimation_title" : "Picture decimation",
+ "edt_conf_fg_pixelDecimation_expl" : "Reduce picture size (factor) based on original size. A factor of 1 means no change",
"edt_conf_fg_device_title" : "Device",
"edt_conf_fg_display_title" : "Display",
"edt_conf_fg_display_expl" : "Select which desktop should be captured (multi monitor setup)",
diff --git a/assets/webconfig/index.html b/assets/webconfig/index.html
index f222ff77..c2f61a19 100644
--- a/assets/webconfig/index.html
+++ b/assets/webconfig/index.html
@@ -31,6 +31,9 @@
+
+
+
diff --git a/assets/webconfig/js/content_dashboard.js b/assets/webconfig/js/content_dashboard.js
index ca0cae1e..de61dffd 100644
--- a/assets/webconfig/js/content_dashboard.js
+++ b/assets/webconfig/js/content_dashboard.js
@@ -1,6 +1,6 @@
$(document).ready( function() {
performTranslation();
-
+
function newsCont(t,e,l)
{
var h = '
');
else if(type == "wizard")
@@ -247,8 +268,8 @@ function valValue(id,value,min,max)
{
if(typeof max === 'undefined' || max == "")
max = 999999;
-
- if(Number(value) > Number(max))
+
+ if(Number(value) > Number(max))
{
$('#'+id).val(max);
showInfoDialog("warning","",$.i18n('edt_msg_error_maximum_incl',max));
@@ -260,7 +281,7 @@ function valValue(id,value,min,max)
showInfoDialog("warning","",$.i18n('edt_msg_error_minimum_incl',min));
return min;
}
- return value;
+ return value;
}
function readImg(input,cb)
@@ -294,12 +315,12 @@ function createJsonEditor(container,schema,setconfig,usePanel,arrayre)
{
$('#'+container).off();
$('#'+container).html("");
-
+
//JSONEditor.plugins.selectize.enable = true;
-
+
if (typeof arrayre === 'undefined')
arrayre = true;
-
+
var editor = new JSONEditor(document.getElementById(container),
{
theme: 'bootstrap3',
@@ -338,18 +359,18 @@ function createJsonEditor(container,schema,setconfig,usePanel,arrayre)
}
function buildWL(link,linkt,cl)
-{
+{
var baseLink = "https://docs.hyperion-project.org/";
var lang;
-
+
if(typeof linkt == "undefined")
linkt = "Placeholder";
-
+
if(storedLang == "de" || navigator.locale == "de")
lang = "de";
else
lang = "en";
-
+
if(cl === true)
{
linkt = $.i18n(linkt);
@@ -366,7 +387,7 @@ function rgbToHex(rgb)
return "#" +
("0" + parseInt(rgb[0],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
- ("0" + parseInt(rgb[2],10).toString(16)).slice(-2);
+ ("0" + parseInt(rgb[2],10).toString(16)).slice(-2);
}
else
debugMessage('rgbToHex: Given rgb is no array or has wrong length');
@@ -381,6 +402,57 @@ function hexToRgb(hex) {
} : null;
}
+/*
+ Show a notification
+ @param type Valid types are "info","success","warning","danger"
+ @param message The message to show
+ @param title A title (optional)
+ */
+function showNotification(type, message, title="")
+{
+ if(title == "")
+ {
+ switch(type)
+ {
+ case "info":
+ title = $.i18n('infoDialog_general_info_title');
+ break;
+ case "success":
+ title = $.i18n('infoDialog_general_success_title');
+ break;
+ case "warning":
+ title = $.i18n('infoDialog_general_warning_title');
+ break;
+ case "danger":
+ title = $.i18n('infoDialog_general_error_title');
+ break;
+ }
+ }
+
+ $.notify({
+ // options
+ title: title,
+ message: message
+ },{
+ // settings
+ type: type,
+ animate: {
+ enter: 'animated fadeInRight',
+ exit: 'animated fadeOutRight'
+ },
+ mouse_over : 'pause',
+ template: '
' +
+ '' +
+ ' ' +
+ '
{1}
' +
+ '{2}' +
+ '
' +
+ '' +
+ '
' +
+ '' +
+ '
'
+ });
+}
function createCP(id, color, cb)
{
@@ -388,7 +460,7 @@ function createCP(id, color, cb)
color = rgbToHex(color);
else if(color == "undefined")
color = "#AA3399";
-
+
if(color.startsWith("#"))
{
$('#'+id).colorpicker({
@@ -425,7 +497,7 @@ function createTable(hid, bid, cont, bless, tclass)
var table = document.createElement('table');
var thead = document.createElement('thead');
var tbody = document.createElement('tbody');
-
+
table.className = "table";
if(bless === true)
table.className += " borderless";
@@ -438,30 +510,30 @@ function createTable(hid, bid, cont, bless, tclass)
if(hid != "")
table.appendChild(thead);
table.appendChild(tbody);
-
+
$('#'+cont).append(table);
}
// Creates a table row
// @param array list :innerHTML content for
/
// @param bool head :if null or false it's body
-// @param bool align :if null or false no alignment
+// @param bool align :if null or false no alignment
//
// @return :
with
or
as child(s)
function createTableRow(list, head, align)
{
var row = document.createElement('tr');
-
+
for(var i = 0; i < list.length; i++)
{
if(head === true)
var el = document.createElement('th');
else
var el = document.createElement('td');
-
+
if(align)
el.style.verticalAlign = "middle";
-
+
el.innerHTML = list[i];
row.appendChild(el);
}
@@ -483,7 +555,7 @@ function createOptPanel(phicon, phead, bodyid, footerid)
pfooter.className = "btn btn-primary";
pfooter.setAttribute("id", footerid);
pfooter.innerHTML = ''+$.i18n('general_button_savesettings');
-
+
return createPanel(phead, "", pfooter, "panel-default", bodyid);
}
@@ -506,30 +578,30 @@ function createHelpTable(list, phead){
var thead = document.createElement('thead');
var tbody = document.createElement('tbody');
list = sortProperties(list);
-
+
phead = ''+phead+' '+$.i18n("conf_helptable_expl");
-
+
table.className = 'table table-hover borderless';
-
+
thead.appendChild(createTableRow([$.i18n('conf_helptable_option'), $.i18n('conf_helptable_expl')], true, false));
-
+
for (key in list)
{
if(list[key].access != 'system')
{
var text = list[key].title.replace('title', 'expl');
tbody.appendChild(createTableRow([$.i18n(list[key].title), $.i18n(text)], false, false));
-
+
if(list[key].items && list[key].items.properties)
{
var ilist = sortProperties(list[key].items.properties);
for (ikey in ilist)
{
-
+
var itext = ilist[ikey].title.replace('title', 'expl');
tbody.appendChild(createTableRow([$.i18n(ilist[ikey].title), $.i18n(itext)], false, false));
}
- }
+ }
}
}
table.appendChild(thead);
@@ -544,42 +616,42 @@ function createPanel(head, body, footer, type, bodyid){
var phead = document.createElement('div');
var pbody = document.createElement('div');
var pfooter = document.createElement('div');
-
+
cont.className = "col-lg-6";
-
+
if(typeof type == 'undefined')
type = 'panel-default';
-
+
p.className = 'panel '+type;
phead.className = 'panel-heading';
pbody.className = 'panel-body';
pfooter.className = 'panel-footer';
-
+
phead.innerHTML = head;
-
+
if(typeof bodyid != 'undefined')
{
pfooter.style.textAlign = 'right';
pbody.setAttribute("id", bodyid)
}
-
+
if(typeof body != 'undefined' && body != "")
pbody.appendChild(body);
-
+
if(typeof footer != 'undefined')
pfooter.appendChild(footer);
-
+
p.appendChild(phead);
p.appendChild(pbody);
-
+
if(typeof footer != 'undefined')
{
pfooter.style.textAlign = "right";
p.appendChild(pfooter);
}
-
+
cont.appendChild(p);
-
+
return cont;
}
@@ -589,12 +661,12 @@ function createSelGroup(group)
el.setAttribute('label', group);
return el;
}
-
+
function createSelOpt(opt, title)
{
var el = document.createElement('option');
el.setAttribute('value', opt);
- if (typeof title == 'undefined')
+ if (typeof title == 'undefined')
el.innerHTML = opt;
else
el.innerHTML = title;
diff --git a/config/hyperion.config.json.commented b/config/hyperion.config.json.commented
index 10f1a8ce..30375404 100644
--- a/config/hyperion.config.json.commented
+++ b/config/hyperion.config.json.commented
@@ -43,7 +43,7 @@
/// * 'id' : The unique identifier of the channel adjustments (eg 'device_1')
/// * 'leds' : The indices (or index ranges) of the leds to which this channel adjustment applies
/// (eg '0-5, 9, 11, 12-17'). The indices are zero based.
- /// * 'black'/'white'/'red'/'green'/'blue'/'cyan'/'magenta'/'yellow' : Array of RGB to adjust the output color
+ /// * 'white'/'red'/'green'/'blue'/'cyan'/'magenta'/'yellow' : Array of RGB to adjust the output color
/// * 'gammaRed'/'gammaGreen'/'gammaBlue' : Gamma value for each channel
/// * 'id' : The unique identifier of the channel adjustments (eg 'device_1')
/// * 'id' : The unique identifier of the channel adjustments (eg 'device_1')
@@ -60,7 +60,6 @@
{
"id" : "default",
"leds" : "*",
- "black" : [0,0,0],
"white" : [255,255,255],
"red" : [255,0,0],
"green" : [0,255,0],
@@ -99,15 +98,10 @@
},
/// Configuration for the embedded V4L2 grabber
- /// * enable : Enable or disable the v4lgrabber (true/false)
/// * device : V4L2 Device to use [default="/dev/video0"]
/// * input : V4L2 input to use [default=0]
- /// * standard : Video standard (PAL/NTSC/SECAM) [default="PAL"]
- /// * width : V4L2 width to set [default=-1]
- /// * height : V4L2 height to set [default=-1]
- /// * frameDecimation : Frame decimation factor [default=2]
+ /// * standard : Video standard (PAL/NTSC/SECAM/NO_CHANGE) [default="NO_CHANGE"]
/// * sizeDecimation : Size decimation factor [default=8]
- /// * priority : Hyperion priority channel [default=900]
/// * cropLeft : Cropping from the left [default=0]
/// * cropRight : Cropping from the right [default=0]
/// * cropTop : Cropping from the top [default=0]
@@ -123,13 +117,9 @@
"grabberV4L2" :
[
{
- "enable" : false,
"device" : "auto",
"input" : 0,
- "standard" : "PAL",
- "width" : 0,
- "height" : 0,
- "frameDecimation" : 2,
+ "standard" : "NO_CHANGE",
"sizeDecimation" : 8,
"priority" : 240,
"cropLeft" : 0,
@@ -148,20 +138,16 @@
],
/// The configuration for the frame-grabber, contains the following items:
- /// * enable : true if the framegrabber (platform grabber) should be activated
/// * type : type of grabber. (auto|osx|dispmanx|amlogic|x11|framebuffer) [auto]
/// * width : The width of the grabbed frames [pixels]
/// * height : The height of the grabbed frames [pixels]
/// * frequency_Hz : The frequency of the frame grab [Hz]
- /// * priority : The priority of the frame-gabber (Default=250) HINT: lower value result in HIGHER priority!
/// * ATTENTION : Power-of-Two resolution is not supported and leads to unexpected behaviour!
"framegrabber" :
{
// for all type of grabbers
- "enable" : true,
"type" : "framebuffer",
"frequency_Hz" : 10,
- "priority" : 250,
"cropLeft" : 0,
"cropRight" : 0,
"cropTop" : 0,
@@ -172,9 +158,7 @@
"height" : 96,
// valid for x11
- "useXGetImage" : false,
- "horizontalPixelDecimation" : 8,
- "verticalPixelDecimation" : 8,
+ "pixelDecimation" : 8,
// valid for framebuffer
"device" : "/dev/fb0"
@@ -313,6 +297,13 @@
]
},
+ "instCapture" : {
+ "systemEnable" : true,
+ "systemPriority" : 250,
+ "v4lEnable" : false,
+ "v4lPriority" : 240
+ },
+
/// Recreate and save led layouts made with web config. These values are just helpers for ui, not for Hyperion.
"ledConfig" :
{
diff --git a/config/hyperion.config.json.default b/config/hyperion.config.json.default
index e5385f55..33f27ece 100644
--- a/config/hyperion.config.json.default
+++ b/config/hyperion.config.json.default
@@ -26,7 +26,6 @@
{
"id" : "default",
"leds" : "*",
- "black" : [0,0,0],
"white" : [255,255,255],
"red" : [255,0,0],
"green" : [0,255,0],
@@ -58,15 +57,10 @@
"grabberV4L2" :
[
{
- "enable" : false,
"device" : "auto",
"input" : 0,
- "standard" : "PAL",
- "width" : 0,
- "height" : 0,
- "frameDecimation" : 2,
+ "standard" : "NO_CHANGE",
"sizeDecimation" : 8,
- "priority" : 240,
"cropLeft" : 0,
"cropRight" : 0,
"cropTop" : 0,
@@ -84,15 +78,11 @@
"framegrabber" :
{
- "enable" : true,
"type" : "auto",
"width" : 80,
"height" : 45,
"frequency_Hz" : 10,
- "priority" : 250,
- "useXGetImage" : false,
- "horizontalPixelDecimation" : 8,
- "verticalPixelDecimation" : 8,
+ "pixelDecimation" : 8,
"cropLeft" : 0,
"cropRight" : 0,
"cropTop" : 0,
@@ -175,6 +165,13 @@
"disable": [""]
},
+ "instCapture" : {
+ "systemEnable" : true,
+ "systemPriority" : 250,
+ "v4lEnable" : false,
+ "v4lPriority" : 240
+ },
+
"ledConfig" :
{
"top" : 8,
diff --git a/include/blackborder/BlackBorderProcessor.h b/include/blackborder/BlackBorderProcessor.h
index d5f1b9de..0b625f08 100644
--- a/include/blackborder/BlackBorderProcessor.h
+++ b/include/blackborder/BlackBorderProcessor.h
@@ -4,30 +4,28 @@
// QT includes
#include
+// util
+#include
+#include
+#include
+
// Local Hyperion includes
#include "BlackBorderDetector.h"
+class Hyperion;
+
namespace hyperion
{
///
/// The BlackBorder processor is a wrapper around the black-border detector for keeping track of
/// detected borders and count of the type and size of detected borders.
///
- class BlackBorderProcessor
+ class BlackBorderProcessor : public QObject
{
+ Q_OBJECT
public:
- ///
- /// Constructor for the BlackBorderProcessor
- /// @param unknownFrameCnt The number of frames(images) that need to contain an unknown
- /// border before the current border is set to unknown
- /// @param borderFrameCnt The number of frames(images) that need to contain a vertical or
- /// horizontal border becomes the current border
- /// @param blurRemoveCnt The size to add to a horizontal or vertical border (because the
- /// outer pixels is blurred (black and color combined due to image scaling))
- /// @param[in] blackborderThreshold The threshold which the blackborder detector should use
- ///
- BlackBorderProcessor(const QJsonObject &blackborderConfig);
-
+ BlackBorderProcessor(Hyperion* hyperion, QObject* parent);
+ ~BlackBorderProcessor();
///
/// Return the current (detected) border
/// @return The current border
@@ -46,6 +44,13 @@ namespace hyperion
///
void setEnabled(bool enable);
+ ///
+ /// Sets the _hardDisabled state, if True prevents the enable from COMP_BLACKBORDER state emit (mimiks wrong state to external!)
+ /// It's not possible to enable bb from this method, if the user requsted a disable!
+ /// @param disable The new state
+ ///
+ void setHardDisable(const bool& disable);
+
///
/// Processes the image. This performs detecion of black-border on the given image and
/// updates the current border accordingly. If the current border is updated the method call
@@ -70,11 +75,11 @@ namespace hyperion
}
if (_detectionMode == "default") {
- imageBorder = _detector.process(image);
+ imageBorder = _detector->process(image);
} else if (_detectionMode == "classic") {
- imageBorder = _detector.process_classic(image);
+ imageBorder = _detector->process_classic(image);
} else if (_detectionMode == "osd") {
- imageBorder = _detector.process_osd(image);
+ imageBorder = _detector->process_osd(image);
}
// add blur to the border
if (imageBorder.horizontalSize > 0)
@@ -89,8 +94,23 @@ namespace hyperion
const bool borderUpdated = updateBorder(imageBorder);
return borderUpdated;
}
+ private slots:
+ ///
+ /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
+ /// @param type settingyType from enum
+ /// @param config configuration object
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
+
+ ///
+ /// @brief Handle component state changes, it's not possible for BB to be enabled, when a hardDisable is active
+ ///
+ void componentStateChanged(const hyperion::Components component, bool enable);
private:
+ /// Hyperion instance
+ Hyperion* _hyperion;
+
///
/// Updates the current border based on the newly detected border. Returns true if the
/// current border has changed.
@@ -102,24 +122,24 @@ namespace hyperion
/// flag for blackborder detector usage
bool _enabled;
-
+
/// The number of unknown-borders detected before it becomes the current border
- const unsigned _unknownSwitchCnt;
+ unsigned _unknownSwitchCnt;
/// The number of horizontal/vertical borders detected before it becomes the current border
- const unsigned _borderSwitchCnt;
+ unsigned _borderSwitchCnt;
// The number of frames that are "ignored" before a new border gets set as _previousDetectedBorder
- const unsigned _maxInconsistentCnt;
+ unsigned _maxInconsistentCnt;
/// The number of pixels to increase a detected border for removing blury pixels
unsigned _blurRemoveCnt;
/// The border detection mode
- const QString _detectionMode;
+ QString _detectionMode;
/// The blackborder detector
- BlackBorderDetector _detector;
+ BlackBorderDetector* _detector;
/// The current detected border
BlackBorder _currentBorder;
@@ -131,5 +151,12 @@ namespace hyperion
unsigned _consistentCnt;
/// The number of frame the previous detected border NOT matched the incomming border
unsigned _inconsistentCnt;
+ /// old threshold
+ double _oldThreshold;
+ /// True when disabled in specific situations, this prevents to enable BB when the visible priority requested a disable
+ bool _hardDisabled;
+ /// Reflect the last component state request from user (comp change)
+ bool _userEnabled;
+
};
} // end namespace hyperion
diff --git a/include/boblightserver/BoblightServer.h b/include/boblightserver/BoblightServer.h
index 42ed587c..3b711816 100644
--- a/include/boblightserver/BoblightServer.h
+++ b/include/boblightserver/BoblightServer.h
@@ -4,15 +4,19 @@
#include
// Qt includes
-#include
#include
+#include
// Hyperion includes
-#include
#include
#include
+// settings
+#include
+
class BoblightClientConnection;
+class Hyperion;
+class QTcpServer;
///
/// This class creates a TCP server which accepts connections from boblight clients.
@@ -27,25 +31,24 @@ public:
/// @param hyperion Hyperion instance
/// @param port port number on which to start listening for connections
///
- BoblightServer(const int priority, uint16_t port = 19333);
+ BoblightServer(const QJsonDocument& config);
~BoblightServer();
///
/// @return the port number on which this TCP listens for incoming connections
///
uint16_t getPort() const;
-
+
/// @return true if server is active (bind to a port)
///
- bool active() { return _isActive; };
- bool componentState() { return active(); };
+ bool active();
public slots:
///
/// bind server to network
///
void start();
-
+
///
/// close server
///
@@ -53,8 +56,12 @@ public slots:
void componentStateChanged(const hyperion::Components component, bool enable);
-signals:
- void statusChanged(bool isActive);
+ ///
+ /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
+ /// @param type settingyType from enum
+ /// @param config configuration object
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
private slots:
///
@@ -73,19 +80,17 @@ private:
Hyperion * _hyperion;
/// The TCP server object
- QTcpServer _server;
+ QTcpServer * _server;
/// List with open connections
QSet _openConnections;
/// hyperion priority
- const int _priority;
+ int _priority;
/// Logger instance
Logger * _log;
- /// state of connection
- bool _isActive;
-
+ // current port
uint16_t _port;
};
diff --git a/include/bonjour/bonjourbrowserwrapper.h b/include/bonjour/bonjourbrowserwrapper.h
new file mode 100644
index 00000000..527576d4
--- /dev/null
+++ b/include/bonjour/bonjourbrowserwrapper.h
@@ -0,0 +1,68 @@
+#pragma once
+// qt incl
+#include
+#include
+#include
+
+#include
+
+class BonjourServiceBrowser;
+class BonjourServiceResolver;
+class QTimer;
+
+class BonjourBrowserWrapper : public QObject
+{
+ Q_OBJECT
+private:
+ friend class HyperionDaemon;
+ ///
+ /// @brief Browse for hyperion services in bonjour, constructed from HyperionDaemon
+ /// Searching for hyperion http service by default
+ ///
+ BonjourBrowserWrapper(QObject * parent = 0);
+
+public:
+
+ ///
+ /// @brief Browse for a service
+ ///
+ bool browseForServiceType(const QString &serviceType);
+ ///
+ /// @brief Get all available sessions
+ ///
+ QMap getAllServices() { return _hyperionSessions; };
+
+ static BonjourBrowserWrapper* instance;
+ static BonjourBrowserWrapper* getInstance(){ return instance; };
+
+signals:
+ ///
+ /// @brief Emits whenever a change happend
+ ///
+ void browserChange(const QMap& bRegisters);
+
+private:
+ /// map of service names and browsers
+ QMap< QString, BonjourServiceBrowser* > _browsedServices;
+ /// Resolver
+ BonjourServiceResolver* _bonjourResolver;
+
+ // contains all current active service sessions
+ QMap _hyperionSessions;
+
+ QString _bonjourCurrentServiceToResolve;
+ /// timer to resolve changes
+ QTimer* _timerBonjourResolver;
+
+private slots:
+ ///
+ /// @brief is called whenever a BonjourServiceBrowser emits change
+ void currentBonjourRecordsChanged(const QList &list);
+ /// @brief new record resolved
+ void bonjourRecordResolved(const QHostInfo &hostInfo, int port);
+
+ ///
+ /// @brief timer slot which updates regularly entries
+ ///
+ void bonjourResolve();
+};
diff --git a/include/bonjour/bonjourserviceregister.h b/include/bonjour/bonjourserviceregister.h
index 137f97cf..6e3e14ec 100755
--- a/include/bonjour/bonjourserviceregister.h
+++ b/include/bonjour/bonjourserviceregister.h
@@ -43,7 +43,8 @@ public:
BonjourServiceRegister(QObject *parent = 0);
~BonjourServiceRegister();
- void registerService(const BonjourRecord &record, quint16 servicePort, std::vector> txt);
+ void registerService(const QString& service, const int& port);
+ void registerService(const BonjourRecord &record, quint16 servicePort, std::vector> txt = std::vector>());
inline BonjourRecord registeredRecord() const {return finalRecord; }
signals:
diff --git a/include/effectengine/Effect.h b/include/effectengine/Effect.h
new file mode 100644
index 00000000..e028a36a
--- /dev/null
+++ b/include/effectengine/Effect.h
@@ -0,0 +1,89 @@
+#pragma once
+
+// Python includes
+// collide of qt slots macro
+#undef slots
+#include "Python.h"
+#define slots
+
+// Qt includes
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Hyperion includes
+#include
+#include
+
+class Hyperion;
+class Logger;
+
+class Effect : public QThread
+{
+ Q_OBJECT
+
+public:
+ friend class EffectModule;
+
+ Effect(Hyperion* hyperion, int priority, int timeout, const QString & script, const QString & name, const QJsonObject & args = QJsonObject());
+ virtual ~Effect();
+
+ virtual void run();
+
+ int getPriority() const { return _priority; };
+
+ ///
+ /// @brief Set manual interuption to true,
+ /// Note: DO NOT USE QThread::interuption!
+ ///
+ void setInteruptionFlag() { _interupt = true; };
+
+ ///
+ /// @brief Check if the interuption flag has been set
+ /// @return The flag state
+ ///
+ bool hasInteruptionFlag() { return _interupt; };
+
+ QString getScript() const { return _script; }
+ QString getName() const { return _name; }
+
+ int getTimeout() const {return _timeout; }
+
+ QJsonObject getArgs() const { return _args; }
+
+signals:
+ void setInput(const int priority, const std::vector& ledColors, const int timeout_ms, const bool& clearEffect);
+ void setInputImage(const int priority, const Image& image, const int timeout_ms, const bool& clearEffect);
+
+private:
+
+ void addImage();
+
+ Hyperion* _hyperion;
+
+ const int _priority;
+
+ const int _timeout;
+
+ const QString _script;
+ const QString _name;
+
+ const QJsonObject _args;
+
+ int64_t _endTime;
+
+ /// Buffer for colorData
+ QVector _colors;
+
+ Logger* _log;
+ // Reflects whenever this effects should interupt (timeout or external request)
+ bool _interupt = false;
+
+ QSize _imageSize;
+ QImage _image;
+ QPainter* _painter;
+ QVector _imageStack;
+};
diff --git a/include/effectengine/EffectEngine.h b/include/effectengine/EffectEngine.h
index 323b8270..138e6ebf 100644
--- a/include/effectengine/EffectEngine.h
+++ b/include/effectengine/EffectEngine.h
@@ -19,7 +19,6 @@
// pre-declarioation
class Effect;
-typedef struct _ts PyThreadState;
class EffectEngine : public QObject
{
@@ -43,6 +42,20 @@ public:
return _effectSchemas;
};
+ ///
+ /// @brief Get all init data of the running effects and stop them
+ ///
+ void cacheRunningEffects();
+
+ ///
+ /// @brief Start all cached effects, origin and smooth cfg is default
+ ///
+ void startCachedEffects();
+
+signals:
+ /// Emit when the effect list has been updated
+ void effectListUpdated();
+
public slots:
/// Run the specified effect on the given priority channel and optionally specify a timeout
int runEffect(const QString &effectName, int priority, int timeout = -1, const QString &origin="System");
@@ -78,9 +91,9 @@ private:
std::list _availableActiveEffects;
+ std::list _cachedActiveEffects;
+
std::list _effectSchemas;
Logger * _log;
-
- PyThreadState* _mainThreadState;
};
diff --git a/libsrc/effectengine/Effect.h b/include/effectengine/EffectModule.h
similarity index 55%
rename from libsrc/effectengine/Effect.h
rename to include/effectengine/EffectModule.h
index 7d51d5a5..c274d05b 100644
--- a/libsrc/effectengine/Effect.h
+++ b/include/effectengine/EffectModule.h
@@ -1,49 +1,27 @@
#pragma once
-// Python includes
-// collide of qt slots macro
#undef slots
#include
#define slots
-// Qt includes
-#include
-#include
-#include
-#include
-#include
+#include
-// Hyperion includes
-#include
-#include
+class Effect;
-class Effect : public QThread
+class EffectModule
{
- Q_OBJECT
-
public:
- Effect(PyThreadState* mainThreadState, int priority, int timeout, const QString & script, const QString & name, const QJsonObject & args = QJsonObject(), const QString & origin="System", unsigned smoothCfg=0);
- virtual ~Effect();
+ // Python 3 module def
+ static struct PyModuleDef moduleDef;
- virtual void run();
+ // Init module
+ static PyObject* PyInit_hyperion();
- int getPriority() const { return _priority; };
+ // Register module once
+ static void registerHyperionExtensionModule();
- QString getScript() const { return _script; }
- QString getName() const { return _name; }
-
- int getTimeout() const {return _timeout; }
-
- QJsonObject getArgs() const { return _args; }
-
- /// This function registers the extension module in Python
- static void registerHyperionExtensionModule();
-
-signals:
- void setColors(int priority, const std::vector &ledColors, const int timeout_ms, bool clearEffects, hyperion::Components componentconst, QString origin, unsigned smoothCfg);
-
-private:
- PyObject * json2python(const QJsonValue & jsonData) const;
+ // json 2 python
+ static PyObject * json2python(const QJsonValue & jsonData);
// Wrapper methods for Python interpreter extra buildin methods
static PyMethodDef effectMethods[];
@@ -71,38 +49,5 @@ private:
static PyObject* wrapImageCOffset (PyObject *self, PyObject *args);
static PyObject* wrapImageCShear (PyObject *self, PyObject *args);
static PyObject* wrapImageResetT (PyObject *self, PyObject *args);
- static Effect * getEffect();
-
- static struct PyModuleDef moduleDef;
- static PyObject* PyInit_hyperion();
-
- void addImage();
-
- PyThreadState* _mainThreadState;
-
- const int _priority;
-
- const int _timeout;
-
- const QString _script;
- const QString _name;
- unsigned _smoothCfg;
-
- const QJsonObject _args;
-
- int64_t _endTime;
-
- /// The processor for translating images to led-values
- ImageProcessor * _imageProcessor;
-
- /// Buffer for colorData
- QVector _colors;
-
- Logger* _log;
-
- QString _origin;
- QSize _imageSize;
- QImage _image;
- QPainter* _painter;
- QVector _imageStack;
+ static Effect * getEffect();
};
diff --git a/include/grabber/AmlogicWrapper.h b/include/grabber/AmlogicWrapper.h
index bfcc9552..0f241162 100644
--- a/include/grabber/AmlogicWrapper.h
+++ b/include/grabber/AmlogicWrapper.h
@@ -18,9 +18,8 @@ public:
/// @param[in] grabWidth The width of the grabbed image [pixels]
/// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz]
- /// @param[in] hyperion The instance of Hyperion used to write the led values
///
- AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority);
+ AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz);
///
/// Destructor of this dispmanx frame grabber. Releases any claimed resources.
diff --git a/include/grabber/DispmanxFrameGrabber.h b/include/grabber/DispmanxFrameGrabber.h
index 3d22d3dc..cd885015 100644
--- a/include/grabber/DispmanxFrameGrabber.h
+++ b/include/grabber/DispmanxFrameGrabber.h
@@ -40,14 +40,23 @@ public:
///
int grabFrame(Image & image);
+ ///
+ ///@brief Set new width and height for dispmanx, overwrite Grabber.h impl
+ virtual void setWidthHeight(int width, int height);
+
private:
- ///
+ ///
/// Updates the frame-grab flags as used by the VC library for frame grabbing
///
/// @param vc_flags The snapshot grabbing mask
///
void setFlags(const int vc_flags);
-
+
+ ///
+ /// @brief free _vc_resource and captureBuffer
+ ///
+ void freeResources();
+
/// Handle to the display that is being captured
DISPMANX_DISPLAY_HANDLE_T _vc_display;
diff --git a/include/grabber/DispmanxWrapper.h b/include/grabber/DispmanxWrapper.h
index 618a8b27..e231c809 100644
--- a/include/grabber/DispmanxWrapper.h
+++ b/include/grabber/DispmanxWrapper.h
@@ -7,8 +7,7 @@
///
/// The DispmanxWrapper uses an instance of the DispmanxFrameGrabber to obtain ImageRgb's from the
-/// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the
-/// attached Hyperion.
+/// displayed content. This ImageRgb is forwarded to all Hyperion instances via HyperionDaemon
///
class DispmanxWrapper: public GrabberWrapper
{
@@ -20,9 +19,8 @@ public:
/// @param[in] grabWidth The width of the grabbed image [pixels]
/// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz]
- /// @param[in] hyperion The instance of Hyperion used to write the led values
///
- DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority);
+ DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz);
///
/// Destructor of this dispmanx frame grabber. Releases any claimed resources.
diff --git a/include/grabber/FramebufferFrameGrabber.h b/include/grabber/FramebufferFrameGrabber.h
index 6077bb1b..6296755f 100644
--- a/include/grabber/FramebufferFrameGrabber.h
+++ b/include/grabber/FramebufferFrameGrabber.h
@@ -5,7 +5,7 @@
#include
///
-/// The FramebufferFrameGrabber is used for creating snapshots of the display (screenshots)
+/// The FramebufferFrameGrabber is used for creating snapshots of the display (screenshots)
///
class FramebufferFrameGrabber : public Grabber
{
@@ -30,13 +30,18 @@ public:
///
int grabFrame(Image & image);
+ ///
+ /// @brief Overwrite Grabber.h implememtation
+ ///
+ virtual void setDevicePath(const QString& path);
+
private:
/// Framebuffer file descriptor
int _fbfd;
/// Pointer to framebuffer
unsigned char * _fbp;
-
+
/// Framebuffer device e.g. /dev/fb0
- const QString _fbDevice;
+ QString _fbDevice;
};
diff --git a/include/grabber/FramebufferWrapper.h b/include/grabber/FramebufferWrapper.h
index 164c56b3..a7c9243c 100644
--- a/include/grabber/FramebufferWrapper.h
+++ b/include/grabber/FramebufferWrapper.h
@@ -20,7 +20,7 @@ public:
/// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz]
///
- FramebufferWrapper(const QString & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority);
+ FramebufferWrapper(const QString & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz);
///
/// Destructor of this framebuffer frame grabber. Releases any claimed resources.
diff --git a/include/grabber/OsxFrameGrabber.h b/include/grabber/OsxFrameGrabber.h
index 8cba6394..59e39930 100644
--- a/include/grabber/OsxFrameGrabber.h
+++ b/include/grabber/OsxFrameGrabber.h
@@ -12,7 +12,7 @@
#include
///
-/// The OsxFrameGrabber is used for creating snapshots of the display (screenshots)
+/// The OsxFrameGrabber is used for creating snapshots of the display (screenshots)
///
class OsxFrameGrabber : public Grabber
{
@@ -37,10 +37,15 @@ public:
///
int grabFrame(Image & image);
-private:
+ ///
+ /// @brief Overwrite Grabber.h implementation
+ ///
+ virtual void setDisplayIndex(int index);
+
+private:
/// display
- const unsigned _screenIndex;
-
+ unsigned _screenIndex;
+
/// Reference to the captured diaplay
CGDirectDisplayID _display;
};
diff --git a/include/grabber/OsxWrapper.h b/include/grabber/OsxWrapper.h
index 65b765d7..65ce70ab 100644
--- a/include/grabber/OsxWrapper.h
+++ b/include/grabber/OsxWrapper.h
@@ -19,9 +19,8 @@ public:
/// @param[in] grabWidth The width of the grabbed image [pixels]
/// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz]
- /// @param[in] hyperion The instance of Hyperion used to write the led values
///
- OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority);
+ OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz);
///
/// Destructor of this osx frame grabber. Releases any claimed resources.
diff --git a/include/grabber/V4L2Grabber.h b/include/grabber/V4L2Grabber.h
index b21aa005..7277b69a 100644
--- a/include/grabber/V4L2Grabber.h
+++ b/include/grabber/V4L2Grabber.h
@@ -24,12 +24,9 @@ class V4L2Grabber : public Grabber
public:
V4L2Grabber(const QString & device,
int input,
- VideoStandard videoStandard, PixelFormat pixelFormat,
- unsigned width,
- unsigned height,
- int frameDecimation,
- int horizontalPixelDecimation,
- int verticalPixelDecimation
+ VideoStandard videoStandard,
+ PixelFormat pixelFormat,
+ int pixelDecimation
);
virtual ~V4L2Grabber();
@@ -37,21 +34,46 @@ public:
bool getSignalDetectionEnabled();
int grabFrame(Image &);
-
-public slots:
- void setSignalThreshold(
+
+ ///
+ /// @brief overwrite Grabber.h implementation, as v4l doesn't use width/height
+ ///
+ virtual void setWidthHeight(){};
+
+ ///
+ /// @brief set new PixelDecimation value to ImageResampler
+ /// @param pixelDecimation The new pixelDecimation value
+ ///
+ virtual void setPixelDecimation(int pixelDecimation);
+
+ ///
+ /// @brief overwrite Grabber.h implementation
+ ///
+ virtual void setSignalThreshold(
double redSignalThreshold,
double greenSignalThreshold,
double blueSignalThreshold,
- int noSignalCounterThreshold);
+ int noSignalCounterThreshold = 50);
- void setSignalDetectionOffset(
+ ///
+ /// @brief overwrite Grabber.h implementation
+ ///
+ virtual void setSignalDetectionOffset(
double verticalMin,
double horizontalMin,
double verticalMax,
double horizontalMax);
+ ///
+ /// @brief overwrite Grabber.h implementation
+ ///
+ virtual void setSignalDetectionEnable(bool enable);
- void setSignalDetectionEnable(bool enable);
+ ///
+ /// @brief overwrite Grabber.h implementation
+ ///
+ virtual void setInputVideoStandard(int input, VideoStandard videoStandard);
+
+public slots:
bool start();
@@ -66,7 +88,7 @@ private slots:
private:
void getV4Ldevices();
-
+
bool init();
void uninit();
@@ -120,9 +142,9 @@ private:
std::vector _buffers;
PixelFormat _pixelFormat;
+ int _pixelDecimation;
int _lineLength;
int _frameByteSize;
- int _frameDecimation;
// signal detection
int _noSignalCounterThreshold;
@@ -134,7 +156,6 @@ private:
double _y_frac_min;
double _x_frac_max;
double _y_frac_max;
- int _currentFrame;
QSocketNotifier * _streamNotifier;
diff --git a/include/grabber/V4L2Wrapper.h b/include/grabber/V4L2Wrapper.h
index ffc78a7c..dfa14014 100644
--- a/include/grabber/V4L2Wrapper.h
+++ b/include/grabber/V4L2Wrapper.h
@@ -12,14 +12,7 @@ public:
int input,
VideoStandard videoStandard,
PixelFormat pixelFormat,
- unsigned width,
- unsigned height,
- int frameDecimation,
- int pixelDecimation,
- double redSignalThreshold,
- double greenSignalThreshold,
- double blueSignalThreshold,
- const int priority);
+ int pixelDecimation );
virtual ~V4L2Wrapper() {};
bool getSignalDetectionEnable();
@@ -28,19 +21,16 @@ public slots:
bool start();
void stop();
+ void setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold);
void setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom);
void setSignalDetectionOffset(double verticalMin, double horizontalMin, double verticalMax, double horizontalMax);
void setSignalDetectionEnable(bool enable);
-// signals:
-// void emitColors(int priority, const std::vector &ledColors, const int timeout_ms);
-
private slots:
void newFrame(const Image & image);
void readError(const char* err);
virtual void action();
- void checkSources();
private:
/// The V4L2 grabber
diff --git a/include/grabber/X11Grabber.h b/include/grabber/X11Grabber.h
index 7ef286fb..af833f33 100755
--- a/include/grabber/X11Grabber.h
+++ b/include/grabber/X11Grabber.h
@@ -17,12 +17,12 @@ class X11Grabber : public Grabber
{
public:
- X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation);
+ X11Grabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation);
virtual ~X11Grabber();
bool Setup();
-
+
///
/// Captures a single snapshot of the display and writes the data to the given image. The
/// provided image should have the same dimensions as the configured values (_width and
@@ -32,15 +32,34 @@ public:
/// height)
///
virtual int grabFrame(Image & image, bool forceUpdate=false);
-
+
///
/// update dimension according current screen
int updateScreenDimensions(bool force=false);
virtual void setVideoMode(VideoMode mode);
+ ///
+ /// @brief Apply new width/height values, overwrite Grabber.h implementation as X11 doesn't use width/height, just pixelDecimation to calc dimensions
+ ///
+ virtual void setWidthHeight(int width, int height);
+
+ ///
+ /// @brief Apply new pixelDecimation
+ ///
+ virtual void setPixelDecimation(int pixelDecimation);
+
+ ///
+ /// Set the crop values
+ /// @param cropLeft Left pixel crop
+ /// @param cropRight Right pixel crop
+ /// @param cropTop Top pixel crop
+ /// @param cropBottom Bottom pixel crop
+ ///
+ virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
+
private:
- bool _useXGetImage, _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
+ bool _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
XImage* _xImage;
XShmSegmentInfo _shminfo;
@@ -49,17 +68,16 @@ private:
Display* _x11Display;
Window _window;
XWindowAttributes _windowAttr;
-
+
Pixmap _pixmap;
XRenderPictFormat* _srcFormat;
XRenderPictFormat* _dstFormat;
XRenderPictureAttributes _pictAttr;
Picture _srcPicture;
Picture _dstPicture;
-
+
XTransform _transform;
- int _horizontalDecimation;
- int _verticalDecimation;
+ int _pixelDecimation;
unsigned _screenWidth;
unsigned _screenHeight;
@@ -67,7 +85,7 @@ private:
unsigned _src_y;
Image _image;
-
+
void freeResources();
void setupResources();
};
diff --git a/include/grabber/X11Wrapper.h b/include/grabber/X11Wrapper.h
index e29b3ca4..51f2c77c 100644
--- a/include/grabber/X11Wrapper.h
+++ b/include/grabber/X11Wrapper.h
@@ -24,7 +24,7 @@ public:
/// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz]
///
- X11Wrapper(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation, const unsigned updateRate_Hz, const int priority);
+ X11Wrapper(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, const unsigned updateRate_Hz);
///
/// Destructor of this framebuffer frame grabber. Releases any claimed resources.
@@ -43,4 +43,3 @@ private:
bool _init;
};
-
diff --git a/include/hyperion/BGEffectHandler.h b/include/hyperion/BGEffectHandler.h
new file mode 100644
index 00000000..3ca229dc
--- /dev/null
+++ b/include/hyperion/BGEffectHandler.h
@@ -0,0 +1,71 @@
+#pragma once
+
+#include
+#include
+#include
+
+///
+/// @brief Handle the background Effect settings, reacts on runtime to settings changes
+///
+class BGEffectHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ BGEffectHandler(Hyperion* hyperion)
+ : QObject(hyperion)
+ , _hyperion(hyperion)
+ {
+ // listen for config changes
+ connect(_hyperion, &Hyperion::settingsChanged, this, &BGEffectHandler::handleSettingsUpdate);
+
+ // init
+ handleSettingsUpdate(settings::BGEFFECT, _hyperion->getSetting(settings::BGEFFECT));
+ };
+
+private slots:
+ ///
+ /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
+ /// @param type settingyType from enum
+ /// @param config configuration object
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
+ {
+ if(type == settings::BGEFFECT)
+ {
+ const QJsonObject& BGEffectConfig = config.object();
+
+ #define BGCONFIG_ARRAY bgColorConfig.toArray()
+ // clear bg prioritiy
+ _hyperion->clear(254);
+ // initial background effect/color
+ if (BGEffectConfig["enable"].toBool(true))
+ {
+ const QString bgTypeConfig = BGEffectConfig["type"].toString("effect");
+ const QString bgEffectConfig = BGEffectConfig["effect"].toString("Warm mood blobs");
+ const QJsonValue bgColorConfig = BGEffectConfig["color"];
+ if (bgTypeConfig.contains("color"))
+ {
+ ColorRgb bg_color = {
+ (uint8_t)BGCONFIG_ARRAY.at(0).toInt(0),
+ (uint8_t)BGCONFIG_ARRAY.at(1).toInt(0),
+ (uint8_t)BGCONFIG_ARRAY.at(2).toInt(0)
+ };
+ _hyperion->setColor(254, bg_color);
+ Info(Logger::getInstance("HYPERION"),"Inital background color set (%d %d %d)",bg_color.red,bg_color.green,bg_color.blue);
+ }
+ else
+ {
+ int result = _hyperion->setEffect(bgEffectConfig, 254);
+ Info(Logger::getInstance("HYPERION"),"Inital background effect '%s' %s", QSTRING_CSTR(bgEffectConfig), ((result == 0) ? "started" : "failed"));
+ }
+ }
+
+ #undef BGCONFIG_ARRAY
+ }
+ };
+
+private:
+ /// Hyperion instance pointer
+ Hyperion* _hyperion;
+};
diff --git a/include/hyperion/CaptureCont.h b/include/hyperion/CaptureCont.h
new file mode 100644
index 00000000..4322776c
--- /dev/null
+++ b/include/hyperion/CaptureCont.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+class Hyperion;
+
+///
+/// @brief Capture Control class which is a interface to the HyperionDaemon native capture classes.
+/// It controls the instance based enable/disable of capture feeds and PriorityMuxer registrations
+///
+class CaptureCont : public QObject
+{
+ Q_OBJECT
+public:
+ CaptureCont(Hyperion* hyperion);
+ ~CaptureCont();
+
+ void setSystemCaptureEnable(const bool& enable);
+ void setV4LCaptureEnable(const bool& enable);
+
+private slots:
+ ///
+ /// @brief Handle component state change of V4L and SystemCapture
+ /// @param component The component from enum
+ /// @param enable The new state
+ ///
+ void componentStateChanged(const hyperion::Components component, bool enable);
+
+ ///
+ /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
+ /// @param type settingyType from enum
+ /// @param config configuration object
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
+
+ ///
+ /// @brief forward system image
+ /// @param image The image
+ ///
+ void handleSystemImage(const Image& image);
+
+ ///
+ /// @brief forward v4l image
+ /// @param image The image
+ ///
+ void handleV4lImage(const Image & image);
+
+private:
+ /// Hyperion instance
+ Hyperion* _hyperion;
+
+ /// Reflect state of System capture and prio
+ bool _systemCaptEnabled;
+ quint8 _systemCaptPrio;
+
+ /// Reflect state of v4l capture and prio
+ bool _v4lCaptEnabled;
+ quint8 _v4lCaptPrio;
+};
diff --git a/include/hyperion/ComponentRegister.h b/include/hyperion/ComponentRegister.h
index 5ae442b0..91bd7228 100644
--- a/include/hyperion/ComponentRegister.h
+++ b/include/hyperion/ComponentRegister.h
@@ -1,6 +1,6 @@
#pragma once
-#include
+#include
#include
// STL includes
@@ -8,21 +8,61 @@
#include
+class Hyperion;
+
+///
+/// @brief The component register reflects and manages the current state of all components and Hyperion as a whole
+/// It emits also real component state changes (triggert from the specific component), which can be used for listening APIs (Network Clients/Plugins)
+///
class ComponentRegister : public QObject
{
Q_OBJECT
public:
- ComponentRegister();
+ ComponentRegister(Hyperion* hyperion);
~ComponentRegister();
+ ///
+ /// @brief Enable or disable Hyperion (all components)
+ /// @param state The new state of Hyperion
+ ///
+ /// @return Returns true on success, false when Hyperion is already at the requested state
+ ///
+ bool setHyperionEnable(const bool& state);
+
+ ///
+ /// @brief Check if a component is currently enabled
+ /// @param comp The component from enum
+ /// @return True if component is running else false
+ ///
+ bool isComponentEnabled(const hyperion::Components& comp) const;
+
+ /// contains all components and their state
std::map getRegister() { return _componentStates; };
+signals:
+ ///
+ /// @brief Emits whenever a component changed (really) the state
+ /// @param comp The component
+ /// @param state The new state of the component
+ ///
+ void updatedComponentState(const hyperion::Components comp, const bool state);
+
public slots:
+ ///
+ /// @brief is called whenever a component change a state, DO NOT CALL FROM API (use hyperion->setComponentState() instead)
+ /// @param comp The component
+ /// @param state The new state of the component
+ ///
void componentStateChanged(const hyperion::Components comp, const bool activated);
private:
- std::map _componentStates;
+ /// Hyperion instance
+ Hyperion * _hyperion;
+ /// Logger instance
Logger * _log;
+ /// current state of all components
+ std::map _componentStates;
+ /// on hyperion off we save the previous states of all components
+ std::map _prevComponentStates;
};
-
diff --git a/include/hyperion/Grabber.h b/include/hyperion/Grabber.h
index fa81a57b..88207e03 100644
--- a/include/hyperion/Grabber.h
+++ b/include/hyperion/Grabber.h
@@ -6,10 +6,14 @@
#include
#include
#include
+#include
#include
#include
-
+///
+/// @brief The Grabber class is responsible to apply image resizes (with or without ImageResampler)
+/// Overwrite the videoMode with setVideoMode()
+/// Overwrite setCropping()
class Grabber : public QObject
{
Q_OBJECT
@@ -24,14 +28,71 @@ public:
///
virtual void setVideoMode(VideoMode mode);
+ ///
+ /// @brief Apply new crop values, on errors reject the values
+ ///
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
- /// gets resulting height of image
+ ///
+ /// @brief Apply new width/height values, on errors (collide with cropping) reject the values
+ ///
+ virtual void setWidthHeight(int width, int height);
+
+ ///
+ /// @brief Apply new pixelDecimation (used from x11)
+ ///
+ virtual void setPixelDecimation(int pixelDecimation) {};
+
+ ///
+ /// @brief Apply new signalThreshold (used from v4l)
+ ///
+ virtual void setSignalThreshold(
+ double redSignalThreshold,
+ double greenSignalThreshold,
+ double blueSignalThreshold,
+ int noSignalCounterThreshold = 50) {};
+ ///
+ /// @brief Apply new SignalDetectionOffset (used from v4l)
+ ///
+ virtual void setSignalDetectionOffset(
+ double verticalMin,
+ double horizontalMin,
+ double verticalMax,
+ double horizontalMax) {};
+
+ ///
+ /// @brief Apply SignalDetectionEnable (used from v4l)
+ ///
+ virtual void setSignalDetectionEnable(bool enable) {};
+
+ ///
+ /// @brief Apply input and videoStanded (used from v4l)
+ ///
+ virtual void setInputVideoStandard(int input, VideoStandard videoStandard) {};
+
+ ///
+ /// @brief Apply display index (used from x11)
+ ///
+ virtual void setDisplayIndex(int index) {};
+
+ ///
+ /// @brief Apply path for device (used from framebuffer)
+ ///
+ virtual void setDevicePath(const QString& path) {};
+
+ ///
+ /// @brief get current resulting height of image (after crop)
+ ///
virtual const int getImageWidth() { return _width; };
- /// gets resulting width of image
+ ///
+ /// @brief get current resulting width of image (after crop)
+ ///
virtual const int getImageHeight() { return _height; };
+ ///
+ /// @brief Prevent the real capture implementation from capturing if disabled
+ ///
void setEnabled(bool enable);
protected:
diff --git a/include/hyperion/GrabberWrapper.h b/include/hyperion/GrabberWrapper.h
index 7e893a82..ca70a436 100644
--- a/include/hyperion/GrabberWrapper.h
+++ b/include/hyperion/GrabberWrapper.h
@@ -1,27 +1,29 @@
#pragma once
#include
-#include
#include
#include
#include
#include
#include
-#include
#include
#include
#include
+#include
-class ImageProcessor;
class Grabber;
class DispmanxFrameGrabber;
+class QTimer;
+///
+/// This class will be inherted by FramebufferWrapper and others which contains the real capture interface
+///
class GrabberWrapper : public QObject
{
Q_OBJECT
public:
- GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned width, unsigned height, const unsigned updateRate_Hz, const int priority, hyperion::Components grabberComponentId=hyperion::COMP_GRABBER);
+ GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned width, unsigned height, const unsigned updateRate_Hz);
virtual ~GrabberWrapper();
@@ -35,8 +37,6 @@ public:
///
virtual void stop();
- void setImageProcessorEnabled(bool enable);
-
static QStringList availableGrabbers();
public:
@@ -45,18 +45,15 @@ public:
{
unsigned w = grabber.getImageWidth();
unsigned h = grabber.getImageHeight();
- if (_imageProcessorEnabled && ( _image.width() != w || _image.height() != h))
+ if ( _image.width() != w || _image.height() != h)
{
- _processor->setSize(w, h);
_image.resize(w, h);
}
int ret = grabber.grabFrame(_image);
if (ret >= 0)
{
- emit emitImage(_priority, _image, _timeout_ms);
- _processor->process(_image, _ledColors);
- setColors(_ledColors, _timeout_ms);
+ emit systemImage(_image);
return true;
}
return false;
@@ -64,46 +61,51 @@ public:
public slots:
- void componentStateChanged(const hyperion::Components component, bool enable);
-
///
/// virtual method, should perform single frame grab and computes the led-colors
///
virtual void action() = 0;
- void actionWrapper();
-
///
/// Set the video mode (2D/3D)
/// @param[in] mode The new video mode
///
- virtual void setVideoMode(const VideoMode videoMode);
+ virtual void setVideoMode(const VideoMode& videoMode);
+ ///
+ /// Set the crop values
+ /// @param cropLeft Left pixel crop
+ /// @param cropRight Right pixel crop
+ /// @param cropTop Top pixel crop
+ /// @param cropBottom Bottom pixel crop
+ ///
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
+ ///
+ /// @brief Handle settings update from HyperionDaemon Settingsmanager emit
+ /// @param type settingyType from enum
+ /// @param config configuration object
+ ///
+ virtual void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
+
signals:
- void emitImage(int priority, const Image & image, const int timeout_ms);
+ ///
+ /// @brief Emit the final processed image
+ ///
+ void systemImage(const Image& image);
protected:
- void setColors(const std::vector &ledColors, const int timeout_ms);
-
QString _grabberName;
/// Pointer to Hyperion for writing led values
Hyperion * _hyperion;
- /// The priority of the led colors
- const int _priority;
-
/// The timer for generating events with the specified update rate
- QTimer _timer;
+ QTimer* _timer;
- /// The update rate [Hz]
- const int _updateInterval_ms;
-
- /// The timeout of the led colors [ms]
- const int _timeout_ms;
+ /// The calced update rate [ms]
+ int _updateInterval_ms;
/// The Logger instance
Logger * _log;
@@ -111,18 +113,8 @@ protected:
// forwarding enabled
bool _forward;
- /// The processor for transforming images to led colors
- ImageProcessor * _processor;
-
- hyperion::Components _grabberComponentId;
-
Grabber *_ggrabber;
/// The image used for grabbing frames
Image _image;
-
- /// The list with computed led colors
- std::vector _ledColors;
-
- bool _imageProcessorEnabled;
};
diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h
index 28c34c4d..c39dce72 100644
--- a/include/hyperion/Hyperion.h
+++ b/include/hyperion/Hyperion.h
@@ -8,12 +8,10 @@
#include
#include
#include
-#include
#include
#include
#include
#include
-#include
#include
// hyperion-utils includes
@@ -27,7 +25,6 @@
#include
#include
#include
-#include
#include
// Effect engine includes
@@ -35,17 +32,23 @@
#include
#include
-// bonjour includes
-#include
-#include
+// settings utils
+#include
// Forward class declaration
+class QTimer;
+
+class HyperionDaemon;
+class ImageProcessor;
+class MessageForwarder;
class LedDevice;
class LinearColorSmoothing;
-class RgbTransform;
class EffectEngine;
-class RgbChannelAdjustment;
class MultiColorAdjustment;
+class ColorAdjustment;
+class SettingsManager;
+class BGEffectHandler;
+class CaptureCont;
///
/// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through
@@ -57,8 +60,6 @@ class Hyperion : public QObject
public:
/// Type definition of the info structure used by the priority muxer
typedef PriorityMuxer::InputInfo InputInfo;
- typedef QMap PriorityRegister;
- typedef QMap BonjourRegister;
///
/// RGB-Color channel enumeration
///
@@ -79,23 +80,54 @@ public:
///
/// @brief creates a new Hyperion instance, usually called from the Hyperion Daemon
- /// @param[in] qjsonConfig The configuration file
+ /// @param[in] daemon The Hyperion daemon parent
+ /// @param[in] instance The instance id
/// @param[in] rootPath Root path of all hyperion userdata
/// @return Hyperion instance pointer
///
- static Hyperion* initInstance(const QJsonObject& qjsonConfig, const QString configFile, const QString rootPath);
+ static Hyperion* initInstance(HyperionDaemon* daemon, const quint8& instance, const QString configFile, const QString rootPath);
///
/// @brief Get a pointer of this Hyperion instance
- /// @return Hyperion instance pointer
+ /// @return Hyperion instance pointer
///
static Hyperion* getInstance();
+ ///
+ /// @brief Get a pointer to the effect engine
+ /// @return EffectEngine instance pointer
+ ///
+ EffectEngine* getEffectEngineInstance() { return _effectEngine; };
+
+ ///
+ /// @brief Get a pointer to the priorityMuxer instance
+ /// @return PriorityMuxer instance pointer
+ ///
+ PriorityMuxer* getMuxerInstance() { return &_muxer; };
+
+ ///
+ /// @brief Get a setting by settings::type from SettingsManager
+ /// @param type The settingsType from enum
+ /// @return Data Document
+ ///
+ QJsonDocument getSetting(const settings::type& type);
+
+ ///
+ /// @brief Save a complete json config
+ /// @param config The entire config object
+ /// @param correct If true will correct json against schema before save
+ /// @return True on success else false
+ ///
+ bool saveSettings(QJsonObject config, const bool& correct = false);
+
///
/// Returns the number of attached leds
///
unsigned getLedCount() const;
+ ///
+ /// @brief Return the size of led grid
+ ///
QSize getLedGridSize() const { return _ledGridSize; };
///
@@ -124,11 +156,9 @@ public:
///
/// @param[in] priority The priority channel
///
- /// @return The information of the given
+ /// @return The information of the given, a not found priority will return lowest priority as fallback
///
- /// @throw std::runtime_error when the priority channel does not exist
- ///
- const InputInfo& getPriorityInfo(const int priority) const;
+ const InputInfo getPriorityInfo(const int priority) const;
/// Reload the list of available effects
void reloadEffects();
@@ -145,27 +175,29 @@ public:
/// @return The list of available effect schema files
const std::list &getEffectSchemas();
- /// gets the current json config object
+ /// gets the current json config object from SettingsManager
/// @return json config
- const QJsonObject& getQJsonConfig() { return _qjsonConfig; };
+ const QJsonObject& getQJsonConfig();
+
+ /// get path+filename of configfile
+ /// @return the current config path+filename
+ QString getConfigFilePath() { return _configFile; };
/// get filename of configfile
/// @return the current config filename
- QString getConfigFileName() { return _configFile; };
+ QString getConfigFileName() const;
- /// register a input source to a priority channel
- /// @param name uniq name of input source
- /// @param origin External setter
- /// @param priority priority channel
- void registerPriority(const QString &name, const int priority);
+ ///
+ /// @brief Register a new input by priority, the priority is not active (timeout -100 isn't muxer recognized) until you start to update the data with setInput()
+ /// A repeated call to update the base data of a known priority won't overwrite their current timeout
+ /// @param[in] priority The priority of the channel
+ /// @param[in] component The component of the channel
+ /// @param[in] origin Who set the channel (CustomString@IP)
+ /// @param[in] owner Speicifc owner string, might be empty
+ /// @param[in] smooth_cfg The smooth id to use
+ ///
+ void registerInput(const int priority, const hyperion::Components& component, const QString& origin = "System", const QString& owner = "", unsigned smooth_cfg = 0);
- /// unregister a input source to a priority channel
- /// @param name uniq name of input source
- void unRegisterPriority(const QString &name);
-
- /// gets current priority register
- /// @return the priority register
- const PriorityRegister& getPriorityRegister() { return _priorityRegister; }
/// enable/disable automatic/priorized source selection
/// @param enabled the state
@@ -178,12 +210,18 @@ public:
/// gets current state of automatic/priorized source selection
/// @return the state
- bool sourceAutoSelectEnabled() { return _sourceAutoSelectEnabled; };
+ bool sourceAutoSelectEnabled();
///
- /// Enable/Disable components during runtime
+ /// @brief Get the last untransformed/unadjusted led colors
+ /// @return The _rawLedBuffer leds
///
- /// @param component The component [SMOOTHING, BLACKBORDER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]
+ const std::vector& getRawLedBuffer() { return _rawLedBuffer; };
+
+ ///
+ /// @brief Enable/Disable components during runtime, called from external API (requests)
+ ///
+ /// @param component The component from enum
/// @param state The state of the component [true | false]
///
void setComponentState(const hyperion::Components component, const bool state);
@@ -195,54 +233,63 @@ public:
bool configWriteable() { return _configWrite; };
/// gets the methode how image is maped to leds
- int getLedMappingType() { return _ledMAppingType; };
-
- /// get the configuration
- QJsonObject getConfig() { return _qjsonConfig; };
+ const int & getLedMappingType();
/// get the root path for all hyperion user data files
- QString getRootPath() { return _rootPath; };
+ const QString &getRootPath() { return _rootPath; };
- /// unique id per instance
- QString id;
+ /// get unique id per instance
+ const QString &getId(){ return _id; };
+ /// set unique id
+ void setId(QString id){ _id = id; };
int getLatchTime() const;
/// forward smoothing config
unsigned addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0);
- VideoMode getCurrentVideoMode() { return _videoMode; };
+ const VideoMode & getCurrentVideoMode();
+
+ ///
+ /// @brief Get the current active led device
+ /// @return The device nam
+ /// e
+ const QString & getActiveDevice();
public slots:
+ ///
+ /// @brief Update the current color of a priority (prev registered with registerInput())
+ /// DO NOT use this together with setInputImage() at the same time!
+ /// @param priority The priority to update
+ /// @param ledColors The colors
+ /// @param timeout_ms The new timeout (defaults to -1 endless)
+ /// @param clearEffect Should be true when NOT called from an effect
+ /// @return True on success, false when priority is not found
+ ///
+ const bool setInput(const int priority, const std::vector& ledColors, const int timeout_ms = -1, const bool& clearEffect = true);
+
+ ///
+ /// @brief Update the current image of a priority (prev registered with registerInput())
+ /// DO NOT use this together with setInput() at the same time!
+ /// @param priority The priority to update
+ /// @param image The new image
+ /// @param timeout_ms The new timeout (defaults to -1 endless)
+ /// @param clearEffect Should be true when NOT called from an effect
+ /// @return True on success, false when priority is not found
+ ///
+ const bool setInputImage(const int priority, const Image& image, int64_t timeout_ms = -1, const bool& clearEffect = true);
+
///
/// Writes a single color to all the leds for the given time and priority
+ /// Registers comp color or provided type against muxer
+ /// Should be never used to update leds continuous
///
/// @param[in] priority The priority of the written color
/// @param[in] ledColor The color to write to the leds
+ /// @param[in] origin The setter
/// @param[in] timeout_ms The time the leds are set to the given color [ms]
///
- void setColor(int priority, const ColorRgb &ledColor, const int timeout_ms, bool clearEffects = true);
-
- ///
- /// Writes the given colors to all leds for the given time and priority
- ///
- /// @param[in] priority The priority of the written colors
- /// @param[in] ledColors The colors to write to the leds
- /// @param[in] timeout_ms The time the leds are set to the given colors [ms]
- /// @param[in] component The current component
- /// @param[in] origin Who set it
- /// @param[in] smoothCfg smoothing config id
- ///
- void setColors(int priority, const std::vector &ledColors, const int timeout_ms, bool clearEffects = true, hyperion::Components component=hyperion::COMP_INVALID, const QString origin="System", unsigned smoothCfg=SMOOTHING_MODE_DEFAULT);
-
- ///
- /// Writes the given colors to all leds for the given time and priority
- ///
- /// @param[in] priority The priority of the written colors
- /// @param[in] ledColors The colors to write to the leds
- /// @param[in] timeout_ms The time the leds are set to the given colors [ms]
- ///
- void setImage(int priority, const Image & image, int duration_ms);
+ void setColor(int priority, const ColorRgb &ledColor, const int timeout_ms = -1, const QString& origin = "System" ,bool clearEffects = true);
///
/// Returns the list with unique adjustment identifiers
@@ -270,8 +317,9 @@ public slots:
/// lower priority channel (or off if no more channels are set)
///
/// @param[in] priority The priority channel
+ /// @return True on success else false (not found)
///
- void clear(int priority);
+ const bool clear(int priority);
///
/// Clears all priority channels. This will switch the leds off until a new priority is written.
@@ -292,44 +340,18 @@ public slots:
int setEffect(const QString & effectName, const QJsonObject & args, int priority,
int timeout = -1, const QString & pythonScript = "", const QString & origin="System");
- /// sets the methode how image is maped to leds
- void setLedMappingType(int mappingType);
-
- ///
- Hyperion::BonjourRegister getHyperionSessions();
-
- /// Slot which is called, when state of hyperion has been changed
- void hyperionStateChanged();
+ /// sets the methode how image is maped to leds at ImageProcessor
+ void setLedMappingType(const int& mappingType);
///
/// Set the video mode (2D/3D)
/// @param[in] mode The new video mode
///
- void setVideoMode(VideoMode mode);
+ void setVideoMode(const VideoMode& mode);
public:
static Hyperion *_hyperion;
- static ColorOrder createColorOrder(const QJsonObject & deviceConfig);
- /**
- * Construct the 'led-string' with the integration area definition per led and the color
- * ordering of the RGB channels
- * @param ledsConfig The configuration of the led areas
- * @param deviceOrder The default RGB channel ordering
- * @return The constructed ledstring
- */
- static LedString createLedString(const QJsonValue & ledsConfig, const ColorOrder deviceOrder);
- static LedString createLedStringClone(const QJsonValue & ledsConfig, const ColorOrder deviceOrder);
-
- static MultiColorAdjustment * createLedColorsAdjustment(const unsigned ledCnt, const QJsonObject & colorAdjustmentConfig);
- static ColorAdjustment * createColorAdjustment(const QJsonObject & adjustmentConfig);
- static RgbTransform * createRgbTransform(const QJsonObject& colorConfig);
- static RgbChannelAdjustment * createRgbChannelAdjustment(const QJsonObject & colorConfig, const QString channelName, const int defaultR, const int defaultG, const int defaultB);
-
- static LinearColorSmoothing * createColorSmoothing(const QJsonObject & smoothingConfig, LedDevice* leddevice);
- static MessageForwarder * createMessageForwarder(const QJsonObject & forwarderConfig);
- static QSize getLedLayoutGridSize(const QJsonValue& ledsConfig);
-
signals:
/// Signal which is emitted when a priority channel is actively cleared
/// This signal will not be emitted when a priority channel time out
@@ -339,25 +361,67 @@ signals:
/// This signal will not be emitted when a priority channel time out
void allChannelsCleared();
+ ///
+ /// @brief Emits whenever a user request a component state change, it's up the component to listen
+ /// and update the component state at the componentRegister
+ /// @param component The component from enum
+ /// @param enabled The new state of the component
+ ///
void componentStateChanged(const hyperion::Components component, bool enabled);
- void imageToLedsMappingChanged(int mappingType);
- void emitImage(int priority, const Image & image, const int timeout_ms);
+ ///
+ /// @brief Emits whenever the imageToLedsMapping has changed
+ /// @param mappingType The new mapping type
+ ///
+ void imageToLedsMappingChanged(const int& mappingType);
+
+ ///
+ /// @brief Emits whenever the visible priority delivers a image which is applied in update()
+ /// priorities with ledColors won't emit this signal
+ /// @param image The current image
+ ///
+ void currentImage(const Image & image);
+
void closing();
/// Signal which is emitted, when a new json message should be forwarded
void forwardJsonMessage(QJsonObject);
- /// Signal which is emitted, after the hyperionStateChanged has been processed with a emit count blocker (250ms interval)
- void sendServerInfo();
-
- /// Signal emitted when a 3D movie is detected
- void videoMode(VideoMode mode);
+ ///
+ /// @brief Is emitted from clients who request a videoMode change
+ ///
+ void videoMode(const VideoMode& mode);
///
- /// @brief Emits whenever new untransformed ledColos data is available, reflects the current visible device
+ /// @brief A new videoMode was requested (called from Daemon!)
///
- void rawLedColors(const std::vector& ledValues);
+ void newVideoMode(const VideoMode& mode);
+
+ ///
+ /// @brief Emits whenever a config part changed. SIGNAL PIPE helper for SettingsManager -> HyperionDaemon
+ /// @param type The settings type from enum
+ /// @param data The data as QJsonDocument
+ ///
+ void settingsChanged(const settings::type& type, const QJsonDocument& data);
+
+ ///
+ /// @brief Emits whenever the adjustments have been updated
+ ///
+ void adjustmentChanged();
+
+ ///
+ /// @brief Signal pipe from EffectEngine to external, emits when effect list has been updated
+ ///
+ void effectListUpdated();
+
+ ///
+ /// @brief systemImage from the parent HyperionDaemon SystemCapture
+ ///
+ void systemImage(const Image& image);
+ ///
+ /// @brief v4lImage from the parent HyperionDaemon V4lCapture
+ ///
+ void v4lImage(const Image & image);
private slots:
///
@@ -366,13 +430,23 @@ private slots:
///
void update();
- void currentBonjourRecordsChanged(const QList &list);
- void bonjourRecordResolved(const QHostInfo &hostInfo, int port);
- void bonjourResolve();
-
/// check for configWriteable and modified changes, called by _fsWatcher or fallback _cTimer
void checkConfigState(QString cfile = NULL);
+ ///
+ /// @brief Apply ComponentRegister emits for COMP_ALL. Enables/Disables core timers
+ /// @param comp The component
+ /// @param state The new state of the component
+ ///
+ void updatedComponentState(const hyperion::Components comp, const bool state);
+
+ ///
+ /// @brief Apply settings updates for LEDS and COLOR
+ /// @param type The type from enum
+ /// @param config The configuration
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
+
private:
///
@@ -380,7 +454,16 @@ private:
///
/// @param[in] qjsonConfig The Json configuration
///
- Hyperion(const QJsonObject& qjsonConfig, const QString configFile, const QString rootPath);
+ Hyperion(HyperionDaemon* daemon, const quint8& instance, const QString configFile, const QString rootPath);
+
+ /// The parent Hyperion Daemon
+ HyperionDaemon* _daemon;
+
+ /// Settings manager of this instance
+ SettingsManager* _settingsManager;
+
+ /// Register that holds component states
+ ComponentRegister _componentRegister;
/// The specifiation of the led frame construction and picture integration
LedString _ledString;
@@ -388,6 +471,9 @@ private:
/// specifiation of cloned leds
LedString _ledStringClone;
+ /// Image Processor
+ ImageProcessor* _imageProcessor;
+
std::vector _ledStringColorOrder;
/// The priority muxer
@@ -408,21 +494,14 @@ private:
// proto and json Message forwarder
MessageForwarder * _messageForwarder;
- // json configuration
- const QJsonObject& _qjsonConfig;
-
/// the name of config file
QString _configFile;
/// root path for all hyperion user data files
QString _rootPath;
- /// The timer for handling priority channel timeouts
- QTimer _timer;
- QTimer _timerBonjourResolver;
-
- /// buffer for leds (with adjustment)
- std::vector _ledBuffer;
+ /// unique id per instance
+ QString _id;
/// Logger instance
Logger * _log;
@@ -430,32 +509,16 @@ private:
/// count of hardware leds
unsigned _hwLedCount;
- ComponentRegister _componentRegister;
-
- /// register of input sources and it's prio channel
- PriorityRegister _priorityRegister;
-
- /// flag indicates state for autoselection of input source
- bool _sourceAutoSelectEnabled;
-
- /// holds the current priority channel that is manualy selected
- int _currentSourcePriority;
-
QByteArray _configHash;
QSize _ledGridSize;
- int _ledMAppingType;
-
+ /// Store the previous compID for smarter update()
hyperion::Components _prevCompId;
- BonjourServiceBrowser _bonjourBrowser;
- BonjourServiceResolver _bonjourResolver;
- BonjourRegister _hyperionSessions;
- QString _bonjourCurrentServiceToResolve;
/// Observe filesystem changes (_configFile), if failed use Timer
QFileSystemWatcher _fsWatcher;
- QTimer _cTimer;
+ QTimer* _cTimer;
/// holds the prev states of configWriteable and modified
bool _prevConfigMod = false;
@@ -465,9 +528,16 @@ private:
bool _configMod = false;
bool _configWrite = true;
- /// timers to handle severinfo blocking
- QTimer _fsi_timer;
- QTimer _fsi_blockTimer;
+ /// Background effect instance, kept active to react on setting changes
+ BGEffectHandler* _BGEffectHandler;
+ /// Capture control for Daemon native capture
+ CaptureCont* _captureCont;
- VideoMode _videoMode;
+ // lock Hyperion::update() for exec
+ bool _lockUpdate = false;
+
+ /// buffer for leds (with adjustment)
+ std::vector _ledBuffer;
+ /// buffer for leds (without adjustment)
+ std::vector _rawLedBuffer;
};
diff --git a/include/hyperion/ImageProcessor.h b/include/hyperion/ImageProcessor.h
index 935fcaea..d2c16216 100644
--- a/include/hyperion/ImageProcessor.h
+++ b/include/hyperion/ImageProcessor.h
@@ -6,14 +6,18 @@
#include
// Hyperion includes
-#include
#include
#include
#include
+// settings
+#include
+
// Black border includes
#include
+class Hyperion;
+
///
/// The ImageProcessor translates an RGB-image to RGB-values for the leds. The processing is
/// performed in two steps. First the average color per led-region is computed. Second a
@@ -24,14 +28,16 @@ class ImageProcessor : public QObject
Q_OBJECT
public:
+ ///
+ /// Constructs an image-processor for translating an image to led-color values based on the
+ /// given led-string specification
+ /// @param[in] ledString LedString data
+ /// @param[in] hyperion Hyperion instance pointer
+ ///
+ ImageProcessor(const LedString& ledString, Hyperion* hyperion);
~ImageProcessor();
- ///
- /// Returns the number of attached leds
- ///
- unsigned getLedCount() const;
-
///
/// Specifies the width and height of 'incomming' images. This will resize the buffer-image to
/// match the given size.
@@ -42,20 +48,39 @@ public:
///
void setSize(const unsigned width, const unsigned height);
+ ///
+ /// @brief Update the led string (eg on settings change)
+ ///
+ void setLedString(const LedString& ledString);
+
/// Returns starte of black border detector
bool blackBorderDetectorEnabled();
- /// Returns starte of black border detector
- int ledMappingType();
+ /// Returns the current _userMappingType, this may not be the current applied type!
+ const int & getUserLedMappingType() { return _userMappingType; };
+
+ /// Returns the current _mappingType
+ const int & ledMappingType() { return _mappingType; };
static int mappingTypeToInt(QString mappingType);
static QString mappingTypeToStr(int mappingType);
-public slots:
- /// Enable or disable the black border detector
- void enableBlackBorderDetector(bool enable);
+ ///
+ /// @brief Set the Hyperion::update() requestes led mapping type. This type is used in favour of type set with setLedMappingType.
+ /// If you don't want to force a mapType set this to -1 (user choice will be set)
+ /// @param mapType The new mapping type
+ ///
+ void setHardLedMappingType(int mapType);
- /// Enable or disable the black border detector
+public slots:
+ /// Enable or disable the black border detector based on component
+ void setBlackbarDetectDisable(bool enable);
+
+ ///
+ /// @brief Set the user requested led mapping.
+ /// The type set with setHardLedMappingType() will be used in favour to respect comp specific settings
+ /// @param mapType The new mapping type
+ ///
void setLedMappingType(int mapType);
public:
@@ -101,7 +126,7 @@ public:
}
else
{
- Warning(_log, "ImageProcessor::process called without image size 0");
+ Warning(_log, "ImageProcessor::process called with image size 0");
}
// return the computed colors
@@ -134,7 +159,7 @@ public:
}
else
{
- Warning(_log, "ImageProcessor::process called without image size 0");
+ Warning(_log, "Called with image size 0");
}
}
@@ -150,18 +175,6 @@ public:
bool getScanParameters(size_t led, double & hscanBegin, double & hscanEnd, double & vscanBegin, double & vscanEnd) const;
private:
- /// Friend declaration of the factory for creating ImageProcessor's
- friend class ImageProcessorFactory;
-
- ///
- /// Constructs an image-processor for translating an image to led-color values based on the
- /// given led-string specification
- ///
- /// @param[in] ledString The led-string specification
- /// @param[in] blackborderThreshold The threshold which the blackborder detector should use
- ///
- ImageProcessor(const LedString &ledString, const QJsonObject &blackborderConfig);
-
///
/// Performs black-border detection (if enabled) on the given image
///
@@ -172,7 +185,7 @@ private:
{
if (!_borderProcessor->enabled() && ( _imageToLeds->horizontalBorder()!=0 || _imageToLeds->verticalBorder()!=0 ))
{
- Debug(Logger::getInstance("BLACKBORDER"), "disabled, reset border");
+ Debug(_log, "Reset border");
_borderProcessor->process(image);
delete _imageToLeds;
_imageToLeds = new hyperion::ImageToLedsMap(image.width(), image.height(), 0, 0, _ledString.leds());
@@ -180,8 +193,6 @@ private:
if(_borderProcessor->enabled() && _borderProcessor->process(image))
{
- //Debug(Logger::getInstance("BLACKBORDER"), "BORDER SWITCH REQUIRED!!");
-
const hyperion::BlackBorder border = _borderProcessor->getCurrentBorder();
// Clean up the old mapping
@@ -203,10 +214,13 @@ private:
}
}
+private slots:
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
+
private:
Logger * _log;
/// The Led-string specification
- const LedString _ledString;
+ LedString _ledString;
/// The processor for black border detection
hyperion::BlackBorderProcessor * _borderProcessor;
@@ -216,4 +230,11 @@ private:
/// Type of image 2 led mapping
int _mappingType;
+ /// Type of last requested user type
+ int _userMappingType;
+ /// Type of last requested hard type
+ int _hardMappingType;
+
+ /// Hyperion instance pointer
+ Hyperion* _hyperion;
};
diff --git a/include/hyperion/ImageProcessorFactory.h b/include/hyperion/ImageProcessorFactory.h
deleted file mode 100644
index e7381ad0..00000000
--- a/include/hyperion/ImageProcessorFactory.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-// STL includes
-#include
-
-// QT includes
-#include
-
-#include
-
-// Forward class declaration
-class ImageProcessor;
-
-///
-/// The ImageProcessor is a singleton factor for creating ImageProcessors that translate images to
-/// led color values.
-///
-class ImageProcessorFactory
-{
-public:
- ///
- /// Returns the 'singleton' instance (creates the singleton if it does not exist)
- ///
- /// @return The singleton instance of the ImageProcessorFactory
- ///
- static ImageProcessorFactory& getInstance();
-
-public:
- ///
- /// Initialises this factory with the given led-configuration
- ///
- /// @param[in] ledString The led configuration
- /// @param[in] blackborderConfig Contains the blackborder configuration
- ///
- void init(const LedString& ledString, const QJsonObject &blackborderConfig, int mappingType);
-
- ///
- /// Creates a new ImageProcessor. The onwership of the processor is transferred to the caller.
- ///
- /// @return The newly created ImageProcessor
- ///
- ImageProcessor* newImageProcessor() const;
-
-private:
- /// The Led-string specification
- LedString _ledString;
-
- /// Reference to the blackborder json configuration values
- QJsonObject _blackborderConfig;
-
- // image 2 led mapping type
- int _mappingType;
-};
diff --git a/include/hyperion/ImageToLedsMap.h b/include/hyperion/ImageToLedsMap.h
index 116d4760..7896592d 100644
--- a/include/hyperion/ImageToLedsMap.h
+++ b/include/hyperion/ImageToLedsMap.h
@@ -7,6 +7,7 @@
// hyperion-utils includes
#include
+#include
// hyperion includes
#include
@@ -58,7 +59,7 @@ namespace hyperion
const unsigned horizontalBorder() const { return _horizontalBorder; };
const unsigned verticalBorder() const { return _verticalBorder; };
-
+
///
/// Determines the mean-color for each led using the mapping the image given
/// at construction.
@@ -86,7 +87,12 @@ namespace hyperion
void getMeanLedColor(const Image & image, std::vector & ledColors) const
{
// Sanity check for the number of leds
- assert(_colorsMap.size() == ledColors.size());
+ //assert(_colorsMap.size() == ledColors.size());
+ if(_colorsMap.size() != ledColors.size())
+ {
+ Debug(Logger::getInstance("HYPERION"), "ImageToLedsMap: colorsMap.size != ledColors.size -> %d != %d", _colorsMap.size(), ledColors.size());
+ return;
+ }
// Iterate each led and compute the mean
auto led = ledColors.begin();
@@ -96,7 +102,7 @@ namespace hyperion
*led = color;
}
}
-
+
///
/// Determines the mean-color for each led using the mapping the image given
/// at construction.
@@ -124,7 +130,13 @@ namespace hyperion
void getUniLedColor(const Image & image, std::vector & ledColors) const
{
// Sanity check for the number of leds
- assert(_colorsMap.size() == ledColors.size());
+ // assert(_colorsMap.size() == ledColors.size());
+ if(_colorsMap.size() != ledColors.size())
+ {
+ Debug(Logger::getInstance("HYPERION"), "ImageToLedsMap: colorsMap.size != ledColors.size -> %d != %d", _colorsMap.size(), ledColors.size());
+ return;
+ }
+
// calculate uni color
const ColorRgb color = calcMeanColor(image);
@@ -136,11 +148,11 @@ namespace hyperion
const unsigned _width;
/// The height of the indexed image
const unsigned _height;
-
+
const unsigned _horizontalBorder;
-
+
const unsigned _verticalBorder;
-
+
/// The absolute indices into the image for each led
std::vector> _colorsMap;
diff --git a/include/hyperion/MessageForwarder.h b/include/hyperion/MessageForwarder.h
index d0d5de1a..ea247c53 100644
--- a/include/hyperion/MessageForwarder.h
+++ b/include/hyperion/MessageForwarder.h
@@ -10,31 +10,45 @@
#include
#include
#include
+#include
+#include
+#include
// Utils includes
#include
-class MessageForwarder
+#include
+#include
+
+class Hyperion;
+
+class MessageForwarder : public QObject
{
+ Q_OBJECT
public:
- struct JsonSlaveAddress {
- QHostAddress addr;
- quint16 port;
- };
-
- MessageForwarder();
+ MessageForwarder(Hyperion* hyperion, const QJsonDocument & config);
~MessageForwarder();
-
+
void addJsonSlave(QString slave);
void addProtoSlave(QString slave);
bool protoForwardingEnabled();
bool jsonForwardingEnabled();
bool forwardingEnabled() { return jsonForwardingEnabled() || protoForwardingEnabled(); };
- QStringList getProtoSlaves();
- QList getJsonSlaves();
+ QStringList getProtoSlaves() const { return _protoSlaves; };
+ QStringList getJsonSlaves() const { return _jsonSlaves; };
+
+private slots:
+ ///
+ /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
+ /// @param type settingyType from enum
+ /// @param config configuration object
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
private:
- QStringList _protoSlaves;
- QList _jsonSlaves;
+ Hyperion* _hyperion;
+ Logger* _log;
+ QStringList _protoSlaves;
+ QStringList _jsonSlaves;
};
diff --git a/libsrc/hyperion/MultiColorAdjustment.h b/include/hyperion/MultiColorAdjustment.h
similarity index 98%
rename from libsrc/hyperion/MultiColorAdjustment.h
rename to include/hyperion/MultiColorAdjustment.h
index f6568049..df101122 100644
--- a/libsrc/hyperion/MultiColorAdjustment.h
+++ b/include/hyperion/MultiColorAdjustment.h
@@ -26,7 +26,7 @@ public:
*/
void addAdjustment(ColorAdjustment * adjustment);
- void setAdjustmentForLed(const QString& id, const unsigned startLed, const unsigned endLed);
+ void setAdjustmentForLed(const QString& id, const unsigned startLed, unsigned endLed);
bool verifyAdjustments() const;
diff --git a/include/hyperion/PriorityMuxer.h b/include/hyperion/PriorityMuxer.h
index a3316940..21af614b 100644
--- a/include/hyperion/PriorityMuxer.h
+++ b/include/hyperion/PriorityMuxer.h
@@ -7,23 +7,25 @@
// QT includes
#include
#include
-#include
#include
#include
// Utils includes
#include
+#include
#include
// global defines
#define SMOOTHING_MODE_DEFAULT 0
#define SMOOTHING_MODE_PAUSE 1
+class QTimer;
+class Logger;
///
-/// The PriorityMuxer handles the priority channels. Led values input is written to the priority map
+/// The PriorityMuxer handles the priority channels. Led values input/ images are written to the priority map
/// and the muxer keeps track of all active priorities. The current priority can be queried and per
-/// priority the led colors.
+/// priority the led colors. Handles also manual/auto selection mode, provides a lot of signals to hook into priority related events
///
class PriorityMuxer : public QObject
{
@@ -36,17 +38,20 @@ public:
{
/// The priority of this channel
int priority;
-
/// The absolute timeout of the channel
int64_t timeoutTime_ms;
/// The colors for each led of the channel
std::vector ledColors;
+ /// The raw Image (size should be preprocessed!)
+ Image image;
/// The component
hyperion::Components componentId;
/// Who set it
QString origin;
- /// id fo smoothing config
+ /// id of smoothing config
unsigned smooth_cfg;
+ /// specific owner description
+ QString owner;
};
/// The lowest possible priority, which is used when no priority channels are active
@@ -65,6 +70,38 @@ public:
///
~PriorityMuxer();
+ ///
+ /// @brief Start/Stop the PriorityMuxer update timer; On disabled no priority and timeout updates will be performend
+ /// @param enable The new state
+ ///
+ void setEnable(const bool& enable);
+
+ /// @brief Enable or disable auto source selection
+ /// @param enable True if it should be enabled else false
+ /// @param update True to update _currentPriority - INTERNAL usage.
+ /// @return True if changed has been applied, false if the state is unchanged
+ ///
+ bool setSourceAutoSelectEnabled(const bool& enabel, const bool& update = true);
+
+ ///
+ /// @brief Get the state of source auto selection
+ /// @return True if enabled, else false
+ ///
+ bool isSourceAutoSelectEnabled() const { return _sourceAutoSelectEnabled; };
+
+ ///
+ /// @brief Overwrite current lowest piority with manual selection; On success disables aito selection
+ /// @param priority The
+ /// @return True on success, false if priority not found
+ ///
+ bool setPriority(const uint8_t priority);
+
+ ///
+ /// @brief Update all ledColos with min length of >= 1 to fit the new led length
+ /// @param[in] ledCount The count of leds
+ ///
+ void updateLedColorsLength(const int& ledCount);
+
///
/// Returns the current priority
///
@@ -87,69 +124,134 @@ public:
QList getPriorities() const;
///
- /// Returns the information of a specified priority channel
+ /// Returns the information of a specified priority channel.
+ /// If a priority is no longer available the _lowestPriorityInfo (255) is returned
///
/// @param priority The priority channel
///
/// @return The information for the specified priority channel
///
- /// @throws std::runtime_error if the priority channel does not exist
- ///
- const InputInfo& getInputInfo(const int priority) const;
+ const InputInfo getInputInfo(const int priority) const;
///
- /// Sets/Updates the data for a priority channel
+ /// @brief Register a new input by priority, the priority is not active (timeout -100 isn't muxer recognized) until you start to update the data with setInput()
+ /// A repeated call to update the base data of a known priority won't overwrite their current timeout
+ /// @param[in] priority The priority of the channel
+ /// @param[in] component The component of the channel
+ /// @param[in] origin Who set the channel (CustomString@IP)
+ /// @param[in] owner Speicifc owner string, might be empty
+ /// @param[in] smooth_cfg The smooth id to use
///
- /// @param[in] priority The priority of the channel
- /// @param[in] ledColors The led colors of the priority channel
- /// @param[in] timeoutTime_ms The absolute timeout time of the channel
- /// @param[in] component The component of the channel
- /// @param[in] origin Who set the channel
- ///
- void setInput(const int priority, const std::vector& ledColors, const int64_t timeoutTime_ms=-1, hyperion::Components component=hyperion::COMP_INVALID, const QString origin="System", unsigned smooth_cfg=SMOOTHING_MODE_DEFAULT);
+ void registerInput(const int priority, const hyperion::Components& component, const QString& origin = "System", const QString& owner = "", unsigned smooth_cfg = SMOOTHING_MODE_DEFAULT);
///
- /// Clears the specified priority channel
+ /// @brief Update the current color of a priority (prev registered with registerInput())
+ /// @param priority The priority to update
+ /// @param ledColors The colors
+ /// @param timeout_ms The new timeout (defaults to -1 endless)
+ /// @return True on success, false when priority is not found
+ ///
+ const bool setInput(const int priority, const std::vector& ledColors, int64_t timeout_ms = -1);
+
+ ///
+ /// @brief Update the current image of a priority (prev registered with registerInput())
+ /// @param priority The priority to update
+ /// @param image The new image
+ /// @param timeout_ms The new timeout (defaults to -1 endless)
+ /// @return True on success, false when priority is not found
+ ///
+ const bool setInputImage(const int priority, const Image& image, int64_t timeout_ms = -1);
+
+ ///
+ /// Clears the specified priority channel and update _currentPriority on success
///
/// @param[in] priority The priority of the channel to clear
+ /// @return True if priority has been cleared else false (not found)
///
- void clearInput(const int priority);
+ const bool clearInput(const uint8_t priority);
///
/// Clears all priority channels
///
void clearAll(bool forceClearAll=false);
+signals:
+ ///
+ /// @brief Signal which emits when a effect or color with timeout > -1 is running, once per second
+ ///
+ void timeRunner();
+
+ ///
+ /// @brief A priority has been added (registerInput()) or deleted, method clear or timeout clear
+ /// @param priority The priority which has changed
+ /// @param state If true it was added else it was removed!
+ ///
+ void priorityChanged(const quint8& priority, const bool& state);
+
+ ///
+ /// @brief Emits whenever the visible priority has changed
+ /// @param priority The new visible prioritiy
+ ///
+ void visiblePriorityChanged(const quint8& priority);
+
+ ///
+ /// @brief Emits whenever a priority changes active state
+ /// @param priority The priority who changed the active state
+ /// @param state The new state, state true = active else false
+ ///
+ void activeStateChanged(const quint8& priority, const bool& state);
+
+ ///
+ /// @brief Emits whenever the auto selection state has been changed
+ /// @param state The new state of auto selection; True enabled else false
+ ///
+ void autoSelectChanged(const bool& state);
+
+ ///
+ /// @brief Emits whenever something changes which influences the priorities listing
+ /// Emits also in 1s interval when a COLOR or EFFECT is running with a timeout > -1
+ ///
+ void prioritiesChanged(void);
+
+ ///
+ /// internal used signal to resolve treading issues with timer
+ ///
+ void signalTimeTrigger();
+
+private slots:
+ ///
+ /// Slot which is called to adapt to 1s interval for signal timeRunner() / prioritiesChanged()
+ ///
+ void timeTrigger();
+
///
/// Updates the current time. Channels with a configured time out will be checked and cleared if
/// required.
///
- /// @param[in] now The current time
- ///
- void setCurrentTime(const int64_t& now);
-
-signals:
- ///
- /// Signal which is called, when a effect or color with timeout is running, once per second
- ///
- void timerunner();
-
-private slots:
- ///
- /// Slots which is called to adapt to 1s interval for signal timerunner()
- ///
- void emitReq();
+ void setCurrentTime(void);
private:
+ /// Logger instance
+ Logger* _log;
+
/// The current priority (lowest value in _activeInputs)
int _currentPriority;
+ /// The manual select priority set with setPriority
+ int _manualSelectedPriority;
+
/// The mapping from priority channel to led-information
QMap _activeInputs;
/// The information of the lowest priority channel
InputInfo _lowestPriorityInfo;
- QTimer _timer;
- QTimer _blockTimer;
+ // Reflect the state of auto select
+ bool _sourceAutoSelectEnabled;
+
+ // Timer to update Muxer times independent
+ QTimer* _updateTimer;
+
+ QTimer* _timer;
+ QTimer* _blockTimer;
};
diff --git a/include/hyperion/SettingsManager.h b/include/hyperion/SettingsManager.h
new file mode 100644
index 00000000..f3fa1d63
--- /dev/null
+++ b/include/hyperion/SettingsManager.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#include
+#include
+
+// qt incl
+#include
+
+class SettingsTable;
+class Hyperion;
+
+///
+/// @brief Manage the settings read write from/to database, on settings changed will emit a signal to update components accordingly
+///
+class SettingsManager : public QObject
+{
+ Q_OBJECT
+public:
+ ///
+ /// @brief Construct a settings manager and assign a hyperion instance
+ /// @params hyperion The parent hyperion instance
+ /// @params instance Instance number of Hyperion
+ ///
+ SettingsManager(Hyperion* hyperion, const quint8& instance, const QString& configFile);
+
+ ///
+ /// @brief Construct a settings manager for HyperionDaemon
+ ///
+ SettingsManager(const quint8& instance, const QString& configFile);
+ ~SettingsManager();
+
+ ///
+ /// @brief Save a complete json config
+ /// @param config The entire config object
+ /// @param correct If true will correct json against schema before save
+ /// @return True on success else false
+ ///
+ const bool saveSettings(QJsonObject config, const bool& correct = false);
+
+ ///
+ /// @brief get a single setting json from database
+ /// @param type The settings::type from enum
+ /// @return The requested json data as QJsonDocument
+ ///
+ const QJsonDocument getSetting(const settings::type& type);
+
+ ///
+ /// @brief get the full settings object of this instance (with global settings)
+ /// @return The requested json
+ ///
+ const QJsonObject & getSettings() { return _qconfig; };
+
+signals:
+ ///
+ /// @brief Emits whenever a config part changed. Comparison of database and new data to prevent false positive
+ /// @param type The settings type from enum
+ /// @param data The data as QJsonDocument
+ ///
+ void settingsChanged(const settings::type& type, const QJsonDocument& data);
+
+private:
+ /// Hyperion instance
+ Hyperion* _hyperion;
+ /// Logger instance
+ Logger* _log;
+ /// instance of database table interface
+ SettingsTable* _sTable;
+ /// the schema
+ static QJsonObject schemaJson;
+ /// the current config of this instance
+ QJsonObject _qconfig;
+};
diff --git a/include/jsonserver/JsonServer.h b/include/jsonserver/JsonServer.h
index 912e14ac..e0c64206 100644
--- a/include/jsonserver/JsonServer.h
+++ b/include/jsonserver/JsonServer.h
@@ -1,14 +1,20 @@
#pragma once
// Qt includes
-#include
#include
// Hyperion includes
-#include
+#include
#include
+#include
+class Hyperion;
+class QTcpServer;
+class QTcpSocket;
class JsonClientConnection;
+class BonjourServiceRegister;
+class ComponentRegister;
+class NetOrigin;
///
/// This class creates a TCP server which accepts connections wich can then send
@@ -22,10 +28,9 @@ class JsonServer : public QObject
public:
///
/// JsonServer constructor
- /// @param hyperion Hyperion instance
- /// @param port port number on which to start listening for connections
+ /// @param The configuration
///
- JsonServer(uint16_t port = 19444);
+ JsonServer(const QJsonDocument& config);
~JsonServer();
///
@@ -59,9 +64,16 @@ public slots:
///
void sendMessage(const QJsonObject & message, QTcpSocket * socket);
+ ///
+ /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
+ /// @param type settingyType from enum
+ /// @param config configuration object
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
+
private:
/// The TCP server object
- QTcpServer _server;
+ QTcpServer * _server;
/// Link to Hyperion to get config state emiter
Hyperion * _hyperion;
@@ -72,6 +84,16 @@ private:
/// the logger instance
Logger * _log;
- /// Flag if forwarder is enabled
- bool _forwarder_enabled = true;
+ /// Component Register pointer
+ ComponentRegister* _componentRegister;
+
+ NetOrigin* _netOrigin;
+
+ /// port
+ uint16_t _port = 0;
+
+ BonjourServiceRegister * _serviceRegister = nullptr;
+
+ void start();
+ void stop();
};
diff --git a/include/leddevice/LedDevice.h b/include/leddevice/LedDevice.h
index 27218e5a..8b9977e2 100644
--- a/include/leddevice/LedDevice.h
+++ b/include/leddevice/LedDevice.h
@@ -55,13 +55,19 @@ public:
///
virtual int open();
+ ///
+ /// @brief Get color order of device
+ /// @return The color order
+ ///
+ const QString & getColorOrder() { return _colorOrder; };
+
static int addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr);
static const LedDeviceRegistry& getDeviceMap();
- static void setActiveDevice(QString dev);
- static QString activeDevice() { return _activeDevice; }
+ void setActiveDevice(QString dev);
+ const QString & getActiveDevice() { return _activeDevice; };
static QJsonObject getLedDeviceSchemas();
- static void setLedCount(int ledCount);
- static int getLedCount() { return _ledCount; }
+ void setLedCount(int ledCount);
+ int getLedCount() { return _ledCount; }
void setEnable(bool enable);
bool enabled() { return _enabled; };
@@ -95,12 +101,12 @@ protected:
bool _deviceReady;
- static QString _activeDevice;
+ QString _activeDevice;
static LedDeviceRegistry _ledDeviceMap;
- static int _ledCount;
- static int _ledRGBCount;
- static int _ledRGBWCount;
+ int _ledCount;
+ int _ledRGBCount;
+ int _ledRGBWCount;
/// Timer object which makes sure that led data is written at a minimum rate
/// e.g. Adalight device will switch off when it does not receive data at least every 15 seconds
@@ -116,4 +122,5 @@ private:
std::vector _ledValues;
bool _componentRegistered;
bool _enabled;
+ QString _colorOrder;
};
diff --git a/include/leddevice/LedDeviceFactory.h b/include/leddevice/LedDeviceFactory.h
index 29691a98..5a26a8ed 100644
--- a/include/leddevice/LedDeviceFactory.h
+++ b/include/leddevice/LedDeviceFactory.h
@@ -4,7 +4,6 @@
// Leddevice includes
#include
-
///
/// The LedDeviceFactory is responsible for constructing 'LedDevices'
///
@@ -20,5 +19,5 @@ public:
/// @return The constructed LedDevice or nullptr if configuration is invalid. The ownership of
/// the constructed LedDevice is tranferred to the caller
///
- static LedDevice * construct(const QJsonObject & deviceConfig, const int ledCount);
+ static LedDevice * construct(const QJsonObject & deviceConfig);
};
diff --git a/include/protoserver/ProtoServer.h b/include/protoserver/ProtoServer.h
index 12daf1c8..e285a6cb 100644
--- a/include/protoserver/ProtoServer.h
+++ b/include/protoserver/ProtoServer.h
@@ -4,23 +4,29 @@
#include
// Qt includes
-#include
#include
#include
#include
-
-// Hyperion includes
-#include
+#include
// hyperion includes
#include
#include
#include
#include
+#include
+
+// settings
+#include
// forward decl
class ProtoClientConnection;
class ProtoConnection;
+class QTcpServer;
+class Hyperion;
+class BonjourServiceRegister;
+class ComponentRegister;
+class NetOrigin;
namespace proto {
class HyperionRequest;
@@ -38,10 +44,9 @@ class ProtoServer : public QObject
public:
///
/// ProtoServer constructor
- /// @param hyperion Hyperion instance
- /// @param port port number on which to start listening for connections
+ /// @param config the configuration
///
- ProtoServer(uint16_t port = 19445);
+ ProtoServer(const QJsonDocument& config);
~ProtoServer();
///
@@ -53,6 +58,13 @@ public slots:
void sendImageToProtoSlaves(int priority, const Image & image, int duration_ms);
void componentStateChanged(const hyperion::Components component, bool enable);
+ ///
+ /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
+ /// @param type settingyType from enum
+ /// @param config configuration object
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
+
signals:
///
/// Forwarding videoMode
@@ -78,7 +90,7 @@ private:
Hyperion * _hyperion;
/// The TCP server object
- QTcpServer _server;
+ QTcpServer * _server;
/// List with open connections
QSet _openConnections;
@@ -90,6 +102,22 @@ private:
/// Logger instance
Logger * _log;
+ /// Component Register
+ ComponentRegister* _componentRegister;
+
+ /// Network Origin Check
+ NetOrigin* _netOrigin;
+
+ /// Service register
+ BonjourServiceRegister * _serviceRegister = nullptr;
+
/// flag if forwarder is enabled
bool _forwarder_enabled;
+
+ uint16_t _port = 0;
+
+ /// Start server
+ void start();
+ /// Stop server
+ void stop();
};
diff --git a/include/python/PythonInit.h b/include/python/PythonInit.h
new file mode 100644
index 00000000..97b0cb16
--- /dev/null
+++ b/include/python/PythonInit.h
@@ -0,0 +1,13 @@
+#pragma once
+
+///
+/// @brief Handle the PythonInit, module registers and DeInit
+///
+class PythonInit
+{
+private:
+ friend class HyperionDaemon;
+
+ PythonInit();
+ ~PythonInit();
+};
diff --git a/include/python/PythonUtils.h b/include/python/PythonUtils.h
new file mode 100644
index 00000000..e7cd08b4
--- /dev/null
+++ b/include/python/PythonUtils.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#undef slots
+#include
+#define slots
+
+// decl
+extern PyThreadState* mainThreadState;
+
+// py path seperator
+#ifdef TARGET_WINDOWS
+ #define PY_PATH_SEP ";";
+#else // not windows
+ #define PY_PATH_SEP ":";
+#endif
diff --git a/include/udplistener/UDPListener.h b/include/udplistener/UDPListener.h
index 2e7c9e64..bf294df6 100644
--- a/include/udplistener/UDPListener.h
+++ b/include/udplistener/UDPListener.h
@@ -4,16 +4,22 @@
#include
// Qt includes
-#include
#include
#include
+#include
// Hyperion includes
-#include
#include
#include
+// settings
+#include
+
+class Hyperion;
class UDPClientConnection;
+class BonjourServiceRegister;
+class QUdpSocket;
+class NetOrigin;
///
/// This class creates a UDP server which accepts connections from boblight clients.
@@ -28,26 +34,25 @@ public:
/// @param hyperion Hyperion instance
/// @param port port number on which to start listening for connections
///
- UDPListener(const int priority, const int timeout, const QString& address, quint16 listenPort, bool shared);
+ UDPListener(const QJsonDocument& config);
~UDPListener();
///
/// @return the port number on which this UDP listens for incoming connections
///
uint16_t getPort() const;
-
+
///
/// @return true if server is active (bind to a port)
///
bool active() { return _isActive; };
- bool componentState() { return active(); };
public slots:
///
/// bind server to network
///
void start();
-
+
///
/// close server
///
@@ -55,8 +60,12 @@ public slots:
void componentStateChanged(const hyperion::Components component, bool enable);
-signals:
- void statusChanged(bool isActive);
+ ///
+ /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
+ /// @param type settingyType from enum
+ /// @param config configuration object
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
private slots:
///
@@ -83,12 +92,18 @@ private:
/// Logger instance
Logger * _log;
-
+
+ /// Bonjour Service Register
+ BonjourServiceRegister* _bonjourService = nullptr;
+
/// state of connection
bool _isActive;
-
+
/// address to bind
QHostAddress _listenAddress;
- quint16 _listenPort;
+ uint16_t _listenPort;
QAbstractSocket::BindFlag _bondage;
+
+ /// Check Network Origin
+ NetOrigin* _netOrigin;
};
diff --git a/include/utils/Components.h b/include/utils/Components.h
index 6af45394..3e917d9a 100644
--- a/include/utils/Components.h
+++ b/include/utils/Components.h
@@ -3,12 +3,14 @@
namespace hyperion
{
+
/**
* Enumeration of components in Hyperion.
*/
enum Components
{
COMP_INVALID,
+ COMP_ALL,
COMP_SMOOTHING,
COMP_BLACKBORDER,
COMP_FORWARDER,
@@ -17,6 +19,7 @@ enum Components
COMP_GRABBER,
COMP_V4L,
COMP_COLOR,
+ COMP_IMAGE,
COMP_EFFECT,
COMP_PROTOSERVER,
COMP_LEDDEVICE
@@ -26,6 +29,7 @@ inline const char* componentToString(Components c)
{
switch (c)
{
+ case COMP_ALL: return "Hyperion";
case COMP_SMOOTHING: return "Smoothing";
case COMP_BLACKBORDER: return "Blackborder detector";
case COMP_FORWARDER: return "Json/Proto forwarder";
@@ -35,6 +39,7 @@ inline const char* componentToString(Components c)
case COMP_V4L: return "V4L capture device";
case COMP_COLOR: return "Solid color";
case COMP_EFFECT: return "Effect";
+ case COMP_IMAGE: return "Image";
case COMP_PROTOSERVER: return "Proto Server";
case COMP_LEDDEVICE: return "LED device";
default: return "";
@@ -45,6 +50,7 @@ inline const char* componentToIdString(Components c)
{
switch (c)
{
+ case COMP_ALL: return "ALL";
case COMP_SMOOTHING: return "SMOOTHING";
case COMP_BLACKBORDER: return "BLACKBORDER";
case COMP_FORWARDER: return "FORWARDER";
@@ -54,6 +60,7 @@ inline const char* componentToIdString(Components c)
case COMP_V4L: return "V4L";
case COMP_COLOR: return "COLOR";
case COMP_EFFECT: return "EFFECT";
+ case COMP_IMAGE: return "IMAGE";
case COMP_PROTOSERVER: return "PROTOSERVER";
case COMP_LEDDEVICE: return "LEDDEVICE";
default: return "";
@@ -63,6 +70,7 @@ inline const char* componentToIdString(Components c)
inline Components stringToComponent(QString component)
{
component = component.toUpper();
+ if (component == "ALL") return COMP_ALL;
if (component == "SMOOTHING") return COMP_SMOOTHING;
if (component == "BLACKBORDER") return COMP_BLACKBORDER;
if (component == "FORWARDER") return COMP_FORWARDER;
@@ -72,6 +80,7 @@ inline Components stringToComponent(QString component)
if (component == "V4L") return COMP_V4L;
if (component == "COLOR") return COMP_COLOR;
if (component == "EFFECT") return COMP_EFFECT;
+ if (component == "IMAGE") return COMP_IMAGE;
if (component == "PROTOSERVER") return COMP_PROTOSERVER;
if (component == "LEDDEVICE") return COMP_LEDDEVICE;
diff --git a/include/utils/FileUtils.h b/include/utils/FileUtils.h
index 52a7e569..e0d29e13 100644
--- a/include/utils/FileUtils.h
+++ b/include/utils/FileUtils.h
@@ -13,6 +13,11 @@ namespace FileUtils {
QString getBaseName( QString sourceFile);
QString getDirName( QString sourceFile);
+ ///
+ /// @brief remove directory recursive given by path
+ /// @param[in] path Path to directory
+ bool removeDir(const QString& path, Logger* log);
+
///
/// @brief check if the file exists
/// @param[in] path The file path to check
@@ -45,9 +50,10 @@ QString getDirName( QString sourceFile);
/// @brief delete a file by given path
/// @param[in] path The file path to delete
/// @param[in] log The logger of the caller to print errors
+ /// @param[in] ignError Ignore errors during file delete (no log output)
/// @return true on success else false
///
- bool removeFile(const QString& path, Logger* log);
+ bool removeFile(const QString& path, Logger* log, bool ignError=false);
///
/// @brief Convert a path that may contain special placeholders
diff --git a/include/utils/Image.h b/include/utils/Image.h
index d2c427e5..633dddf8 100644
--- a/include/utils/Image.h
+++ b/include/utils/Image.h
@@ -71,6 +71,38 @@ public:
memcpy(_pixels, other._pixels, other._width * other._height * sizeof(Pixel_T));
}
+ // Define assignment operator in terms of the copy constructor
+ // More to read: https://stackoverflow.com/questions/255612/dynamically-allocating-an-array-of-objects?answertab=active#tab-top
+ Image& operator=(Image rhs)
+ {
+ rhs.swap(*this);
+ return *this;
+ }
+
+ void swap(Image& s) noexcept
+ {
+ using std::swap;
+ swap(this->_width, s._width);
+ swap(this->_height, s._height);
+ swap(this->_pixels, s._pixels);
+ swap(this->_endOfPixels, s._endOfPixels);
+ }
+
+ // C++11
+ Image(Image&& src) noexcept
+ : _width(0)
+ , _height(0)
+ , _pixels(NULL)
+ , _endOfPixels(NULL)
+ {
+ src.swap(*this);
+ }
+ Image& operator=(Image&& src) noexcept
+ {
+ src.swap(*this);
+ return *this;
+ }
+
///
/// Destructor
///
diff --git a/include/utils/JsonProcessor.h b/include/utils/JsonProcessor.h
deleted file mode 100644
index e256ff79..00000000
--- a/include/utils/JsonProcessor.h
+++ /dev/null
@@ -1,280 +0,0 @@
-#pragma once
-
-// hyperion includes
-#include
-#include
-#include
-#include
-
-// qt includess
-#include
-#include
-#include
-
-// createEffect helper
-struct find_schema: std::unary_function
-{
- QString pyFile;
- find_schema(QString pyFile):pyFile(pyFile) { }
- bool operator()(EffectSchema const& schema) const
- {
- return schema.pyFile == pyFile;
- }
-};
-
-// deleteEffect helper
-struct find_effect: std::unary_function
-{
- QString effectName;
- find_effect(QString effectName) :effectName(effectName) { }
- bool operator()(EffectDefinition const& effectDefinition) const
- {
- return effectDefinition.name == effectName;
- }
-};
-
-class ImageProcessor;
-
-class JsonProcessor : public QObject
-{
- Q_OBJECT
-
-public:
- ///
- /// Constructor
- ///
- /// @param peerAddress provide the Address of the peer
- /// @param log The Logger class of the creator
- /// @param parent Parent QObject
- /// @param noListener if true, this instance won't listen for hyperion push events
- ///
- JsonProcessor(QString peerAddress, Logger* log, QObject* parent, bool noListener = false);
-
- ///
- /// Handle an incoming JSON message
- ///
- /// @param message the incoming message as string
- ///
- void handleMessage(const QString & message);
-
- ///
- /// send a forced serverinfo to a client
- ///
- void forceServerInfo();
-
-public slots:
- ///
- /// @brief is called whenever the current Hyperion instance pushes new led raw values (if enabled)
- /// @param ledColors The current ledColors
- ///
- void streamLedcolorsUpdate(const std::vector& ledColors);
-
- /// push images whenever hyperion emits (if enabled)
- void setImage(int priority, const Image & image, int duration_ms);
-
- /// process and push new log messages from logger (if enabled)
- void incommingLogMessage(Logger::T_LOG_MESSAGE);
-
-signals:
- ///
- /// Signal which is emitted when a sendSuccessReply() has been executed
- ///
- void pushReq();
- ///
- /// Signal emits with the reply message provided with handleMessage()
- ///
- void callbackMessage(QJsonObject);
-
- ///
- /// Signal emits whenever a jsonmessage should be forwarded
- ///
- void forwardJsonMessage(QJsonObject);
-
-private:
- /// The peer address of the client
- QString _peerAddress;
-
- /// Log instance
- Logger* _log;
-
- /// Hyperion instance
- Hyperion* _hyperion;
-
- /// The processor for translating images to led-values
- ImageProcessor * _imageProcessor;
-
- /// holds the state before off state
- static std::map _componentsPrevState;
-
- /// returns if hyperion is on or off
- inline bool hyperionIsActive() { return JsonProcessor::_componentsPrevState.empty(); };
-
- // streaming buffers
- QJsonObject _streaming_leds_reply;
- QJsonObject _streaming_image_reply;
- QJsonObject _streaming_logging_reply;
- bool _ledcolorsLedsActive = false;
-
- /// flag to determine state of log streaming
- bool _streaming_logging_activated;
-
- /// mutex to determine state of image streaming
- QMutex _image_stream_mutex;
- /// mutex to determine state of led color streaming
- QMutex _led_stream_mutex;
-
- /// timeout for live video refresh
- volatile qint64 _image_stream_timeout;
-
- /// timeout for led color refresh
- volatile qint64 _led_stream_timeout;
-
- ///
- /// Handle an incoming JSON Color message
- ///
- /// @param message the incoming message
- ///
- void handleColorCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON Image message
- ///
- /// @param message the incoming message
- ///
- void handleImageCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON Effect message
- ///
- /// @param message the incoming message
- ///
- void handleEffectCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON Effect message (Write JSON Effect)
- ///
- /// @param message the incoming message
- ///
- void handleCreateEffectCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON Effect message (Delete JSON Effect)
- ///
- /// @param message the incoming message
- ///
- void handleDeleteEffectCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON System info message
- ///
- /// @param message the incoming message
- ///
- void handleSysInfoCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON Server info message
- ///
- /// @param message the incoming message
- ///
- void handleServerInfoCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON Clear message
- ///
- /// @param message the incoming message
- ///
- void handleClearCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON Clearall message
- ///
- /// @param message the incoming message
- ///
- void handleClearallCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON Adjustment message
- ///
- /// @param message the incoming message
- ///
- void handleAdjustmentCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON SourceSelect message
- ///
- /// @param message the incoming message
- ///
- void handleSourceSelectCommand(const QJsonObject & message, const QString &command, const int tan);
-
- /// Handle an incoming JSON GetConfig message and check subcommand
- ///
- /// @param message the incoming message
- ///
- void handleConfigCommand(const QJsonObject & message, const QString &command, const int tan);
-
- /// Handle an incoming JSON GetConfig message from handleConfigCommand()
- ///
- /// @param message the incoming message
- ///
- void handleSchemaGetCommand(const QJsonObject & message, const QString &command, const int tan);
-
- /// Handle an incoming JSON GetConfig message from handleConfigCommand()
- ///
- /// @param message the incoming message
- ///
- void handleConfigGetCommand(const QJsonObject & message, const QString &command, const int tan);
-
- /// Handle an incoming JSON SetConfig message from handleConfigCommand()
- ///
- /// @param message the incoming message
- ///
- void handleConfigSetCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON Component State message
- ///
- /// @param message the incoming message
- ///
- void handleComponentStateCommand(const QJsonObject & message, const QString &command, const int tan);
-
- /// Handle an incoming JSON Led Colors message
- ///
- /// @param message the incoming message
- ///
- void handleLedColorsCommand(const QJsonObject & message, const QString &command, const int tan);
-
- /// Handle an incoming JSON Logging message
- ///
- /// @param message the incoming message
- ///
- void handleLoggingCommand(const QJsonObject & message, const QString &command, const int tan);
-
- /// Handle an incoming JSON Proccessing message
- ///
- /// @param message the incoming message
- ///
- void handleProcessingCommand(const QJsonObject & message, const QString &command, const int tan);
-
- /// Handle an incoming JSON VideoMode message
- ///
- /// @param message the incoming message
- ///
- void handleVideoModeCommand(const QJsonObject & message, const QString &command, const int tan);
-
- ///
- /// Handle an incoming JSON message of unknown type
- ///
- void handleNotImplemented();
-
- ///
- /// Send a standard reply indicating success
- ///
- void sendSuccessReply(const QString &command="", const int tan=0);
-
- ///
- /// Send an error message back to the client
- ///
- /// @param error String describing the error
- ///
- void sendErrorReply(const QString & error, const QString &command="", const int tan=0);
-};
diff --git a/include/utils/JsonUtils.h b/include/utils/JsonUtils.h
index 6187b226..4f55475d 100644
--- a/include/utils/JsonUtils.h
+++ b/include/utils/JsonUtils.h
@@ -26,7 +26,7 @@ namespace JsonUtils{
bool readSchema(const QString& path, QJsonObject& obj, Logger* log);
///
- /// @brief parse a json QString and get the result on success
+ /// @brief parse a json QString and get a QJsonObject. Overloaded funtion
/// @param[in] path The file path/name just used for log messages
/// @param[in] data Data to parse
/// @param[out] obj Retuns the parsed QJsonObject
@@ -35,6 +35,26 @@ namespace JsonUtils{
///
bool parse(const QString& path, const QString& data, QJsonObject& obj, Logger* log);
+ ///
+ /// @brief parse a json QString and get a QJsonArray. Overloaded function
+ /// @param[in] path The file path/name just used for log messages
+ /// @param[in] data Data to parse
+ /// @param[out] arr Retuns the parsed QJsonArray
+ /// @param[in] log The logger of the caller to print errors
+ /// @return true on success else false
+ ///
+ bool parse(const QString& path, const QString& data, QJsonArray& arr, Logger* log);
+
+ ///
+ /// @brief parse a json QString and get a QJsonDocument
+ /// @param[in] path The file path/name just used for log messages
+ /// @param[in] data Data to parse
+ /// @param[out] doc Retuns the parsed QJsonDocument
+ /// @param[in] log The logger of the caller to print errors
+ /// @return true on success else false
+ ///
+ bool parse(const QString& path, const QString& data, QJsonDocument& doc, Logger* log);
+
///
/// @brief Validate json data against a schema
/// @param[in] file The path/name of json file just used for log messages
@@ -45,6 +65,16 @@ namespace JsonUtils{
///
bool validate(const QString& file, const QJsonObject& json, const QString& schemaPath, Logger* log);
+ ///
+ /// @brief Validate json data against a schema
+ /// @param[in] file The path/name of json file just used for log messages
+ /// @param[in] json The json data
+ /// @param[in] schema The schema object
+ /// @param[in] log The logger of the caller to print errors
+ /// @return true on success else false
+ ///
+ bool validate(const QString& file, const QJsonObject& json, const QJsonObject& schema, Logger* log);
+
///
/// @brief Write json data to file
/// @param[in] filenameThe file path to write
diff --git a/include/utils/hyperion.h b/include/utils/hyperion.h
new file mode 100644
index 00000000..3751ec49
--- /dev/null
+++ b/include/utils/hyperion.h
@@ -0,0 +1,320 @@
+#pragma once
+
+#include
+#include
+#include
+// fg effect
+#include
+
+///
+/// @brief Provide utility methods for Hyperion class
+///
+namespace hyperion {
+
+ void handleInitialEffect(Hyperion* hyperion, const QJsonObject& FGEffectConfig)
+ {
+ #define FGCONFIG_ARRAY fgColorConfig.toArray()
+ const int FG_PRIORITY = 0;
+ const int DURATION_INFINITY = 0;
+
+ // initial foreground effect/color
+ if (FGEffectConfig["enable"].toBool(true))
+ {
+ const QString fgTypeConfig = FGEffectConfig["type"].toString("effect");
+ const QString fgEffectConfig = FGEffectConfig["effect"].toString("Rainbow swirl fast");
+ const QJsonValue fgColorConfig = FGEffectConfig["color"];
+ int default_fg_duration_ms = 3000;
+ int fg_duration_ms = FGEffectConfig["duration_ms"].toInt(default_fg_duration_ms);
+ if (fg_duration_ms == DURATION_INFINITY)
+ {
+ fg_duration_ms = default_fg_duration_ms;
+ Warning(Logger::getInstance("HYPERION"), "foreground effect duration 'infinity' is forbidden, set to default value %d ms",default_fg_duration_ms);
+ }
+ if ( fgTypeConfig.contains("color") )
+ {
+ ColorRgb fg_color = {
+ (uint8_t)FGCONFIG_ARRAY.at(0).toInt(0),
+ (uint8_t)FGCONFIG_ARRAY.at(1).toInt(0),
+ (uint8_t)FGCONFIG_ARRAY.at(2).toInt(0)
+ };
+ hyperion->setColor(FG_PRIORITY, fg_color, fg_duration_ms);
+ Info(Logger::getInstance("HYPERION"),"Inital foreground color set (%d %d %d)",fg_color.red,fg_color.green,fg_color.blue);
+ }
+ else
+ {
+ int result = hyperion->setEffect(fgEffectConfig, FG_PRIORITY, fg_duration_ms);
+ Info(Logger::getInstance("HYPERION"),"Inital foreground effect '%s' %s", QSTRING_CSTR(fgEffectConfig), ((result == 0) ? "started" : "failed"));
+ }
+ }
+ #undef FGCONFIG_ARRAY
+ }
+
+ ColorOrder createColorOrder(const QJsonObject &deviceConfig)
+ {
+ return stringToColorOrder(deviceConfig["colorOrder"].toString("rgb"));
+ }
+
+ RgbTransform* createRgbTransform(const QJsonObject& colorConfig)
+ {
+ const double backlightThreshold = colorConfig["backlightThreshold"].toDouble(0.0);
+ const bool backlightColored = colorConfig["backlightColored"].toBool(false);
+ const double brightness = colorConfig["brightness"].toInt(100);
+ const double brightnessComp= colorConfig["brightnessCompensation"].toInt(100);
+ const double gammaR = colorConfig["gammaRed"].toDouble(1.0);
+ const double gammaG = colorConfig["gammaGreen"].toDouble(1.0);
+ const double gammaB = colorConfig["gammaBlue"].toDouble(1.0);
+
+ RgbTransform* transform = new RgbTransform(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, brightness, brightnessComp);
+ return transform;
+ }
+
+ RgbChannelAdjustment* createRgbChannelAdjustment(const QJsonObject& colorConfig, const QString channelName, const int defaultR, const int defaultG, const int defaultB)
+ {
+ const QJsonArray& channelConfig = colorConfig[channelName].toArray();
+ RgbChannelAdjustment* adjustment = new RgbChannelAdjustment(
+ channelConfig[0].toInt(defaultR),
+ channelConfig[1].toInt(defaultG),
+ channelConfig[2].toInt(defaultB),
+ "ChannelAdjust_"+channelName.toUpper()
+ );
+ return adjustment;
+ }
+
+ ColorAdjustment * createColorAdjustment(const QJsonObject & adjustmentConfig)
+ {
+ const QString id = adjustmentConfig["id"].toString("default");
+
+ RgbChannelAdjustment * blackAdjustment = createRgbChannelAdjustment(adjustmentConfig, "black" , 0, 0, 0);
+ RgbChannelAdjustment * whiteAdjustment = createRgbChannelAdjustment(adjustmentConfig, "white" , 255,255,255);
+ RgbChannelAdjustment * redAdjustment = createRgbChannelAdjustment(adjustmentConfig, "red" , 255, 0, 0);
+ RgbChannelAdjustment * greenAdjustment = createRgbChannelAdjustment(adjustmentConfig, "green" , 0,255, 0);
+ RgbChannelAdjustment * blueAdjustment = createRgbChannelAdjustment(adjustmentConfig, "blue" , 0, 0,255);
+ RgbChannelAdjustment * cyanAdjustment = createRgbChannelAdjustment(adjustmentConfig, "cyan" , 0,255,255);
+ RgbChannelAdjustment * magentaAdjustment = createRgbChannelAdjustment(adjustmentConfig, "magenta", 255, 0,255);
+ RgbChannelAdjustment * yellowAdjustment = createRgbChannelAdjustment(adjustmentConfig, "yellow" , 255,255, 0);
+ RgbTransform * rgbTransform = createRgbTransform(adjustmentConfig);
+
+ ColorAdjustment * adjustment = new ColorAdjustment();
+ adjustment->_id = id;
+ adjustment->_rgbBlackAdjustment = *blackAdjustment;
+ adjustment->_rgbWhiteAdjustment = *whiteAdjustment;
+ adjustment->_rgbRedAdjustment = *redAdjustment;
+ adjustment->_rgbGreenAdjustment = *greenAdjustment;
+ adjustment->_rgbBlueAdjustment = *blueAdjustment;
+ adjustment->_rgbCyanAdjustment = *cyanAdjustment;
+ adjustment->_rgbMagentaAdjustment = *magentaAdjustment;
+ adjustment->_rgbYellowAdjustment = *yellowAdjustment;
+ adjustment->_rgbTransform = *rgbTransform;
+
+ // Cleanup the allocated individual adjustments
+ delete blackAdjustment;
+ delete whiteAdjustment;
+ delete redAdjustment;
+ delete greenAdjustment;
+ delete blueAdjustment;
+ delete cyanAdjustment;
+ delete magentaAdjustment;
+ delete yellowAdjustment;
+ delete rgbTransform;
+
+ return adjustment;
+ }
+
+ MultiColorAdjustment * createLedColorsAdjustment(const unsigned ledCnt, const QJsonObject & colorConfig)
+ {
+ // Create the result, the transforms are added to this
+ MultiColorAdjustment * adjustment = new MultiColorAdjustment(ledCnt);
+
+ const QJsonValue adjustmentConfig = colorConfig["channelAdjustment"];
+ const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
+
+ const QJsonArray & adjustmentConfigArray = adjustmentConfig.toArray();
+ for (signed i = 0; i < adjustmentConfigArray.size(); ++i)
+ {
+ const QJsonObject & config = adjustmentConfigArray.at(i).toObject();
+ ColorAdjustment * colorAdjustment = createColorAdjustment(config);
+ adjustment->addAdjustment(colorAdjustment);
+
+ const QString ledIndicesStr = config["leds"].toString("").trimmed();
+ if (ledIndicesStr.compare("*") == 0)
+ {
+ // Special case for indices '*' => all leds
+ adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
+ //Info(_log, "ColorAdjustment '%s' => [0; %d]", QSTRING_CSTR(colorAdjustment->_id), ledCnt-1);
+ continue;
+ }
+
+ if (!overallExp.exactMatch(ledIndicesStr))
+ {
+ //Error(_log, "Given led indices %d not correct format: %s", i, QSTRING_CSTR(ledIndicesStr));
+ continue;
+ }
+
+ std::stringstream ss;
+ const QStringList ledIndexList = ledIndicesStr.split(",");
+ for (int i=0; i 0)
+ {
+ ss << ", ";
+ }
+ if (ledIndexList[i].contains("-"))
+ {
+ QStringList ledIndices = ledIndexList[i].split("-");
+ int startInd = ledIndices[0].toInt();
+ int endInd = ledIndices[1].toInt();
+
+ adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd);
+ ss << startInd << "-" << endInd;
+ }
+ else
+ {
+ int index = ledIndexList[i].toInt();
+ adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index);
+ ss << index;
+ }
+ }
+ //Info(_log, "ColorAdjustment '%s' => [%s]", QSTRING_CSTR(colorAdjustment->_id), ss.str().c_str());
+ }
+
+ return adjustment;
+ }
+
+ /**
+ * Construct the 'led-string' with the integration area definition per led and the color
+ * ordering of the RGB channels
+ * @param ledsConfig The configuration of the led areas
+ * @param deviceOrder The default RGB channel ordering
+ * @return The constructed ledstring
+ */
+ LedString createLedString(const QJsonArray& ledConfigArray, const ColorOrder deviceOrder)
+ {
+ LedString ledString;
+ const QString deviceOrderStr = colorOrderToString(deviceOrder);
+ int maxLedId = ledConfigArray.size();
+
+ for (signed i = 0; i < ledConfigArray.size(); ++i)
+ {
+ const QJsonObject& index = ledConfigArray[i].toObject();
+
+ Led led;
+ led.index = index["index"].toInt();
+ led.clone = index["clone"].toInt(-1);
+ if ( led.clone < -1 || led.clone >= maxLedId )
+ {
+ //Warning(_log, "LED %d: clone index of %d is out of range, clone ignored", led.index, led.clone);
+ led.clone = -1;
+ }
+
+ if ( led.clone < 0 )
+ {
+ const QJsonObject& hscanConfig = ledConfigArray[i].toObject()["hscan"].toObject();
+ const QJsonObject& vscanConfig = ledConfigArray[i].toObject()["vscan"].toObject();
+ led.minX_frac = qMax(0.0, qMin(1.0, hscanConfig["minimum"].toDouble()));
+ led.maxX_frac = qMax(0.0, qMin(1.0, hscanConfig["maximum"].toDouble()));
+ led.minY_frac = qMax(0.0, qMin(1.0, vscanConfig["minimum"].toDouble()));
+ led.maxY_frac = qMax(0.0, qMin(1.0, vscanConfig["maximum"].toDouble()));
+ // Fix if the user swapped min and max
+ if (led.minX_frac > led.maxX_frac)
+ {
+ std::swap(led.minX_frac, led.maxX_frac);
+ }
+ if (led.minY_frac > led.maxY_frac)
+ {
+ std::swap(led.minY_frac, led.maxY_frac);
+ }
+
+ // Get the order of the rgb channels for this led (default is device order)
+ led.colorOrder = stringToColorOrder(index["colorOrder"].toString(deviceOrderStr));
+ ledString.leds().push_back(led);
+ }
+ }
+
+ // Make sure the leds are sorted (on their indices)
+ std::sort(ledString.leds().begin(), ledString.leds().end(), [](const Led& lhs, const Led& rhs){ return lhs.index < rhs.index; });
+ return ledString;
+ }
+
+ LedString createLedStringClone(const QJsonArray& ledConfigArray, const ColorOrder deviceOrder)
+ {
+ LedString ledString;
+ const QString deviceOrderStr = colorOrderToString(deviceOrder);
+ int maxLedId = ledConfigArray.size();
+
+ for (signed i = 0; i < ledConfigArray.size(); ++i)
+ {
+ const QJsonObject& index = ledConfigArray[i].toObject();
+
+ Led led;
+ led.index = index["index"].toInt();
+ led.clone = index["clone"].toInt(-1);
+ if ( led.clone < -1 || led.clone >= maxLedId )
+ {
+ //Warning(_log, "LED %d: clone index of %d is out of range, clone ignored", led.index, led.clone);
+ led.clone = -1;
+ }
+
+ if ( led.clone >= 0 )
+ {
+ //Debug(_log, "LED %d: clone from led %d", led.index, led.clone);
+ led.minX_frac = 0;
+ led.maxX_frac = 0;
+ led.minY_frac = 0;
+ led.maxY_frac = 0;
+ // Get the order of the rgb channels for this led (default is device order)
+ led.colorOrder = stringToColorOrder(index["colorOrder"].toString(deviceOrderStr));
+
+ ledString.leds().push_back(led);
+ }
+
+ }
+
+ // Make sure the leds are sorted (on their indices)
+ std::sort(ledString.leds().begin(), ledString.leds().end(), [](const Led& lhs, const Led& rhs){ return lhs.index < rhs.index; });
+ return ledString;
+ }
+
+ QSize getLedLayoutGridSize(const QJsonArray& ledConfigArray)
+ {
+ std::vector midPointsX;
+ std::vector midPointsY;
+
+ for (signed i = 0; i < ledConfigArray.size(); ++i)
+ {
+ const QJsonObject& index = ledConfigArray[i].toObject();
+
+ if (index["clone"].toInt(-1) < 0 )
+ {
+ const QJsonObject& hscanConfig = ledConfigArray[i].toObject()["hscan"].toObject();
+ const QJsonObject& vscanConfig = ledConfigArray[i].toObject()["vscan"].toObject();
+ double minX_frac = qMax(0.0, qMin(1.0, hscanConfig["minimum"].toDouble()));
+ double maxX_frac = qMax(0.0, qMin(1.0, hscanConfig["maximum"].toDouble()));
+ double minY_frac = qMax(0.0, qMin(1.0, vscanConfig["minimum"].toDouble()));
+ double maxY_frac = qMax(0.0, qMin(1.0, vscanConfig["maximum"].toDouble()));
+ // Fix if the user swapped min and max
+ if (minX_frac > maxX_frac)
+ {
+ std::swap(minX_frac, maxX_frac);
+ }
+ if (minY_frac > maxY_frac)
+ {
+ std::swap(minY_frac, maxY_frac);
+ }
+
+ // calculate mid point and make grid calculation
+ midPointsX.push_back( int(1000.0*(minX_frac + maxX_frac) / 2.0) );
+ midPointsY.push_back( int(1000.0*(minY_frac + maxY_frac) / 2.0) );
+ }
+ }
+
+ // remove duplicates
+ std::sort(midPointsX.begin(), midPointsX.end());
+ midPointsX.erase(std::unique(midPointsX.begin(), midPointsX.end()), midPointsX.end());
+ std::sort(midPointsY.begin(), midPointsY.end());
+ midPointsY.erase(std::unique(midPointsY.begin(), midPointsY.end()), midPointsY.end());
+
+ QSize gridSize( midPointsX.size(), midPointsY.size() );
+ //Debug(_log, "led layout grid: %dx%d", gridSize.width(), gridSize.height());
+
+ return gridSize;
+ }
+};
diff --git a/include/utils/settings.h b/include/utils/settings.h
new file mode 100644
index 00000000..7af1a262
--- /dev/null
+++ b/include/utils/settings.h
@@ -0,0 +1,99 @@
+#pragma once
+#include
+#include
+
+///
+/// @brief Provide util methods to work with SettingsManager class
+///
+namespace settings {
+// all available settings sections
+enum type {
+ BGEFFECT,
+ FGEFFECT,
+ BLACKBORDER,
+ BOBLSERVER,
+ COLOR,
+ DEVICE,
+ EFFECTS,
+ NETFORWARD,
+ SYSTEMCAPTURE,
+ GENERAL,
+ V4L2,
+ JSONSERVER,
+ LEDCONFIG,
+ LEDS,
+ LOGGER,
+ PROTOSERVER,
+ SMOOTHING,
+ UDPLISTENER,
+ WEBSERVER,
+ INSTCAPTURE,
+ NETWORK,
+ INVALID
+};
+
+///
+/// @brief Convert settings::type to string representation
+/// @param type The settings::type from enum
+/// @return The settings type as string
+///
+inline QString typeToString(const type& type)
+{
+ switch (type)
+ {
+ case BGEFFECT: return "backgroundEffect";
+ case FGEFFECT: return "foregroundEffect";
+ case BLACKBORDER: return "blackborderdetector";
+ case BOBLSERVER: return "boblightServer";
+ case COLOR: return "color";
+ case DEVICE: return "device";
+ case EFFECTS: return "effects";
+ case NETFORWARD: return "forwarder";
+ case SYSTEMCAPTURE: return "framegrabber";
+ case GENERAL: return "general";
+ case V4L2: return "grabberV4L2";
+ case JSONSERVER: return "jsonServer";
+ case LEDCONFIG: return "ledConfig";
+ case LEDS: return "leds";
+ case LOGGER: return "logger";
+ case PROTOSERVER: return "protoServer";
+ case SMOOTHING: return "smoothing";
+ case UDPLISTENER: return "udpListener";
+ case WEBSERVER: return "webConfig";
+ case INSTCAPTURE: return "instCapture";
+ case NETWORK: return "network";
+ default: return "invalid";
+ }
+}
+
+///
+/// @brief Convert string to settings::type representation
+/// @param type The string to convert
+/// @return The settings type from enum
+///
+inline type stringToType(const QString& type)
+{
+ if (type == "backgroundEffect") return BGEFFECT;
+ else if (type == "foregroundEffect") return FGEFFECT;
+ else if (type == "blackborderdetector") return BLACKBORDER;
+ else if (type == "boblightServer") return BOBLSERVER;
+ else if (type == "color") return COLOR;
+ else if (type == "device") return DEVICE;
+ else if (type == "effects") return EFFECTS;
+ else if (type == "forwarder") return NETFORWARD;
+ else if (type == "framegrabber") return SYSTEMCAPTURE;
+ else if (type == "general") return GENERAL;
+ else if (type == "grabberV4L2") return V4L2;
+ else if (type == "jsonServer") return JSONSERVER;
+ else if (type == "ledConfig") return LEDCONFIG;
+ else if (type == "leds") return LEDS;
+ else if (type == "logger") return LOGGER;
+ else if (type == "protoServer") return PROTOSERVER;
+ else if (type == "smoothing") return SMOOTHING;
+ else if (type == "udpListener") return UDPLISTENER;
+ else if (type == "webConfig") return WEBSERVER;
+ else if (type == "instCapture") return INSTCAPTURE;
+ else if (type == "network") return NETWORK;
+ else return INVALID;
+}
+};
diff --git a/include/webconfig/WebConfig.h b/include/webconfig/WebConfig.h
deleted file mode 100644
index c9b58bfe..00000000
--- a/include/webconfig/WebConfig.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef WEBCONFIG_H
-#define WEBCONFIG_H
-
-#include
-#include
-#include
-
-class StaticFileServing;
-
-class WebConfig : public QObject {
- Q_OBJECT
-
-public:
- WebConfig (QObject * parent = NULL);
-
- virtual ~WebConfig (void);
-
- void start();
- void stop();
-
- quint16 getPort() { return _port; };
-
-private:
- Hyperion* _hyperion;
- QString _baseUrl;
- quint16 _port;
- StaticFileServing* _server;
-
- const QString WEBCONFIG_DEFAULT_PATH = ":/webconfig";
- const quint16 WEBCONFIG_DEFAULT_PORT = 8099;
-};
-
-#endif // WEBCONFIG_H
-
diff --git a/include/webserver/WebServer.h b/include/webserver/WebServer.h
new file mode 100644
index 00000000..7d0aaf39
--- /dev/null
+++ b/include/webserver/WebServer.h
@@ -0,0 +1,55 @@
+#ifndef WEBSERVER_H
+#define WEBSERVER_H
+
+#include
+#include
+#include