diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b0f98e1..fdfcb92b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,32 +6,118 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/hyperion-project/hyperion.ng/compare/2.0.0-alpha.9...HEAD) +The focus of this release is on user experience. +We tried as much as possible supporting you in getting valid setup done, as well as providing enough room for expert users to tweak configurations here and there. +The reworked dashboard provides you now with the ability to control individual components, jump to key configuration items, as well as to switch between LED instances easily. +The refined color coding in the user-interfaces, helps you to quickly identify instance specific and global configuration items. + +Of course, the release brings new features (e.g. USB Capture on Windows), as well as minor enhancements and a good number of fixes. + +Note: + +- Hyperion packages can now be installed under Ubuntu (x64) and Debian (amd64/armhf) (incl. Raspberry Pi OS) via our own APT server. +Details about the installation can be found in the [installation.md](https://github.com/hyperion-project/hyperion.ng/blob/master/Installation.md) and at [apt.hyperion-project.org](apt.hyperion-project.org). +- Find here more details on [supported platforms and configuration sets](https://github.com/hyperion-project/hyperion.ng/blob/master/doc/development/SupportedPlatforms.md) + ### Breaking ### Added -- LED-Devices: basic support for Hue Play Gradient Lightstrip -- WLED: Support of ["live" property] (https://github.com/Aircoookie/WLED/issues/1308), addresses #1095 -- WLED: Support storing/restoring state, fixes #1101 -- LED-Devices: Allow to get properties for Atmo and Karatedevices to limit LED numbers configurable -- LED-Devices: Add timeouts for REST-API calls -- new Flags: Russia, Cameroon, Great Britain, England, Scotland +- The Dashboard is now a one-stop control element to control instances and link into configuration areas +- LED Instance independent configuration objects (e.g. capturing hardware) are now separated out in the menu +- New menu item "Sources" per LED instances configuration to enable/disable screen or usb grabber per instance + +#### Grabbers +- Windows Media Foundation USB grabber (incl. Media Foundation transform/Turbo-JPEG scaling) +- Linux V4L2 Grabber now supports the following formats: NV12, YUV420 +- Image flipping ability in ImageResampler/Turbo-JPEG +- UI: Simplified screens for non-expert usage, do only show elements relevant +- Discover available Grabbers (incl. their capabilities for selection), not supported grabbers are not presented. Note: Screen capturing on Wayland is not supported (given the Wayland security architecture) +- USB Grabber: New ability to configure hardware controls (brightness, contrast, saturation, hue), as well as populating defaults +- Configuration item ranges are automatically adopted based on grabber capabilities, +- Grabbers can only be saved with a valid configuration +- Standalone grabbers: Added consistent options/capabilities for standalone grabbers, debug logging support +- Screen grabbers: Allow to set capture frequency, size decimation and cropping across all grabber types +- Screen grabber: QT-Grabber allows to capture individual displays or all displays in a multi-display setup +- Display Signal Detection area in preview (expert users) +- UI: Only show CEC detection, if supported by platform + +#### LED-Devices +- Select device from list of available devices (UI Optimization - Select device from list of available devices #1053) - Cololight, Nanoleaf, Serial Devices (e.g. Adalight), SPI-Device, Pi-Blaster +- Get device properties for automatic configuration of number of LEDs and initial layout (WLED, Cololight, Nanoleaf) +- Identify/Test device (WLED, Cololight, Nanoleaf, Adalight) +- For selected devices a default layout configuration is created, if the user chooses "Overwrite" (WLED, Cololight, Nanoleaf, all serial devices, all spi device, pi-blaster) +- Ensure Hardware LED count matches number of lights (Philips Hue, Yeelight, Atmo Orb) +- User is presented a warning/error, if there is a mismatch between configured LED number and available hardware LEDs +- Add udev support for Serial-Devices +- Allow to get properties for Atmo and Karatedevices to limit LED numbers configurable +- Philips Hue: Add basic support for the Play Gradient Lightstrip +- WLED: Support of ["live" property] (https://github.com/Aircoookie/WLED/issues/1308) (#1095) +- WLED: Brightness overwrite control by configuration +- WLED: Allow to disable WLED synchronization when streaming via hyperion +- WLED: Support storing/restoring state (#1101) +- Adalight: Fix LED Num for non analogue output in arduino firmware + +- Allow to blacklist LEDs in layout via UI +- Live Video image to LedLayout preview (#1136) + +#### Other + +- Effects: Support Custom Effect Templates in UI for custom effect creation and configuration +- Effects: Custom effect separation in the systray menu + +- New languages - Portuguese (Std/Brazil) & Norwegian (Bokmål) +- New Flags: Russia, Cameroon, Great Britain, England, Scotland + +- Provide cross compilation on x86_64 for developers using docker. This includes the ability to use local code, as well as build incrementally ### Changed -- Updated dependency rpi_ws281x to latest upstream -- Fix High CPU load (RPI3B+) (#1013) -- Nanoleaf: Consider Nanoleaf-Shape Controlers + +- Grabbers use now precise timings for better timing accuracy + +- Nanoleaf: Consider Nanoleaf-Shape Controllers - LED-Devices: Show HW-Ledcount in all setting levels -- Documentation: Add link to [Hyperion-py](https://github.com/dermotduffy/hyperion-py) +- System Log Screen: Support to copy loglines, system info and status of the current instance to the clipboard (to share it for investigation) + +- Updated dependency rpi_ws281x to latest upstream +- Fix High CPU load (RPI3B+) (#1013) ### Fixed -- Fix issue #1127: LED-Devices: Correct total packet count in tpm2net implementation -- LED-Hue: Proper black in Entertainement mode if min brightness is set +- Active grabbers are displayed correctly after updating the WebUI +- Issue Crop values are checked against decimated resolution (#1160) +- Framebuffer grabber is deactivated in case of error +- Fix/no signal detection (#1087) + +- Fix that global settings were not correctly reflected across instances after updates in other non default instance (#1131,#1186,#1188) +- Fix UI: Handle error scenario properly, when last instance number used does not exist any longer. +- UI Allow to have password handled by Password-Manager (#1263) + +- Fixed effect freezing during startup +- Effects were not started from tray (#1199) +- Interrupt effect on timeout (#1013) +- Fixed color and effect handling and duplicate priorities (#993,#1113,#1216) +- Stop background effect, when it gets out of scope (to not use resources unnecessarily) +- Custom Effect Templates (schemas) are now loaded +- Effects: Uploaded images were not found executing custom image effects +- "LED Test" effect description is in wrong order (#1229) + +- LED-Devices: Only consider Hardware LED count (#673) +- LED-Devices: Correct total packet count in tpm2net implementation (#1127) +- LED-Hue: Proper black in Entertainment mode if min brightness is set - LED-Hue: Minor fix of setColor command -- Nanoleaf: Fix,if external control mode cannot be set -- Fix issue #1229: "LED Test" effect description is in wrong order +- Nanoleaf: Fixed behaviour, if external control mode cannot be set + +- System Log Screen: Fixed Auto-Scrolling, Update Look & Feel, Works across multiple Browser tabs/windows, as log stream is not stopped by a new UI + +- Rename Instance and Change Password: Modal did not close +- Read-Only mode was not handled in the SysInfo function + +- WebSockets: Handling of fragmented frames fixed +- Fixed libcec dependencies + +- General language and grammar updates ### Removed diff --git a/assets/webconfig/content/login.html b/assets/webconfig/content/login.html index f6c371dc..2e68b7ab 100644 --- a/assets/webconfig/content/login.html +++ b/assets/webconfig/content/login.html @@ -8,12 +8,12 @@
- - +
+
- +
@@ -26,8 +26,12 @@ removeOverlay(); $('#password').off().on('input', function (e) { - if (e.currentTarget.value.length >= 8) - $('#btn_password').removeAttr('disabled'); + if (e.currentTarget.value.length >= 8) { + $('#btn_password').prop('disabled', false); + } + else { + $('#btn_password').prop('disabled', true); + } }); $('#show_pw').off().on('change', function (e) { diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index e5bb52ba..2cb042c5 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -11,7 +11,9 @@ "InfoDialog_nowrite_text": "Hyperion can't write to your current loaded configuration file. Please repair the file permissions to proceed.", "InfoDialog_nowrite_title": "write permission error!", "infoDialog_password_current_text": "Current password", + "infoDialog_password_minimum_length": "Passwords must be minimum 8 characters.", "infoDialog_password_new_text": "New password", + "infoDialog_username_text": "Username", "about_3rd_party_licenses": "3rd party licenses", "about_3rd_party_licenses_error": "We had trouble collecting 3rd party licenses information from web.
Please follow this link to the GitHub Resource.", "about_build": "Build", @@ -464,17 +466,17 @@ "edt_conf_v4l2_flip_expl": "This allows you to flip the image horizontally, vertically, or both.", "edt_conf_v4l2_flip_title": "Image flip", "edt_conf_v4l2_fpsSoftwareDecimation_title": "Software frame skipping", - "edt_conf_v4l2_fpsSoftwareDecimation_expl": "To save resources every n'th frame will be processed only. For ex. if grabber is set to 30FPS with this option set to 5 the final result will be around 6FPS (1 - disabled)", + "edt_conf_v4l2_fpsSoftwareDecimation_expl": "To save resources every n'th frame will be processed only. For ex. if grabber is set to 30fps with this option set to 5 the final result will be around 6fps", "edt_conf_v4l2_encoding_title": "Encoding format", "edt_conf_v4l2_encoding_expl": "Force video encoding for multiformat capable grabbers", "edt_conf_v4l2_hardware_brightness_title": "Hardware brightness control", - "edt_conf_v4l2_hardware_brightness_expl": "Set hardware brightness if device supports it, check logs (0=disabled)", + "edt_conf_v4l2_hardware_brightness_expl": "Set hardware brightness", "edt_conf_v4l2_hardware_contrast_title": "Hardware contrast control", - "edt_conf_v4l2_hardware_contrast_expl": "Set hardware contrast if device supports it, check logs (0=disabled)", + "edt_conf_v4l2_hardware_contrast_expl": "Set hardware contrast", "edt_conf_v4l2_hardware_hue_title": "Hardware hue control", - "edt_conf_v4l2_hardware_hue_expl": "Set hardware hue if device supports it, check logs (0=disabled)", + "edt_conf_v4l2_hardware_hue_expl": "Set hardware hue", "edt_conf_v4l2_hardware_saturation_title": "Hardware saturation control", - "edt_conf_v4l2_hardware_saturation_expl": "Set hardware saturation if device supports it, check logs (0=disabled)", + "edt_conf_v4l2_hardware_saturation_expl": "Set hardware saturation", "edt_conf_v4l2_hardware_set_defaults": "Default hardware controls", "edt_conf_v4l2_hardware_set_defaults_tip": "Set device's default values for brightness, contrast, hue and saturation", "edt_conf_v4l2_noSignalCounterThreshold_title": "Signal Counter Threshold", diff --git a/assets/webconfig/js/content_colors.js b/assets/webconfig/js/content_colors.js index 39bb8a4f..abd35f0b 100755 --- a/assets/webconfig/js/content_colors.js +++ b/assets/webconfig/js/content_colors.js @@ -22,7 +22,7 @@ $(document).ready(function () { //blackborder $('#conf_cont').append(createRow('conf_cont_blackborder')); $('#conf_cont_blackborder').append(createOptPanel('fa-photo', $.i18n("edt_conf_bb_heading_title"), 'editor_container_blackborder', 'btn_submit_blackborder')); - $('#conf_cont_blackborder').append(createHelpTable(window.schema.blackborderdetector.properties, $.i18n("edt_conf_bb_heading_title"), "blackborderHelpPanelId")) + $('#conf_cont_blackborder').append(createHelpTable(window.schema.blackborderdetector.properties, $.i18n("edt_conf_bb_heading_title"), "blackborderHelpPanelId")); } else { $('#conf_cont').addClass('row'); diff --git a/assets/webconfig/js/content_dashboard.js b/assets/webconfig/js/content_dashboard.js index 4ef8d069..129bdf26 100644 --- a/assets/webconfig/js/content_dashboard.js +++ b/assets/webconfig/js/content_dashboard.js @@ -10,7 +10,7 @@ $(document).ready(function () { instances_html += ''; instances_html += '
'; instances_html += '
'; - instances_html += '
' + instances_html += ''; instances_html += ''; instances_html += '
'; @@ -114,7 +114,7 @@ $(document).ready(function () { var jsonPort = window.serverConfig.jsonServer.port; $('#dash_jsonPort').html(jsonPort); - var wsPorts = window.serverConfig.webConfig.port + ' | ' + window.serverConfig.webConfig.sslPort + var wsPorts = window.serverConfig.webConfig.port + ' | ' + window.serverConfig.webConfig.sslPort; $('#dash_wsPorts').html(wsPorts); $('#dash_currv').html(window.currentVersion); diff --git a/assets/webconfig/js/content_grabber.js b/assets/webconfig/js/content_grabber.js index 36003c31..089837bb 100755 --- a/assets/webconfig/js/content_grabber.js +++ b/assets/webconfig/js/content_grabber.js @@ -205,7 +205,7 @@ $(document).ready(function () { if (enumVals.length > 0) { if (deviceSelected === configuredDevice) { var configuredResolutionText = window.serverConfig.framegrabber.width + "x" + window.serverConfig.framegrabber.height; - var idx = $.inArray(configuredResolutionText, enumTitelVals) + var idx = $.inArray(configuredResolutionText, enumTitelVals); if (idx != -1) { enumDefaultVal = idx.toString(); } @@ -266,6 +266,10 @@ $(document).ready(function () { if ($.inArray(configuredFps, enumVals) != -1) { enumDefaultVal = configuredFps; } + } else if (deviceProperties.hasOwnProperty('default') && !jQuery.isEmptyObject(deviceProperties.default.video_input)) { + if (deviceProperties.default.video_input.resolution.fps) { + enumDefaultVal = deviceProperties.default.video_input.resolution.fps; + } } updateJsonEditorSelection(conf_editor_screen, 'root.framegrabber', 'framerates', addSchemaElements, enumVals, [], enumDefaultVal, false); @@ -413,7 +417,7 @@ $(document).ready(function () { contrast: { current: window.serverConfig.grabberV4L2.hardware_contrast }, saturation: { current: window.serverConfig.grabberV4L2.hardware_saturation }, hue: { current: window.serverConfig.grabberV4L2.hardware_hue } - } + }; deviceProperties.properties = properties; } } @@ -551,7 +555,7 @@ $(document).ready(function () { if (enumVals.length > 0) { if (deviceSelected === configuredDevice) { var configuredResolutionText = window.serverConfig.grabberV4L2.width + "x" + window.serverConfig.grabberV4L2.height; - var idx = $.inArray(configuredResolutionText, enumTitelVals) + var idx = $.inArray(configuredResolutionText, enumTitelVals); if (idx != -1) { enumDefaultVal = idx.toString(); } @@ -719,7 +723,7 @@ $(document).ready(function () { updateJsonEditorSelection(conf_editor_screen, 'root.framegrabber', 'available_devices', {}, enumVals, enumTitelVals, enumDefaultVal, addSelect, false); } - } + }; // build dynamic video input enum var updateVideoSourcesList = function (type, discoveryInfo) { @@ -763,7 +767,7 @@ $(document).ready(function () { else { discoveryResult = { "video_sources": [] - } + }; } switch (type) { diff --git a/assets/webconfig/js/content_leds.js b/assets/webconfig/js/content_leds.js index 92a6a494..a99b68af 100755 --- a/assets/webconfig/js/content_leds.js +++ b/assets/webconfig/js/content_leds.js @@ -884,6 +884,8 @@ $(document).ready(function () { break; default: conf_editor.getEditor(specOptPath + "host").disable(); + //Reset host value, to trigger getProperties via host value + conf_editor.getEditor(specOptPath + "host").setValue(""); conf_editor.getEditor(specOptPath + "host").setValue(val); break; } @@ -1199,7 +1201,8 @@ function saveLedConfig(genDefLayout = false) { result.smoothing = { enable: false }; if (genDefLayout === true) { - if (devicesProperties[ledType][host].modelType === "Strip") { + + if (!jQuery.isEmptyObject(devicesProperties) && devicesProperties[ledType][host].modelType === "Strip") { ledConfig = { "classic": { "top": hardwareLedCount / 2, @@ -1269,8 +1272,6 @@ function saveLedConfig(genDefLayout = false) { break; } - - //Rewrite whole LED & Layout configuration, in case changes were done accross tabs and no default layout if (genDefLayout !== true) { result.ledConfig = getLedConfig(); @@ -1283,7 +1284,6 @@ function saveLedConfig(genDefLayout = false) { // build dynamic enum var updateSelectList = function (ledType, discoveryInfo) { - // Only update, if ledType is equal of selected controller type and discovery info exists if (ledType !== $("#leddevices").val() || !discoveryInfo.devices) { return; @@ -1369,19 +1369,18 @@ var updateSelectList = function (ledType, discoveryInfo) { else { enumTitelVals.push(host); } + } - addCustom = true; - - // Select configured device - var configuredDeviceType = window.serverConfig.device.type; - var configuredHost = window.serverConfig.device.hostList; - if (ledType === configuredDeviceType && $.inArray(configuredHost, enumVals) != -1) { - enumDefaultVal = configuredHost; - } - else { - addSelect = true; - addCustom = true; - } + //Always allow to add custom configuration + addCustom = true; + // Select configured device + var configuredDeviceType = window.serverConfig.device.type; + var configuredHost = window.serverConfig.device.hostList; + if (ledType === configuredDeviceType && $.inArray(configuredHost, enumVals) != -1) { + enumDefaultVal = configuredHost; + } + else { + addSelect = true; } } break; diff --git a/assets/webconfig/js/ledsim.js b/assets/webconfig/js/ledsim.js index 541cbc6f..4838870a 100644 --- a/assets/webconfig/js/ledsim.js +++ b/assets/webconfig/js/ledsim.js @@ -17,8 +17,8 @@ $(document).ready(function () { var activeComponent = ""; - const image = new Image() - image.src = "img/hyperion/logo_negativ.png", + const image = new Image(); + image.src = "img/hyperion/logo_negativ.png"; /// add prototype for simple canvas clear() method CanvasRenderingContext2D.prototype.clear = function () { diff --git a/assets/webconfig/js/settings.js b/assets/webconfig/js/settings.js index ba746b53..68a9beec 100644 --- a/assets/webconfig/js/settings.js +++ b/assets/webconfig/js/settings.js @@ -7,17 +7,18 @@ function changePassword(){ // fill default pw if default is set if(window.defaultPasswordIsSet) - $('#oldPw').val('hyperion') + $('#current-password').val('hyperion') $('#id_btn_ok').off().on('click',function() { - var oldPw = $('#oldPw').val(); - var newPw = $('#newPw').val(); + var oldPw = $('#current-password').val(); + var newPw = $('#new-password').val(); - requestChangePassword(oldPw, newPw) + requestChangePassword(oldPw, newPw); + history.pushState({}, "New password"); }); - $('#newPw, #oldPw').off().on('input',function(e) { - ($('#oldPw').val().length >= 8 && $('#newPw').val().length >= 8) && !window.readOnlyMode ? $('#id_btn_ok').attr('disabled', false) : $('#id_btn_ok').attr('disabled', true); + $('#new-password, #current-password').off().on('input',function(e) { + ($('#current-password').val().length >= 8 && $('#new-password').val().length >= 8) && !window.readOnlyMode ? $('#id_btn_ok').attr('disabled', false) : $('#id_btn_ok').attr('disabled', true); }); } diff --git a/assets/webconfig/js/ui_utils.js b/assets/webconfig/js/ui_utils.js index 9c9d49fe..f8f46844 100644 --- a/assets/webconfig/js/ui_utils.js +++ b/assets/webconfig/js/ui_utils.js @@ -288,11 +288,14 @@ function showInfoDialog(type, header, message) { else if (type == "changePassword") { $('#id_body_rename').html('
'); $('#id_body_rename').append('

' + header + '


'); - $('#id_body_rename').append('

' + $.i18n('infoDialog_password_current_text') + - '


'); - $('#id_body_rename').append('

' + $.i18n('infoDialog_password_new_text')+ - '

'); - $('#id_footer_rename').html(''); + $('#id_body_rename').append('

' + $.i18n('infoDialog_username_text') + + '


'); + $('#id_body_rename').append('

' + $.i18n('infoDialog_password_current_text') + + '


'); + $('#id_body_rename').append('

' + $.i18n('infoDialog_password_new_text')+ + '

'); + $('#id_body_rename').append('
' + $.i18n('infoDialog_password_minimum_length') + '
'); + $('#id_footer_rename').html('
'); $('#id_footer_rename').append(''); } else if (type == "checklist") { diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index e00395b3..7efc183d 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -1,5 +1,5 @@ macro(DeployUnix TARGET) - if(EXISTS ${TARGET_FILE}) + if (EXISTS ${TARGET_FILE}) message(STATUS "Collecting Dependencies for target file: ${TARGET_FILE}") include(GetPrerequisites) @@ -27,7 +27,7 @@ macro(DeployUnix TARGET) "libz" ) - if(ENABLE_DISPMANX) + if (ENABLE_DISPMANX) list(APPEND SYSTEM_LIBS_SKIP "libcec") endif() @@ -89,9 +89,9 @@ macro(DeployUnix TARGET) ) # Copy Qt plugins to 'share/hyperion/lib' - if(QT_PLUGINS_DIR) + if (QT_PLUGINS_DIR) foreach(PLUGIN "platforms" "sqldrivers" "imageformats") - if(EXISTS ${QT_PLUGINS_DIR}/${PLUGIN}) + if (EXISTS ${QT_PLUGINS_DIR}/${PLUGIN}) file(GLOB files "${QT_PLUGINS_DIR}/${PLUGIN}/*") foreach(file ${files}) get_prerequisites(${file} PLUGINS 0 1 "" "") @@ -189,7 +189,7 @@ macro(DeployUnix TARGET) endmacro() macro(DeployWindows TARGET) - if(EXISTS ${TARGET_FILE}) + if (EXISTS ${TARGET_FILE}) message(STATUS "Collecting Dependencies for target file: ${TARGET_FILE}") find_package(Qt5Core REQUIRED) find_package(OpenSSL REQUIRED) @@ -248,7 +248,7 @@ macro(DeployWindows TARGET) list(GET openssl_versions 1 openssl_version_minor) set(library_suffix "-${openssl_version_major}_${openssl_version_minor}") - if(CMAKE_SIZEOF_VOID_P EQUAL 8) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) string(APPEND library_suffix "-x64") endif() @@ -272,25 +272,29 @@ macro(DeployWindows TARGET) endif(OPENSSL_FOUND) # Copy libjpeg-turbo to 'hyperion' - if (ENABLE_MF AND TURBOJPEG_FOUND) - find_file(TURBOJPEG_DLL - NAMES "turbojpeg.dll" - PATHS ${TurboJPEG_INCLUDE_DIRS}/.. ${TurboJPEG_INCLUDE_DIRS}/../bin - NO_DEFAULT_PATH - ) + if (ENABLE_MF) + find_package(TurboJPEG) - find_file(JPEG_DLL - NAMES "jpeg62.dll" - PATHS ${TurboJPEG_INCLUDE_DIRS}/.. ${TurboJPEG_INCLUDE_DIRS}/../bin - NO_DEFAULT_PATH - ) + if (TURBOJPEG_FOUND) + find_file(TURBOJPEG_DLL + NAMES "turbojpeg.dll" + PATHS ${TurboJPEG_INCLUDE_DIRS}/.. ${TurboJPEG_INCLUDE_DIRS}/../bin + NO_DEFAULT_PATH + ) - install( - FILES ${TURBOJPEG_DLL} ${JPEG_DLL} - DESTINATION "bin" - COMPONENT "Hyperion" - ) - endif() + find_file(JPEG_DLL + NAMES "jpeg62.dll" + PATHS ${TurboJPEG_INCLUDE_DIRS}/.. ${TurboJPEG_INCLUDE_DIRS}/../bin + NO_DEFAULT_PATH + ) + + install( + FILES ${TURBOJPEG_DLL} ${JPEG_DLL} + DESTINATION "bin" + COMPONENT "Hyperion" + ) + endif(TURBOJPEG_FOUND) + endif(ENABLE_MF) # Create a qt.conf file in 'bin' to override hard-coded search paths in Qt plugins file(WRITE "${CMAKE_BINARY_DIR}/qt.conf" "[Paths]\nPlugins=../lib/\n") @@ -300,12 +304,12 @@ macro(DeployWindows TARGET) COMPONENT "Hyperion" ) - # Download embed python package + # Download embed python package (only release build package available) # Currently only cmake version >= 3.12 implemented set(url "https://www.python.org/ftp/python/${Python3_VERSION}/") set(filename "python-${Python3_VERSION}-embed-amd64.zip") - if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${filename}" OR NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/python") + if (NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${filename}" OR NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/python") file(DOWNLOAD "${url}${filename}" "${CMAKE_CURRENT_BINARY_DIR}/${filename}" STATUS result ) @@ -339,17 +343,17 @@ macro(DeployWindows TARGET) ) endforeach() - if(ENABLE_DX) + if (ENABLE_DX) # Download DirectX End-User Runtimes (June 2010) set(url "https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe") - if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/dx_redist.exe") + if (NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/dx_redist.exe") file(DOWNLOAD "${url}" "${CMAKE_CURRENT_BINARY_DIR}/dx_redist.exe" STATUS result ) # Check if the download is successful list(GET result 0 result_code) - if(NOT result_code EQUAL 0) + if (NOT result_code EQUAL 0) list(GET result 1 reason) message(FATAL_ERROR "Could not download DirectX End-User Runtimes: ${reason}") endif() diff --git a/cmake/nsis/header.bmp b/cmake/nsis/header.bmp index dcd1d643..29c7db77 100644 Binary files a/cmake/nsis/header.bmp and b/cmake/nsis/header.bmp differ diff --git a/libsrc/grabber/amlogic/AmlogicGrabber.cpp b/libsrc/grabber/amlogic/AmlogicGrabber.cpp index 19981e65..97185129 100644 --- a/libsrc/grabber/amlogic/AmlogicGrabber.cpp +++ b/libsrc/grabber/amlogic/AmlogicGrabber.cpp @@ -280,6 +280,13 @@ QJsonObject AmlogicGrabber::discover(const QJsonObject& params) inputsDiscovered["device_name"] = "AmLogic"; inputsDiscovered["type"] = "screen"; inputsDiscovered["video_inputs"] = video_inputs; + + QJsonObject defaults, video_inputs_default, resolution_default; + resolution_default["fps"] = _fps; + video_inputs_default["resolution"] = resolution_default; + video_inputs_default["inputIdx"] = 0; + defaults["video_input"] = video_inputs_default; + inputsDiscovered["default"] = defaults; } } diff --git a/libsrc/grabber/directx/DirectXGrabber.cpp b/libsrc/grabber/directx/DirectXGrabber.cpp index 581d80b3..735db502 100644 --- a/libsrc/grabber/directx/DirectXGrabber.cpp +++ b/libsrc/grabber/directx/DirectXGrabber.cpp @@ -267,8 +267,17 @@ QJsonObject DirectXGrabber::discover(const QJsonObject& params) in["formats"] = formats; video_inputs.append(in); + + } inputsDiscovered["video_inputs"] = video_inputs; + + QJsonObject defaults, video_inputs_default, resolution_default; + resolution_default["fps"] = _fps; + video_inputs_default["resolution"] = resolution_default; + video_inputs_default["inputIdx"] = 0; + defaults["video_input"] = video_inputs_default; + inputsDiscovered["default"] = defaults; } else { diff --git a/libsrc/grabber/dispmanx/DispmanxFrameGrabber.cpp b/libsrc/grabber/dispmanx/DispmanxFrameGrabber.cpp index 631ff28e..2a3f1783 100644 --- a/libsrc/grabber/dispmanx/DispmanxFrameGrabber.cpp +++ b/libsrc/grabber/dispmanx/DispmanxFrameGrabber.cpp @@ -277,6 +277,13 @@ QJsonObject DispmanxFrameGrabber::discover(const QJsonObject& params) inputsDiscovered["device_name"] = "DispmanX"; inputsDiscovered["type"] = "screen"; inputsDiscovered["video_inputs"] = video_inputs; + + QJsonObject defaults, video_inputs_default, resolution_default; + resolution_default["fps"] = _fps; + video_inputs_default["resolution"] = resolution_default; + video_inputs_default["inputIdx"] = 0; + defaults["video_input"] = video_inputs_default; + inputsDiscovered["default"] = defaults; } if (inputsDiscovered.isEmpty()) diff --git a/libsrc/grabber/framebuffer/FramebufferFrameGrabber.cpp b/libsrc/grabber/framebuffer/FramebufferFrameGrabber.cpp index 9016a862..f9c32c92 100644 --- a/libsrc/grabber/framebuffer/FramebufferFrameGrabber.cpp +++ b/libsrc/grabber/framebuffer/FramebufferFrameGrabber.cpp @@ -256,6 +256,13 @@ QJsonObject FramebufferFrameGrabber::discover(const QJsonObject& params) inputsDiscovered["device_name"] = "Framebuffer"; inputsDiscovered["type"] = "screen"; inputsDiscovered["video_inputs"] = video_inputs; + + QJsonObject defaults, video_inputs_default, resolution_default; + resolution_default["fps"] = _fps; + video_inputs_default["resolution"] = resolution_default; + video_inputs_default["inputIdx"] = 0; + defaults["video_input"] = video_inputs_default; + inputsDiscovered["default"] = defaults; } } diff --git a/libsrc/grabber/osx/OsxFrameGrabber.cpp b/libsrc/grabber/osx/OsxFrameGrabber.cpp index 899f1868..54ea28f7 100644 --- a/libsrc/grabber/osx/OsxFrameGrabber.cpp +++ b/libsrc/grabber/osx/OsxFrameGrabber.cpp @@ -193,6 +193,13 @@ QJsonObject OsxFrameGrabber::discover(const QJsonObject& params) video_inputs.append(in); } inputsDiscovered["video_inputs"] = video_inputs; + + QJsonObject defaults, video_inputs_default, resolution_default; + resolution_default["fps"] = _fps; + video_inputs_default["resolution"] = resolution_default; + video_inputs_default["inputIdx"] = 0; + defaults["video_input"] = video_inputs_default; + inputsDiscovered["default"] = defaults; } delete [] activeDspys; } diff --git a/libsrc/grabber/qt/QtGrabber.cpp b/libsrc/grabber/qt/QtGrabber.cpp index d81150ae..7ee698ef 100644 --- a/libsrc/grabber/qt/QtGrabber.cpp +++ b/libsrc/grabber/qt/QtGrabber.cpp @@ -384,6 +384,13 @@ QJsonObject QtGrabber::discover(const QJsonObject& params) video_inputs.append(in); } inputsDiscovered["video_inputs"] = video_inputs; + + QJsonObject defaults, video_inputs_default, resolution_default; + resolution_default["fps"] = _fps; + video_inputs_default["resolution"] = resolution_default; + video_inputs_default["inputIdx"] = 0; + defaults["video_input"] = video_inputs_default; + inputsDiscovered["default"] = defaults; } if (inputsDiscovered.isEmpty()) diff --git a/libsrc/grabber/x11/X11Grabber.cpp b/libsrc/grabber/x11/X11Grabber.cpp index ffa87f9b..de1af37c 100644 --- a/libsrc/grabber/x11/X11Grabber.cpp +++ b/libsrc/grabber/x11/X11Grabber.cpp @@ -461,6 +461,13 @@ QJsonObject X11Grabber::discover(const QJsonObject& params) if ( !video_inputs.isEmpty() ) { inputsDiscovered["video_inputs"] = video_inputs; + + QJsonObject defaults, video_inputs_default, resolution_default; + resolution_default["fps"] = _fps; + video_inputs_default["resolution"] = resolution_default; + video_inputs_default["inputIdx"] = 0; + defaults["video_input"] = video_inputs_default; + inputsDiscovered["default"] = defaults; } } } diff --git a/libsrc/grabber/xcb/XcbGrabber.cpp b/libsrc/grabber/xcb/XcbGrabber.cpp index b824289e..6c0b0d51 100644 --- a/libsrc/grabber/xcb/XcbGrabber.cpp +++ b/libsrc/grabber/xcb/XcbGrabber.cpp @@ -582,6 +582,13 @@ QJsonObject XcbGrabber::discover(const QJsonObject& params) if ( !video_inputs.isEmpty() ) { inputsDiscovered["video_inputs"] = video_inputs; + + QJsonObject defaults, video_inputs_default, resolution_default; + resolution_default["fps"] = _fps; + video_inputs_default["resolution"] = resolution_default; + video_inputs_default["inputIdx"] = 0; + defaults["video_input"] = video_inputs_default; + inputsDiscovered["default"] = defaults; } } } diff --git a/libsrc/hyperion/GrabberWrapper.cpp b/libsrc/hyperion/GrabberWrapper.cpp index 0235d807..93641ac3 100644 --- a/libsrc/hyperion/GrabberWrapper.cpp +++ b/libsrc/hyperion/GrabberWrapper.cpp @@ -10,7 +10,7 @@ #include GrabberWrapper* GrabberWrapper::instance = nullptr; -const int GrabberWrapper::DEFAULT_RATE_HZ = 10; +const int GrabberWrapper::DEFAULT_RATE_HZ = 25; const int GrabberWrapper::DEFAULT_MIN_GRAB_RATE_HZ = 1; const int GrabberWrapper::DEFAULT_MAX_GRAB_RATE_HZ = 30; const int GrabberWrapper::DEFAULT_PIXELDECIMATION = 8; diff --git a/libsrc/hyperion/SettingsManager.cpp b/libsrc/hyperion/SettingsManager.cpp index b92202c7..bf201796 100644 --- a/libsrc/hyperion/SettingsManager.cpp +++ b/libsrc/hyperion/SettingsManager.cpp @@ -424,10 +424,18 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config) if (newGrabberV4L2Config.contains("encoding_format")) { newGrabberV4L2Config.remove("encoding_format"); - config["grabberV4L2"] = newGrabberV4L2Config; + newGrabberV4L2Config["grabberV4L2"] = newGrabberV4L2Config; migrated = true; - Debug(_log, "GrabberV4L2 records migrated"); } + + //Add new element enable + if (!newGrabberV4L2Config.contains("enable")) + { + newGrabberV4L2Config["enable"] = false; + migrated = true; + } + config["grabberV4L2"] = newGrabberV4L2Config; + Debug(_log, "GrabberV4L2 records migrated"); } if (config.contains("framegrabber")) @@ -438,18 +446,33 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config) //Rename element type -> device if (newFramegrabberConfig.contains("type")) { - newFramegrabberConfig["device"] = newFramegrabberConfig["type"]; + newFramegrabberConfig["device"] = "auto"; //newFramegrabberConfig["type"].toString(); newFramegrabberConfig.remove("type"); migrated = true; } //Rename element frequency_Hz -> fps if (newFramegrabberConfig.contains("frequency_Hz")) { - newFramegrabberConfig["fps"] = newFramegrabberConfig["frequency_Hz"]; + newFramegrabberConfig["fps"] = newFramegrabberConfig["frequency_Hz"].toInt(25); newFramegrabberConfig.remove("frequency_Hz"); migrated = true; } + //Rename element display -> input + if (newFramegrabberConfig.contains("display")) + { + newFramegrabberConfig["input"] = newFramegrabberConfig["display"]; + newFramegrabberConfig.remove("display"); + migrated = true; + } + + //Add new element enable + if (!newFramegrabberConfig.contains("enable")) + { + newFramegrabberConfig["enable"] = false; + migrated = true; + } + config["framegrabber"] = newFramegrabberConfig; Debug(_log, "Framegrabber records migrated"); } diff --git a/libsrc/hyperion/schema/schema-framegrabber.json b/libsrc/hyperion/schema/schema-framegrabber.json index 4b0e6a4d..8c3f2ab2 100644 --- a/libsrc/hyperion/schema/schema-framegrabber.json +++ b/libsrc/hyperion/schema/schema-framegrabber.json @@ -88,7 +88,6 @@ "type": "integer", "title": "edt_conf_enum_custom", "default":10, - "minimum": 1, "append": "fps", "options": { "hidden": true