Merge remote-tracking branch 'origin/grabberDiscovery' into mediafoundation

This commit is contained in:
Paulchen Panther
2021-04-04 12:43:29 +02:00
committed by LordGrey
187 changed files with 3716 additions and 15430 deletions

View File

@@ -27,6 +27,11 @@ void QtWrapper::stop()
_timer.stop();
}
bool QtWrapper::displayInit()
{
return _grabber.setupDisplay();
}
void QtWrapper::capture()
{
if(unsigned(_grabber.getImageWidth()) != unsigned(_screenshot.width()) || unsigned(_grabber.getImageHeight()) != unsigned(_screenshot.height()))

View File

@@ -24,6 +24,8 @@ public:
void stop();
bool displayInit();
signals:
void sig_screenshot(const Image<ColorRgb> & screenshot);

View File

@@ -56,7 +56,7 @@ int main(int argc, char ** argv)
parser.showHelp(0);
}
QtWrapper grabber(
QtWrapper qtWrapper(
1000 / argFps.getInt(parser),
argCropLeft.getInt(parser),
argCropRight.getInt(parser),
@@ -65,10 +65,13 @@ int main(int argc, char ** argv)
argSizeDecimation.getInt(parser),
argDisplay.getInt(parser));
if (!qtWrapper.displayInit())
return -1;
if (parser.isSet(argScreenshot))
{
// Capture a single screenshot and finish
const Image<ColorRgb> &screenshot = grabber.getScreenshot();
const Image<ColorRgb> &screenshot = qtWrapper.getScreenshot();
saveScreenshot("screenshot.png", screenshot);
}
else
@@ -89,10 +92,10 @@ int main(int argc, char ** argv)
FlatBufferConnection flatbuf("Qt Standalone", address, argPriority.getInt(parser), parser.isSet(argSkipReply));
// Connect the screen capturing to flatbuf connection processing
QObject::connect(&grabber, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &flatbuf, SLOT(setImage(Image<ColorRgb>)));
QObject::connect(&qtWrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &flatbuf, SLOT(setImage(Image<ColorRgb>)));
// Start the capturing
grabber.start();
qtWrapper.start();
// Start the application
app.exec();

View File

@@ -59,6 +59,7 @@ int main(int argc, char** argv)
IntOption & argFps = parser.add<IntOption> ('f', "framerate", "Capture frame rate [default: %1]", "15", 1, 25);
IntOption & argWidth = parser.add<IntOption> (0x0, "width", "Width of the captured image [default: %1]", "160", 160);
IntOption & argHeight = parser.add<IntOption> (0x0, "height", "Height of the captured image [default: %1]", "160", 160);
SwitchOption<FlipMode> & argFlipMode = parser.add<SwitchOption<FlipMode>>(0x0, "flip-mode", "The used image flip mode. Valid values are HORIZONTAL, VERTICAL, BOTH or no-change. [default: %1]", "no-change");
IntOption & argCropWidth = parser.add<IntOption> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: %1]", "0");
IntOption & argCropHeight = parser.add<IntOption> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: %1]", "0");
IntOption & argCropLeft = parser.add<IntOption> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
@@ -99,6 +100,11 @@ int main(int argc, char** argv)
#endif
argPixelFormat.addSwitch("no-change", PixelFormat::NO_CHANGE);
argFlipMode.addSwitch("horizontal", FlipMode::HORIZONTAL);
argFlipMode.addSwitch("vertical", FlipMode::VERTICAL);
argFlipMode.addSwitch("both", FlipMode::BOTH);
argFlipMode.addSwitch("no-change", FlipMode::NO_CHANGE);
// parse all options
parser.process(app);
@@ -109,15 +115,31 @@ int main(int argc, char** argv)
}
// initialize the grabber
V4L2Grabber grabber(
argDevice.value(parser),
argWidth.getInt(parser),
argHeight.getInt(parser),
1000 / argFps.getInt(parser),
argInput.getInt(parser),
argVideoStandard.switchValue(parser),
argPixelFormat.switchValue(parser),
std::max(1, argSizeDecimation.getInt(parser)));
V4L2Grabber grabber;
// set device
grabber.setDevice(argDevice.value(parser));
// set input
grabber.setInput(argInput.getInt(parser));
// set resolution
grabber.setWidthHeight(argWidth.getInt(parser), argHeight.getInt(parser));
// set fps
grabber.setFramerate(1000 / argFps.getInt(parser));
// TODO set encoding format
// grabber.setEncoding(argPixelFormat.switchValue(parser));
// set video standard
grabber.setVideoStandard(argVideoStandard.switchValue(parser));
// set image size decimation
grabber.setPixelDecimation(std::max(1, argSizeDecimation.getInt(parser)));
// set flip mode
grabber.setFlipMode(argFlipMode.switchValue(parser));
// set signal detection
grabber.setSignalDetectionEnable(! parser.isSet(argSignalDetection));

