2013-11-11 10:00:37 +01:00
// STL includes
2016-06-17 01:25:40 +02:00
# include <exception>
2016-07-01 23:20:41 +02:00
# include <sstream>
2013-11-11 10:00:37 +01:00
2013-08-21 16:25:27 +02:00
// QT includes
2013-11-22 11:48:10 +01:00
# include <QString>
# include <QStringList>
2019-07-14 22:43:22 +02:00
# include <QThread>
2013-08-14 17:02:09 +02:00
2013-07-26 22:38:34 +02:00
// hyperion include
# include <hyperion/Hyperion.h>
2018-12-27 23:11:32 +01:00
# include <hyperion/MessageForwarder.h>
2016-12-19 23:59:50 +01:00
# include <hyperion/ImageProcessor.h>
2016-04-02 00:04:11 +02:00
# include <hyperion/ColorAdjustment.h>
2013-07-26 22:38:34 +02:00
2018-12-27 23:11:32 +01:00
// utils
# include <utils/hyperion.h>
2019-07-29 19:09:26 +02:00
# include <utils/GlobalSignals.h>
2020-08-02 10:44:42 +02:00
# include <utils/Logger.h>
2018-12-27 23:11:32 +01:00
2020-11-14 17:58:56 +01:00
// LedDevice includes
2019-01-01 19:47:07 +01:00
# include <leddevice/LedDeviceWrapper.h>
2013-08-13 11:10:45 +02:00
2018-12-27 23:11:32 +01:00
# include <hyperion/MultiColorAdjustment.h>
2013-10-27 18:04:37 +01:00
# include "LinearColorSmoothing.h"
2013-11-24 16:10:48 +01:00
// effect engine includes
# include <effectengine/EffectEngine.h>
2018-12-27 23:11:32 +01:00
// settingsManagaer
# include <hyperion/SettingsManager.h>
// BGEffectHandler
# include <hyperion/BGEffectHandler.h>
// CaptureControl (Daemon capture)
# include <hyperion/CaptureCont.h>
2017-01-10 19:58:41 +01:00
2018-12-28 18:12:45 +01:00
// Boblight
# include <boblightserver/BoblightServer.h>
2020-11-01 19:47:30 +01:00
Hyperion : : Hyperion ( quint8 instance , bool readonlyMode )
2019-07-14 22:43:22 +02:00
: QObject ( )
, _instIndex ( instance )
2020-11-01 19:47:30 +01:00
, _settingsManager ( new SettingsManager ( instance , this , readonlyMode ) )
2018-12-27 23:11:32 +01:00
, _componentRegister ( this )
, _ledString ( hyperion : : createLedString ( getSetting ( settings : : LEDS ) . array ( ) , hyperion : : createColorOrder ( getSetting ( settings : : DEVICE ) . object ( ) ) ) )
, _imageProcessor ( new ImageProcessor ( _ledString , this ) )
2020-11-14 17:58:56 +01:00
, _muxer ( static_cast < int > ( _ledString . leds ( ) . size ( ) ) , this )
, _raw2ledAdjustment ( hyperion : : createLedColorsAdjustment ( static_cast < int > ( _ledString . leds ( ) . size ( ) ) , getSetting ( settings : : COLOR ) . object ( ) ) )
, _ledDeviceWrapper ( nullptr )
, _deviceSmooth ( nullptr )
2016-07-15 23:08:55 +02:00
, _effectEngine ( nullptr )
2019-07-20 11:28:16 +02:00
, _messageForwarder ( nullptr )
2018-12-27 23:11:32 +01:00
, _log ( Logger : : getInstance ( " HYPERION " ) )
, _hwLedCount ( )
, _ledGridSize ( hyperion : : getLedLayoutGridSize ( getSetting ( settings : : LEDS ) . array ( ) ) )
2020-11-14 17:58:56 +01:00
, _BGEffectHandler ( nullptr )
Media Foundation/V4L2 grabber ... (#1119)
* - New Media Foundation grabber
- JsonAPI available grabber fix
- commented json config removed
* Added libjpeg-turbo to dependencies
* Fix OSX build
Removed Azure Pipelines from build scripts
* Remove Platform from Dashboard
* Correct Grabber Namings
* Grabber UI improvements, generic JSONEditor Selection Update
* Active grabber fix
* Stop Framebuffer grabber on failure
* - Image format NV12 and I420 added
- Flip mode
- Scaling factor for MJPEG
- VSCode (compile before run)
- CI (push) dependency libjpeg-turbo added
* Refactor MediaFoundation (Part 1)
* Remove QDebug output
* Added image flipping ability to MF Grabber
* fix issue 1160
* -Reload MF Grabber only once per WebUI update
- Cleanup
* Improvements
* - Set 'Software Frame Decimation' begin to 0
- Removed grabber specific device name from Log
- Keep pixel format when switching resolution
- Display 'Flip mode' correct in Log
- BGR24 images always flipped
* Refactor MediaFoundation (Part 2)
* Refactor V4L2 grabber (part 1) (#62)
* Media Foundation grabber adapted to V4L2 change
* Enable Media Foundation grabber on windows
* Have fps as int, fix height typo
* Added video standards to JsonAPI output
* Error handling in source reader improved
* Fix "Frame to small" error
* Discovery VideoSources and Dynamically Update Editor
* Hide all element when no video grabber discovered, upate naming
* Do not show unsupported grabbers
* Copy Log to Clipboard
* Update Grabber schema and Defaults
* Update access levels and validate crop ranges
* Height and width in Qt grabber corrected
* Correct formatting
* Untabify
* Global component states across instances
* Components divided on the dashboard
* refactor
* Fix Merge-issues
* Database migration aligning with updated grabber model
* Align Grabber.js with new utility functions
* Allow editor-validation for enum-lists
* Handle "Show Explainations scenario" correctly
* Grabber - Ensure save is only possible on valid content
* Dashboard update + fix GlobalSignal connection
* Ensure default database is populated with current release
* Correct grabber4L2 access level
* Display Signal detection area in preview
* Write Hyperion version into default config on compiling.
* Create defaultconfig.json dynamically
* WebUI changes
* Correct grabber config look-ups
* Refactor i18n language loading
* Fix en.json
* Split global capture from instance capture config
* Update grabber default values
* Standalone grabber: Add --debug switch
* Enhance showInputOptionsForKey for multiple keys
* Add grabber instance link to system grabber config
* Only show signal detection area, if grabber is enabled
* Always show Active element on grabber page
* Remote control - Only display gabber status, if global grabber is enabled
* WebUI optimization (thx to @mkcologne)
Start Grabber only when global settings are enabled
Fixed an issue in the WebUI preview
* V4L2/MF changes
* Jsoneditor, Correct translation for default values
* Refactor LED-Device handling in UI and make element naming consistent
* MF Discovery extended
* Fix LGTM finding
* Support Grabber Bri, Hue, Sat and Con in UI, plus their defaults
* Concider Access level for item filtering
* Concider Access level for item filtering
* Revert "Concider Access level for item filtering"
This reverts commit 5b0ce3c0f2de67e0c43788190cfff45614706129.
* Disable fpsSoftwareDecimation for framegrabber, as not supported yet
* JSON-Editor- Add updated schema for validation on dynamic elements
* added V4L2 color IDs
* LGTM findings fix
* destroy SR callback only on exit
* Grabber.js - Hide elements not supported by platform
* Fixed freezing start effect
* Grabber UI - Hardware controls - Show current values and allow to reset to defaults
* Grabber - Discovery - Add current values to properties
* Small things
* Clean-up Effects and have ENDLESS consistently defined
* Fix on/off/on priority during startup, by initializing _prevVisComp in line with background priority
* Add missing translation mappings
* DirectX Grabber reactivated/ QT Grabber size decimation fixed
* typo in push-master workflow
* Use PreciseTimer for Grabber to ensure stable FPS timing
* Set default Screencapture rate consistently
* Fix libjpeg-turbo download
* Remove Zero character from file
* docker-compile Add PLATFORM parameter, only copy output file after successful compile
* Framebuffer, Dispmanx, OSX, AML Grabber discovery, various clean-up and consistencies across grabbers
* Fix merge problem - on docker-compile Add PLATFORM parameter, only copy output file after successful compile
* Fix definition
* OSXFRameGrabber - Revert cast
* Clean-ups nach Feedback
* Disable certain libraries when building armlogic via standard stretch image as developer
* Add CEC availability to ServerInfo to have it platform independent
* Grabber UI - Fix problem that crop values are not populated when refining editor rage
* Preserve value when updating json-editor range
* LEDVisualisation - Clear image when source changes
* Fix - Preserve value when updating json-editor range
* LEDVisualisation - Clear image when no component is active
* Allow to have password handled by Password-Manager (#1263)
* Update default signal detection area to green assuming rainbow grabber
* LED Visualisation - Handle empty priority update
* Fix yuv420 in v4l2 grabber
* V4L2-Grabber discovery - Only report grabbers with valid video input information
* Grabber - Update static variables to have them working in release build
* LED Visualisation - ClearImage when no priorities
* LED Visualisation - Fix Logo resizing issue
* LED Visualisation - Have nearly black background and negative logo
Co-authored-by: LordGrey <lordgrey.emmel@gmail.com>
Co-authored-by: LordGrey <48840279+Lord-Grey@users.noreply.github.com>
2021-07-14 20:48:33 +02:00
, _captureCont ( nullptr )
2018-12-27 23:11:32 +01:00
, _ledBuffer ( _ledString . leds ( ) . size ( ) , ColorRgb : : BLACK )
2020-11-14 17:58:56 +01:00
, _boblightServer ( nullptr )
2020-11-01 19:47:30 +01:00
, _readOnlyMode ( readonlyMode )
2019-07-14 22:43:22 +02:00
{
}
Hyperion : : ~ Hyperion ( )
{
2020-08-02 22:32:00 +02:00
freeObjects ( ) ;
2019-07-14 22:43:22 +02:00
}
void Hyperion : : start ( )
2013-07-26 22:38:34 +02:00
{
2019-07-12 16:54:26 +02:00
// forward settings changed to Hyperion
connect ( _settingsManager , & SettingsManager : : settingsChanged , this , & Hyperion : : settingsChanged ) ;
2019-07-14 22:43:22 +02:00
// get newVideoMode from HyperionIManager
connect ( this , & Hyperion : : newVideoMode , this , & Hyperion : : handleNewVideoMode ) ;
2016-04-02 00:04:11 +02:00
if ( ! _raw2ledAdjustment - > verifyAdjustments ( ) )
2019-07-14 22:43:22 +02:00
{
2018-12-27 23:11:32 +01:00
Warning ( _log , " At least one led has no color calibration, please add all leds from your led layout to an 'LED index' field! " ) ;
2019-07-14 22:43:22 +02:00
}
2017-03-21 17:55:46 +01:00
2018-12-27 23:11:32 +01:00
// handle hwLedCount
2021-04-24 19:37:29 +02:00
_hwLedCount = getSetting ( settings : : DEVICE ) . object ( ) [ " hardwareLedCount " ] . toInt ( getLedCount ( ) ) ;
2017-06-24 11:52:22 +02:00
2020-11-14 17:58:56 +01:00
// Initialize colororder vector
2020-08-02 10:44:42 +02:00
for ( const Led & led : _ledString . leds ( ) )
2018-12-27 23:11:32 +01:00
{
_ledStringColorOrder . push_back ( led . colorOrder ) ;
}
2017-06-24 11:52:22 +02:00
2019-07-14 22:43:22 +02:00
// connect Hyperion::update with Muxer visible priority changes as muxer updates independent
connect ( & _muxer , & PriorityMuxer : : visiblePriorityChanged , this , & Hyperion : : update ) ;
2021-08-31 10:56:06 +02:00
connect ( & _muxer , & PriorityMuxer : : visiblePriorityChanged , this , & Hyperion : : handleSourceAvailability ) ;
2020-02-15 22:47:27 +01:00
connect ( & _muxer , & PriorityMuxer : : visibleComponentChanged , this , & Hyperion : : handleVisibleComponentChanged ) ;
2019-07-14 22:43:22 +02:00
2018-12-27 23:11:32 +01:00
// listens for ComponentRegister changes of COMP_ALL to perform core enable/disable actions
2020-02-15 22:47:27 +01:00
// connect(&_componentRegister, &ComponentRegister::updatedComponentState, this, &Hyperion::updatedComponentState);
2013-10-27 18:04:37 +01:00
2018-12-27 23:11:32 +01:00
// listen for settings updates of this instance (LEDS & COLOR)
connect ( _settingsManager , & SettingsManager : : settingsChanged , this , & Hyperion : : handleSettingsUpdate ) ;
2017-08-04 12:01:45 +02:00
2020-11-14 17:58:56 +01:00
#if 0
2018-12-27 23:11:32 +01:00
// set color correction activity state
const QJsonObject color = getSetting ( settings : : COLOR ) . object ( ) ;
2020-11-14 17:58:56 +01:00
# endif
2013-08-14 17:02:09 +02:00
2020-11-14 17:58:56 +01:00
// initialize LED-devices
2018-12-28 18:12:45 +01:00
QJsonObject ledDevice = getSetting ( settings : : DEVICE ) . object ( ) ;
2020-11-14 17:58:56 +01:00
ledDevice [ " currentLedCount " ] = _hwLedCount ; // Inject led count info
2017-03-21 17:55:46 +01:00
2019-01-01 19:47:07 +01:00
_ledDeviceWrapper = new LedDeviceWrapper ( this ) ;
2020-02-26 18:54:56 +01:00
connect ( this , & Hyperion : : compStateChangeRequest , _ledDeviceWrapper , & LedDeviceWrapper : : handleComponentState ) ;
2020-02-10 15:21:58 +01:00
connect ( this , & Hyperion : : ledDeviceData , _ledDeviceWrapper , & LedDeviceWrapper : : updateLeds ) ;
2019-01-01 19:47:07 +01:00
_ledDeviceWrapper - > createLedDevice ( ledDevice ) ;
2017-06-24 11:52:22 +02:00
2019-01-01 19:47:07 +01:00
// smoothing
_deviceSmooth = new LinearColorSmoothing ( getSetting ( settings : : SMOOTHING ) , this ) ;
connect ( this , & Hyperion : : settingsChanged , _deviceSmooth , & LinearColorSmoothing : : handleSettingsUpdate ) ;
2018-12-27 23:11:32 +01:00
2019-07-20 11:28:16 +02:00
// create the message forwarder only on main instance
if ( _instIndex = = 0 )
2020-11-14 17:58:56 +01:00
{
2019-07-20 11:28:16 +02:00
_messageForwarder = new MessageForwarder ( this ) ;
2020-11-14 17:58:56 +01:00
}
2019-07-20 11:28:16 +02:00
2019-01-01 19:47:07 +01:00
// create the effect engine; needs to be initialized after smoothing!
2018-12-31 15:48:29 +01:00
_effectEngine = new EffectEngine ( this ) ;
2018-12-27 23:11:32 +01:00
connect ( _effectEngine , & EffectEngine : : effectListUpdated , this , & Hyperion : : effectListUpdated ) ;
2013-11-24 16:10:48 +01:00
2018-12-27 23:11:32 +01:00
// initial startup effect
hyperion : : handleInitialEffect ( this , getSetting ( settings : : FGEFFECT ) . object ( ) ) ;
2019-01-01 19:47:07 +01:00
2018-12-27 23:11:32 +01:00
// handle background effect
_BGEffectHandler = new BGEffectHandler ( this ) ;
2016-09-14 13:51:28 +02:00
2018-12-27 23:11:32 +01:00
// create the Daemon capture interface
_captureCont = new CaptureCont ( this ) ;
2017-06-24 11:52:22 +02:00
2019-07-29 19:09:26 +02:00
// forwards global signals to the corresponding slots
connect ( GlobalSignals : : getInstance ( ) , & GlobalSignals : : registerGlobalInput , this , & Hyperion : : registerInput ) ;
connect ( GlobalSignals : : getInstance ( ) , & GlobalSignals : : clearGlobalInput , this , & Hyperion : : clear ) ;
connect ( GlobalSignals : : getInstance ( ) , & GlobalSignals : : setGlobalColor , this , & Hyperion : : setColor ) ;
connect ( GlobalSignals : : getInstance ( ) , & GlobalSignals : : setGlobalImage , this , & Hyperion : : setInputImage ) ;
2020-11-14 17:58:56 +01:00
// if there is no startup / background effect and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a priority change)
2013-08-18 13:33:56 +02:00
update ( ) ;
2018-12-28 18:12:45 +01:00
// boblight, can't live in global scope as it depends on layout
_boblightServer = new BoblightServer ( this , getSetting ( settings : : BOBLSERVER ) ) ;
connect ( this , & Hyperion : : settingsChanged , _boblightServer , & BoblightServer : : handleSettingsUpdate ) ;
2019-06-05 18:19:08 +02:00
2020-11-14 17:58:56 +01:00
// instance initiated, enter thread event loop
2019-07-14 22:43:22 +02:00
emit started ( ) ;
2013-07-26 22:38:34 +02:00
}
2019-07-14 22:43:22 +02:00
void Hyperion : : stop ( )
2017-08-04 12:01:45 +02:00
{
2019-07-14 22:43:22 +02:00
emit finished ( ) ;
2019-07-25 18:23:19 +02:00
thread ( ) - > wait ( ) ;
2017-08-04 12:01:45 +02:00
}
2020-08-02 22:32:00 +02:00
void Hyperion : : freeObjects ( )
2013-07-26 22:38:34 +02:00
{
2017-08-12 07:55:32 +02:00
// switch off all leds
2020-02-26 18:54:56 +01:00
clear ( - 1 , true ) ;
2017-08-12 07:55:32 +02:00
2016-07-01 23:20:41 +02:00
// delete components on exit of hyperion core
2018-12-28 18:12:45 +01:00
delete _boblightServer ;
2018-12-27 23:11:32 +01:00
delete _captureCont ;
2013-11-24 16:10:48 +01:00
delete _effectEngine ;
2016-04-02 00:04:11 +02:00
delete _raw2ledAdjustment ;
2019-07-20 11:28:16 +02:00
delete _messageForwarder ;
2018-12-27 23:11:32 +01:00
delete _settingsManager ;
2019-01-01 19:47:07 +01:00
delete _ledDeviceWrapper ;
2013-07-26 22:38:34 +02:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : handleSettingsUpdate ( settings : : type type , const QJsonDocument & config )
2016-10-10 23:08:01 +02:00
{
2020-02-10 15:21:58 +01:00
// std::cout << "Hyperion::handleSettingsUpdate" << std::endl;
// std::cout << config.toJson().toStdString() << std::endl;
2018-12-27 23:11:32 +01:00
if ( type = = settings : : COLOR )
{
const QJsonObject obj = config . object ( ) ;
// change in color recreate ledAdjustments
delete _raw2ledAdjustment ;
2020-11-14 17:58:56 +01:00
_raw2ledAdjustment = hyperion : : createLedColorsAdjustment ( static_cast < int > ( _ledString . leds ( ) . size ( ) ) , obj ) ;
2018-12-27 23:11:32 +01:00
if ( ! _raw2ledAdjustment - > verifyAdjustments ( ) )
{
Warning ( _log , " At least one led has no color calibration, please add all leds from your led layout to an 'LED index' field! " ) ;
}
}
else if ( type = = settings : : LEDS )
{
const QJsonArray leds = config . array ( ) ;
2020-11-14 17:58:56 +01:00
// stop and cache all running effects, as effects depend heavily on LED-layout
2018-12-27 23:11:32 +01:00
_effectEngine - > cacheRunningEffects ( ) ;
2020-11-14 17:58:56 +01:00
// ledstring, img processor, muxer, ledGridSize (effect-engine image based effects), _ledBuffer and ByteOrder of ledstring
2018-12-27 23:11:32 +01:00
_ledString = hyperion : : createLedString ( leds , hyperion : : createColorOrder ( getSetting ( settings : : DEVICE ) . object ( ) ) ) ;
_imageProcessor - > setLedString ( _ledString ) ;
2020-11-14 17:58:56 +01:00
_muxer . updateLedColorsLength ( static_cast < int > ( _ledString . leds ( ) . size ( ) ) ) ;
2018-12-27 23:11:32 +01:00
_ledGridSize = hyperion : : getLedLayoutGridSize ( leds ) ;
std : : vector < ColorRgb > color ( _ledString . leds ( ) . size ( ) , ColorRgb { 0 , 0 , 0 } ) ;
_ledBuffer = color ;
_ledStringColorOrder . clear ( ) ;
2020-08-02 10:44:42 +02:00
for ( const Led & led : _ledString . leds ( ) )
2018-12-27 23:11:32 +01:00
{
_ledStringColorOrder . push_back ( led . colorOrder ) ;
}
// handle hwLedCount update
2021-04-24 19:37:29 +02:00
_hwLedCount = getSetting ( settings : : DEVICE ) . object ( ) [ " hardwareLedCount " ] . toInt ( getLedCount ( ) ) ;
2018-12-27 23:11:32 +01:00
// change in leds are also reflected in adjustment
delete _raw2ledAdjustment ;
2020-11-14 17:58:56 +01:00
_raw2ledAdjustment = hyperion : : createLedColorsAdjustment ( static_cast < int > ( _ledString . leds ( ) . size ( ) ) , getSetting ( settings : : COLOR ) . object ( ) ) ;
2018-12-27 23:11:32 +01:00
// start cached effects
_effectEngine - > startCachedEffects ( ) ;
}
else if ( type = = settings : : DEVICE )
{
2018-12-28 18:12:45 +01:00
QJsonObject dev = config . object ( ) ;
2018-12-27 23:11:32 +01:00
// handle hwLedCount update
2021-04-24 19:37:29 +02:00
_hwLedCount = dev [ " hardwareLedCount " ] . toInt ( getLedCount ( ) ) ;
2018-12-27 23:11:32 +01:00
// force ledString update, if device ByteOrder changed
2019-01-01 19:47:07 +01:00
if ( _ledDeviceWrapper - > getColorOrder ( ) ! = dev [ " colorOrder " ] . toString ( " rgb " ) )
2018-12-27 23:11:32 +01:00
{
_ledString = hyperion : : createLedString ( getSetting ( settings : : LEDS ) . array ( ) , hyperion : : createColorOrder ( dev ) ) ;
_imageProcessor - > setLedString ( _ledString ) ;
2019-09-07 01:17:26 +02:00
_ledStringColorOrder . clear ( ) ;
2020-08-02 10:44:42 +02:00
for ( const Led & led : _ledString . leds ( ) )
2019-09-07 01:17:26 +02:00
{
_ledStringColorOrder . push_back ( led . colorOrder ) ;
}
2018-12-27 23:11:32 +01:00
}
2019-01-01 19:47:07 +01:00
// do always reinit until the led devices can handle dynamic changes
2020-11-14 17:58:56 +01:00
dev [ " currentLedCount " ] = _hwLedCount ; // Inject led count info
2019-01-01 19:47:07 +01:00
_ledDeviceWrapper - > createLedDevice ( dev ) ;
2020-02-10 15:21:58 +01:00
// TODO: Check, if framegrabber frequency is lower than latchtime..., if yes, stop
}
else if ( type = = settings : : SMOOTHING )
{
_deviceSmooth - > handleSettingsUpdate ( type , config ) ;
2018-12-27 23:11:32 +01:00
}
2019-07-14 22:43:22 +02:00
2018-12-28 18:12:45 +01:00
// update once to push single color sets / adjustments/ ledlayout resizes and update ledBuffer color
2018-12-27 23:11:32 +01:00
update ( ) ;
2016-10-10 23:08:01 +02:00
}
2020-08-08 13:09:15 +02:00
QJsonDocument Hyperion : : getSetting ( settings : : type type ) const
2013-08-14 10:54:49 +02:00
{
2018-12-27 23:11:32 +01:00
return _settingsManager - > getSetting ( type ) ;
2013-08-14 10:54:49 +02:00
}
2020-08-08 23:12:43 +02:00
bool Hyperion : : saveSettings ( const QJsonObject & config , bool correct )
2017-03-21 17:55:46 +01:00
{
2018-12-27 23:11:32 +01:00
return _settingsManager - > saveSettings ( config , correct ) ;
2017-03-21 17:55:46 +01:00
}
2018-12-27 23:11:32 +01:00
int Hyperion : : getLatchTime ( ) const
{
2020-08-02 10:44:42 +02:00
return _ledDeviceWrapper - > getLatchTime ( ) ;
2017-03-21 17:55:46 +01:00
}
2018-12-27 23:11:32 +01:00
unsigned Hyperion : : addSmoothingConfig ( int settlingTime_ms , double ledUpdateFrequency_hz , unsigned updateDelay )
2017-03-21 17:55:46 +01:00
{
2018-12-27 23:11:32 +01:00
return _deviceSmooth - > addConfig ( settlingTime_ms , ledUpdateFrequency_hz , updateDelay ) ;
2017-03-21 17:55:46 +01:00
}
2020-02-10 15:21:58 +01:00
unsigned Hyperion : : updateSmoothingConfig ( unsigned id , int settlingTime_ms , double ledUpdateFrequency_hz , unsigned updateDelay )
{
return _deviceSmooth - > updateConfig ( id , settlingTime_ms , ledUpdateFrequency_hz , updateDelay ) ;
}
2020-11-14 17:58:56 +01:00
int Hyperion : : getLedCount ( ) const
2017-03-21 17:55:46 +01:00
{
2020-11-14 17:58:56 +01:00
return static_cast < int > ( _ledString . leds ( ) . size ( ) ) ;
2017-03-21 17:55:46 +01:00
}
2016-09-14 13:51:28 +02:00
2020-08-08 13:09:15 +02:00
void Hyperion : : setSourceAutoSelect ( bool state )
2016-07-31 22:21:35 +02:00
{
2020-03-26 17:59:41 +01:00
_muxer . setSourceAutoSelectEnabled ( state ) ;
2016-07-31 22:21:35 +02:00
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : setVisiblePriority ( int priority )
2016-07-31 22:21:35 +02:00
{
2018-12-27 23:11:32 +01:00
return _muxer . setPriority ( priority ) ;
}
2016-07-31 22:21:35 +02:00
2020-08-08 23:12:43 +02:00
bool Hyperion : : sourceAutoSelectEnabled ( ) const
2018-12-27 23:11:32 +01:00
{
return _muxer . isSourceAutoSelectEnabled ( ) ;
2016-07-31 22:21:35 +02:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : setNewComponentState ( hyperion : : Components component , bool state )
2016-08-04 13:10:53 +02:00
{
2020-02-26 18:54:56 +01:00
_componentRegister . setNewComponentState ( component , state ) ;
2019-01-01 19:47:07 +01:00
}
2017-03-21 17:55:46 +01:00
2020-08-02 10:44:42 +02:00
std : : map < hyperion : : Components , bool > Hyperion : : getAllComponents ( ) const
2019-01-01 19:47:07 +01:00
{
2020-02-26 18:54:56 +01:00
return _componentRegister . getRegister ( ) ;
}
2020-08-08 23:12:43 +02:00
int Hyperion : : isComponentEnabled ( hyperion : : Components comp ) const
2020-02-26 18:54:56 +01:00
{
return _componentRegister . isComponentEnabled ( comp ) ;
2016-08-04 13:10:53 +02:00
}
2016-07-15 23:08:55 +02:00
2020-08-08 13:09:15 +02:00
void Hyperion : : registerInput ( int priority , hyperion : : Components component , const QString & origin , const QString & owner , unsigned smooth_cfg )
2013-07-26 22:38:34 +02:00
{
2018-12-27 23:11:32 +01:00
_muxer . registerInput ( priority , component , origin , owner , smooth_cfg ) ;
2013-08-18 13:33:56 +02:00
}
2013-07-26 22:38:34 +02:00
2020-08-08 13:09:15 +02:00
bool Hyperion : : setInput ( int priority , const std : : vector < ColorRgb > & ledColors , int timeout_ms , bool clearEffect )
2013-07-26 22:38:34 +02:00
{
2018-12-27 23:11:32 +01:00
if ( _muxer . setInput ( priority , ledColors , timeout_ms ) )
2013-12-08 17:45:26 +01:00
{
2018-12-27 23:11:32 +01:00
// clear effect if this call does not come from an effect
if ( clearEffect )
2020-11-14 17:58:56 +01:00
{
2018-12-27 23:11:32 +01:00
_effectEngine - > channelCleared ( priority ) ;
2020-11-14 17:58:56 +01:00
}
2013-12-08 17:45:26 +01:00
2018-12-27 23:11:32 +01:00
// if this priority is visible, update immediately
if ( priority = = _muxer . getCurrentPriority ( ) )
2020-02-10 15:21:58 +01:00
{
2018-12-27 23:11:32 +01:00
update ( ) ;
2020-02-10 15:21:58 +01:00
}
2013-07-26 22:38:34 +02:00
2018-12-27 23:11:32 +01:00
return true ;
2013-08-14 17:02:09 +02:00
}
2018-12-27 23:11:32 +01:00
return false ;
2013-08-14 17:02:09 +02:00
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : setInputImage ( int priority , const Image < ColorRgb > & image , int64_t timeout_ms , bool clearEffect )
2016-12-18 19:00:14 +01:00
{
2019-07-29 19:09:26 +02:00
if ( ! _muxer . hasPriority ( priority ) )
{
emit GlobalSignals : : getInstance ( ) - > globalRegRequired ( priority ) ;
return false ;
}
2018-12-27 23:11:32 +01:00
if ( _muxer . setInputImage ( priority , image , timeout_ms ) )
2016-12-18 19:00:14 +01:00
{
2018-12-27 23:11:32 +01:00
// clear effect if this call does not come from an effect
if ( clearEffect )
2020-11-14 17:58:56 +01:00
{
2018-12-27 23:11:32 +01:00
_effectEngine - > channelCleared ( priority ) ;
2020-11-14 17:58:56 +01:00
}
2018-12-27 23:11:32 +01:00
// if this priority is visible, update immediately
if ( priority = = _muxer . getCurrentPriority ( ) )
2020-02-10 15:21:58 +01:00
{
2018-12-27 23:11:32 +01:00
update ( ) ;
2020-02-10 15:21:58 +01:00
}
2018-12-27 23:11:32 +01:00
return true ;
2016-12-18 19:00:14 +01:00
}
2018-12-27 23:11:32 +01:00
return false ;
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : setInputInactive ( quint8 priority )
2018-12-28 18:12:45 +01:00
{
return _muxer . setInputInactive ( priority ) ;
}
2020-08-08 13:09:15 +02:00
void Hyperion : : setColor ( int priority , const std : : vector < ColorRgb > & ledColors , int timeout_ms , const QString & origin , bool clearEffects )
2018-12-27 23:11:32 +01:00
{
// clear effect if this call does not come from an effect
2020-02-26 18:54:56 +01:00
if ( clearEffects )
2020-11-14 17:58:56 +01:00
{
2018-12-27 23:11:32 +01:00
_effectEngine - > channelCleared ( priority ) ;
2020-11-14 17:58:56 +01:00
}
2018-12-27 23:11:32 +01:00
2020-02-26 18:54:56 +01:00
// create full led vector from single/multiple colors
2020-07-27 20:00:36 +02:00
size_t size = _ledString . leds ( ) . size ( ) ;
2020-02-26 18:54:56 +01:00
std : : vector < ColorRgb > newLedColors ;
2020-07-27 20:00:36 +02:00
while ( true )
{
for ( const auto & entry : ledColors )
{
newLedColors . emplace_back ( entry ) ;
if ( newLedColors . size ( ) = = size )
2020-11-14 17:58:56 +01:00
{
2020-07-27 20:00:36 +02:00
goto end ;
2020-11-14 17:58:56 +01:00
}
2020-07-27 20:00:36 +02:00
}
}
end :
2018-12-27 23:11:32 +01:00
2019-08-24 22:53:30 +02:00
if ( getPriorityInfo ( priority ) . componentId ! = hyperion : : COMP_COLOR )
2020-11-14 17:58:56 +01:00
{
2019-08-24 22:53:30 +02:00
clear ( priority ) ;
2020-11-14 17:58:56 +01:00
}
2019-08-24 22:53:30 +02:00
2018-12-27 23:11:32 +01:00
// register color
registerInput ( priority , hyperion : : COMP_COLOR , origin ) ;
2020-11-01 19:15:22 +01:00
// write color to muxer
2020-02-26 18:54:56 +01:00
setInput ( priority , newLedColors , timeout_ms ) ;
2016-12-18 19:00:14 +01:00
}
2020-08-08 23:12:43 +02:00
QStringList Hyperion : : getAdjustmentIds ( ) const
2016-04-02 00:04:11 +02:00
{
return _raw2ledAdjustment - > getAdjustmentIds ( ) ;
}
2020-08-02 10:44:42 +02:00
ColorAdjustment * Hyperion : : getAdjustment ( const QString & id ) const
2016-04-02 00:04:11 +02:00
{
return _raw2ledAdjustment - > getAdjustment ( id ) ;
}
void Hyperion : : adjustmentsUpdated ( )
{
2018-12-27 23:11:32 +01:00
emit adjustmentChanged ( ) ;
2016-04-02 00:04:11 +02:00
update ( ) ;
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : clear ( int priority , bool forceClearAll )
2013-08-18 13:33:56 +02:00
{
2020-11-14 17:58:56 +01:00
bool isCleared = false ;
2020-02-26 18:54:56 +01:00
if ( priority < 0 )
{
_muxer . clearAll ( forceClearAll ) ;
2018-12-27 23:11:32 +01:00
2020-02-26 18:54:56 +01:00
// send clearall signal to the effect engine
_effectEngine - > allChannelsCleared ( ) ;
2020-11-14 17:58:56 +01:00
isCleared = true ;
2020-02-26 18:54:56 +01:00
}
else
{
// send clear signal to the effect engine
// (outside the check so the effect gets cleared even when the effect is not sending colors)
_effectEngine - > channelCleared ( priority ) ;
2018-12-27 23:11:32 +01:00
2020-02-26 18:54:56 +01:00
if ( _muxer . clearInput ( priority ) )
2020-11-14 17:58:56 +01:00
{
isCleared = true ;
}
2020-02-26 18:54:56 +01:00
}
2020-11-14 17:58:56 +01:00
return isCleared ;
2013-08-18 13:33:56 +02:00
}
2016-05-30 22:39:12 +02:00
int Hyperion : : getCurrentPriority ( ) const
{
2018-12-27 23:11:32 +01:00
return _muxer . getCurrentPriority ( ) ;
2016-05-30 22:39:12 +02:00
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : isCurrentPriority ( int priority ) const
2017-09-01 08:50:37 +02:00
{
return getCurrentPriority ( ) = = priority ;
}
2013-08-19 20:33:36 +02:00
QList < int > Hyperion : : getActivePriorities ( ) const
{
return _muxer . getPriorities ( ) ;
}
2020-08-08 13:09:15 +02:00
Hyperion : : InputInfo Hyperion : : getPriorityInfo ( int priority ) const
2013-08-19 20:33:36 +02:00
{
return _muxer . getInputInfo ( priority ) ;
}
2020-03-26 17:59:41 +01:00
QString Hyperion : : saveEffect ( const QJsonObject & obj )
2018-12-31 15:48:29 +01:00
{
2020-03-26 17:59:41 +01:00
return _effectEngine - > saveEffect ( obj ) ;
2018-12-31 15:48:29 +01:00
}
2020-03-26 17:59:41 +01:00
QString Hyperion : : deleteEffect ( const QString & effectName )
2016-11-20 18:41:10 +01:00
{
2020-03-26 17:59:41 +01:00
return _effectEngine - > deleteEffect ( effectName ) ;
2016-11-20 18:41:10 +01:00
}
2020-08-08 23:12:43 +02:00
std : : list < EffectDefinition > Hyperion : : getEffects ( ) const
2013-11-24 16:10:48 +01:00
{
return _effectEngine - > getEffects ( ) ;
}
2020-08-08 23:12:43 +02:00
std : : list < ActiveEffectDefinition > Hyperion : : getActiveEffects ( ) const
2016-04-24 17:07:31 +02:00
{
return _effectEngine - > getActiveEffects ( ) ;
}
2020-08-08 23:12:43 +02:00
std : : list < EffectSchema > Hyperion : : getEffectSchemas ( ) const
2016-10-24 23:52:53 +02:00
{
return _effectEngine - > getEffectSchemas ( ) ;
}
2020-08-08 23:12:43 +02:00
QJsonObject Hyperion : : getQJsonConfig ( ) const
2018-12-27 23:11:32 +01:00
{
return _settingsManager - > getSettings ( ) ;
}
2017-03-01 15:23:53 +01:00
int Hyperion : : setEffect ( const QString & effectName , int priority , int timeout , const QString & origin )
2013-11-24 16:10:48 +01:00
{
2017-03-01 15:23:53 +01:00
return _effectEngine - > runEffect ( effectName , priority , timeout , origin ) ;
2013-11-24 16:10:48 +01:00
}
2019-01-06 19:49:56 +01:00
int Hyperion : : setEffect ( const QString & effectName , const QJsonObject & args , int priority , int timeout , const QString & pythonScript , const QString & origin , const QString & imageData )
2013-12-01 14:09:01 +01:00
{
2019-01-06 19:49:56 +01:00
return _effectEngine - > runEffect ( effectName , args , priority , timeout , pythonScript , origin , 0 , imageData ) ;
2013-12-01 14:09:01 +01:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : setLedMappingType ( int mappingType )
2018-12-27 23:11:32 +01:00
{
if ( mappingType ! = _imageProcessor - > getUserLedMappingType ( ) )
{
_imageProcessor - > setLedMappingType ( mappingType ) ;
emit imageToLedsMappingChanged ( mappingType ) ;
}
}
2020-08-02 10:44:42 +02:00
int Hyperion : : getLedMappingType ( ) const
2016-12-19 23:59:50 +01:00
{
2018-12-27 23:11:32 +01:00
return _imageProcessor - > getUserLedMappingType ( ) ;
2016-12-19 23:59:50 +01:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : setVideoMode ( VideoMode mode )
2017-08-04 23:08:15 +02:00
{
emit videoMode ( mode ) ;
}
2020-08-02 10:44:42 +02:00
VideoMode Hyperion : : getCurrentVideoMode ( ) const
2018-12-27 23:11:32 +01:00
{
2019-07-14 22:43:22 +02:00
return _currVideoMode ;
2018-12-27 23:11:32 +01:00
}
2017-08-04 23:08:15 +02:00
2020-08-02 10:44:42 +02:00
QString Hyperion : : getActiveDeviceType ( ) const
2017-06-24 11:52:22 +02:00
{
2019-12-08 13:12:01 +01:00
return _ledDeviceWrapper - > getActiveDeviceType ( ) ;
2018-12-27 23:11:32 +01:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : handleVisibleComponentChanged ( hyperion : : Components comp )
2018-12-27 23:11:32 +01:00
{
2020-02-15 22:47:27 +01:00
_imageProcessor - > setBlackbarDetectDisable ( ( comp = = hyperion : : COMP_EFFECT ) ) ;
_imageProcessor - > setHardLedMappingType ( ( comp = = hyperion : : COMP_EFFECT ) ? 0 : - 1 ) ;
_raw2ledAdjustment - > setBacklightEnabled ( ( comp ! = hyperion : : COMP_COLOR & & comp ! = hyperion : : COMP_EFFECT ) ) ;
2017-06-24 11:52:22 +02:00
}
2021-08-31 10:56:06 +02:00
void Hyperion : : handleSourceAvailability ( const quint8 & priority )
{ int previousPriority = _muxer . getPreviousPriority ( ) ;
2020-09-14 17:19:14 +02:00
2020-11-14 17:58:56 +01:00
Debug ( _log , " priority[%d], previousPriority[%d] " , priority , previousPriority ) ;
2020-09-14 17:19:14 +02:00
if ( priority = = PriorityMuxer : : LOWEST_PRIORITY )
{
2021-08-31 10:56:06 +02:00
Debug ( _log , " No source left -> Pause output processing and switch LED-Device off " ) ;
2020-09-14 17:19:14 +02:00
emit _ledDeviceWrapper - > switchOff ( ) ;
2021-08-31 10:56:06 +02:00
emit _deviceSmooth - > setPause ( true ) ;
2020-09-14 17:19:14 +02:00
}
else
{
if ( previousPriority = = PriorityMuxer : : LOWEST_PRIORITY )
{
2021-08-31 10:56:06 +02:00
Debug ( _log , " new source available -> Resume output processing and switch LED-Device on " ) ;
2020-09-14 17:19:14 +02:00
emit _ledDeviceWrapper - > switchOn ( ) ;
2021-08-31 10:56:06 +02:00
emit _deviceSmooth - > setPause ( false ) ;
2020-09-14 17:19:14 +02:00
}
}
}
2013-08-14 17:02:09 +02:00
void Hyperion : : update ( )
{
2018-12-27 23:11:32 +01:00
// Obtain the current priority channel
int priority = _muxer . getCurrentPriority ( ) ;
const PriorityMuxer : : InputInfo priorityInfo = _muxer . getInputInfo ( priority ) ;
2018-12-20 15:12:45 +01:00
2018-12-27 23:11:32 +01:00
// copy image & process OR copy ledColors from muxer
Image < ColorRgb > image = priorityInfo . image ;
2021-05-16 18:33:24 +02:00
if ( image . width ( ) > 1 | | image . height ( ) > 1 )
2016-08-08 00:17:00 +02:00
{
2018-12-27 23:11:32 +01:00
emit currentImage ( image ) ;
2019-07-02 19:06:36 +02:00
_ledBuffer = _imageProcessor - > process ( image ) ;
2016-08-08 00:17:00 +02:00
}
2018-12-27 23:11:32 +01:00
else
2020-08-02 10:44:42 +02:00
{
2018-12-27 23:11:32 +01:00
_ledBuffer = priorityInfo . ledColors ;
2020-08-02 10:44:42 +02:00
}
2018-12-31 15:48:29 +01:00
// emit rawLedColors before transform
emit rawLedColors ( _ledBuffer ) ;
2018-12-27 23:11:32 +01:00
_raw2ledAdjustment - > applyAdjustment ( _ledBuffer ) ;
2017-06-24 11:52:22 +02:00
2015-01-01 19:31:04 +01:00
int i = 0 ;
2016-07-01 23:20:41 +02:00
for ( ColorRgb & color : _ledBuffer )
2013-08-21 21:50:17 +02:00
{
2013-11-04 20:52:57 +01:00
// correct the color byte order
2016-08-08 00:17:00 +02:00
switch ( _ledStringColorOrder . at ( i ) )
2013-10-27 10:18:31 +01:00
{
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_RGB :
2013-11-04 20:52:57 +01:00
// leave as it is
break ;
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_BGR :
2013-10-27 10:18:31 +01:00
std : : swap ( color . red , color . blue ) ;
2013-11-04 20:52:57 +01:00
break ;
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_RBG :
2013-11-04 20:52:57 +01:00
std : : swap ( color . green , color . blue ) ;
break ;
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_GRB :
2013-11-04 20:52:57 +01:00
std : : swap ( color . red , color . green ) ;
break ;
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_GBR :
2016-05-22 00:30:53 +02:00
std : : swap ( color . red , color . green ) ;
std : : swap ( color . green , color . blue ) ;
2013-11-04 20:52:57 +01:00
break ;
2017-01-10 19:58:41 +01:00
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_BRG :
2016-05-22 00:30:53 +02:00
std : : swap ( color . red , color . blue ) ;
std : : swap ( color . green , color . blue ) ;
2013-11-04 20:52:57 +01:00
break ;
}
2015-01-01 19:31:04 +01:00
i + + ;
2013-08-21 21:50:17 +02:00
}
2019-07-02 19:06:36 +02:00
2020-11-14 17:58:56 +01:00
// fill additional hardware LEDs with black
if ( _hwLedCount > static_cast < int > ( _ledBuffer . size ( ) ) )
2016-07-01 23:20:41 +02:00
{
_ledBuffer . resize ( _hwLedCount , ColorRgb : : BLACK ) ;
}
2017-06-24 11:52:22 +02:00
2013-08-14 17:02:09 +02:00
// Write the data to the device
2019-01-01 19:47:07 +01:00
if ( _ledDeviceWrapper - > enabled ( ) )
2017-03-21 17:55:46 +01:00
{
2019-12-08 13:12:01 +01:00
// Smoothing is disabled
2017-03-30 06:20:20 +02:00
if ( ! _deviceSmooth - > enabled ( ) )
2019-12-08 13:12:01 +01:00
{
2020-02-10 15:21:58 +01:00
//std::cout << "Hyperion::update()> Non-Smoothing - "; LedDevice::printLedValues ( _ledBuffer);
2019-01-01 19:47:07 +01:00
emit ledDeviceData ( _ledBuffer ) ;
2019-12-08 13:12:01 +01:00
}
2020-02-10 15:21:58 +01:00
else
{
_deviceSmooth - > selectConfig ( priorityInfo . smooth_cfg ) ;
2020-11-14 17:58:56 +01:00
// feed smoothing in pause mode to maintain a smooth transition back to smooth mode
2020-02-10 15:21:58 +01:00
if ( _deviceSmooth - > enabled ( ) | | _deviceSmooth - > pause ( ) )
{
_deviceSmooth - > updateLedValues ( _ledBuffer ) ;
}
}
2019-12-08 13:12:01 +01:00
}
2020-11-14 17:58:56 +01:00
#if 0
else
{
//LEDDevice is disabled
Debug ( _log , " LEDDevice is disabled - no update required " ) ;
}
# endif
2013-07-26 22:38:34 +02:00
}