mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Merge remote-tracking branch 'origin/grabberDiscovery' into mediafoundation
This commit is contained in:
@@ -21,6 +21,9 @@ class Effect : public QThread
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
static const int ENDLESS;
|
||||
|
||||
friend class EffectModule;
|
||||
|
||||
Effect(Hyperion *hyperion
|
||||
@@ -44,10 +47,21 @@ public:
|
||||
void requestInterruption() { _interupt = true; }
|
||||
|
||||
///
|
||||
/// @brief Check if the interruption flag has been set
|
||||
/// @brief Check an interruption was requested.
|
||||
/// This can come from requestInterruption()
|
||||
/// or the effect's timeout expiring.
|
||||
///
|
||||
/// @return The flag state
|
||||
///
|
||||
bool isInterruptionRequested() { return _interupt; }
|
||||
bool isInterruptionRequested();
|
||||
|
||||
///
|
||||
/// @brief Get the remaining timeout, or indication it is endless
|
||||
///
|
||||
/// @return The flag state
|
||||
///
|
||||
int getRemaining() const;
|
||||
|
||||
|
||||
QString getScript() const { return _script; }
|
||||
QString getName() const { return _name; }
|
||||
@@ -76,7 +90,7 @@ private:
|
||||
const QJsonObject _args;
|
||||
const QString _imageData;
|
||||
|
||||
int64_t _endTime;
|
||||
qint64 _endTime;
|
||||
|
||||
/// Buffer for colorData
|
||||
QVector<ColorRgb> _colors;
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
// Effect engine includes
|
||||
#include <effectengine/EffectDefinition.h>
|
||||
#include <effectengine/Effect.h>
|
||||
#include <effectengine/ActiveEffectDefinition.h>
|
||||
#include <effectengine/EffectSchema.h>
|
||||
#include <utils/Logger.h>
|
||||
@@ -69,13 +70,13 @@ signals:
|
||||
|
||||
public slots:
|
||||
/// Run the specified effect on the given priority channel and optionally specify a timeout
|
||||
int runEffect(const QString &effectName, int priority, int timeout = -1, const QString &origin="System");
|
||||
int runEffect(const QString &effectName, int priority, int timeout = Effect::ENDLESS, const QString &origin="System");
|
||||
|
||||
/// Run the specified effect on the given priority channel and optionally specify a timeout
|
||||
int runEffect(const QString &effectName
|
||||
, const QJsonObject &args
|
||||
, int priority
|
||||
, int timeout = -1
|
||||
, int timeout = Effect::ENDLESS
|
||||
, const QString &pythonScript = ""
|
||||
, const QString &origin = "System"
|
||||
, unsigned smoothCfg=0
|
||||
@@ -102,7 +103,7 @@ private:
|
||||
,const QString &name
|
||||
, const QJsonObject &args
|
||||
, int priority
|
||||
, int timeout = -1
|
||||
, int timeout = Effect::ENDLESS
|
||||
, const QString &origin="System"
|
||||
, unsigned smoothCfg=0
|
||||
, const QString &imageData = ""
|
||||
|
@@ -64,12 +64,12 @@ private:
|
||||
///
|
||||
/// @brief Load the effect definition, called by updateEffects()
|
||||
///
|
||||
bool loadEffectDefinition(const QString & path, const QString & effectConfigFile, EffectDefinition &effectDefinition);
|
||||
bool loadEffectDefinition(const QString& path, const QString& effectConfigFile, EffectDefinition& effectDefinition);
|
||||
|
||||
///
|
||||
/// @brief load effect schemas, called by updateEffects()
|
||||
///
|
||||
bool loadEffectSchema(const QString & path, const QString & effectSchemaFile, EffectSchema &effectSchema);
|
||||
bool loadEffectSchema(const QString& path, const QString& effectSchemaFile, EffectSchema& effectSchema);
|
||||
|
||||
private:
|
||||
QJsonObject _effectConfig;
|
||||
|
@@ -54,6 +54,11 @@ public:
|
||||
///
|
||||
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
|
||||
|
||||
///
|
||||
/// @brief Apply display index
|
||||
///
|
||||
void setDisplayIndex(int index) override;
|
||||
|
||||
private:
|
||||
///
|
||||
/// @brief Setup a new capture display, will free the previous one
|
||||
@@ -68,6 +73,7 @@ private:
|
||||
|
||||
private:
|
||||
int _pixelDecimation;
|
||||
unsigned _display;
|
||||
unsigned _displayWidth;
|
||||
unsigned _displayHeight;
|
||||
RECT* _srcRect;
|
||||
|
@@ -11,6 +11,9 @@
|
||||
#include <QRectF>
|
||||
#include <QMap>
|
||||
#include <QMultiMap>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
// utils includes
|
||||
#include <utils/PixelFormat.h>
|
||||
@@ -38,7 +41,6 @@ class MFGrabber : public Grabber
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class SourceReaderCB;
|
||||
|
||||
public:
|
||||
struct DeviceProperties
|
||||
{
|
||||
@@ -52,79 +54,72 @@ public:
|
||||
GUID guid = GUID_NULL;
|
||||
};
|
||||
|
||||
MFGrabber(const QString & device, const unsigned width, const unsigned height, const unsigned fps, int pixelDecimation, QString flipMode);
|
||||
MFGrabber();
|
||||
~MFGrabber() override;
|
||||
|
||||
void receive_image(const void *frameImageBuffer, int size);
|
||||
QRectF getSignalDetectionOffset() const { return QRectF(_x_frac_min, _y_frac_min, _x_frac_max, _y_frac_max); }
|
||||
bool getSignalDetectionEnabled() const { return _signalDetectionEnabled; }
|
||||
bool getCecDetectionEnabled() const { return _cecDetectionEnabled; }
|
||||
QStringList getDevices() const override;
|
||||
QString getDeviceName(const QString& devicePath) const override { return devicePath; }
|
||||
QMultiMap<QString, int> getDeviceInputs(const QString& devicePath) const override { return { {devicePath, 0} }; }
|
||||
QStringList getAvailableEncodingFormats(const QString& devicePath, const int& /*deviceInput*/) const override;
|
||||
QMultiMap<int, int> getAvailableDeviceResolutions(const QString& devicePath, const int& /*deviceInput*/, const PixelFormat& encFormat) const override;
|
||||
QIntList getAvailableDeviceFramerates(const QString& devicePath, const int& /*deviceInput*/, const PixelFormat& encFormat, const unsigned width, const unsigned height) const override;
|
||||
void setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, int noSignalCounterThreshold) override;
|
||||
void setSignalDetectionOffset( double verticalMin, double horizontalMin, double verticalMax, double horizontalMax) override;
|
||||
void setSignalDetectionEnable(bool enable) override;
|
||||
void setPixelDecimation(int pixelDecimation) override;
|
||||
void setCecDetectionEnable(bool enable) override;
|
||||
bool setDevice(QString device) override;
|
||||
void setDevice(const QString& device);
|
||||
bool setInput(int input) override;
|
||||
bool setWidthHeight(int width, int height) override;
|
||||
bool setFramerate(int fps) override;
|
||||
void setFpsSoftwareDecimation(int decimation);
|
||||
bool setEncoding(QString enc);
|
||||
void setFlipMode(QString flipMode);
|
||||
bool setBrightnessContrastSaturationHue(int brightness, int contrast, int saturation, int hue);
|
||||
void setEncoding(QString enc);
|
||||
void setBrightnessContrastSaturationHue(int brightness, int contrast, int saturation, int hue);
|
||||
void setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, int noSignalCounterThreshold);
|
||||
void setSignalDetectionOffset( double verticalMin, double horizontalMin, double verticalMax, double horizontalMax);
|
||||
void setSignalDetectionEnable(bool enable);
|
||||
bool reload(bool force = false);
|
||||
|
||||
void reloadGrabber();
|
||||
///
|
||||
/// @brief Discover available Media Foundation USB devices (for configuration).
|
||||
/// @param[in] params Parameters used to overwrite discovery default behaviour
|
||||
/// @return A JSON structure holding a list of USB devices found
|
||||
///
|
||||
QJsonArray discover(const QJsonObject& params);
|
||||
|
||||
public slots:
|
||||
bool prepare();
|
||||
bool start();
|
||||
void stop();
|
||||
void newThreadFrame(unsigned int _workerIndex, const Image<ColorRgb>& image,unsigned int sourceCount);
|
||||
void newThreadFrame(Image<ColorRgb> image);
|
||||
|
||||
signals:
|
||||
void newFrame(const Image<ColorRgb> & image);
|
||||
void readError(const char* err);
|
||||
|
||||
private:
|
||||
bool init();
|
||||
void uninit();
|
||||
HRESULT init_device(QString device, DeviceProperties props);
|
||||
void uninit_device();
|
||||
void enumVideoCaptureDevices();
|
||||
void start_capturing();
|
||||
void process_image(const void *frameImageBuffer, int size);
|
||||
void checkSignalDetectionEnabled(Image<ColorRgb> image);
|
||||
|
||||
QString _currentDeviceName, _newDeviceName;
|
||||
QString _currentDeviceName,
|
||||
_newDeviceName;
|
||||
QMap<QString, QList<DeviceProperties>> _deviceProperties;
|
||||
HRESULT _hr;
|
||||
IMFSourceReader* _sourceReader;
|
||||
SourceReaderCB* _sourceReaderCB;
|
||||
PixelFormat _pixelFormat, _pixelFormatConfig;
|
||||
int _pixelDecimation,
|
||||
_lineLength,
|
||||
MFThreadManager* _threadManager;
|
||||
PixelFormat _pixelFormat,
|
||||
_pixelFormatConfig;
|
||||
int _lineLength,
|
||||
_frameByteSize,
|
||||
_noSignalCounterThreshold,
|
||||
_noSignalCounter,
|
||||
_fpsSoftwareDecimation,
|
||||
_brightness,
|
||||
_contrast,
|
||||
_saturation,
|
||||
_hue;
|
||||
volatile unsigned int _currentFrame;
|
||||
QAtomicInt _currentFrame;
|
||||
ColorRgb _noSignalThresholdColor;
|
||||
bool _signalDetectionEnabled,
|
||||
_cecDetectionEnabled,
|
||||
_noSignalDetected,
|
||||
_initialized;
|
||||
_initialized,
|
||||
_reload;
|
||||
double _x_frac_min,
|
||||
_y_frac_min,
|
||||
_x_frac_max,
|
||||
_y_frac_max;
|
||||
MFThreadManager _threadManager;
|
||||
IMFSourceReader* _sourceReader;
|
||||
|
||||
#ifdef HAVE_TURBO_JPEG
|
||||
int _subsamp;
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
// Qt includes
|
||||
#include <QThread>
|
||||
#include <QSemaphore>
|
||||
|
||||
// util includes
|
||||
#include <utils/PixelFormat.h>
|
||||
@@ -15,31 +14,27 @@
|
||||
#include <turbojpeg.h>
|
||||
#endif
|
||||
|
||||
// Forward class declaration
|
||||
class MFThreadManager;
|
||||
|
||||
/// Encoder thread for USB devices
|
||||
class MFThread : public QThread
|
||||
class MFThread : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class MFThreadManager;
|
||||
|
||||
public:
|
||||
MFThread();
|
||||
explicit MFThread();
|
||||
~MFThread();
|
||||
|
||||
void setup(
|
||||
unsigned int threadIndex, PixelFormat pixelFormat, uint8_t* sharedData,
|
||||
PixelFormat pixelFormat, uint8_t* sharedData,
|
||||
int size, int width, int height, int lineLength,
|
||||
int subsamp, unsigned cropLeft, unsigned cropTop, unsigned cropBottom, unsigned cropRight,
|
||||
VideoMode videoMode, FlipMode flipMode, int currentFrame, int pixelDecimation);
|
||||
void run();
|
||||
VideoMode videoMode, FlipMode flipMode, int pixelDecimation);
|
||||
|
||||
bool isBusy();
|
||||
void noBusy();
|
||||
void process();
|
||||
|
||||
bool isBusy() { return _busy; }
|
||||
QAtomicInt _busy = false;
|
||||
|
||||
signals:
|
||||
void newFrame(unsigned int threadIndex, const Image<ColorRgb>& data, unsigned int sourceCount);
|
||||
void newFrame(const Image<ColorRgb>& data);
|
||||
|
||||
private:
|
||||
void processImageMjpeg();
|
||||
@@ -51,73 +46,132 @@ private:
|
||||
tjtransform* _xform;
|
||||
#endif
|
||||
|
||||
static volatile bool _isActive;
|
||||
volatile bool _isBusy;
|
||||
QSemaphore _semaphore;
|
||||
unsigned int _threadIndex;
|
||||
PixelFormat _pixelFormat;
|
||||
uint8_t* _localData, *_flipBuffer;
|
||||
int _scalingFactorsCount, _width, _height, _lineLength, _subsamp, _currentFrame, _pixelDecimation;
|
||||
unsigned long _size;
|
||||
unsigned _cropLeft, _cropTop, _cropBottom, _cropRight;
|
||||
FlipMode _flipMode;
|
||||
ImageResampler _imageResampler;
|
||||
PixelFormat _pixelFormat;
|
||||
uint8_t* _localData,
|
||||
*_flipBuffer;
|
||||
int _scalingFactorsCount,
|
||||
_width,
|
||||
_height,
|
||||
_lineLength,
|
||||
_subsamp,
|
||||
_currentFrame,
|
||||
_pixelDecimation;
|
||||
unsigned long _size;
|
||||
unsigned _cropLeft,
|
||||
_cropTop,
|
||||
_cropBottom,
|
||||
_cropRight;
|
||||
FlipMode _flipMode;
|
||||
ImageResampler _imageResampler;
|
||||
};
|
||||
|
||||
template <typename TThread> class Thread : public QThread
|
||||
{
|
||||
public:
|
||||
TThread *_thread;
|
||||
explicit Thread(TThread *thread, QObject *parent = nullptr)
|
||||
: QThread(parent)
|
||||
, _thread(thread)
|
||||
{
|
||||
_thread->moveToThread(this);
|
||||
start();
|
||||
}
|
||||
|
||||
~Thread()
|
||||
{
|
||||
quit();
|
||||
wait();
|
||||
}
|
||||
|
||||
MFThread* thread() const { return qobject_cast<MFThread*>(_thread); }
|
||||
|
||||
void setup(
|
||||
PixelFormat pixelFormat, uint8_t* sharedData,
|
||||
int size, int width, int height, int lineLength,
|
||||
int subsamp, unsigned cropLeft, unsigned cropTop, unsigned cropBottom, unsigned cropRight,
|
||||
VideoMode videoMode, FlipMode flipMode, int pixelDecimation)
|
||||
{
|
||||
auto mfthread = qobject_cast<MFThread*>(_thread);
|
||||
if (mfthread != nullptr)
|
||||
mfthread->setup(pixelFormat, sharedData,
|
||||
size, width, height, lineLength,
|
||||
subsamp, cropLeft, cropTop, cropBottom, cropRight,
|
||||
videoMode, flipMode, pixelDecimation);
|
||||
}
|
||||
|
||||
bool isBusy()
|
||||
{
|
||||
auto mfthread = qobject_cast<MFThread*>(_thread);
|
||||
if (mfthread != nullptr)
|
||||
return mfthread->isBusy();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
auto mfthread = qobject_cast<MFThread*>(_thread);
|
||||
if (mfthread != nullptr)
|
||||
mfthread->process();
|
||||
}
|
||||
|
||||
protected:
|
||||
void run() override
|
||||
{
|
||||
QThread::run();
|
||||
delete _thread;
|
||||
}
|
||||
};
|
||||
|
||||
class MFThreadManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
MFThreadManager() : _threads(nullptr)
|
||||
explicit MFThreadManager(QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
, _threadCount(qMax(QThread::idealThreadCount(), 1))
|
||||
, _threads(nullptr)
|
||||
{
|
||||
_maxThreads = qBound(1, (QThread::idealThreadCount() > 4 ? (QThread::idealThreadCount() - 1) : QThread::idealThreadCount()), 8);
|
||||
_threads = new Thread<MFThread>*[_threadCount];
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_threads[i] = new Thread<MFThread>(new MFThread, this);
|
||||
_threads[i]->setObjectName("MFThread " + i);
|
||||
}
|
||||
}
|
||||
|
||||
~MFThreadManager()
|
||||
{
|
||||
if (_threads != nullptr)
|
||||
{
|
||||
for(unsigned i=0; i < _maxThreads; i++)
|
||||
if (_threads[i] != nullptr)
|
||||
{
|
||||
_threads[i]->deleteLater();
|
||||
_threads[i] = nullptr;
|
||||
}
|
||||
for(int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_threads[i]->deleteLater();
|
||||
_threads[i] = nullptr;
|
||||
}
|
||||
|
||||
delete[] _threads;
|
||||
_threads = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void initThreads()
|
||||
void start()
|
||||
{
|
||||
if (_maxThreads >= 1)
|
||||
{
|
||||
_threads = new MFThread*[_maxThreads];
|
||||
for (unsigned i=0; i < _maxThreads; i++)
|
||||
_threads[i] = new MFThread();
|
||||
}
|
||||
if (_threads != nullptr)
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
connect(_threads[i]->thread(), &MFThread::newFrame, this, &MFThreadManager::newFrame);
|
||||
}
|
||||
|
||||
void start() { MFThread::_isActive = true; }
|
||||
bool isActive() { return MFThread::_isActive; }
|
||||
|
||||
void stop()
|
||||
{
|
||||
MFThread::_isActive = false;
|
||||
|
||||
if (_threads != nullptr)
|
||||
{
|
||||
for(unsigned i = 0; i < _maxThreads; i++)
|
||||
if (_threads[i] != nullptr)
|
||||
{
|
||||
_threads[i]->quit();
|
||||
_threads[i]->wait();
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < _threadCount; i++)
|
||||
disconnect(_threads[i]->thread(), nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
unsigned int _maxThreads;
|
||||
MFThread** _threads;
|
||||
int _threadCount;
|
||||
Thread<MFThread>** _threads;
|
||||
|
||||
signals:
|
||||
void newFrame(const Image<ColorRgb>& data);
|
||||
};
|
||||
|
@@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
#include <grabber/MFGrabber.h>
|
||||
|
||||
class MFWrapper : public GrabberWrapper
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MFWrapper(const QString & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned fps, int pixelDecimation, QString flipMode);
|
||||
~MFWrapper() override;
|
||||
|
||||
bool getSignalDetectionEnable() const;
|
||||
bool getCecDetectionEnable() const;
|
||||
|
||||
public slots:
|
||||
bool start() override;
|
||||
void stop() override;
|
||||
|
||||
void setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, int noSignalCounterThreshold);
|
||||
void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom) override;
|
||||
void setSignalDetectionOffset(double verticalMin, double horizontalMin, double verticalMax, double horizontalMax);
|
||||
void setSignalDetectionEnable(bool enable);
|
||||
void setCecDetectionEnable(bool enable);
|
||||
bool setDevice(const QString& device);
|
||||
void setFpsSoftwareDecimation(int decimation);
|
||||
bool setEncoding(QString enc);
|
||||
bool setBrightnessContrastSaturationHue(int brightness, int contrast, int saturation, int hue);
|
||||
void handleSettingsUpdate(settings::type type, const QJsonDocument& config) override;
|
||||
|
||||
private slots:
|
||||
void newFrame(const Image<ColorRgb> & image);
|
||||
|
||||
void action() override;
|
||||
|
||||
private:
|
||||
/// The Media Foundation grabber
|
||||
MFGrabber _grabber;
|
||||
};
|
@@ -15,7 +15,7 @@ class QtGrabber : public Grabber
|
||||
{
|
||||
public:
|
||||
|
||||
QtGrabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, int display);
|
||||
QtGrabber(int cropLeft=0, int cropRight=0, int cropTop=0, int cropBottom=0, int pixelDecimation=8, int display=0);
|
||||
|
||||
~QtGrabber() override;
|
||||
|
||||
@@ -39,11 +39,6 @@ public:
|
||||
///
|
||||
bool setWidthHeight(int width, int height) override { return true; }
|
||||
|
||||
///
|
||||
/// @brief Apply new pixelDecimation
|
||||
///
|
||||
void setPixelDecimation(int pixelDecimation) override;
|
||||
|
||||
///
|
||||
/// Set the crop values
|
||||
/// @param cropLeft Left pixel crop
|
||||
@@ -58,6 +53,28 @@ public:
|
||||
///
|
||||
void setDisplayIndex(int index) override;
|
||||
|
||||
///
|
||||
/// @brief Discover QT screens available (for configuration).
|
||||
///
|
||||
/// @param[in] params Parameters used to overwrite discovery default behaviour
|
||||
///
|
||||
/// @return A JSON structure holding a list of devices found
|
||||
///
|
||||
QJsonObject discover(const QJsonObject& params);
|
||||
|
||||
///
|
||||
/// @brief Setup a new capture display, will free the previous one
|
||||
/// @return True on success, false if no display is found
|
||||
///
|
||||
bool setupDisplay();
|
||||
|
||||
///
|
||||
/// @brief Opens the input device.
|
||||
///
|
||||
/// @return Zero, on success (i.e. device is ready), else negative
|
||||
///
|
||||
bool open();
|
||||
|
||||
private slots:
|
||||
///
|
||||
/// @brief is called whenever the current _screen changes it's geometry
|
||||
@@ -66,11 +83,7 @@ private slots:
|
||||
void geometryChanged(const QRect &geo);
|
||||
|
||||
private:
|
||||
///
|
||||
/// @brief Setup a new capture display, will free the previous one
|
||||
/// @return True on success, false if no display is found
|
||||
///
|
||||
bool setupDisplay();
|
||||
|
||||
|
||||
///
|
||||
/// @brief Is called whenever we need new screen dimension calculations based on window geometry
|
||||
@@ -84,13 +97,20 @@ private:
|
||||
|
||||
private:
|
||||
|
||||
unsigned _display;
|
||||
int _display;
|
||||
int _numberOfSDisplays;
|
||||
|
||||
int _pixelDecimation;
|
||||
unsigned _calculatedWidth;
|
||||
unsigned _calculatedHeight;
|
||||
unsigned _src_x;
|
||||
unsigned _src_y;
|
||||
unsigned _src_x_max;
|
||||
unsigned _src_y_max;
|
||||
int _calculatedWidth;
|
||||
int _calculatedHeight;
|
||||
int _src_x;
|
||||
int _src_y;
|
||||
int _src_x_max;
|
||||
int _src_y_max;
|
||||
bool _isWayland;
|
||||
|
||||
QScreen* _screen;
|
||||
bool _isVirtual;
|
||||
|
||||
Logger * _logger;
|
||||
};
|
||||
|
@@ -21,6 +21,11 @@ public:
|
||||
///
|
||||
QtWrapper(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, int display, unsigned updateRate_Hz);
|
||||
|
||||
///
|
||||
/// Starts the grabber which produces led values with the specified update rate
|
||||
///
|
||||
bool open() override;
|
||||
|
||||
public slots:
|
||||
///
|
||||
/// Performs a single frame grab and computes the led-colors
|
||||
|
@@ -16,7 +16,12 @@
|
||||
#include <hyperion/Grabber.h>
|
||||
#include <utils/VideoStandard.h>
|
||||
#include <utils/Components.h>
|
||||
#include <cec/CECEvent.h>
|
||||
|
||||
#include <HyperionConfig.h> // Required to determine the cmake options
|
||||
|
||||
#if defined(ENABLE_CEC)
|
||||
#include <cec/CECEvent.h>
|
||||
#endif
|
||||
|
||||
// general JPEG decoder includes
|
||||
#ifdef HAVE_JPEG_DECODER
|
||||
@@ -53,8 +58,8 @@ public:
|
||||
QList<VideoStandard> standards = QList<VideoStandard>();
|
||||
struct EncodingProperties
|
||||
{
|
||||
unsigned int width = 0;
|
||||
unsigned int height = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
QList<int> framerates = QList<int>();
|
||||
};
|
||||
QMultiMap<PixelFormat, EncodingProperties> encodingFormats = QMultiMap<PixelFormat, EncodingProperties>();
|
||||
@@ -62,115 +67,40 @@ public:
|
||||
QMap<int, InputProperties> inputs = QMap<int, InputProperties>();
|
||||
};
|
||||
|
||||
V4L2Grabber(const QString & device, const unsigned width, const unsigned height, const unsigned fps, const unsigned input, VideoStandard videoStandard, PixelFormat pixelFormat, int pixelDecimation);
|
||||
V4L2Grabber();
|
||||
~V4L2Grabber() override;
|
||||
|
||||
QRectF getSignalDetectionOffset() const
|
||||
{
|
||||
return QRectF(_x_frac_min, _y_frac_min, _x_frac_max, _y_frac_max);
|
||||
}
|
||||
|
||||
bool getSignalDetectionEnabled() const { return _signalDetectionEnabled; }
|
||||
bool getCecDetectionEnabled() const { return _cecDetectionEnabled; }
|
||||
|
||||
int grabFrame(Image<ColorRgb> &);
|
||||
|
||||
///
|
||||
/// @brief set new PixelDecimation value to ImageResampler
|
||||
/// @param pixelDecimation The new pixelDecimation value
|
||||
///
|
||||
void setPixelDecimation(int pixelDecimation) override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
void setSignalThreshold(
|
||||
double redSignalThreshold,
|
||||
double greenSignalThreshold,
|
||||
double blueSignalThreshold,
|
||||
int noSignalCounterThreshold = 50) override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
void setSignalDetectionOffset(
|
||||
double verticalMin,
|
||||
double horizontalMin,
|
||||
double verticalMax,
|
||||
double horizontalMax) override;
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
void setSignalDetectionEnable(bool enable) override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
void setCecDetectionEnable(bool enable) override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
void setDeviceVideoStandard(QString device, VideoStandard videoStandard) override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
void setDevice(const QString& device);
|
||||
bool setInput(int input) override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
bool setWidthHeight(int width, int height) override;
|
||||
void setEncoding(QString enc);
|
||||
void setBrightnessContrastSaturationHue(int brightness, int contrast, int saturation, int hue);
|
||||
void setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, int noSignalCounterThreshold = 50);
|
||||
void setSignalDetectionOffset( double verticalMin, double horizontalMin, double verticalMax, double horizontalMax);
|
||||
void setSignalDetectionEnable(bool enable);
|
||||
void setCecDetectionEnable(bool enable);
|
||||
bool reload(bool force = false);
|
||||
|
||||
QRectF getSignalDetectionOffset() const { return QRectF(_x_frac_min, _y_frac_min, _x_frac_max, _y_frac_max); } //used from hyperion-v4l2
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
/// @brief Discover available V4L2 USB devices (for configuration).
|
||||
/// @param[in] params Parameters used to overwrite discovery default behaviour
|
||||
/// @return A JSON structure holding a list of USB devices found
|
||||
///
|
||||
bool setFramerate(int fps) override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
QStringList getDevices() const override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
QString getDeviceName(const QString& devicePath) const override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
QMultiMap<QString, int> getDeviceInputs(const QString& devicePath) const override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
QList<VideoStandard> getAvailableDeviceStandards(const QString& devicePath, const int& deviceInput) const override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
QStringList getAvailableEncodingFormats(const QString& devicePath, const int& deviceInput) const override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
QMultiMap<int, int> getAvailableDeviceResolutions(const QString& devicePath, const int& deviceInput, const PixelFormat& encFormat) const override;
|
||||
|
||||
///
|
||||
/// @brief overwrite Grabber.h implementation
|
||||
///
|
||||
QIntList getAvailableDeviceFramerates(const QString& devicePath, const int& deviceInput, const PixelFormat& encFormat, const unsigned width, const unsigned height) const override;
|
||||
|
||||
QJsonArray discover(const QJsonObject& params);
|
||||
|
||||
public slots:
|
||||
|
||||
bool prepare() { return true; }
|
||||
bool start();
|
||||
|
||||
void stop();
|
||||
|
||||
#if defined(ENABLE_CEC)
|
||||
void handleCecEvent(CECEvent event);
|
||||
#endif
|
||||
|
||||
signals:
|
||||
void newFrame(const Image<ColorRgb> & image);
|
||||
@@ -180,36 +110,21 @@ private slots:
|
||||
int read_frame();
|
||||
|
||||
private:
|
||||
void getV4Ldevices();
|
||||
|
||||
void enumVideoCaptureDevices();
|
||||
bool init();
|
||||
|
||||
void uninit();
|
||||
|
||||
bool open_device();
|
||||
|
||||
void close_device();
|
||||
|
||||
void init_read(unsigned int buffer_size);
|
||||
|
||||
void init_mmap();
|
||||
|
||||
void init_userp(unsigned int buffer_size);
|
||||
|
||||
void init_device(VideoStandard videoStandard);
|
||||
|
||||
void uninit_device();
|
||||
|
||||
void start_capturing();
|
||||
|
||||
void stop_capturing();
|
||||
|
||||
bool process_image(const void *p, int size);
|
||||
|
||||
void process_image(const uint8_t *p, int size);
|
||||
|
||||
int xioctl(int request, void *arg);
|
||||
|
||||
int xioctl(int fileDescriptor, int request, void *arg);
|
||||
|
||||
void throw_exception(const QString & error)
|
||||
@@ -264,16 +179,14 @@ private:
|
||||
#endif
|
||||
|
||||
private:
|
||||
QString _deviceName;
|
||||
std::map<QString, QString> _v4lDevices;
|
||||
QString _currentDeviceName, _newDeviceName;
|
||||
QMap<QString, V4L2Grabber::DeviceProperties> _deviceProperties;
|
||||
|
||||
VideoStandard _videoStandard;
|
||||
io_method _ioMethod;
|
||||
int _fileDescriptor;
|
||||
std::vector<buffer> _buffers;
|
||||
|
||||
PixelFormat _pixelFormat;
|
||||
PixelFormat _pixelFormat, _pixelFormatConfig;
|
||||
int _pixelDecimation;
|
||||
int _lineLength;
|
||||
int _frameByteSize;
|
||||
@@ -281,10 +194,7 @@ private:
|
||||
// signal detection
|
||||
int _noSignalCounterThreshold;
|
||||
ColorRgb _noSignalThresholdColor;
|
||||
bool _signalDetectionEnabled;
|
||||
bool _cecDetectionEnabled;
|
||||
bool _cecStandbyActivated;
|
||||
bool _noSignalDetected;
|
||||
bool _cecDetectionEnabled, _cecStandbyActivated, _signalDetectionEnabled, _noSignalDetected;
|
||||
int _noSignalCounter;
|
||||
double _x_frac_min;
|
||||
double _y_frac_min;
|
||||
@@ -293,8 +203,7 @@ private:
|
||||
|
||||
QSocketNotifier *_streamNotifier;
|
||||
|
||||
bool _initialized;
|
||||
bool _deviceAutoDiscoverEnabled;
|
||||
bool _initialized, _reload;
|
||||
|
||||
protected:
|
||||
void enumFrameIntervals(QList<int> &framerates, int fileDescriptor, int pixelformat, int width, int height);
|
||||
|
@@ -1,46 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
#include <grabber/V4L2Grabber.h>
|
||||
|
||||
class V4L2Wrapper : public GrabberWrapper
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
V4L2Wrapper(const QString & device,
|
||||
const unsigned grabWidth,
|
||||
const unsigned grabHeight,
|
||||
const unsigned fps,
|
||||
const unsigned input,
|
||||
VideoStandard videoStandard,
|
||||
PixelFormat pixelFormat,
|
||||
int pixelDecimation);
|
||||
~V4L2Wrapper() override;
|
||||
|
||||
bool getSignalDetectionEnable() const;
|
||||
bool getCecDetectionEnable() const;
|
||||
|
||||
public slots:
|
||||
bool start() override;
|
||||
void stop() override;
|
||||
|
||||
void setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold);
|
||||
void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom) override;
|
||||
void setSignalDetectionOffset(double verticalMin, double horizontalMin, double verticalMax, double horizontalMax);
|
||||
void setSignalDetectionEnable(bool enable);
|
||||
void setCecDetectionEnable(bool enable);
|
||||
void setDeviceVideoStandard(const QString& device, VideoStandard videoStandard);
|
||||
void handleCecEvent(CECEvent event);
|
||||
void handleSettingsUpdate(settings::type type, const QJsonDocument& config) override;
|
||||
|
||||
private slots:
|
||||
void newFrame(const Image<ColorRgb> & image);
|
||||
void readError(const char* err);
|
||||
|
||||
void action() override;
|
||||
|
||||
private:
|
||||
/// The V4L2 grabber
|
||||
V4L2Grabber _grabber;
|
||||
};
|
47
include/grabber/VideoWrapper.h
Normal file
47
include/grabber/VideoWrapper.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <HyperionConfig.h> // Required to determine the cmake options
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
|
||||
#if defined(ENABLE_MF)
|
||||
#include <grabber/MFGrabber.h>
|
||||
#elif defined(ENABLE_V4L2)
|
||||
#include <grabber/V4L2Grabber.h>
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_CEC)
|
||||
#include <cec/CECEvent.h>
|
||||
#endif
|
||||
|
||||
class VideoWrapper : public GrabberWrapper
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
VideoWrapper();
|
||||
~VideoWrapper() override;
|
||||
|
||||
public slots:
|
||||
bool start() override;
|
||||
void stop() override;
|
||||
|
||||
#if defined(ENABLE_CEC)
|
||||
void handleCecEvent(CECEvent event);
|
||||
#endif
|
||||
|
||||
void handleSettingsUpdate(settings::type type, const QJsonDocument& config) override;
|
||||
|
||||
private slots:
|
||||
void newFrame(const Image<ColorRgb> & image);
|
||||
void readError(const char* err);
|
||||
|
||||
void action() override;
|
||||
|
||||
private:
|
||||
/// The Media Foundation or V4L2 grabber
|
||||
#if defined(ENABLE_MF)
|
||||
MFGrabber _grabber;
|
||||
#elif defined(ENABLE_V4L2)
|
||||
V4L2Grabber _grabber;
|
||||
#endif
|
||||
};
|
@@ -2,7 +2,13 @@
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <QCoreApplication>
|
||||
|
||||
// QT includes
|
||||
#include <QObject>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
|
||||
// Hyperion-utils includes
|
||||
#include <utils/ColorRgb.h>
|
||||
@@ -20,11 +26,13 @@ class X11Grabber : public Grabber , public QAbstractNativeEventFilter
|
||||
{
|
||||
public:
|
||||
|
||||
X11Grabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation);
|
||||
X11Grabber(int cropLeft=0, int cropRight=0, int cropTop=0, int cropBottom=0, int pixelDecimation=8);
|
||||
|
||||
~X11Grabber() override;
|
||||
|
||||
bool Setup();
|
||||
bool open();
|
||||
|
||||
bool setupDisplay();
|
||||
|
||||
///
|
||||
/// Captures a single snapshot of the display and writes the data to the given image. The
|
||||
@@ -50,7 +58,7 @@ public:
|
||||
///
|
||||
/// @brief Apply new pixelDecimation
|
||||
///
|
||||
void setPixelDecimation(int pixelDecimation) override;
|
||||
bool setPixelDecimation(int pixelDecimation) override;
|
||||
|
||||
///
|
||||
/// Set the crop values
|
||||
@@ -61,20 +69,31 @@ public:
|
||||
///
|
||||
void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom) override;
|
||||
|
||||
///
|
||||
/// @brief Discover X11 screens available (for configuration).
|
||||
///
|
||||
/// @param[in] params Parameters used to overwrite discovery default behaviour
|
||||
///
|
||||
/// @return A JSON structure holding a list of devices found
|
||||
///
|
||||
QJsonObject discover(const QJsonObject& params);
|
||||
|
||||
protected:
|
||||
bool nativeEventFilter(const QByteArray & eventType, void * message, long int * result) override;
|
||||
|
||||
private:
|
||||
bool _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable, _XRandRAvailable;
|
||||
|
||||
XImage* _xImage;
|
||||
XShmSegmentInfo _shminfo;
|
||||
void freeResources();
|
||||
void setupResources();
|
||||
|
||||
/// Reference to the X11 display (nullptr if not opened)
|
||||
Display* _x11Display;
|
||||
Window _window;
|
||||
XWindowAttributes _windowAttr;
|
||||
|
||||
XImage* _xImage;
|
||||
XShmSegmentInfo _shminfo;
|
||||
|
||||
Pixmap _pixmap;
|
||||
XRenderPictFormat* _srcFormat;
|
||||
XRenderPictFormat* _dstFormat;
|
||||
@@ -92,8 +111,13 @@ private:
|
||||
unsigned _src_x;
|
||||
unsigned _src_y;
|
||||
|
||||
Image<ColorRgb> _image;
|
||||
bool _XShmAvailable;
|
||||
bool _XShmPixmapAvailable;
|
||||
bool _XRenderAvailable;
|
||||
bool _XRandRAvailable;
|
||||
bool _isWayland;
|
||||
|
||||
void freeResources();
|
||||
void setupResources();
|
||||
Logger * _logger;
|
||||
|
||||
Image<ColorRgb> _image;
|
||||
};
|
||||
|
@@ -1,7 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractNativeEventFilter>
|
||||
// QT includes
|
||||
#include <QObject>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <hyperion/Grabber.h>
|
||||
@@ -21,17 +25,29 @@ class XcbGrabber : public Grabber, public QAbstractNativeEventFilter
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
XcbGrabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation);
|
||||
XcbGrabber(int cropLeft=0, int cropRight=0, int cropTop=0, int cropBottom=0, int pixelDecimation=8);
|
||||
|
||||
~XcbGrabber() override;
|
||||
|
||||
bool Setup();
|
||||
bool open();
|
||||
bool setupDisplay();
|
||||
|
||||
int grabFrame(Image<ColorRgb> & image, bool forceUpdate = false);
|
||||
int updateScreenDimensions(bool force = false);
|
||||
void setVideoMode(VideoMode mode) override;
|
||||
bool setWidthHeight(int width, int height) override { return true; }
|
||||
void setPixelDecimation(int pixelDecimation) override;
|
||||
bool setPixelDecimation(int pixelDecimation) override;
|
||||
void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom) override;
|
||||
|
||||
///
|
||||
/// @brief Discover XCB screens available (for configuration).
|
||||
///
|
||||
/// @param[in] params Parameters used to overwrite discovery default behaviour
|
||||
///
|
||||
/// @return A JSON structure holding a list of devices found
|
||||
///
|
||||
QJsonObject discover(const QJsonObject& params);
|
||||
|
||||
private:
|
||||
bool nativeEventFilter(const QByteArray & eventType, void * message, long int * result) override;
|
||||
void freeResources();
|
||||
@@ -54,6 +70,7 @@ private:
|
||||
|
||||
int _pixelDecimation;
|
||||
|
||||
int _screen_num;
|
||||
unsigned _screenWidth;
|
||||
unsigned _screenHeight;
|
||||
unsigned _src_x;
|
||||
@@ -63,6 +80,8 @@ private:
|
||||
bool _XcbRandRAvailable;
|
||||
bool _XcbShmAvailable;
|
||||
bool _XcbShmPixmapAvailable;
|
||||
bool _isWayland;
|
||||
|
||||
Logger * _logger;
|
||||
|
||||
uint8_t * _shmData;
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include <utils/Logger.h>
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <utils/settings.h>
|
||||
#include <effectengine/Effect.h>
|
||||
|
||||
///
|
||||
/// @brief Handle the background Effect settings, reacts on runtime to settings changes
|
||||
@@ -37,7 +38,7 @@ private slots:
|
||||
|
||||
#define BGCONFIG_ARRAY bgColorConfig.toArray()
|
||||
// clear background priority
|
||||
_hyperion->clear(254);
|
||||
_hyperion->clear(PriorityMuxer::BG_PRIORITY);
|
||||
// initial background effect/color
|
||||
if (BGEffectConfig["enable"].toBool(true))
|
||||
{
|
||||
@@ -53,12 +54,12 @@ private slots:
|
||||
static_cast<uint8_t>(BGCONFIG_ARRAY.at(2).toInt(0))
|
||||
}
|
||||
};
|
||||
_hyperion->setColor(254, bg_color);
|
||||
_hyperion->setColor(PriorityMuxer::BG_PRIORITY, bg_color);
|
||||
Info(Logger::getInstance("HYPERION"),"Initial background color set (%d %d %d)",bg_color.at(0).red, bg_color.at(0).green, bg_color.at(0).blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
int result = _hyperion->setEffect(bgEffectConfig, 254);
|
||||
int result = _hyperion->setEffect(bgEffectConfig, PriorityMuxer::BG_PRIORITY, Effect::ENDLESS);
|
||||
Info(Logger::getInstance("HYPERION"),"Initial background effect '%s' %s", QSTRING_CSTR(bgEffectConfig), ((result == 0) ? "started" : "failed"));
|
||||
}
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ public:
|
||||
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
|
||||
|
||||
///
|
||||
/// @brief Apply new video input (used from v4l)
|
||||
/// @brief Apply new video input (used from v4l2/MediaFoundation)
|
||||
/// @param input device input
|
||||
///
|
||||
virtual bool setInput(int input);
|
||||
@@ -53,52 +53,26 @@ public:
|
||||
virtual bool setWidthHeight(int width, int height);
|
||||
|
||||
///
|
||||
/// @brief Apply new framerate (used from v4l)
|
||||
/// @brief Apply new framerate (used from v4l2/MediaFoundation)
|
||||
/// @param fps framesPerSecond
|
||||
///
|
||||
virtual bool setFramerate(int fps);
|
||||
|
||||
///
|
||||
/// @brief Apply new pixelDecimation (used from x11, xcb and qt)
|
||||
/// @brief Apply new framerate software decimation (used from v4l2/MediaFoundation)
|
||||
/// @param decimation how many frames per second to omit
|
||||
///
|
||||
virtual void setPixelDecimation(int pixelDecimation) {}
|
||||
virtual void setFpsSoftwareDecimation(int decimation);
|
||||
|
||||
///
|
||||
/// @brief Apply new signalThreshold (used from v4l)
|
||||
/// @brief Apply videoStandard (used from v4l2)
|
||||
///
|
||||
virtual void setSignalThreshold(
|
||||
double redSignalThreshold,
|
||||
double greenSignalThreshold,
|
||||
double blueSignalThreshold,
|
||||
int noSignalCounterThreshold = 50) {}
|
||||
///
|
||||
/// @brief Apply new SignalDetectionOffset (used from v4l)
|
||||
///
|
||||
virtual void setSignalDetectionOffset(
|
||||
double verticalMin,
|
||||
double horizontalMin,
|
||||
double verticalMax,
|
||||
double horizontalMax) {}
|
||||
virtual void setVideoStandard(VideoStandard videoStandard);
|
||||
|
||||
///
|
||||
/// @brief Apply SignalDetectionEnable (used from v4l)
|
||||
/// @brief Apply new pixelDecimation (used from v4l2, MediaFoundation, x11, xcb and qt)
|
||||
///
|
||||
virtual void setSignalDetectionEnable(bool enable) {}
|
||||
|
||||
///
|
||||
/// @brief Apply CecDetectionEnable (used from v4l)
|
||||
///
|
||||
virtual void setCecDetectionEnable(bool enable) {}
|
||||
|
||||
///
|
||||
/// @brief Apply device and videoStandard (used from v4l)
|
||||
///
|
||||
virtual void setDeviceVideoStandard(QString device, VideoStandard videoStandard) {}
|
||||
|
||||
///
|
||||
/// @brief Apply device (used from MediaFoundation)
|
||||
///
|
||||
virtual bool setDevice(QString device) { return false; }
|
||||
virtual bool setPixelDecimation(int pixelDecimation);
|
||||
|
||||
///
|
||||
/// @brief Apply display index (used from qt)
|
||||
@@ -125,71 +99,26 @@ public:
|
||||
///
|
||||
void setEnabled(bool enable);
|
||||
|
||||
///
|
||||
/// @brief Get a list of all available devices
|
||||
/// @return List of all available devices on success else empty List
|
||||
///
|
||||
virtual QStringList getDevices() const { return QStringList(); }
|
||||
|
||||
///
|
||||
/// @brief Get the device name by path
|
||||
/// @param devicePath The device path
|
||||
/// @return The name of the device on success else empty String
|
||||
///
|
||||
virtual QString getDeviceName(const QString& /*devicePath*/) const { return QString(); }
|
||||
|
||||
///
|
||||
/// @brief Get a name/index pair of supported device inputs
|
||||
/// @param devicePath The device path
|
||||
/// @return multi pair of name/index on success else empty pair
|
||||
///
|
||||
virtual QMultiMap<QString, int> getDeviceInputs(const QString& /*devicePath*/) const { return QMultiMap<QString, int>(); }
|
||||
|
||||
///
|
||||
/// @brief Get a list of available device video standards depends on device input
|
||||
/// @param devicePath The device path
|
||||
/// @param inputIndex The device input index
|
||||
/// @return List of video standards on success else empty List
|
||||
///
|
||||
virtual QList<VideoStandard> getAvailableDeviceStandards(const QString& /*devicePath*/, const int& /*deviceInput*/) const { return QList<VideoStandard>(); }
|
||||
|
||||
///
|
||||
/// @brief Get a list of all available device encoding formats depends on device input
|
||||
/// @param devicePath The device path
|
||||
/// @param inputIndex The device input index
|
||||
/// @return List of device encoding formats on success else empty List
|
||||
///
|
||||
virtual QStringList getAvailableEncodingFormats(const QString& /*devicePath*/, const int& /*deviceInput*/) const { return QStringList(); }
|
||||
|
||||
///
|
||||
/// @brief Get a map of available device resolutions (width/heigth) depends on device input and encoding format
|
||||
/// @param devicePath The device path
|
||||
/// @param inputIndex The device input index
|
||||
/// @param encFormat The device encoding format
|
||||
/// @return Map of resolutions (width/heigth) on success else empty List
|
||||
///
|
||||
virtual QMultiMap<int, int> getAvailableDeviceResolutions(const QString& /*devicePath*/, const int& /*deviceInput*/, const PixelFormat& /*encFormat*/) const { return QMultiMap<int, int>(); }
|
||||
|
||||
///
|
||||
/// @brief Get a list of available device framerates depends on device input, encoding format and resolution
|
||||
/// @param devicePath The device path
|
||||
/// @param inputIndex The device input index
|
||||
/// @param encFormat The device encoding format
|
||||
/// @param width The device width
|
||||
/// @param heigth The device heigth
|
||||
/// @return List of framerates on success else empty List
|
||||
///
|
||||
virtual QIntList getAvailableDeviceFramerates(const QString& /*devicePath*/, const int& /*deviceInput*/, const PixelFormat& /*encFormat*/, const unsigned /*width*/, const unsigned /*height*/) const { return QIntList(); }
|
||||
QString getGrabberName() const { return _grabberName; }
|
||||
|
||||
protected:
|
||||
|
||||
QString _grabberName;
|
||||
|
||||
ImageResampler _imageResampler;
|
||||
|
||||
bool _useImageResampler;
|
||||
|
||||
/// The selected VideoMode
|
||||
/// the selected VideoMode
|
||||
VideoMode _videoMode;
|
||||
|
||||
/// The used Flip Mode
|
||||
/// the used video standard
|
||||
VideoStandard _videoStandard;
|
||||
|
||||
/// Image size decimation
|
||||
int _pixelDecimation;
|
||||
|
||||
/// the used Flip Mode
|
||||
FlipMode _flipMode;
|
||||
|
||||
/// With of the captured snapshot [pixels]
|
||||
@@ -201,6 +130,9 @@ protected:
|
||||
/// frame per second
|
||||
int _fps;
|
||||
|
||||
/// fps software decimation
|
||||
int _fpsSoftwareDecimation;
|
||||
|
||||
/// device input
|
||||
int _input;
|
||||
|
||||
|
@@ -58,62 +58,6 @@ public:
|
||||
///
|
||||
virtual bool isActive() const;
|
||||
|
||||
///
|
||||
/// @brief Get a list of all available devices
|
||||
/// @return List of all available devices on success else empty List
|
||||
///
|
||||
virtual QStringList getDevices() const;
|
||||
|
||||
///
|
||||
/// @brief Get the device name by path
|
||||
/// @param devicePath The device path
|
||||
/// @return The name of the device on success else empty String
|
||||
///
|
||||
virtual QString getDeviceName(const QString& devicePath) const;
|
||||
|
||||
///
|
||||
/// @brief Get a map of name/index pair of supported device inputs
|
||||
/// @param devicePath The device path
|
||||
/// @return multi pair of name/index on success else empty pair
|
||||
///
|
||||
virtual QMultiMap<QString, int> getDeviceInputs(const QString& devicePath) const;
|
||||
|
||||
///
|
||||
/// @brief Get a list of available device video standards depends on device input
|
||||
/// @param devicePath The device path
|
||||
/// @param inputIndex The device input index
|
||||
/// @return List of video standards on success else empty List
|
||||
///
|
||||
virtual QList<VideoStandard> getAvailableDeviceStandards(const QString& devicePath, const int& deviceInput) const;
|
||||
|
||||
///
|
||||
/// @brief Get a list of all available device encoding formats depends on device input
|
||||
/// @param devicePath The device path
|
||||
/// @param inputIndex The device input index
|
||||
/// @return List of device encoding formats on success else empty List
|
||||
///
|
||||
virtual QStringList getAvailableEncodingFormats(const QString& devicePath, const int& deviceInput) const;
|
||||
|
||||
///
|
||||
/// @brief Get a map of available device resolutions (width/heigth) depends on device input and encoding format
|
||||
/// @param devicePath The device path
|
||||
/// @param inputIndex The device input index
|
||||
/// @param encFormat The device encoding format
|
||||
/// @return Map of resolutions (width/heigth) on success else empty List
|
||||
///
|
||||
virtual QMultiMap<int, int> getAvailableDeviceResolutions(const QString& devicePath, const int& deviceInput, const PixelFormat& encFormat) const;
|
||||
|
||||
///
|
||||
/// @brief Get a list of available device framerates depends on device input, encoding format and resolution
|
||||
/// @param devicePath The device path
|
||||
/// @param inputIndex The device input index
|
||||
/// @param encFormat The device encoding format
|
||||
/// @param width The device width
|
||||
/// @param heigth The device heigth
|
||||
/// @return List of framerates on success else empty List
|
||||
///
|
||||
virtual QIntList getAvailableDeviceFramerates(const QString& devicePath, const int& deviceInput, const PixelFormat& encFormat, const unsigned width, const unsigned height) const;
|
||||
|
||||
///
|
||||
/// @brief Get active grabber name
|
||||
/// @param hyperionInd The instance index
|
||||
@@ -155,6 +99,12 @@ public slots:
|
||||
///
|
||||
virtual void setVideoMode(VideoMode videoMode);
|
||||
|
||||
///
|
||||
/// Set the Flip mode
|
||||
/// @param flipMode The new flip mode
|
||||
///
|
||||
virtual void setFlipMode(QString flipMode);
|
||||
|
||||
///
|
||||
/// Set the crop values
|
||||
/// @param cropLeft Left pixel crop
|
||||
@@ -166,7 +116,7 @@ public slots:
|
||||
|
||||
///
|
||||
/// @brief Handle settings update from HyperionDaemon Settingsmanager emit
|
||||
/// @param type settingyType from enum
|
||||
/// @param type settingsType from enum
|
||||
/// @param config configuration object
|
||||
///
|
||||
virtual void handleSettingsUpdate(settings::type type, const QJsonDocument& config);
|
||||
@@ -189,6 +139,22 @@ private slots:
|
||||
void updateTimer(int interval);
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
/// @brief Opens the input device.
|
||||
///
|
||||
/// @return True, on success (i.e. device is ready)
|
||||
///
|
||||
virtual bool open() { return true; }
|
||||
|
||||
///
|
||||
/// @brief Closes the input device.
|
||||
///
|
||||
/// @return True on success (i.e. device is closed)
|
||||
///
|
||||
virtual bool close() { return true; }
|
||||
|
||||
|
||||
QString _grabberName;
|
||||
|
||||
/// The timer for generating events with the specified update rate
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
// Effect engine includes
|
||||
#include <effectengine/EffectDefinition.h>
|
||||
#include <effectengine/Effect.h>
|
||||
#include <effectengine/ActiveEffectDefinition.h>
|
||||
#include <effectengine/EffectSchema.h>
|
||||
|
||||
@@ -217,7 +218,7 @@ public slots:
|
||||
/// @param effectName Name of the effec to run
|
||||
/// @param priority The priority channel of the effect
|
||||
/// @param timeout The timeout of the effect (after the timout, the effect will be cleared)
|
||||
int setEffect(const QString & effectName, int priority, int timeout = -1, const QString & origin="System");
|
||||
int setEffect(const QString & effectName, int priority, int timeout = Effect::ENDLESS, const QString & origin="System");
|
||||
|
||||
/// Run the specified effect on the given priority channel and optionally specify a timeout
|
||||
/// @param effectName Name of the effec to run
|
||||
@@ -227,7 +228,7 @@ public slots:
|
||||
int setEffect(const QString &effectName
|
||||
, const QJsonObject &args
|
||||
, int priority
|
||||
, int timeout = -1
|
||||
, int timeout = Effect::ENDLESS
|
||||
, const QString &pythonScript = ""
|
||||
, const QString &origin="System"
|
||||
, const QString &imageData = ""
|
||||
|
@@ -54,6 +54,9 @@ public:
|
||||
QString owner;
|
||||
};
|
||||
|
||||
//Foreground and Background priorities
|
||||
const static int FG_PRIORITY;
|
||||
const static int BG_PRIORITY;
|
||||
/// The lowest possible priority, which is used when no priority channels are active
|
||||
const static int LOWEST_PRIORITY;
|
||||
|
||||
|
27
include/utils/WaitTime.h
Normal file
27
include/utils/WaitTime.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef WAITTIME_H
|
||||
#define WAITTIME_H
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QTimer>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
inline void wait(std::chrono::milliseconds millisecondsWait)
|
||||
{
|
||||
QEventLoop loop;
|
||||
QTimer t;
|
||||
t.connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||
t.start(millisecondsWait.count());
|
||||
loop.exec();
|
||||
}
|
||||
|
||||
inline void wait(int millisecondsWait)
|
||||
{
|
||||
QEventLoop loop;
|
||||
QTimer t;
|
||||
t.connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||
t.start(millisecondsWait);
|
||||
loop.exec();
|
||||
}
|
||||
|
||||
#endif // WAITTIME_H
|
@@ -7,6 +7,7 @@
|
||||
#include <hyperion/LedString.h>
|
||||
// fg effect
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/PriorityMuxer.h>
|
||||
|
||||
///
|
||||
/// @brief Provide utility methods for Hyperion class
|
||||
@@ -16,7 +17,6 @@ namespace hyperion {
|
||||
void handleInitialEffect(Hyperion* hyperion, const QJsonObject& FGEffectConfig)
|
||||
{
|
||||
#define FGCONFIG_ARRAY fgColorConfig.toArray()
|
||||
const int FG_PRIORITY = 0;
|
||||
const int DURATION_INFINITY = 0;
|
||||
|
||||
// initial foreground effect/color
|
||||
@@ -41,12 +41,12 @@ namespace hyperion {
|
||||
static_cast<uint8_t>(FGCONFIG_ARRAY.at(2).toInt(0))
|
||||
}
|
||||
};
|
||||
hyperion->setColor(FG_PRIORITY, fg_color, fg_duration_ms);
|
||||
hyperion->setColor(PriorityMuxer::FG_PRIORITY, fg_color, fg_duration_ms);
|
||||
Info(Logger::getInstance("HYPERION"),"Initial foreground color set (%d %d %d)",fg_color.at(0).red,fg_color.at(0).green,fg_color.at(0).blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
int result = hyperion->setEffect(fgEffectConfig, FG_PRIORITY, fg_duration_ms);
|
||||
int result = hyperion->setEffect(fgEffectConfig, PriorityMuxer::FG_PRIORITY, fg_duration_ms);
|
||||
Info(Logger::getInstance("HYPERION"),"Initial foreground effect '%s' %s", QSTRING_CSTR(fgEffectConfig), ((result == 0) ? "started" : "failed"));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user