hyperion.ng/include/hyperion/PriorityMuxer.h
Markus c135d91986
Media Foundation/V4L2 grabber ... (#1119)
* - New Media Foundation grabber
- JsonAPI available grabber fix
- commented json config removed

* Added libjpeg-turbo to dependencies

* Fix OSX build
Removed Azure Pipelines from build scripts

* Remove Platform from Dashboard

* Correct Grabber Namings

* Grabber UI improvements, generic JSONEditor Selection Update

* Active grabber fix

* Stop Framebuffer grabber on failure

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

* Refactor MediaFoundation (Part 1)

* Remove QDebug output

* Added image flipping ability to MF Grabber

* fix issue 1160

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

* Improvements

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

* Refactor MediaFoundation (Part 2)

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

* Media Foundation grabber adapted to V4L2 change

* Enable Media Foundation grabber on windows

* Have fps as int, fix height typo

* Added video standards to JsonAPI output

* Error handling in source reader improved

* Fix "Frame to small" error

* Discovery VideoSources and Dynamically Update Editor

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

* Do not show unsupported grabbers

* Copy Log to Clipboard

* Update Grabber schema and Defaults

* Update access levels and validate crop ranges

* Height and width in Qt grabber corrected

* Correct formatting

* Untabify

* Global component states across instances

* Components divided on the dashboard

* refactor

* Fix Merge-issues

* Database migration aligning with updated grabber model

* Align Grabber.js with new utility functions

* Allow editor-validation for enum-lists

* Handle "Show Explainations scenario" correctly

* Grabber - Ensure save is only possible on valid content

* Dashboard update + fix GlobalSignal connection

* Ensure default database is populated with current release

* Correct grabber4L2 access level

* Display Signal detection area in preview

* Write Hyperion version into default config on compiling.

* Create defaultconfig.json dynamically

* WebUI changes

* Correct grabber config look-ups

* Refactor i18n language loading

* Fix en.json

* Split global capture from instance capture config

* Update grabber default values

* Standalone grabber: Add --debug switch

* Enhance showInputOptionsForKey for multiple keys

* Add grabber instance link to system grabber config

* Only show signal detection area, if grabber is enabled

* Always show Active element on grabber page

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

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

* V4L2/MF changes

* Jsoneditor, Correct translation for default values

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

* MF Discovery extended

* Fix LGTM finding

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

* Concider Access level for item filtering

* Concider Access level for item filtering

* Revert "Concider Access level for item filtering"

This reverts commit 5b0ce3c0f2.

* Disable fpsSoftwareDecimation for framegrabber, as not supported yet

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

* added V4L2 color IDs

* LGTM findings fix

* destroy SR callback only on exit

* Grabber.js - Hide elements not supported by platform

* Fixed freezing start effect

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

* Grabber - Discovery - Add current values to properties

* Small things

* Clean-up Effects and have ENDLESS consistently defined

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

* Add missing translation mappings

* DirectX Grabber reactivated/ QT Grabber size decimation fixed

* typo in push-master workflow

* Use PreciseTimer for Grabber to ensure stable FPS timing

* Set default Screencapture rate consistently

* Fix libjpeg-turbo download

* Remove Zero character from file

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

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

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

* Fix definition

* OSXFRameGrabber - Revert cast

* Clean-ups nach Feedback

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

* Add CEC availability to ServerInfo to have it platform independent

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

* Preserve value when updating json-editor range

* LEDVisualisation - Clear image when source changes

* Fix - Preserve value when updating json-editor range

* LEDVisualisation - Clear image when no component is active

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

* Update default signal detection area to green assuming rainbow grabber

* LED Visualisation - Handle empty priority update

* Fix yuv420 in v4l2 grabber

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

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

* LED Visualisation - ClearImage when no priorities

* LED Visualisation - Fix Logo resizing issue

* LED Visualisation - Have nearly black background and negative logo

Co-authored-by: LordGrey <lordgrey.emmel@gmail.com>
Co-authored-by: LordGrey <48840279+Lord-Grey@users.noreply.github.com>
2021-07-14 20:48:33 +02:00

281 lines
8.2 KiB
C++

#pragma once
// STL includes
#include <vector>
#include <cstdint>
// QT includes
#include <QMap>
#include <QObject>
#include <QMap>
#include <QVector>
// Utils includes
#include <utils/ColorRgb.h>
#include <utils/Image.h>
#include <utils/Components.h>
// global defines
#define SMOOTHING_MODE_DEFAULT 0
#define SMOOTHING_MODE_PAUSE 1
class QTimer;
class Logger;
///
/// The PriorityMuxer handles the priority channels. Led values input/ images are written to the priority map
/// and the muxer keeps track of all active priorities. The current priority can be queried and per
/// priority the led colors. Handles also manual/auto selection mode, provides a lot of signals to hook into priority related events
///
class PriorityMuxer : public QObject
{
Q_OBJECT
public:
///
/// The information structure for a single priority channel
///
struct InputInfo
{
/// The priority of this channel
int priority;
/// The absolute timeout of the channel
int64_t timeoutTime_ms;
/// The colors for each led of the channel
std::vector<ColorRgb> ledColors;
/// The raw Image (size should be preprocessed!)
Image<ColorRgb> image;
/// The component
hyperion::Components componentId;
/// Who set it
QString origin;
/// id of smoothing config
unsigned smooth_cfg;
/// specific owner description
QString owner;
};
//Foreground and Background priorities
const static int FG_PRIORITY;
const static int BG_PRIORITY;
const static int MANUAL_SELECTED_PRIORITY;
/// The lowest possible priority, which is used when no priority channels are active
const static int LOWEST_PRIORITY;
/// Timeout used to identify a non active priority
const static int TIMEOUT_NOT_ACTIVE_PRIO;
///
/// Constructs the PriorityMuxer for the given number of LEDs (used to switch to black when
/// there are no priority channels
///
/// @param ledCount The number of LEDs
///
PriorityMuxer(int ledCount, QObject * parent);
///
/// Destructor
///
~PriorityMuxer() override;
///
/// @brief Start/Stop the PriorityMuxer update timer; On disabled no priority and timeout updates will be performend
/// @param enable The new state
///
void setEnable(bool enable);
/// @brief Enable or disable auto source selection
/// @param enable True if it should be enabled else false
/// @param update True to update _currentPriority - INTERNAL usage.
/// @return True if changed has been applied, false if the state is unchanged
///
bool setSourceAutoSelectEnabled(bool enable, bool update = true);
///
/// @brief Get the state of source auto selection
/// @return True if enabled, else false
///
bool isSourceAutoSelectEnabled() const { return _sourceAutoSelectEnabled; }
///
/// @brief Overwrite current lowest priority with manual selection; On success disables auto selection
/// @param priority The
/// @return True on success, false if priority not found
///
bool setPriority(int priority);
///
/// @brief Update all LED-Colors with min length of >= 1 to fit the new led length
/// @param[in] ledCount The count of LEDs
///
void updateLedColorsLength(int ledCount);
///
/// Returns the current priority
///
/// @return The current priority
///
int getCurrentPriority() const { return _currentPriority; }
///
/// Returns the previous priority before current priority
///
/// @return The previous priority
///
int getPreviousPriority() const { return _previousPriority; }
///
/// Returns the state (enabled/disabled) of a specific priority channel
/// @param priority The priority channel
/// @return True if the priority channel exists else false
///
bool hasPriority(int priority) const;
///
/// Returns the number of active priorities
///
/// @return The list with active priorities
///
QList<int> getPriorities() const;
///
/// Returns the information of a specified priority channel.
/// If a priority is no longer available the _lowestPriorityInfo (255) is returned
///
/// @param priority The priority channel
///
/// @return The information for the specified priority channel
///
InputInfo getInputInfo(int priority) const;
///
/// @brief Register a new input by priority, the priority is not active (timeout -100 isn't muxer recognized) until you start to update the data with setInput()
/// A repeated call to update the base data of a known priority won't overwrite their current timeout
/// @param[in] priority The priority of the channel
/// @param[in] component The component of the channel
/// @param[in] origin Who set the channel (CustomString@IP)
/// @param[in] owner Specific owner string, might be empty
/// @param[in] smooth_cfg The smooth id to use
///
void registerInput(int priority, hyperion::Components component, const QString& origin = "System", const QString& owner = "", unsigned smooth_cfg = SMOOTHING_MODE_DEFAULT);
///
/// @brief Update the current color of a priority (previous registered with registerInput())
/// @param priority The priority to update
/// @param ledColors The colors
/// @param timeout_ms The new timeout (defaults to -1 endless)
/// @return True on success, false when priority is not found
///
bool setInput(int priority, const std::vector<ColorRgb>& ledColors, int64_t timeout_ms = -1);
///
/// @brief Update the current image of a priority (prev registered with registerInput())
/// @param priority The priority to update
/// @param image The new image
/// @param timeout_ms The new timeout (defaults to -1 endless)
/// @return True on success, false when priority is not found
///
bool setInputImage(int priority, const Image<ColorRgb>& image, int64_t timeout_ms = -1);
///
/// @brief Set the given priority to inactive
/// @param priority The priority
/// @return True on success false if not found
///
bool setInputInactive(int priority);
///
/// Clears the specified priority channel and update _currentPriority on success
///
/// @param[in] priority The priority of the channel to clear
/// @return True if priority has been cleared else false (not found)
///
bool clearInput(int priority);
///
/// Clears all priority channels
///
void clearAll(bool forceClearAll=false);
///
/// @brief Queue a manual push where muxer doesn't recognize them (e.g. continuous single color pushes)
///
void queuePush() { emit timeRunner(); }
signals:
///
/// @brief Signal which emits when a effect or color with timeout > -1 is running, once per second
///
void timeRunner();
///
/// @brief Emits whenever the visible priority has changed
/// @param priority The new visible priority
///
void visiblePriorityChanged(quint8 priority);
///
/// @brief Emits whenever the current visible component changed
/// @param comp The new component
///
void visibleComponentChanged(hyperion::Components comp);
///
/// @brief Emits whenever something changes which influences the priorities listing
/// Emits also in 1s interval when a COLOR or EFFECT is running with a timeout > -1
///
void prioritiesChanged();
///
/// internal used signal to resolve treading issues with timer
///
void signalTimeTrigger();
private slots:
///
/// Slot which is called to adapt to 1s interval for signal timeRunner() / prioritiesChanged()
///
void timeTrigger();
///
/// Updates the current time. Channels with a configured time out will be checked and cleared if
/// required.
///
void setCurrentTime();
private:
///
/// @brief Get the component of the given priority
/// @return The component
///
hyperion::Components getComponentOfPriority(int priority) const;
/// Logger instance
Logger* _log;
/// The current priority (lowest value in _activeInputs)
int _currentPriority;
/// The previous priority before current priority
int _previousPriority;
/// The manual select priority set with setPriority
int _manualSelectedPriority;
// The last visible component
hyperion::Components _prevVisComp = hyperion::COMP_INVALID;
/// The mapping from priority channel to led-information
QMap<int, InputInfo> _activeInputs;
/// The information of the lowest priority channel
InputInfo _lowestPriorityInfo;
// Reflect the state of auto select
bool _sourceAutoSelectEnabled;
// Timer to update Muxer times independent
QTimer* _updateTimer;
QTimer* _timer;
QTimer* _blockTimer;
};