View File

@@ -31,7 +31,7 @@ void X11Wrapper::stop()
bool X11Wrapper::displayInit()
{
return _grabber.Setup();
return _grabber.setupDisplay();
}
void X11Wrapper::capture()

View File

@@ -31,7 +31,7 @@ void XcbWrapper::stop()
bool XcbWrapper::displayInit()
{
return _grabber.Setup();
return _grabber.setupDisplay();
}
void XcbWrapper::capture()

View File

@@ -73,8 +73,7 @@ HyperionDaemon::HyperionDaemon(const QString& rootPath, QObject* parent, bool lo
, _webserver(nullptr)
, _sslWebserver(nullptr)
, _jsonServer(nullptr)
, _v4l2Grabber(nullptr)
, _mfGrabber(nullptr)
, _videoGrabber(nullptr)
, _dispmanx(nullptr)
, _x11Grabber(nullptr)
, _xcbGrabber(nullptr)
@@ -253,11 +252,9 @@ void HyperionDaemon::freeObjects()
delete _osxGrabber;
delete _qtGrabber;
delete _dxGrabber;
delete _v4l2Grabber;
delete _mfGrabber;
delete _videoGrabber;
_v4l2Grabber = nullptr;
_mfGrabber = nullptr;
_videoGrabber = nullptr;
_amlGrabber = nullptr;
_dispmanx = nullptr;
_fbGrabber = nullptr;
@@ -373,7 +370,7 @@ void HyperionDaemon::handleSettingsUpdate(settings::type settingsType, const QJs
#ifdef ENABLE_OSX
QString type = "osx";
#else
QString type = grabberConfig["type"].toString("auto");
QString type = grabberConfig["device"].toString("auto");
#endif
// auto eval of type
@@ -596,101 +593,23 @@ void HyperionDaemon::handleSettingsUpdate(settings::type settingsType, const QJs
}
#endif
#if defined(ENABLE_MF)
if (_mfGrabber == nullptr)
#if defined(ENABLE_V4L2) || defined(ENABLE_MF)
if (_videoGrabber == nullptr)
{
_mfGrabber = new MFWrapper(
grabberConfig["device"].toString("auto"),
grabberConfig["width"].toInt(0),
grabberConfig["height"].toInt(0),
grabberConfig["fps"].toInt(15),
grabberConfig["sizeDecimation"].toInt(8),
grabberConfig["flip"].toString("auto"));
// Image cropping
_mfGrabber->setCropping(
grabberConfig["cropLeft"].toInt(0),
grabberConfig["cropRight"].toInt(0),
grabberConfig["cropTop"].toInt(0),
grabberConfig["cropBottom"].toInt(0));
// Software frame decimation
_mfGrabber->setFpsSoftwareDecimation(grabberConfig["fpsSoftwareDecimation"].toInt(1));
// Hardware encoding format
_mfGrabber->setEncoding(grabberConfig["encoding"].toString("NO_CHANGE"));
// Signal detection
_mfGrabber->setSignalDetectionEnable(grabberConfig["signalDetection"].toBool(true));
_mfGrabber->setSignalDetectionOffset(
grabberConfig["sDHOffsetMin"].toDouble(0.25),
grabberConfig["sDVOffsetMin"].toDouble(0.25),
grabberConfig["sDHOffsetMax"].toDouble(0.75),
grabberConfig["sDVOffsetMax"].toDouble(0.75));
_mfGrabber->setSignalThreshold(
grabberConfig["redSignalThreshold"].toDouble(0.0) / 100.0,
grabberConfig["greenSignalThreshold"].toDouble(0.0) / 100.0,
grabberConfig["blueSignalThreshold"].toDouble(0.0) / 100.0,
grabberConfig["noSignalCounterThreshold"].toInt(50) );
// CEC Standby
_mfGrabber->setCecDetectionEnable(grabberConfig["cecDetection"].toBool(true));
// Brightness, Contrast, Saturation, Hue
_mfGrabber->setBrightnessContrastSaturationHue(grabberConfig["hardware_brightness"].toInt(0),
grabberConfig["hardware_contrast"].toInt(0),
grabberConfig["hardware_saturation"].toInt(0),
grabberConfig["hardware_hue"].toInt(0));
_videoGrabber = new VideoWrapper();
_videoGrabber->handleSettingsUpdate(settings::V4L2, QJsonDocument(grabberConfig));
#if defined(ENABLE_MF)
Debug(_log, "Media Foundation grabber created");
// connect to HyperionDaemon signal
connect(this, &HyperionDaemon::videoMode, _mfGrabber, &MFWrapper::setVideoMode);
connect(this, &HyperionDaemon::settingsChanged, _mfGrabber, &MFWrapper::handleSettingsUpdate);
}
#elif !defined(ENABLE_V4L2)
Warning(_log, "The Media Foundation grabber can not be instantiated, because it has been left out from the build");
#elif defined(ENABLE_V4L2)
Debug(_log, "V4L2 grabber created");
#endif
if (_v4l2Grabber != nullptr)
{
return;
// connect to HyperionDaemon signal
connect(this, &HyperionDaemon::videoMode, _videoGrabber, &VideoWrapper::setVideoMode);
connect(this, &HyperionDaemon::settingsChanged, _videoGrabber, &VideoWrapper::handleSettingsUpdate);
}
#ifdef ENABLE_V4L2
_v4l2Grabber = new V4L2Wrapper(
grabberConfig["device"].toString("auto"),
grabberConfig["width"].toInt(0),
grabberConfig["height"].toInt(0),
grabberConfig["fps"].toInt(15),
grabberConfig["input"].toInt(-1),
parseVideoStandard(grabberConfig["standard"].toString("no-change")),
parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")),
grabberConfig["sizeDecimation"].toInt(8));
_v4l2Grabber->setSignalThreshold(
grabberConfig["redSignalThreshold"].toDouble(0.0) / 100.0,
grabberConfig["greenSignalThreshold"].toDouble(0.0) / 100.0,
grabberConfig["blueSignalThreshold"].toDouble(0.0) / 100.0);
_v4l2Grabber->setCropping(
grabberConfig["cropLeft"].toInt(0),
grabberConfig["cropRight"].toInt(0),
grabberConfig["cropTop"].toInt(0),
grabberConfig["cropBottom"].toInt(0));
_v4l2Grabber->setCecDetectionEnable(grabberConfig["cecDetection"].toBool(true));
_v4l2Grabber->setSignalDetectionEnable(grabberConfig["signalDetection"].toBool(true));
_v4l2Grabber->setSignalDetectionOffset(
grabberConfig["sDHOffsetMin"].toDouble(0.25),
grabberConfig["sDVOffsetMin"].toDouble(0.25),
grabberConfig["sDHOffsetMax"].toDouble(0.75),
grabberConfig["sDVOffsetMax"].toDouble(0.75));
Debug(_log, "V4L2 grabber created");
// connect to HyperionDaemon signal
connect(this, &HyperionDaemon::videoMode, _v4l2Grabber, &V4L2Wrapper::setVideoMode);
connect(this, &HyperionDaemon::settingsChanged, _v4l2Grabber, &V4L2Wrapper::handleSettingsUpdate);
#elif !defined(ENABLE_MF)
#else
Debug(_log, "The v4l2 grabber is not supported on this platform");
#endif
}
@@ -772,7 +691,7 @@ void HyperionDaemon::createGrabberQt(const QJsonObject& grabberConfig)
_qtGrabber = new QtWrapper(
_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom,
grabberConfig["pixelDecimation"].toInt(8),
grabberConfig["display"].toInt(0),
grabberConfig["input"].toInt(0),
_grabber_frequency);
// connect to HyperionDaemon signal
@@ -851,9 +770,9 @@ void HyperionDaemon::createCecHandler()
thread->start();
connect(_cecHandler, &CECHandler::cecEvent, [&](CECEvent event) {
if (_v4l2Grabber != nullptr)
if (_videoGrabber != nullptr)
{
_v4l2Grabber->handleCecEvent(event);
_videoGrabber->handleCecEvent(event);
}
});

View File

@@ -10,16 +10,10 @@
typedef QObject DispmanxWrapper;
#endif
#ifdef ENABLE_V4L2
#include <grabber/V4L2Wrapper.h>
#if defined(ENABLE_V4L2) || defined(ENABLE_MF)
#include <grabber/VideoWrapper.h>
#else
typedef QObject V4L2Wrapper;
#endif
#ifdef ENABLE_MF
#include <grabber/MFWrapper.h>
#else
typedef QObject MFWrapper;
typedef QObject VideoWrapper;
#endif
#ifdef ENABLE_FB
@@ -176,8 +170,7 @@ private:
WebServer* _webserver;
WebServer* _sslWebserver;
JsonServer* _jsonServer;
V4L2Wrapper* _v4l2Grabber;
MFWrapper* _mfGrabber;
VideoWrapper* _videoGrabber;
DispmanxWrapper* _dispmanx;
X11Wrapper* _x11Grabber;
XcbWrapper* _xcbGrabber;

View File

@@ -15,7 +15,9 @@
#include <utils/ColorRgb.h>
#include <effectengine/EffectDefinition.h>
#include <effectengine/Effect.h>
#include <webserver/WebServer.h>
#include <hyperion/PriorityMuxer.h>
#include "hyperiond.h"
#include "systray.h"
@@ -185,7 +187,7 @@ void SysTray::closeEvent(QCloseEvent *event)
event->ignore();
}
void SysTray::settings()
void SysTray::settings() const
{
#ifndef _WIN32
// Hide error messages when opening webbrowser
@@ -221,7 +223,7 @@ void SysTray::settings()
void SysTray::setEffect()
{
QString efxName = qobject_cast<QAction*>(sender())->text();
_hyperion->setEffect(efxName, 1);
_hyperion->setEffect(efxName, PriorityMuxer::FG_PRIORITY, Effect::ENDLESS);
}
void SysTray::clearEfxColor()
@@ -229,7 +231,7 @@ void SysTray::clearEfxColor()
_hyperion->clear(1);
}
void SysTray::handleInstanceStateChange(InstanceState state, quint8 instance, const QString& name)
void SysTray::handleInstanceStateChange(InstanceState state, quint8 instance, const QString& /*name*/)
{
switch(state){
case InstanceState::H_STARTED:

View File

@@ -24,7 +24,7 @@ public slots:
void showColorDialog();
void setColor(const QColor & color);
void closeEvent(QCloseEvent *event);
void settings();
void settings() const;
void setEffect();
void clearEfxColor();
void setAutorunState();