diff --git a/.gitmodules b/.gitmodules
index 981fff4d..31ddf173 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -5,3 +5,8 @@
[submodule "dependencies/external/flatbuffers"]
path = dependencies/external/flatbuffers
url = https://github.com/google/flatbuffers
+ branch = master
+[submodule "dependencies/external/protobuf"]
+ path = dependencies/external/protobuf
+ url = https://github.com/hyperion-project/protobuf.git
+ branch = master
diff --git a/.travis.yml b/.travis.yml
index e85acbb1..a73d1175 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,11 @@
+linux: &linux
+ os: linux
+ dist: trusty
+ services:
+ - docker
+osx: &osx
+ os: osx
+
cache:
- ccache
- directories:
@@ -5,27 +13,48 @@ cache:
notifications:
email: false
language: cpp
-services:
- - docker
-matrix:
- include:
- - os: linux
- dist: trusty
- env:
- - DOCKER_TAG=ubuntu1604
- - DOCKER_NAME="Ubuntu 16.04"
- - os: linux
- dist: trusty
- env:
- - DOCKER_TAG=cross-qemu-rpistretch
- - DOCKER_NAME="Raspberry Pi"
- - os: osx
- osx_image: xcode8.3
- env:
- - HOMEBREW_CACHE=$HOME/brew-cache
+
before_install:
- ./.travis/travis_install.sh
+
+jobs:
+ include:
+ - <<: *linux
+ name: "AMD64 (x64)"
+ env:
+ - DOCKER_TAG=amd64
+ - DOCKER_NAME="Debian Stretch (AMD64)"
+ - <<: *linux
+ name: "i386 (x86)"
+ env:
+ - DOCKER_TAG=i386
+ - DOCKER_NAME="Debian Stretch (i386)"
+ - <<: *linux
+ name: "ARMv6hf (Raspberry Pi v1 & ZERO)"
+ env:
+ - DOCKER_TAG=armv6hf
+ - DOCKER_NAME="Debian Stretch (Raspberry Pi v1 & ZERO)"
+ - PLATFORM="rpi"
+ - <<: *linux
+ name: "ARMv7hf (Raspberry Pi 2 & 3)"
+ env:
+ - DOCKER_TAG=armv7hf
+ - DOCKER_NAME="Debian Stretch (Raspberry Pi 2 & 3)"
+ - PLATFORM="rpi"
+ - <<: *linux
+ name: "ARMv8 (Generic AARCH64)"
+ env:
+ - DOCKER_TAG=aarch64
+ - DOCKER_NAME="ARMv8 (Generic AARCH64)"
+ - PLATFORM="amlogic"
+ - <<: *osx
+ osx_image: xcode8.3
+ name: "macOS 10.12 (Xcode 8.3.3)"
+ env:
+ - HOMEBREW_CACHE=$HOME/brew-cache
+
script:
- ./.travis/travis_build.sh
after_success:
- ./.travis/travis_deploy.sh
+
diff --git a/.travis/travis_build.sh b/.travis/travis_build.sh
index ddeb569c..7b39b037 100755
--- a/.travis/travis_build.sh
+++ b/.travis/travis_build.sh
@@ -3,7 +3,9 @@
# for executing in non travis environment
[ -z "$TRAVIS_OS_NAME" ] && TRAVIS_OS_NAME="$(uname -s | tr '[:upper:]' '[:lower:]')"
-PLATFORM=x86
+if [ -z "${PLATFORM}" ]; then
+ PLATFORM=x86
+fi
BUILD_TYPE=Debug
PACKAGES=""
@@ -23,10 +25,11 @@ echo "compile jobs: ${JOBS:=4}"
[ -n "${TRAVIS_TAG:-}" ] && BUILD_TYPE=Release
# Determine package creation; True for cron and tag builds
+# Commented because tests are currently broken
[ "${TRAVIS_EVENT_TYPE:-}" == 'cron' ] || [ -n "${TRAVIS_TAG:-}" ] && PACKAGES=package
# Determie -dev appends to platform;
-[ "${TRAVIS_EVENT_TYPE:-}" != 'cron' -a -z "${TRAVIS_TAG:-}" ] && PLATFORM=${PLATFORM}-dev
+# [ "${TRAVIS_EVENT_TYPE:-}" != 'cron' -a -z "${TRAVIS_TAG:-}" ] && PLATFORM=${PLATFORM}-dev
# Build the package on osx
if [[ "$TRAVIS_OS_NAME" == 'osx' || "$TRAVIS_OS_NAME" == 'darwin' ]]
@@ -48,10 +51,10 @@ then
docker run --rm \
-v "${TRAVIS_BUILD_DIR}/deploy:/deploy" \
-v "${TRAVIS_BUILD_DIR}:/source:ro" \
- hyperionorg/hyperion-ci:$DOCKER_TAG \
+ hyperionproject/hyperion-ci:$DOCKER_TAG \
/bin/bash -c "mkdir build && cp -r /source/. /build &&
cd /build && mkdir build && cd build &&
- cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} .. || exit 2 &&
+ cmake -DPLATFORM=${PLATFORM} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} .. || exit 2 &&
make -j $(nproc) ${PACKAGES} || exit 3 &&
echo '---> Copy binaries and packages to host folder: ${TRAVIS_BUILD_DIR}/deploy' &&
cp -v /build/build/bin/h* /deploy/ 2>/dev/null || : &&
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6615eee7..18d7cb66 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,6 +24,7 @@ SET ( DEFAULT_QT ON )
SET ( DEFAULT_WS281XPWM OFF )
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
SET ( DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS OFF )
+SET ( DEFAULT_USE_SYSTEM_PROTO_LIBS OFF )
SET ( DEFAULT_TESTS OFF )
IF ( ${CMAKE_SYSTEM} MATCHES "Linux" )
@@ -164,6 +165,9 @@ message(STATUS "ENABLE_PROFILER = ${ENABLE_PROFILER}")
SET ( FLATBUFFERS_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/flatbuf )
SET ( FLATBUFFERS_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/flatbuf )
+SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto )
+SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )
+
# check all json files
FILE ( GLOB_RECURSE HYPERION_SCHEMAS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libsrc/*schema*.json )
SET( JSON_FILES
@@ -233,6 +237,7 @@ CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-psabi")
endif()
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
diff --git a/CompileHowto.md b/CompileHowto.md
index 205f9a47..2da17bce 100644
--- a/CompileHowto.md
+++ b/CompileHowto.md
@@ -1,13 +1,21 @@
# With Docker
-If you are using [Docker](https://www.docker.com/), you can compile Hyperion inside a docker container. This keeps your system clean and with a simple script it's easy to use. Supported is also cross compilation for Raspberry Pi (Raspbian stretch)
+If you are using [Docker](https://www.docker.com/), you can compile Hyperion inside a docker container. This keeps your system clean and with a simple script it's easy to use. Supported is also cross compilation for Raspberry Pi (Debian Stretch)
-To compile Hyperion for Ubuntu 16.04 (x64) or higher just execute the following command
+To compile Hyperion for Debain Stretch (x64 architecture) or higher just execute the following command
```
wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh
```
-To compile Hyperion for Raspberry Pi
+To compile Hyperion for i386 architecture
```
-wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -t cross-qemu-rpistretch
+wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -t i386
+```
+To compile Hyperion for Raspberry Pi v1 & ZERO
+```
+wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -t armv6hf
+```
+To compile Hyperion for Raspberry Pi 2 & 3
+```
+wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/docker-compile.sh && chmod +x *.sh && ./docker-compile.sh -t armv7hf
```
The compiled binaries and packages will be available at the deploy folder next to the script
Note: call the script with `./docker-compile.sh -h` for more options
diff --git a/README.md b/README.md
index ff1cfd7f..3423c965 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-HYPERION
-========
+# HYPERION
[![Build Status](https://travis-ci.org/hyperion-project/hyperion.ng.svg?branch=master)](https://travis-ci.org/hyperion-project/hyperion.ng)
+[![GitHub license](https://img.shields.io/badge/License-MIT-yellow.svg)](https://raw.githubusercontent.com/hyperion-project/hyperion.ng/master/LICENSE)
This is a pre alpha development repository for the next major version of hyperion
@@ -16,6 +16,7 @@ If you want to use hyperion as 'normal user', please use [current stable version
Besides of that .... Feel free to join us! We are looking always for people who wants to participate.
--------
+## About
Hyperion is an opensource 'AmbiLight' implementation with support for many LED devices and video grabbers.
diff --git a/assets/webconfig/i18n/de.json b/assets/webconfig/i18n/de.json
index 373dd697..bfced0ff 100644
--- a/assets/webconfig/i18n/de.json
+++ b/assets/webconfig/i18n/de.json
@@ -21,6 +21,7 @@
"general_comp_UDPLISTENER" : "UDP Listener",
"general_comp_BOBLIGHTSERVER" : "Boblight Server",
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
+ "general_comp_PROTOSERVER" : "Protocol Buffers Server",
"general_comp_GRABBER" : "Plattform Aufnahme",
"general_comp_V4L" : "USB Aufnahme",
"general_comp_LEDDEVICE" : "LED Hardware",
@@ -48,7 +49,7 @@
"dashboard_infobox_label_latesthyp" : "Aktuellste Hyperion Version:",
"dashboard_infobox_label_platform" : "Plattform:",
"dashboard_infobox_label_instance" : "Instanz:",
- "dashboard_infobox_label_ports" : "Port flatbuf:",
+ "dashboard_infobox_label_ports" : "Ports (flat|proto):",
"dashboard_infobox_message_updatewarning" : "Eine aktuellere Version von Hyperion ist verfügbar! (V$1)",
"dashboard_infobox_message_updatesuccess" : "Du nutzt die aktuellste Version von Hyperion.",
"dashboard_infobox_label_statush" : "Hyperion Status:",
@@ -169,6 +170,7 @@
"conf_network_bobl_intro" : "Boblight Empfänger",
"conf_network_udpl_intro" : "UDP Empfänger",
"conf_network_fbs_intro" : "Google Flatbuffers Empfänger. Wird genutzt für schnellen Bildempfang.",
+ "conf_network_proto_intro" : "Der PROTO-Port dieser Hyperion-Instanz, wird genutzt für \"Bildstreams\" (HyperionScreenCap, Kodi Addon, ...)",
"conf_network_forw_intro" : "Leite alles an eine zweite Hyperion Instanz weiter, diese kann dann mit einer anderen LED Steuerung genutzt werden",
"conf_logging_label_intro" : "Überprüfe die Meldungen im Prokotoll um zu erfahren was Hyperion gerade beschäftigt. Je nach eingestellter Protokoll-Stufe siehst du mehr oder weniger Informationen.",
"conf_logging_btn_pbupload" : "Bericht für Supportanfrage hochladen",
@@ -572,6 +574,9 @@
"edt_conf_fbs_heading_title" : "Flatbuffers Server",
"edt_conf_fbs_timeout_title" : "Zeitüberschreitung",
"edt_conf_fbs_timeout_expl" : "Wenn für die angegebene Zeit keine Daten empfangen werden, wird die Komponente (vorübergehend) deaktiviert",
+ "edt_conf_pbs_heading_title" : "Protocol Buffers Server",
+ "edt_conf_pbs_timeout_title" : "Zeitüberschreitung",
+ "edt_conf_pbs_timeout_expl" : "Wenn für die angegebene Zeit keine Daten empfangen werden, wird die Komponente (vorübergehend) deaktiviert",
"edt_conf_bobls_heading_title" : "Boblight Server",
"edt_conf_udpl_heading_title" : "UDP Listener",
"edt_conf_udpl_address_title" : "Adresse",
diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json
index 6dd08730..496c7e76 100644
--- a/assets/webconfig/i18n/en.json
+++ b/assets/webconfig/i18n/en.json
@@ -21,6 +21,7 @@
"general_comp_UDPLISTENER" : "UDP Listener",
"general_comp_BOBLIGHTSERVER" : "Boblight Server",
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
+ "general_comp_PROTOSERVER" : "Protocol Buffers Server",
"general_comp_GRABBER" : "Platform Capture",
"general_comp_V4L" : "USB Capture",
"general_comp_LEDDEVICE" : "LED device",
@@ -48,7 +49,7 @@
"dashboard_infobox_label_latesthyp" : "Latest Hyperion version:",
"dashboard_infobox_label_platform" : "Platform:",
"dashboard_infobox_label_instance" : "Instance:",
- "dashboard_infobox_label_ports" : "Port flatbuf:",
+ "dashboard_infobox_label_ports" : "Ports (flat|proto):",
"dashboard_infobox_message_updatewarning" : "A newer version of Hyperion is available! ($1)",
"dashboard_infobox_message_updatesuccess" : "You run the latest version of Hyperion.",
"dashboard_infobox_label_statush" : "Hyperion status:",
@@ -169,6 +170,7 @@
"conf_network_bobl_intro" : "Receiver for Boblight",
"conf_network_udpl_intro" : "Receiver for UDP",
"conf_network_fbs_intro" : "Google Flatbuffers Receiver. Used for fast image transmission.",
+ "conf_network_proto_intro" : "The PROTO-Port of this Hyperion instance, used for picture streams (HyperionScreenCap, Kodi Addon, ...)",
"conf_network_forw_intro" : "Forward all input to a second Hyperion instance which could be driven with another led controller",
"conf_logging_label_intro" : "Area to check log messages, depending on loglevel setting you see more or less information.",
"conf_logging_btn_pbupload" : "Upload report for support request",
@@ -573,6 +575,9 @@
"edt_conf_fbs_heading_title" : "Flatbuffers Server",
"edt_conf_fbs_timeout_title" : "Timeout",
"edt_conf_fbs_timeout_expl" : "If no data are received for the given period, the component will be (soft) disabled.",
+ "edt_conf_pbs_heading_title" : "Protocol Buffers Server",
+ "edt_conf_pbs_timeout_title" : "Timeout",
+ "edt_conf_pbs_timeout_expl" : "If no data are received for the given period, the component will be (soft) disabled.",
"edt_conf_bobls_heading_title" : "Boblight Server",
"edt_conf_udpl_heading_title" : "UDP Listener",
"edt_conf_udpl_address_title" : "Address",
diff --git a/assets/webconfig/js/content_dashboard.js b/assets/webconfig/js/content_dashboard.js
index b43ca531..949edab9 100644
--- a/assets/webconfig/js/content_dashboard.js
+++ b/assets/webconfig/js/content_dashboard.js
@@ -77,7 +77,7 @@ $(document).ready( function() {
$('#dash_leddevice').html(serverInfo.ledDevices.active);
$('#dash_currv').html(currentVersion);
$('#dash_instance').html(serverConfig.general.name);
- $('#dash_ports').html(serverConfig.flatbufServer.port);
+ $('#dash_ports').html(serverConfig.flatbufServer.port+' | '+serverConfig.protoServer.port);
$.get( "https://raw.githubusercontent.com/hyperion-project/hyperion.ng/master/version.json", function( data ) {
parsedUpdateJSON = JSON.parse(data);
diff --git a/assets/webconfig/js/content_network.js b/assets/webconfig/js/content_network.js
index 7c747121..3776e18b 100644
--- a/assets/webconfig/js/content_network.js
+++ b/assets/webconfig/js/content_network.js
@@ -21,6 +21,11 @@ $(document).ready( function() {
$('#conf_cont_flatbuf').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver'));
$('#conf_cont_flatbuf').append(createHelpTable(schema.flatbufServer.properties, $.i18n("edt_conf_fbs_heading_title")));
+ //protoserver
+ $('#conf_cont').append(createRow('conf_cont_proto'))
+ $('#conf_cont_proto').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_pbs_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver'));
+ $('#conf_cont_proto').append(createHelpTable(schema.protoServer.properties, $.i18n("edt_conf_pbs_heading_title")));
+
//boblight
$('#conf_cont').append(createRow('conf_cont_bobl'))
$('#conf_cont_bobl').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver'));
@@ -44,6 +49,7 @@ $(document).ready( function() {
$('#conf_cont').addClass('row');
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver'));
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver'));
+ $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_pbs_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver'));
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver'));
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_udpl_heading_title"), 'editor_container_udplistener', 'btn_submit_udplistener'));
if(storedAccess != 'default')
@@ -76,6 +82,19 @@ $(document).ready( function() {
requestWriteConfig(conf_editor_fbs.getValue());
});
+ //protobuffer
+ conf_editor_proto = createJsonEditor('editor_container_protoserver', {
+ protoServer : schema.protoServer
+ }, true, true);
+
+ conf_editor_proto.on('change',function() {
+ conf_editor_proto.validate().length ? $('#btn_submit_protoserver').attr('disabled', true) : $('#btn_submit_protoserver').attr('disabled', false);
+ });
+
+ $('#btn_submit_protoserver').off().on('click',function() {
+ requestWriteConfig(conf_editor_proto.getValue());
+ });
+
//boblight
conf_editor_bobl = createJsonEditor('editor_container_boblightserver', {
boblightServer : schema.boblightServer
@@ -123,6 +142,7 @@ $(document).ready( function() {
{
createHint("intro", $.i18n('conf_network_json_intro'), "editor_container_jsonserver");
createHint("intro", $.i18n('conf_network_fbs_intro'), "editor_container_fbserver");
+ createHint("intro", $.i18n('conf_network_proto_intro'), "editor_container_protoserver");
createHint("intro", $.i18n('conf_network_bobl_intro'), "editor_container_boblightserver");
createHint("intro", $.i18n('conf_network_udpl_intro'), "editor_container_udplistener");
createHint("intro", $.i18n('conf_network_forw_intro'), "editor_container_forwarder");
diff --git a/assets/webconfig/js/content_remote.js b/assets/webconfig/js/content_remote.js
index eab3dca6..ab341632 100644
--- a/assets/webconfig/js/content_remote.js
+++ b/assets/webconfig/js/content_remote.js
@@ -156,9 +156,12 @@ $(document).ready(function() {
case "FLATBUFSERVER":
owner = $.i18n('general_comp_FLATBUFSERVER');
break;
+ case "PROTOSERVER":
+ owner = $.i18n('general_comp_PROTOSERVER');
+ break;
}
- if(duration && compId != "GRABBER" && compId != "PROTOSERVER")
+ if(duration && compId != "GRABBER" && compId != "FLATBUFSERVER" && compId != "PROTOSERVER")
owner += '
'+$.i18n('remote_input_duration')+' '+duration.toFixed(0)+$.i18n('edt_append_s')+'';
var btn = '';
diff --git a/bin/scripts/docker-compile.sh b/bin/scripts/docker-compile.sh
index 6d4215b8..c0e81d60 100644
--- a/bin/scripts/docker-compile.sh
+++ b/bin/scripts/docker-compile.sh
@@ -5,8 +5,8 @@ DOCKER="docker"
GIT_REPO_URL="https://github.com/hyperion-project/hyperion.ng.git"
# cmake build type
BUILD_TYPE="Release"
-# the image tag at hyperionorg/hyperion-ci
-BUILD_TARGET="ubuntu1604"
+# the image tag at hyperionproject/hyperion-ci
+BUILD_TARGET="amd64"
# build packages (.deb .zip ...)
BUILD_PACKAGES=true
# packages string inserted to cmake cmd
@@ -42,8 +42,8 @@ function printHelp {
echo "########################################################
## A script to compile Hyperion inside a docker container
## Requires installed Docker: https://www.docker.com/
-## Without arguments it will compile Hyperion for Ubuntu 16.04 (x64) or higher.
-## Supports Raspberry Pi (armv6) cross compilation (Raspbian Stretch)
+## Without arguments it will compile Hyperion for Debain Stretch (x64) or higher.
+## Supports Raspberry Pi (armv6hf, armv7hf) cross compilation (Debian Stretch)
##
## Homepage: https://www.hyperion-project.org
## Forum: https://forum.hyperion-project.org
@@ -51,10 +51,10 @@ echo "########################################################
# These are possible arguments to modify the script behaviour with their default values
#
# docker-compile.sh -h # Show this help message
-# docker-compile.sh -t ubuntu1604 # The docker tag, one of ubuntu1604 | cross-qemu-rpistretch
+# docker-compile.sh -t amd64 # The docker tag, one of amd64 | i386 | armv6hf | armv7hf
# docker-compile.sh -b Release # cmake Release or Debug build
# docker-compile.sh -p true # If true build packages with CPack
-# More informations to docker tags at: https://hub.docker.com/r/hyperionorg/hyperion-ci/"
+# More informations to docker tags at: https://hub.docker.com/r/hyperionproject/hyperion-ci/"
}
while getopts t:b:p:h option
diff --git a/config/hyperion.config.json.commented b/config/hyperion.config.json.commented
index 422b7145..80b8d873 100644
--- a/config/hyperion.config.json.commented
+++ b/config/hyperion.config.json.commented
@@ -247,6 +247,15 @@
"timeout" : 5
},
+ /// The configuration of the Protobuffer server which enables the Protobuffer remote interface
+ /// * port : Port at which the protobuffer server is started
+ "protoServer" :
+ {
+ "enable" : true,
+ "port" : 19445,
+ "timeout" : 5
+ },
+
/// The configuration of the boblight server which enables the boblight remote interface
/// * enable : Enable or disable the boblight server (true/false)
/// * port : Port at which the boblight server is started
diff --git a/config/hyperion.config.json.default b/config/hyperion.config.json.default
index 866879e0..b8b9f394 100644
--- a/config/hyperion.config.json.default
+++ b/config/hyperion.config.json.default
@@ -140,6 +140,13 @@
"timeout" : 5
},
+ "protoServer" :
+ {
+ "enable" : true,
+ "port" : 19445,
+ "timeout" : 5
+ },
+
"boblightServer" :
{
"enable" : false,
diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt
index 1ff24f50..67e30835 100644
--- a/dependencies/CMakeLists.txt
+++ b/dependencies/CMakeLists.txt
@@ -9,6 +9,10 @@ if(ENABLE_WS281XPWM)
external/rpi_ws281x/rpihw.c)
endif()
+#=============================================================================
+# FLATBUFFER
+#=============================================================================
+
set(USE_SYSTEM_FLATBUFFERS_LIBS ${DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS} CACHE BOOL "use flatbuffers library from system")
if (USE_SYSTEM_FLATBUFFERS_LIBS)
@@ -63,3 +67,115 @@ function(compile_flattbuffer_schema SRC_FBS OUTPUT_DIR)
DEPENDS flatc)
endif()
endfunction()
+
+#=============================================================================
+# PROTOBUFFER
+#=============================================================================
+
+set(USE_SYSTEM_PROTO_LIBS ${DEFAULT_USE_SYSTEM_PROTO_LIBS} CACHE BOOL "use protobuf library from system")
+
+if (USE_SYSTEM_PROTO_LIBS)
+ find_package(Protobuf REQUIRED)
+ if (ENABLE_AMLOGIC)
+ set(PROTOBUF_INCLUDE_DIRS "${Protobuf_INCLUDE_DIRS}" PARENT_SCOPE)
+ set(PROTOBUF_PROTOC_EXECUTABLE "${Protobuf_PROTOC_EXECUTABLE}" PARENT_SCOPE)
+ endif()
+ include_directories(${PROTOBUF_INCLUDE_DIRS})
+else ()
+ set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared protobuf library")
+ add_subdirectory(external/protobuf)
+
+ if(CMAKE_CROSSCOMPILING)
+ # when crosscompiling import the protoc executable targets from a file generated by a native build
+ option(IMPORT_PROTOC "Protoc export file (protoc_export.cmake) from a native build" "IMPORT_PROTOC-FILE_NOT_FOUND")
+ include(${IMPORT_PROTOC})
+ else()
+ # export the protoc compiler so it can be used when cross compiling
+ export(TARGETS protoc_compiler FILE "${CMAKE_BINARY_DIR}/protoc_export.cmake")
+ endif()
+
+ # define the include for the protobuf library at the parent scope
+ set(PROTOBUF_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/protobuf/src")
+ set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE)
+
+ # define the protoc executable at the parent scope
+ get_property(PROTOBUF_PROTOC_EXECUTABLE TARGET protoc_compiler PROPERTY LOCATION)
+ set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE} PARENT_SCOPE)
+endif()
+
+message(STATUS "Using protobuf compiler: " ${PROTOBUF_PROTOC_EXECUTABLE})
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2009-2011 Philip Lowman
+# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+function(PROTOBUF_GENERATE_CPP SRCS HDRS)
+ if(NOT ARGN)
+ message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
+ return()
+ endif()
+
+ if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
+ # Create an include path for each file specified
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ get_filename_component(ABS_PATH ${ABS_FIL} PATH)
+ list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
+ if(${_contains_already} EQUAL -1)
+ list(APPEND _protobuf_include_path -I ${ABS_PATH})
+ endif()
+ endforeach()
+ else()
+ set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+ endif()
+
+ if(DEFINED PROTOBUF_IMPORT_DIRS)
+ foreach(DIR ${PROTOBUF_IMPORT_DIRS})
+ get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
+ list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
+ if(${_contains_already} EQUAL -1)
+ list(APPEND _protobuf_include_path -I ${ABS_PATH})
+ endif()
+ endforeach()
+ endif()
+
+ if(CMAKE_CROSSCOMPILING OR USE_SYSTEM_PROTO_LIBS)
+ set(PROTOC_DEPENDENCY ${PROTOBUF_PROTOC_EXECUTABLE})
+ else()
+ set(PROTOC_DEPENDENCY protoc_compiler)
+ endif()
+
+ set(${SRCS})
+ set(${HDRS})
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ get_filename_component(FIL_WE ${FIL} NAME_WE)
+
+ list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
+ list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
+
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
+ "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
+ COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
+ ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
+ DEPENDS ${ABS_FIL} ${PROTOC_DEPENDENCY}
+ COMMENT "Running C++ protocol buffer compiler on ${FIL}"
+ VERBATIM
+ )
+ endforeach()
+
+ set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
+ set(${SRCS} ${${SRCS}} PARENT_SCOPE)
+ set(${HDRS} ${${HDRS}} PARENT_SCOPE)
+endfunction()
diff --git a/dependencies/external/protobuf b/dependencies/external/protobuf
new file mode 160000
index 00000000..adce8a99
--- /dev/null
+++ b/dependencies/external/protobuf
@@ -0,0 +1 @@
+Subproject commit adce8a99fdab90f290d659b6b3bf2d09b721e24a
diff --git a/dependencies/external/rpi_ws281x b/dependencies/external/rpi_ws281x
index f5807772..6c5ade93 160000
--- a/dependencies/external/rpi_ws281x
+++ b/dependencies/external/rpi_ws281x
@@ -1 +1 @@
-Subproject commit f580777219062568d2e43e998ecb0950deff9e99
+Subproject commit 6c5ade93d1af78cd19e60ee5ecc34adfd111b186
diff --git a/include/hyperion/CaptureCont.h b/include/hyperion/CaptureCont.h
index a5b5059e..3c7e866c 100644
--- a/include/hyperion/CaptureCont.h
+++ b/include/hyperion/CaptureCont.h
@@ -41,13 +41,13 @@ private slots:
/// @brief forward system image
/// @param image The image
///
- void handleSystemImage(const Image& image);
+ void handleSystemImage(const QString& name, const Image& image);
///
/// @brief forward v4l image
/// @param image The image
///
- void handleV4lImage(const Image & image);
+ void handleV4lImage(const QString& name, const Image & image);
///
/// @brief Is called from _v4lInactiveTimer to set source after specific time to inactive
@@ -66,10 +66,12 @@ private:
/// Reflect state of System capture and prio
bool _systemCaptEnabled;
quint8 _systemCaptPrio;
+ QString _systemCaptName;
QTimer* _systemInactiveTimer;
/// Reflect state of v4l capture and prio
bool _v4lCaptEnabled;
quint8 _v4lCaptPrio;
+ QString _v4lCaptName;
QTimer* _v4lInactiveTimer;
};
diff --git a/include/hyperion/GrabberWrapper.h b/include/hyperion/GrabberWrapper.h
index 57c92808..7c3bb53b 100644
--- a/include/hyperion/GrabberWrapper.h
+++ b/include/hyperion/GrabberWrapper.h
@@ -54,7 +54,7 @@ public:
int ret = grabber.grabFrame(_image);
if (ret >= 0)
{
- emit systemImage(_image);
+ emit systemImage(_grabberName, _image);
return true;
}
return false;
@@ -92,7 +92,7 @@ signals:
///
/// @brief Emit the final processed image
///
- void systemImage(const Image& image);
+ void systemImage(const QString& name, const Image& image);
protected:
diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h
index 7440020b..e72dde98 100644
--- a/include/hyperion/Hyperion.h
+++ b/include/hyperion/Hyperion.h
@@ -411,7 +411,7 @@ signals:
void forwardJsonMessage(QJsonObject);
/// Signal which is emitted, when a new proto image should be forwarded
- void forwardProtoMessage(Image);
+ void forwardProtoMessage(const QString, const Image);
///
/// @brief Is emitted from clients who request a videoMode change
diff --git a/include/hyperion/MessageForwarder.h b/include/hyperion/MessageForwarder.h
index 58b3254f..4a37fb76 100644
--- a/include/hyperion/MessageForwarder.h
+++ b/include/hyperion/MessageForwarder.h
@@ -70,7 +70,7 @@ private slots:
/// @brief Forward image to all proto slaves
/// @param image The PROTO image to send
///
- void forwardProtoMessage(const Image &image);
+ void forwardProtoMessage(const QString& name, const Image &image);
///
/// @brief Forward message to a single json slave
diff --git a/include/protoserver/ProtoServer.h b/include/protoserver/ProtoServer.h
new file mode 100644
index 00000000..25cbd5a7
--- /dev/null
+++ b/include/protoserver/ProtoServer.h
@@ -0,0 +1,67 @@
+#pragma once
+
+// util
+#include
+#include
+
+// qt
+#include
+
+class QTcpServer;
+class ProtoClientConnection;
+
+///
+/// @brief This class creates a TCP server which accepts connections wich can then send
+/// in Protocol Buffer encoded commands. This interface to Hyperion is used by various
+/// third-party applications
+///
+class ProtoServer : public QObject
+{
+ Q_OBJECT
+
+public:
+ ProtoServer(const QJsonDocument& config, QObject* parent = nullptr);
+ ~ProtoServer();
+
+public slots:
+ ///
+ /// @brief Handle settings update
+ /// @param type The type from enum
+ /// @param config The configuration
+ ///
+ void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
+
+ void initServer();
+
+private slots:
+ ///
+ /// @brief Is called whenever a new socket wants to connect
+ ///
+ void newConnection();
+
+ ///
+ /// @brief is called whenever a client disconnected
+ ///
+ void clientDisconnected();
+
+private:
+ ///
+ /// @brief Start the server with current _port
+ ///
+ void startServer();
+
+ ///
+ /// @brief Stop server
+ ///
+ void stopServer();
+
+
+private:
+ QTcpServer* _server;
+ Logger* _log;
+ int _timeout;
+ quint16 _port;
+ const QJsonDocument _config;
+
+ QVector _openConnections;
+};
diff --git a/include/udplistener/UDPListener.h b/include/udplistener/UDPListener.h
index 83b50599..167ccb7d 100644
--- a/include/udplistener/UDPListener.h
+++ b/include/udplistener/UDPListener.h
@@ -84,7 +84,6 @@ private slots:
void processTheDatagram(const QByteArray * datagram, const QHostAddress * sender);
private:
-
/// The UDP server object
QUdpSocket * _server;
diff --git a/include/utils/Components.h b/include/utils/Components.h
index ba2350b6..2222a9f7 100644
--- a/include/utils/Components.h
+++ b/include/utils/Components.h
@@ -22,7 +22,8 @@ enum Components
COMP_IMAGE,
COMP_EFFECT,
COMP_LEDDEVICE,
- COMP_FLATBUFSERVER
+ COMP_FLATBUFSERVER,
+ COMP_PROTOSERVER
};
inline const char* componentToString(Components c)
@@ -41,7 +42,8 @@ inline const char* componentToString(Components c)
case COMP_EFFECT: return "Effect";
case COMP_IMAGE: return "Image";
case COMP_LEDDEVICE: return "LED device";
- case COMP_FLATBUFSERVER: return "Image Receiver";
+ case COMP_FLATBUFSERVER: return "Image Receiver";
+ case COMP_PROTOSERVER: return "Proto Server";
default: return "";
}
}
@@ -63,6 +65,7 @@ inline const char* componentToIdString(Components c)
case COMP_IMAGE: return "IMAGE";
case COMP_LEDDEVICE: return "LEDDEVICE";
case COMP_FLATBUFSERVER: return "FLATBUFSERVER";
+ case COMP_PROTOSERVER: return "PROTOSERVER";
default: return "";
}
}
@@ -83,6 +86,7 @@ inline Components stringToComponent(QString component)
if (component == "IMAGE") return COMP_IMAGE;
if (component == "LEDDEVICE") return COMP_LEDDEVICE;
if (component == "FLATBUFSERVER") return COMP_FLATBUFSERVER;
+ if (component == "PROTOSERVER") return COMP_PROTOSERVER;
return COMP_INVALID;
}
diff --git a/include/utils/GlobalSignals.h b/include/utils/GlobalSignals.h
index e3fd8efd..f97302c8 100644
--- a/include/utils/GlobalSignals.h
+++ b/include/utils/GlobalSignals.h
@@ -29,13 +29,15 @@ public:
signals:
///
/// @brief PIPE SystemCapture images from GrabberWrapper to Hyperion class
+ /// @param name The name of the platform capture that is currently active
/// @param image The prepared image
///
- void setSystemImage(const Image& image);
+ void setSystemImage(const QString& name, const Image& image);
///
/// @brief PIPE v4lCapture images from v4lCapture over HyperionDaemon to Hyperion class
+ /// @param name The name of the v4l capture (path) that is currently active
/// @param image The prepared image
///
- void setV4lImage(const Image & image);
+ void setV4lImage(const QString& name, const Image & image);
};
diff --git a/include/utils/settings.h b/include/utils/settings.h
index 607a3719..ef96fa1d 100644
--- a/include/utils/settings.h
+++ b/include/utils/settings.h
@@ -29,6 +29,7 @@ enum type {
INSTCAPTURE,
NETWORK,
FLATBUFSERVER,
+ PROTOSERVER,
INVALID
};
@@ -62,6 +63,7 @@ inline QString typeToString(const type& type)
case INSTCAPTURE: return "instCapture";
case NETWORK: return "network";
case FLATBUFSERVER: return "flatbufServer";
+ case PROTOSERVER: return "protoServer";
default: return "invalid";
}
}
@@ -73,7 +75,7 @@ inline QString typeToString(const type& type)
///
inline type stringToType(const QString& type)
{
- if (type == "backgroundEffect") return BGEFFECT;
+ if (type == "backgroundEffect") return BGEFFECT;
else if (type == "foregroundEffect") return FGEFFECT;
else if (type == "blackborderdetector") return BLACKBORDER;
else if (type == "boblightServer") return BOBLSERVER;
@@ -94,6 +96,7 @@ inline type stringToType(const QString& type)
else if (type == "instCapture") return INSTCAPTURE;
else if (type == "network") return NETWORK;
else if (type == "flatbufServer") return FLATBUFSERVER;
- else return INVALID;
+ else if (type == "protoServer") return PROTOSERVER;
+ else return INVALID;
}
};
diff --git a/libsrc/CMakeLists.txt b/libsrc/CMakeLists.txt
index 4ff02b3b..f858b74d 100644
--- a/libsrc/CMakeLists.txt
+++ b/libsrc/CMakeLists.txt
@@ -8,6 +8,7 @@ add_subdirectory(commandline)
add_subdirectory(blackborder)
add_subdirectory(jsonserver)
add_subdirectory(flatbufserver)
+add_subdirectory(protoserver)
add_subdirectory(bonjour)
add_subdirectory(ssdp)
add_subdirectory(boblightserver)
diff --git a/libsrc/flatbufserver/FlatBufferClient.h b/libsrc/flatbufserver/FlatBufferClient.h
index cc934b32..9fe6f36e 100644
--- a/libsrc/flatbufserver/FlatBufferClient.h
+++ b/libsrc/flatbufserver/FlatBufferClient.h
@@ -31,7 +31,7 @@ public:
/// @param timeout The timeout when a client is automatically disconnected and the priority unregistered
/// @param parent The parent
///
- explicit FlatBufferClient(QTcpSocket* socket, const int &timeout, QObject *parent = nullptr);
+ explicit FlatBufferClient(QTcpSocket* socket, const int &timeout, QObject *parent = nullptr);
signals:
///
@@ -59,12 +59,12 @@ private slots:
///
/// @brief Is called whenever the socket got new data to read
///
- void readyRead();
+ void readyRead();
///
/// @brief Is called when the socket closed the connection, also requests thread exit
///
- void disconnected();
+ void disconnected();
private:
///
diff --git a/libsrc/flatbufserver/FlatBufferServer.cpp b/libsrc/flatbufserver/FlatBufferServer.cpp
index ab87eb3e..0dc953fe 100644
--- a/libsrc/flatbufserver/FlatBufferServer.cpp
+++ b/libsrc/flatbufserver/FlatBufferServer.cpp
@@ -62,8 +62,6 @@ void FlatBufferServer::newConnection()
FlatBufferClient *client = new FlatBufferClient(socket, _timeout, this);
// internal
connect(client, &FlatBufferClient::clientDisconnected, this, &FlatBufferServer::clientDisconnected);
- // forward data
- //connect(clientThread, &FlatBufferClient::);
_openConnections.append(client);
}
}
diff --git a/libsrc/grabber/framebuffer/FramebufferFrameGrabber.cpp b/libsrc/grabber/framebuffer/FramebufferFrameGrabber.cpp
index 9cf2675b..a14cf805 100755
--- a/libsrc/grabber/framebuffer/FramebufferFrameGrabber.cpp
+++ b/libsrc/grabber/framebuffer/FramebufferFrameGrabber.cpp
@@ -46,7 +46,11 @@ int FramebufferFrameGrabber::grabFrame(Image & image)
{
case 16: pixelFormat = PIXELFORMAT_BGR16; break;
case 24: pixelFormat = PIXELFORMAT_BGR24; break;
+#ifdef ENABLE_AMLOGIC
+ case 32: pixelFormat = PIXELFORMAT_RGB32; break;
+#else
case 32: pixelFormat = PIXELFORMAT_BGR32; break;
+#endif
default:
Error(_log, "Unknown pixel format: %d bits per pixel", vinfo.bits_per_pixel);
close(_fbfd);
diff --git a/libsrc/grabber/v4l2/V4L2Grabber.cpp b/libsrc/grabber/v4l2/V4L2Grabber.cpp
index 8d3a3785..2f17f238 100644
--- a/libsrc/grabber/v4l2/V4L2Grabber.cpp
+++ b/libsrc/grabber/v4l2/V4L2Grabber.cpp
@@ -54,6 +54,9 @@ V4L2Grabber::V4L2Grabber(const QString & device
{
setPixelDecimation(pixelDecimation);
getV4Ldevices();
+
+ // init
+ setDeviceVideoStandard(device, videoStandard);
}
V4L2Grabber::~V4L2Grabber()
diff --git a/libsrc/grabber/v4l2/V4L2Wrapper.cpp b/libsrc/grabber/v4l2/V4L2Wrapper.cpp
index 987b016b..320dccd9 100644
--- a/libsrc/grabber/v4l2/V4L2Wrapper.cpp
+++ b/libsrc/grabber/v4l2/V4L2Wrapper.cpp
@@ -53,7 +53,7 @@ void V4L2Wrapper::setSignalDetectionOffset(double verticalMin, double horizontal
void V4L2Wrapper::newFrame(const Image &image)
{
- emit systemImage(image);
+ emit systemImage(_grabberName, image);
}
void V4L2Wrapper::readError(const char* err)
diff --git a/libsrc/hyperion/CaptureCont.cpp b/libsrc/hyperion/CaptureCont.cpp
index 12c5cd32..0eb75ccc 100644
--- a/libsrc/hyperion/CaptureCont.cpp
+++ b/libsrc/hyperion/CaptureCont.cpp
@@ -13,8 +13,10 @@ CaptureCont::CaptureCont(Hyperion* hyperion)
: QObject()
, _hyperion(hyperion)
, _systemCaptEnabled(false)
+ , _systemCaptName()
, _systemInactiveTimer(new QTimer(this))
, _v4lCaptEnabled(false)
+ , _v4lCaptName()
, _v4lInactiveTimer(new QTimer(this))
{
// settings changes
@@ -41,14 +43,24 @@ CaptureCont::~CaptureCont()
{
}
-void CaptureCont::handleV4lImage(const Image & image)
+void CaptureCont::handleV4lImage(const QString& name, const Image & image)
{
+ if(_v4lCaptName != name)
+ {
+ _hyperion->registerInput(_v4lCaptPrio, hyperion::COMP_V4L, "System", name);
+ _v4lCaptName = name;
+ }
_v4lInactiveTimer->start();
_hyperion->setInputImage(_v4lCaptPrio, image);
}
-void CaptureCont::handleSystemImage(const Image& image)
+void CaptureCont::handleSystemImage(const QString& name, const Image& image)
{
+ if(_systemCaptName != name)
+ {
+ _hyperion->registerInput(_systemCaptPrio, hyperion::COMP_GRABBER, "System", name);
+ _systemCaptName = name;
+ }
_systemInactiveTimer->start();
_hyperion->setInputImage(_systemCaptPrio, image);
}
diff --git a/libsrc/hyperion/MessageForwarder.cpp b/libsrc/hyperion/MessageForwarder.cpp
index a8fc4594..ef1423f7 100644
--- a/libsrc/hyperion/MessageForwarder.cpp
+++ b/libsrc/hyperion/MessageForwarder.cpp
@@ -210,7 +210,7 @@ void MessageForwarder::forwardJsonMessage(const QJsonObject &message)
}
}
-void MessageForwarder::forwardProtoMessage(const Image &image)
+void MessageForwarder::forwardProtoMessage(const QString& name, const Image &image)
{
if (_forwarder_enabled)
{
diff --git a/libsrc/hyperion/SettingsManager.cpp b/libsrc/hyperion/SettingsManager.cpp
index e024aa1b..08f20914 100644
--- a/libsrc/hyperion/SettingsManager.cpp
+++ b/libsrc/hyperion/SettingsManager.cpp
@@ -41,6 +41,7 @@ SettingsManager::SettingsManager(Hyperion* hyperion, const quint8& instance, con
Info(_log, "Selected configuration file: %s", QSTRING_CSTR(configFile));
QJsonSchemaChecker schemaCheckerT;
+ schemaCheckerT.setSchema(schemaJson);
if(!JsonUtils::readFile(configFile, _qconfig, _log))
throw std::runtime_error("Failed to load config!");
@@ -96,6 +97,7 @@ SettingsManager::SettingsManager(const quint8& instance, const QString& configFi
Info(_log, "Selected configuration file: %s", QSTRING_CSTR(configFile));
QJsonSchemaChecker schemaCheckerT;
+ schemaCheckerT.setSchema(schemaJson);
if(!JsonUtils::readFile(configFile, _qconfig, _log))
throw std::runtime_error("Failed to load config!");
diff --git a/libsrc/hyperion/hyperion.schema.json b/libsrc/hyperion/hyperion.schema.json
index 8450773f..ca911742 100644
--- a/libsrc/hyperion/hyperion.schema.json
+++ b/libsrc/hyperion/hyperion.schema.json
@@ -55,6 +55,10 @@
{
"$ref": "schema-flatbufServer.json"
},
+ "protoServer" :
+ {
+ "$ref": "schema-protoServer.json"
+ },
"boblightServer" :
{
"$ref": "schema-boblightServer.json"
diff --git a/libsrc/hyperion/resource.qrc b/libsrc/hyperion/resource.qrc
index 2d8c1c36..575c2d48 100644
--- a/libsrc/hyperion/resource.qrc
+++ b/libsrc/hyperion/resource.qrc
@@ -15,6 +15,7 @@
schema/schema-forwarder.json
schema/schema-jsonServer.json
schema/schema-flatbufServer.json
+ schema/schema-protoServer.json
schema/schema-boblightServer.json
schema/schema-udpListener.json
schema/schema-webConfig.json
diff --git a/libsrc/hyperion/schema/schema-protoServer.json b/libsrc/hyperion/schema/schema-protoServer.json
new file mode 100644
index 00000000..6a70e3f9
--- /dev/null
+++ b/libsrc/hyperion/schema/schema-protoServer.json
@@ -0,0 +1,36 @@
+{
+ "type" : "object",
+ "required" : true,
+ "title" : "edt_conf_pbs_heading_title",
+ "properties" :
+ {
+ "enable" :
+ {
+ "type" : "boolean",
+ "required" : true,
+ "title" : "edt_conf_general_enable_title",
+ "default" : true,
+ "propertyOrder" : 1
+ },
+ "port" :
+ {
+ "type" : "integer",
+ "required" : true,
+ "title" : "edt_conf_general_port_title",
+ "minimum" : 1024,
+ "maximum" : 65535,
+ "default" : 19445
+ },
+ "timeout" :
+ {
+ "type" : "integer",
+ "required" : true,
+ "title" : "edt_conf_pbs_timeout_title",
+ "append" : "edt_append_s",
+ "minimum" : 1,
+ "default" : 5,
+ "propertyOrder" : 3
+ }
+ },
+ "additionalProperties" : false
+}
diff --git a/libsrc/protoserver/CMakeLists.txt b/libsrc/protoserver/CMakeLists.txt
new file mode 100644
index 00000000..541d6045
--- /dev/null
+++ b/libsrc/protoserver/CMakeLists.txt
@@ -0,0 +1,44 @@
+
+# Define the current source locations
+set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/protoserver)
+set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/protoserver)
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${PROTOBUF_INCLUDE_DIRS}
+)
+
+set(ProtoServer_PROTOS ${CURRENT_SOURCE_DIR}/message.proto )
+
+protobuf_generate_cpp(ProtoServer_PROTO_SRCS ProtoServer_PROTO_HDRS ${ProtoServer_PROTOS} )
+
+### Split protoclient from protoserver as protoserver relates to HyperionDaemon and standalone capture binarys can't link to it
+
+add_library(protoclient
+ ${CURRENT_SOURCE_DIR}/ProtoClientConnection.h
+ ${CURRENT_SOURCE_DIR}/ProtoClientConnection.cpp
+ ${ProtoServer_PROTO_SRCS}
+ ${ProtoServer_PROTO_HDRS}
+)
+
+add_library(protoserver
+ ${CURRENT_HEADER_DIR}/ProtoServer.h
+ ${CURRENT_SOURCE_DIR}/ProtoServer.cpp
+)
+
+# disable warnings for auto generated proto files, we can't change the files ....
+SET_SOURCE_FILES_PROPERTIES ( ${ProtoServer_PROTO_SRCS} ${ProtoServer_PROTO_HDRS} ${ProtoServer_PROTOS} PROPERTIES COMPILE_FLAGS -w )
+
+target_link_libraries(protoclient
+ hyperion
+ hyperion-utils
+ protobuf
+ Qt5::Gui
+)
+
+target_link_libraries(protoserver
+ hyperion
+ hyperion-utils
+ protoclient
+ Qt5::Gui
+)
diff --git a/libsrc/protoserver/ProtoClientConnection.cpp b/libsrc/protoserver/ProtoClientConnection.cpp
new file mode 100644
index 00000000..5f67a0be
--- /dev/null
+++ b/libsrc/protoserver/ProtoClientConnection.cpp
@@ -0,0 +1,238 @@
+// project includes
+#include "ProtoClientConnection.h"
+
+// qt
+#include
+#include
+#include
+#include
+
+// Hyperion includes
+#include
+
+
+
+ProtoClientConnection::ProtoClientConnection(QTcpSocket* socket, const int &timeout, QObject *parent)
+ : QObject(parent)
+ , _log(Logger::getInstance("PROTOSERVER"))
+ , _socket(socket)
+ , _clientAddress(socket->peerAddress().toString())
+ , _timeoutTimer(new QTimer(this))
+ , _timeout(timeout * 1000)
+ , _priority()
+ , _hyperion(Hyperion::getInstance())
+{
+ // timer setup
+ _timeoutTimer->setSingleShot(true);
+ _timeoutTimer->setInterval(_timeout);
+ connect(_timeoutTimer, &QTimer::timeout, this, &ProtoClientConnection::forceClose);
+
+ // connect socket signals
+ connect(_socket, &QTcpSocket::readyRead, this, &ProtoClientConnection::readyRead);
+ connect(_socket, &QTcpSocket::disconnected, this, &ProtoClientConnection::disconnected);
+}
+
+void ProtoClientConnection::readyRead()
+{
+ _receiveBuffer += _socket->readAll();
+
+ // check if we can read a message size
+ if (_receiveBuffer.size() <= 4)
+ {
+ return;
+ }
+
+ // read the message size
+ uint32_t messageSize =
+ ((_receiveBuffer[0]<<24) & 0xFF000000) |
+ ((_receiveBuffer[1]<<16) & 0x00FF0000) |
+ ((_receiveBuffer[2]<< 8) & 0x0000FF00) |
+ ((_receiveBuffer[3] ) & 0x000000FF);
+
+ // check if we can read a complete message
+ if ((uint32_t) _receiveBuffer.size() < messageSize + 4)
+ {
+ return;
+ }
+
+ // read a message
+ proto::HyperionRequest message;
+ if (!message.ParseFromArray(_receiveBuffer.data() + 4, messageSize))
+ {
+ sendErrorReply("Unable to parse message");
+ }
+
+ // handle the message
+ handleMessage(message);
+
+ // remove message data from buffer
+ _receiveBuffer = _receiveBuffer.mid(messageSize + 4);
+}
+
+void ProtoClientConnection::forceClose()
+{
+ _socket->close();
+}
+
+void ProtoClientConnection::disconnected()
+{
+ Debug(_log, "Socket Closed");
+ _socket->deleteLater();
+ _hyperion->clear(_priority);
+ emit clientDisconnected();
+}
+
+void ProtoClientConnection::handleMessage(const proto::HyperionRequest & message)
+{
+ switch (message.command())
+ {
+ case proto::HyperionRequest::COLOR:
+ if (!message.HasExtension(proto::ColorRequest::colorRequest))
+ {
+ sendErrorReply("Received COLOR command without ColorRequest");
+ break;
+ }
+ handleColorCommand(message.GetExtension(proto::ColorRequest::colorRequest));
+ break;
+ case proto::HyperionRequest::IMAGE:
+ if (!message.HasExtension(proto::ImageRequest::imageRequest))
+ {
+ sendErrorReply("Received IMAGE command without ImageRequest");
+ break;
+ }
+ handleImageCommand(message.GetExtension(proto::ImageRequest::imageRequest));
+ break;
+ case proto::HyperionRequest::CLEAR:
+ if (!message.HasExtension(proto::ClearRequest::clearRequest))
+ {
+ sendErrorReply("Received CLEAR command without ClearRequest");
+ break;
+ }
+ handleClearCommand(message.GetExtension(proto::ClearRequest::clearRequest));
+ break;
+ case proto::HyperionRequest::CLEARALL:
+ handleClearallCommand();
+ break;
+ default:
+ handleNotImplemented();
+ }
+}
+
+void ProtoClientConnection::handleColorCommand(const proto::ColorRequest &message)
+{
+ // extract parameters
+ int priority = message.priority();
+ int duration = message.has_duration() ? message.duration() : -1;
+ ColorRgb color;
+ color.red = qRed(message.rgbcolor());
+ color.green = qGreen(message.rgbcolor());
+ color.blue = qBlue(message.rgbcolor());
+
+ // make sure the prio is registered before setColor()
+ if(priority != _priority)
+ {
+ _hyperion->clear(_priority);
+ _hyperion->registerInput(priority, hyperion::COMP_PROTOSERVER, "Proto@"+_clientAddress);
+ _priority = priority;
+ }
+
+ // set output
+ _hyperion->setColor(_priority, color, duration);
+
+ // send reply
+ sendSuccessReply();
+}
+
+void ProtoClientConnection::handleImageCommand(const proto::ImageRequest &message)
+{
+ // extract parameters
+ int priority = message.priority();
+ int duration = message.has_duration() ? message.duration() : -1;
+ int width = message.imagewidth();
+ int height = message.imageheight();
+ const std::string & imageData = message.imagedata();
+
+ // make sure the prio is registered before setInput()
+ if(priority != _priority)
+ {
+ _hyperion->clear(_priority);
+ _hyperion->registerInput(priority, hyperion::COMP_PROTOSERVER, "Proto@"+_clientAddress);
+ _priority = priority;
+ }
+
+ // check consistency of the size of the received data
+ if ((int) imageData.size() != width*height*3)
+ {
+ sendErrorReply("Size of image data does not match with the width and height");
+ return;
+ }
+
+ // create ImageRgb
+ Image image(width, height);
+ memcpy(image.memptr(), imageData.c_str(), imageData.size());
+
+ _hyperion->setInputImage(_priority, image, duration);
+
+ // send reply
+ sendSuccessReply();
+}
+
+
+void ProtoClientConnection::handleClearCommand(const proto::ClearRequest &message)
+{
+ // extract parameters
+ int priority = message.priority();
+
+ // clear priority
+ _hyperion->clear(priority);
+ // send reply
+ sendSuccessReply();
+}
+
+void ProtoClientConnection::handleClearallCommand()
+{
+ // clear priority
+ _hyperion->clearall();
+
+ // send reply
+ sendSuccessReply();
+}
+
+
+void ProtoClientConnection::handleNotImplemented()
+{
+ sendErrorReply("Command not implemented");
+}
+
+void ProtoClientConnection::sendMessage(const google::protobuf::Message &message)
+{
+ std::string serializedReply = message.SerializeAsString();
+ uint32_t size = serializedReply.size();
+ uint8_t sizeData[] = {uint8_t(size >> 24), uint8_t(size >> 16), uint8_t(size >> 8), uint8_t(size)};
+ _socket->write((const char *) sizeData, sizeof(sizeData));
+ _socket->write(serializedReply.data(), serializedReply.length());
+ _socket->flush();
+}
+
+void ProtoClientConnection::sendSuccessReply()
+{
+ // create reply
+ proto::HyperionReply reply;
+ reply.set_type(proto::HyperionReply::REPLY);
+ reply.set_success(true);
+
+ // send reply
+ sendMessage(reply);
+}
+
+void ProtoClientConnection::sendErrorReply(const std::string &error)
+{
+ // create reply
+ proto::HyperionReply reply;
+ reply.set_type(proto::HyperionReply::REPLY);
+ reply.set_success(false);
+ reply.set_error(error);
+
+ // send reply
+ sendMessage(reply);
+}
diff --git a/libsrc/protoserver/ProtoClientConnection.h b/libsrc/protoserver/ProtoClientConnection.h
new file mode 100644
index 00000000..d57c2969
--- /dev/null
+++ b/libsrc/protoserver/ProtoClientConnection.h
@@ -0,0 +1,135 @@
+#pragma once
+
+// util
+#include
+#include
+#include
+#include
+
+// protobuffer PROTO
+#include "message.pb.h"
+
+class QTcpSocket;
+class QTimer;
+class Hyperion;
+
+namespace proto {
+class HyperionRequest;
+}
+
+///
+/// The Connection object created by a ProtoServer when a new connection is established
+///
+class ProtoClientConnection : public QObject
+{
+ Q_OBJECT
+
+public:
+ ///
+ /// @brief Construct the client
+ /// @param socket The socket
+ /// @param timeout The timeout when a client is automatically disconnected and the priority unregistered
+ /// @param parent The parent
+ ///
+ explicit ProtoClientConnection(QTcpSocket* socket, const int &timeout, QObject *parent);
+
+signals:
+ ///
+ /// @brief Emits whenever the client disconnected
+ ///
+ void clientDisconnected();
+
+public slots:
+ ///
+ /// @brief close the socket and call disconnected()
+ ///
+ void forceClose();
+
+private slots:
+ ///
+ /// @brief Is called whenever the socket got new data to read
+ ///
+ void readyRead();
+
+ ///
+ /// @brief Is called when the socket closed the connection, also requests thread exit
+ ///
+ void disconnected();
+
+private:
+ ///
+ /// Handle an incoming Proto message
+ ///
+ /// @param message the incoming message as string
+ ///
+ void handleMessage(const proto::HyperionRequest &message);
+
+ ///
+ /// Handle an incoming Proto Color message
+ ///
+ /// @param message the incoming message
+ ///
+ void handleColorCommand(const proto::ColorRequest & message);
+
+ ///
+ /// Handle an incoming Proto Image message
+ ///
+ /// @param message the incoming message
+ ///
+ void handleImageCommand(const proto::ImageRequest & message);
+
+ ///
+ /// Handle an incoming Proto Clear message
+ ///
+ /// @param message the incoming message
+ ///
+ void handleClearCommand(const proto::ClearRequest & message);
+
+ ///
+ /// Handle an incoming Proto Clearall message
+ ///
+ void handleClearallCommand();
+
+ ///
+ /// Handle an incoming Proto message of unknown type
+ ///
+ void handleNotImplemented();
+
+ ///
+ /// Send a message to the connected client
+ ///
+ /// @param message The Proto message to send
+ ///
+ void sendMessage(const google::protobuf::Message &message);
+
+ ///
+ /// Send a standard reply indicating success
+ ///
+ void sendSuccessReply();
+
+ ///
+ /// Send an error message back to the client
+ ///
+ /// @param error String describing the error
+ ///
+ void sendErrorReply(const std::string & error);
+
+private:
+ Logger*_log;
+
+ /// The TCP-Socket that is connected tot the Proto-client
+ QTcpSocket* _socket;
+
+ /// address of client
+ const QString _clientAddress;
+
+ QTimer*_timeoutTimer;
+ int _timeout;
+ int _priority;
+
+ /// Link to Hyperion for writing led-values to a priority channel
+ Hyperion* _hyperion;
+
+ /// The buffer used for reading data from the socket
+ QByteArray _receiveBuffer;
+};
diff --git a/libsrc/protoserver/ProtoServer.cpp b/libsrc/protoserver/ProtoServer.cpp
new file mode 100644
index 00000000..6c2d8152
--- /dev/null
+++ b/libsrc/protoserver/ProtoServer.cpp
@@ -0,0 +1,104 @@
+#include
+#include "ProtoClientConnection.h"
+
+// qt
+#include
+#include
+#include
+
+ProtoServer::ProtoServer(const QJsonDocument& config, QObject* parent)
+ : QObject(parent)
+ , _server(new QTcpServer(this))
+ , _log(Logger::getInstance("PROTOSERVER"))
+ , _timeout(5000)
+ , _config(config)
+{
+
+}
+
+ProtoServer::~ProtoServer()
+{
+ stopServer();
+ delete _server;
+}
+
+void ProtoServer::initServer()
+{
+ connect(_server, &QTcpServer::newConnection, this, &ProtoServer::newConnection);
+
+ // apply config
+ handleSettingsUpdate(settings::PROTOSERVER, _config);
+}
+
+void ProtoServer::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
+{
+ if(type == settings::PROTOSERVER)
+ {
+ const QJsonObject& obj = config.object();
+
+ quint16 port = obj["port"].toInt(19445);
+
+ // port check
+ if(_server->serverPort() != port)
+ {
+ stopServer();
+ _port = port;
+ }
+
+ // new timeout just for new connections
+ _timeout = obj["timeout"].toInt(5000);
+ // enable check
+ obj["enable"].toBool(true) ? startServer() : stopServer();
+ }
+}
+
+void ProtoServer::newConnection()
+{
+ while(_server->hasPendingConnections())
+ {
+ if(QTcpSocket * socket = _server->nextPendingConnection())
+ {
+ Debug(_log, "New connection from %s", QSTRING_CSTR(socket->peerAddress().toString()));
+ ProtoClientConnection * client = new ProtoClientConnection(socket, _timeout, this);
+ // internal
+ connect(client, &ProtoClientConnection::clientDisconnected, this, &ProtoServer::clientDisconnected);
+ _openConnections.append(client);
+ }
+ }
+}
+
+void ProtoServer::clientDisconnected()
+{
+ ProtoClientConnection* client = qobject_cast(sender());
+ client->deleteLater();
+ _openConnections.removeAll(client);
+}
+
+void ProtoServer::startServer()
+{
+ if(!_server->isListening())
+ {
+ if(!_server->listen(QHostAddress::Any, _port))
+ {
+ Error(_log,"Failed to bind port %d", _port);
+ }
+ else
+ {
+ Info(_log,"Started on port %d", _port);
+ }
+ }
+}
+
+void ProtoServer::stopServer()
+{
+ if(_server->isListening())
+ {
+ // close client connections
+ for(const auto& client : _openConnections)
+ {
+ client->forceClose();
+ }
+ _server->close();
+ Info(_log, "Stopped");
+ }
+}
diff --git a/libsrc/protoserver/message.proto b/libsrc/protoserver/message.proto
new file mode 100644
index 00000000..9652453e
--- /dev/null
+++ b/libsrc/protoserver/message.proto
@@ -0,0 +1,80 @@
+package proto;
+
+message HyperionRequest {
+ enum Command {
+ COLOR = 1;
+ IMAGE = 2;
+ CLEAR = 3;
+ CLEARALL = 4;
+ }
+
+ // command specification
+ required Command command = 1;
+
+ // extensions to define all specific requests
+ extensions 10 to 100;
+}
+
+message ColorRequest {
+ extend HyperionRequest {
+ optional ColorRequest colorRequest = 10;
+ }
+
+ // priority to use when setting the color
+ required int32 priority = 1;
+
+ // integer value containing the rgb color (0x00RRGGBB)
+ required int32 RgbColor = 2;
+
+ // duration of the request (negative results in infinite)
+ optional int32 duration = 3;
+}
+
+message ImageRequest {
+ extend HyperionRequest {
+ optional ImageRequest imageRequest = 11;
+ }
+
+ // priority to use when setting the image
+ required int32 priority = 1;
+
+ // width of the image
+ required int32 imagewidth = 2;
+
+ // height of the image
+ required int32 imageheight = 3;
+
+ // image data
+ required bytes imagedata = 4;
+
+ // duration of the request (negative results in infinite)
+ optional int32 duration = 5;
+}
+
+message ClearRequest {
+ extend HyperionRequest {
+ optional ClearRequest clearRequest = 12;
+ }
+
+ // priority which need to be cleared
+ required int32 priority = 1;
+}
+
+message HyperionReply {
+ enum Type {
+ REPLY = 1;
+ VIDEO = 2;
+ }
+
+ // Identifies which field is filled in.
+ required Type type = 1;
+
+ // flag indication success or failure
+ optional bool success = 2;
+
+ // string indicating the reason for failure (if applicable)
+ optional string error = 3;
+
+ // Proto Messages for video mode
+ optional int32 video = 4;
+}
diff --git a/libsrc/udplistener/UDPListener.cpp b/libsrc/udplistener/UDPListener.cpp
index 60c4e3cb..678735f4 100644
--- a/libsrc/udplistener/UDPListener.cpp
+++ b/libsrc/udplistener/UDPListener.cpp
@@ -5,6 +5,7 @@
#include
// hyperion includes
+#include
#include "HyperionConfig.h"
// qt includes
@@ -22,6 +23,9 @@ UDPListener::UDPListener(const QJsonDocument& config) :
_isActive(false),
_listenPort(0)
{
+ // listen for component change
+ connect(Hyperion::getInstance(), &Hyperion::componentStateChanged, this, &UDPListener::componentStateChanged);
+
// init
handleSettingsUpdate(settings::UDPLISTENER, config);
}
@@ -70,6 +74,8 @@ void UDPListener::start()
_serviceRegister->registerService("_hyperiond-udp._udp", _listenPort);
}
}
+
+ Hyperion::getInstance()->getComponentRegister().componentStateChanged(COMP_UDPLISTENER, _isActive);
}
void UDPListener::stop()
@@ -80,7 +86,7 @@ void UDPListener::stop()
_server->close();
_isActive = false;
Info(_log, "Stopped");
-// emit clearGlobalPriority(_priority, hyperion::COMP_UDPLISTENER);
+ Hyperion::getInstance()->getComponentRegister().componentStateChanged(COMP_UDPLISTENER, _isActive);
}
void UDPListener::componentStateChanged(const hyperion::Components component, bool enable)
diff --git a/src/hyperiond/CMakeLists.txt b/src/hyperiond/CMakeLists.txt
index b755e106..ebaf09b0 100644
--- a/src/hyperiond/CMakeLists.txt
+++ b/src/hyperiond/CMakeLists.txt
@@ -1,4 +1,5 @@
find_package(PythonLibs 3.4 REQUIRED)
+find_package(Qt5Widgets REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}/..)
add_executable(hyperiond
@@ -16,6 +17,7 @@ target_link_libraries(hyperiond
jsonserver
udplistener
flatbufserver
+ protoserver
webserver
bonjour
ssdp
@@ -66,6 +68,8 @@ if (ENABLE_QT)
target_link_libraries(hyperiond qt-grabber)
endif ()
+target_link_libraries(hyperiond Qt5::Widgets)
+
install ( TARGETS hyperiond DESTINATION "share/hyperion/bin/" COMPONENT "${PLATFORM}" )
install ( DIRECTORY ${CMAKE_SOURCE_DIR}/bin/service DESTINATION "share/hyperion/" COMPONENT "${PLATFORM}" )
install ( FILES ${CMAKE_SOURCE_DIR}/effects/readme.txt DESTINATION "share/hyperion/effects" COMPONENT "${PLATFORM}" )
diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp
index 7cbf64ab..d2c05e3c 100644
--- a/src/hyperiond/hyperiond.cpp
+++ b/src/hyperiond/hyperiond.cpp
@@ -26,9 +26,12 @@
#include // Required to determine the cmake options
#include "hyperiond.h"
-// FlatBufferServer
+// Flatbuffer Server
#include
+// Protobuffer Server
+#include
+
// bonjour browser
#include
@@ -145,6 +148,8 @@ void HyperionDaemon::freeObjects()
delete _jsonServer;
_flatBufferServer->thread()->quit();
_flatBufferServer->thread()->wait(1000);
+ _protoServer->thread()->quit();
+ _protoServer->thread()->wait(1000);
//ssdp before webserver
_ssdp->thread()->quit();
_ssdp->thread()->wait(1000);
@@ -166,17 +171,18 @@ void HyperionDaemon::freeObjects()
_v4l2Grabbers.clear();
_bonjourBrowserWrapper = nullptr;
- _amlGrabber = nullptr;
- _dispmanx = nullptr;
- _fbGrabber = nullptr;
- _osxGrabber = nullptr;
- _qtGrabber = nullptr;
- _flatBufferServer = nullptr;
- _ssdp = nullptr;
- _webserver = nullptr;
- _jsonServer = nullptr;
- _udpListener = nullptr;
- _stats = nullptr;
+ _amlGrabber = nullptr;
+ _dispmanx = nullptr;
+ _fbGrabber = nullptr;
+ _osxGrabber = nullptr;
+ _qtGrabber = nullptr;
+ _flatBufferServer = nullptr;
+ _protoServer = nullptr;
+ _ssdp = nullptr;
+ _webserver = nullptr;
+ _jsonServer = nullptr;
+ _udpListener = nullptr;
+ _stats = nullptr;
}
void HyperionDaemon::startNetworkServices()
@@ -198,6 +204,16 @@ void HyperionDaemon::startNetworkServices()
connect(this, &HyperionDaemon::settingsChanged, _flatBufferServer, &FlatBufferServer::handleSettingsUpdate);
fbThread->start();
+ // Create Proto server in thread
+ _protoServer = new ProtoServer(getSetting(settings::PROTOSERVER));
+ QThread* pThread = new QThread(this);
+ _protoServer->moveToThread(pThread);
+ connect( pThread, &QThread::started, _protoServer, &ProtoServer::initServer );
+ connect( pThread, &QThread::finished, _protoServer, &QObject::deleteLater );
+ connect( pThread, &QThread::finished, pThread, &QObject::deleteLater );
+ connect(this, &HyperionDaemon::settingsChanged, _protoServer, &ProtoServer::handleSettingsUpdate);
+ pThread->start();
+
// Create UDP listener
_udpListener = new UDPListener(getSetting(settings::UDPLISTENER));
connect(this, &HyperionDaemon::settingsChanged, _udpListener, &UDPListener::handleSettingsUpdate);
@@ -411,13 +427,8 @@ void HyperionDaemon::handleSettingsUpdate(const settings::type& type, const QJso
connect(this, &HyperionDaemon::settingsChanged, grabber, &V4L2Wrapper::handleSettingsUpdate);
if (enableV4l)
- {
v4lEnableCount++;
- // init
- grabber->setDeviceVideoStandard(grabberConfig["device"].toString("auto"), parseVideoStandard(grabberConfig["standard"].toString("no-change")));
- }
-
_v4l2Grabbers.push_back(grabber);
#endif
}
diff --git a/src/hyperiond/hyperiond.h b/src/hyperiond/hyperiond.h
index 3fb18916..1aaee749 100644
--- a/src/hyperiond/hyperiond.h
+++ b/src/hyperiond/hyperiond.h
@@ -63,6 +63,7 @@ class SettingsManager;
class PythonInit;
class SSDPHandler;
class FlatBufferServer;
+class ProtoServer;
class HyperionDaemon : public QObject
{
@@ -130,33 +131,34 @@ private:
void createGrabberX11(const QJsonObject & grabberConfig);
void createGrabberQt(const QJsonObject & grabberConfig);
- Logger* _log;
- BonjourBrowserWrapper* _bonjourBrowserWrapper;
- PythonInit* _pyInit;
- WebServer* _webserver;
- JsonServer* _jsonServer;
- UDPListener* _udpListener;
+ Logger* _log;
+ BonjourBrowserWrapper* _bonjourBrowserWrapper;
+ PythonInit* _pyInit;
+ WebServer* _webserver;
+ JsonServer* _jsonServer;
+ UDPListener* _udpListener;
std::vector _v4l2Grabbers;
- DispmanxWrapper* _dispmanx;
- X11Wrapper* _x11Grabber;
- AmlogicWrapper* _amlGrabber;
- FramebufferWrapper* _fbGrabber;
- OsxWrapper* _osxGrabber;
- QtWrapper* _qtGrabber;
- Hyperion* _hyperion;
- Stats* _stats;
- SSDPHandler* _ssdp;
- FlatBufferServer* _flatBufferServer;
+ DispmanxWrapper* _dispmanx;
+ X11Wrapper* _x11Grabber;
+ AmlogicWrapper* _amlGrabber;
+ FramebufferWrapper* _fbGrabber;
+ OsxWrapper* _osxGrabber;
+ QtWrapper* _qtGrabber;
+ Hyperion* _hyperion;
+ Stats* _stats;
+ SSDPHandler* _ssdp;
+ FlatBufferServer* _flatBufferServer;
+ ProtoServer* _protoServer;
- unsigned _grabber_width;
- unsigned _grabber_height;
- unsigned _grabber_frequency;
- unsigned _grabber_cropLeft;
- unsigned _grabber_cropRight;
- unsigned _grabber_cropTop;
- unsigned _grabber_cropBottom;
- int _grabber_ge2d_mode;
- QString _grabber_device;
+ unsigned _grabber_width;
+ unsigned _grabber_height;
+ unsigned _grabber_frequency;
+ unsigned _grabber_cropLeft;
+ unsigned _grabber_cropRight;
+ unsigned _grabber_cropTop;
+ unsigned _grabber_cropBottom;
+ int _grabber_ge2d_mode;
+ QString _grabber_device;
QString _prevType;