new frame grabber handling (#137)

* - implement framegrabber type option
- framegrabber autoselect
- integrate x11 grabber in hyperiond

* add doxy

* v4l: select device by name
hyperiond: fix x11 grabber connection to kodichecker
config: tune default prios of boblight and v4l

* make v4l name finding case insensitive
This commit is contained in:
redPanther 2016-07-24 15:18:34 +02:00 committed by GitHub
parent 01ec4a3655
commit 30b9c20611
16 changed files with 548 additions and 163 deletions

View File

@ -19,10 +19,10 @@ SET ( HYPERION_VERSION_PATCH 0 )
SET ( DEFAULT_AMLOGIC OFF )
SET ( DEFAULT_DISPMANX OFF )
SET ( DEFAULT_FB OFF )
SET ( DEFAULT_FB ON )
SET ( DEFAULT_OSX OFF )
SET ( DEFAULT_X11 OFF )
SET ( DEFAULT_SPIDEV OFF )
SET ( DEFAULT_SPIDEV ON )
SET ( DEFAULT_WS2812BPWM OFF )
SET ( DEFAULT_WS281XPWM OFF )
SET ( DEFAULT_V4L2 ON )
@ -30,8 +30,10 @@ SET ( DEFAULT_USE_SHARED_AVAHI_LIBS OFF )
SET ( DEFAULT_TESTS OFF )
if (APPLE)
SET ( DEFAULT_OSX ON )
SET ( DEFAULT_V4l2 OFF )
SET ( DEFAULT_OSX ON )
SET ( DEFAULT_V4l2 OFF )
SET ( DEFAULT_SPIDEV OFF )
SET ( DEFAULT_FB OFF )
else ()
if ( NOT DEFINED PLATFORM )
if ( "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86" )
@ -56,24 +58,18 @@ else ()
if ( "${PLATFORM}" STREQUAL "rpi" )
SET ( DEFAULT_DISPMANX ON )
SET ( DEFAULT_SPIDEV ON )
elseif ( "${PLATFORM}" STREQUAL "rpi-pwm" )
SET ( DEFAULT_DISPMANX ON )
SET ( DEFAULT_WS2812BPWM ON )
SET ( DEFAULT_WS281XPWM ON )
SET ( DEFAULT_SPIDEV ON )
elseif ( "${PLATFORM}" STREQUAL "wetek" )
SET ( DEFAULT_AMLOGIC ON )
SET ( DEFAULT_FB ON )
elseif ( "${PLATFORM}" STREQUAL "x86" )
SET ( DEFAULT_X11 ON )
SET ( DEFAULT_FB ON )
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
elseif ( "${PLATFORM}" STREQUAL "x86-dev" )
SET ( DEFAULT_X11 ON )
SET ( DEFAULT_FB ON )
SET ( DEFAULT_AMLOGIC ON)
SET ( DEFAULT_SPIDEV ON )
SET ( DEFAULT_WS281XPWM ON )
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
SET ( DEFAULT_TESTS ON )
@ -122,18 +118,6 @@ option(ENABLE_PROFILER "enable profiler capabilities - not for release code" OFF
message(STATUS "ENABLE_PROFILER = " ${ENABLE_PROFILER})
if(ENABLE_FB AND ENABLE_DISPMANX)
message(FATAL_ERROR "dispmanx grabber and framebuffer grabber cannot be used at the same time")
endif()
if(ENABLE_FB AND ENABLE_OSX)
message(FATAL_ERROR "osx grabber and framebuffer grabber cannot be used at the same time")
endif()
if(ENABLE_OSX AND ENABLE_DISPMANX)
message(FATAL_ERROR "dispmanx grabber and osx grabber cannot be used at the same time")
endif()
SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto )
SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )

View File

@ -27,6 +27,9 @@
// Define to enable the osx grabber
#cmakedefine ENABLE_OSX
// Define to enable the x11 grabber
#cmakedefine ENABLE_X11
// Define to enable profiler for development purpose
#cmakedefine ENABLE_PROFILER

View File

@ -44,11 +44,11 @@ void setup() {
// initial RGB flash
LEDS.showColor(CRGB(255, 0, 0));
delay(500);
delay(250);
LEDS.showColor(CRGB(0, 255, 0));
delay(500);
delay(250);
LEDS.showColor(CRGB(0, 0, 255));
delay(500);
delay(250);
LEDS.showColor(CRGB(0, 0, 0));
Serial.begin(serialRate);

View File

@ -172,7 +172,7 @@
"height" : -1,
"frameDecimation" : 2,
"sizeDecimation" : 8,
"priority" : 900,
"priority" : 890,
"mode" : "2D",
"cropLeft" : 0,
"cropRight" : 0,
@ -185,6 +185,7 @@
/// The configuration for the frame-grabber, contains the following items:
/// * enable : true if the framegrabber (platform grabber) should be activated
/// * type : type of grabber. (auto|osx|dispmanx|amlogic|x11|framebuffer) [auto]
/// * width : The width of the grabbed frames [pixels]
/// * height : The height of the grabbed frames [pixels]
/// * frequency_Hz : The frequency of the frame grab [Hz]
@ -192,11 +193,29 @@
/// * ATTENTION : Power-of-Two resolution is not supported and leads to unexpected behaviour!
"framegrabber" :
{
// for all type of grabbers
"enable" : true,
"type" : "framebuffer",
"frequency_Hz" : 10,
"priority" : 890,
// valid for grabber: osx|dispmanx|amlogic|framebuffer
"width" : 96,
"height" : 96,
"frequency_Hz" : 10.0,
"priority" : 890
// valid for x11
"useXGetImage" : false,
"horizontalPixelDecimation" : 8,
"verticalPixelDecimation" : 8,
// valid for dispmanx and x11
"cropLeft" : 0,
"cropRight" : 0,
"cropTop" : 0,
"cropBottom" : 0,
// valid for framebuffer
"device" : "/dev/fb0"
},
/// The black border configuration, contains the following items:

View File

@ -102,7 +102,7 @@
"height" : -1,
"frameDecimation" : 2,
"sizeDecimation" : 8,
"priority" : 900,
"priority" : 890,
"mode" : "2D",
"cropLeft" : 0,
"cropRight" : 0,
@ -116,6 +116,7 @@
"framegrabber" :
{
"enable" : true,
"type" : "auto",
"width" : 96,
"height" : 96,
"frequency_Hz" : 10.0,

View File

@ -28,6 +28,26 @@ public:
bool Setup();
Image<ColorRgb> & grab();
///
/// Captures a single snapshot of the display and writes the data to the given image. The
/// provided image should have the same dimensions as the configured values (_width and
/// _height)
///
/// @param[out] image The snapped screenshot (should be initialized with correct width and
/// height)
///
int grabFrame(Image<ColorRgb> & image);
///
/// update dimension according current screen
int updateScreenDimensions();
/// gets resulting height of image
const unsigned getImageWidth() { return _croppedWidth; };
/// gets resulting width of image
const unsigned getImageHeight() { return _croppedHeight; };
private:
ImageResampler _imageResampler;
@ -63,7 +83,6 @@ private:
void freeResources();
void setupResources();
int updateScreenDimensions();
Logger * _log;
};

View File

@ -0,0 +1,100 @@
#pragma once
// QT includes
#include <QObject>
#include <QTimer>
// Utils includes
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
// Forward class declaration
class X11Grabber;
class Hyperion;
class ImageProcessor;
///
/// The X11Wrapper uses an instance of the X11Grabber to obtain ImageRgb's from the
/// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the
/// attached Hyperion.
///
class X11Wrapper: public QObject
{
Q_OBJECT
public:
///
/// Constructs the framebuffer frame grabber with a specified grab size and update rate.
///
/// @param[in] device X11 device name/path
/// @param[in] grabWidth The width of the grabbed image [pixels]
/// @param[in] grabHeight The height of the grabbed images [pixels]
/// @param[in] updateRate_Hz The image grab rate [Hz]
///
X11Wrapper(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation, const unsigned updateRate_Hz, const int priority);
///
/// Destructor of this framebuffer frame grabber. Releases any claimed resources.
///
virtual ~X11Wrapper();
public slots:
///
/// Starts the grabber wich produces led values with the specified update rate
///
void start();
///
/// Performs a single frame grab and computes the led-colors
///
void action();
///
/// Stops the grabber
///
void stop();
///
/// Set the grabbing mode
/// @param[in] mode The new grabbing mode
///
void setGrabbingMode(const GrabbingMode mode);
///
/// Set the video mode (2D/3D)
/// @param[in] mode The new video mode
///
void setVideoMode(const VideoMode videoMode);
signals:
void emitImage(int priority, const Image<ColorRgb> & image, const int timeout_ms);
private:
/// The update rate [Hz]
const int _updateInterval_ms;
/// The timeout of the led colors [ms]
const int _timeout_ms;
/// The priority of the led colors
const int _priority;
/// The timer for generating events with the specified update rate
QTimer _timer;
/// The image used for grabbing frames
Image<ColorRgb> _image;
/// The actual grabber
X11Grabber * _grabber;
/// The processor for transforming images to led colors
ImageProcessor * _processor;
/// The list with computed led colors
std::vector<ColorRgb> _ledColors;
/// Pointer to Hyperion for writing led values
Hyperion * _hyperion;
bool _init;
bool _x11SetupSuccess;
};

View File

@ -80,11 +80,24 @@ bool V4L2Grabber::init()
if (! _initialized)
{
getV4Ldevices();
if ( _deviceName == "auto" )
std::string v4lDevices_str;
// show list only once
if ( ! QString(_deviceName.c_str()).startsWith("/dev/") )
{
for (auto& dev: _v4lDevices)
{
Debug(_log, "check v4l2 device: %s (%s)",dev.first.c_str(), dev.second.c_str());
v4lDevices_str += "\t"+ dev.first + "\t" + dev.second + "\n";
}
Info(_log, "available V4L2 devices:\n%s", v4lDevices_str.c_str());
}
if ( _deviceName == "auto" )
{
_deviceName = "unknown";
for (auto& dev: _v4lDevices)
{
//Debug(_log, "check v4l2 device: %s (%s)",dev.first.c_str(), dev.second.c_str());
_deviceName = dev.first;
if ( init() )
{
@ -93,6 +106,18 @@ bool V4L2Grabber::init()
}
}
}
else if ( ! QString(_deviceName.c_str()).startsWith("/dev/") )
{
for (auto& dev: _v4lDevices)
{
if ( QString(_deviceName.c_str()).toLower() == QString(dev.second.c_str()).toLower() )
{
_deviceName = dev.first;
Info(_log, "found v4l2 device with configured name: %s (%s)", dev.second.c_str(), dev.first.c_str() );
break;
}
}
}
else
{
Info(_log, "configured v4l device: %s", _deviceName.c_str());

View File

@ -9,6 +9,9 @@ include_directories(
${QT_INCLUDES}
${X11_INCLUDES}
)
SET(X11_QT_HEADERS
${CURRENT_HEADER_DIR}/X11Wrapper.h
)
SET(X11_HEADERS
${CURRENT_HEADER_DIR}/X11Grabber.h
@ -16,6 +19,7 @@ SET(X11_HEADERS
SET(X11_SOURCES
${CURRENT_SOURCE_DIR}/X11Grabber.cpp
${CURRENT_SOURCE_DIR}/X11Wrapper.cpp
)
QT5_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
@ -29,5 +33,7 @@ add_library(x11-grabber
target_link_libraries(x11-grabber
hyperion
${QT_LIBRARIES}
${X11_LIBRARIES}
${X11_Xrender_LIB}
${QT_LIBRARIES}
)

View File

@ -162,6 +162,49 @@ Image<ColorRgb> & X11Grabber::grab()
return _image;
}
int X11Grabber::grabFrame(Image<ColorRgb> & image)
{
if (_XRenderAvailable && !_useXGetImage) {
XRenderComposite( _x11Display, // *dpy,
PictOpSrc, // op,
_srcPicture, // src
None, // mask
_dstPicture, // dst
_cropLeft, // src_x
_cropTop, // src_y
0, // mask_x
0, // mask_y
0, // dst_x
0, // dst_y
_croppedWidth, // width
_croppedHeight); // height
XSync(_x11Display, False);
if (_XShmAvailable) {
XShmGetImage(_x11Display, _pixmap, _xImage, 0, 0, AllPlanes);
} else {
_xImage = XGetImage(_x11Display, _pixmap, 0, 0, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap);
}
} else {
if (_XShmAvailable && !_useXGetImage) {
XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, AllPlanes);
} else {
_xImage = XGetImage(_x11Display, _window, _cropLeft, _cropTop, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap);
}
}
if (_xImage == nullptr)
{
Error(_log, "Grab Failed!");
return -1;
}
_imageResampler.processImage(reinterpret_cast<const uint8_t *>(_xImage->data), _xImage->width, _xImage->height, _xImage->bytes_per_line, PIXELFORMAT_BGR32, image);
return 0;
}
int X11Grabber::updateScreenDimensions()
{
const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr);
@ -176,18 +219,15 @@ int X11Grabber::updateScreenDimensions()
// No update required
return 0;
}
Info(_log, "Update of screen resolution: [%dx%d]", _screenWidth, _screenHeight);
if (_screenWidth || _screenHeight) {
freeResources();
}
Info(_log, "Update of screen resolution: [%dx%d] to [%dx%d]", _screenWidth, _screenHeight, _windowAttr.width, _windowAttr.height);
_screenWidth = _windowAttr.width;
_screenHeight = _windowAttr.height;
Info(_log, " to [%dx%d]", _screenWidth, _screenHeight);
_croppedWidth = (_screenWidth > unsigned(_cropLeft + _cropRight))
? (_screenWidth - _cropLeft - _cropRight)
: _screenWidth;
@ -204,5 +244,5 @@ int X11Grabber::updateScreenDimensions()
setupResources();
return 0;
return 1;
}

View File

@ -0,0 +1,111 @@
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <hyperion/ImageProcessorFactory.h>
#include <hyperion/ImageProcessor.h>
// X11 grabber includes
#include <grabber/X11Wrapper.h>
#include <grabber/X11Grabber.h>
X11Wrapper::X11Wrapper(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation, const unsigned updateRate_Hz, const int priority)
: _updateInterval_ms(1000/updateRate_Hz)
, _timeout_ms(2 * _updateInterval_ms)
, _priority(priority)
, _timer()
// , _image(grabWidth, grabHeight)
, _grabber(new X11Grabber(useXGetImage, cropLeft, cropRight, cropTop, cropBottom, horizontalPixelDecimation, verticalPixelDecimation))
, _processor(ImageProcessorFactory::getInstance().newImageProcessor())
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
, _hyperion(Hyperion::getInstance())
, _init(false)
, _x11SetupSuccess(false)
{
// Configure the timer to generate events every n milliseconds
_timer.setInterval(_updateInterval_ms);
_timer.setSingleShot(false);
// Connect the QTimer to this
QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(action()));
}
X11Wrapper::~X11Wrapper()
{
// Cleanup used resources (ImageProcessor and FrameGrabber)
delete _processor;
delete _grabber;
}
void X11Wrapper::start()
{
if (! _init )
{
_init = true;
_x11SetupSuccess = _grabber->Setup();
if ( _x11SetupSuccess )
{
_x11SetupSuccess = (_grabber->updateScreenDimensions() >= 0);
_processor->setSize(_grabber->getImageWidth(), _grabber->getImageHeight());
_image.resize(_grabber->getImageWidth(), _grabber->getImageHeight());
}
}
// Start the timer with the pre configured interval
if ( _x11SetupSuccess )
{
_timer.start();
_hyperion->registerPriority("X11 Grabber", _priority);
}
ErrorIf( ! _x11SetupSuccess, Logger::getInstance("X11"), "X11 Grabber start failed");
}
void X11Wrapper::action()
{
int result = _grabber->updateScreenDimensions();
if (result < 0 )
{
return;
}
if ( result > 0 )
{
_processor->setSize(_grabber->getImageWidth(), _grabber->getImageHeight());
_image.resize(_grabber->getImageWidth(), _grabber->getImageHeight());
}
// Grab frame into the allocated image
_grabber->grabFrame(_image);
emit emitImage(_priority, _image, _timeout_ms);
_processor->process(_image, _ledColors);
_hyperion->setColors(_priority, _ledColors, _timeout_ms);
}
void X11Wrapper::stop()
{
// Stop the timer, effectivly stopping the process
_timer.stop();
_hyperion->unRegisterPriority("X11 Grabber");
}
void X11Wrapper::setGrabbingMode(const GrabbingMode mode)
{
switch (mode)
{
case GRABBINGMODE_VIDEO:
case GRABBINGMODE_PAUSE:
case GRABBINGMODE_AUDIO:
case GRABBINGMODE_PHOTO:
case GRABBINGMODE_MENU:
case GRABBINGMODE_SCREENSAVER:
case GRABBINGMODE_INVALID:
start();
break;
case GRABBINGMODE_OFF:
stop();
break;
}
}
void X11Wrapper::setVideoMode(const VideoMode mode)
{
_grabber->setVideoMode(mode);
}

View File

@ -499,15 +499,20 @@
"type" : "boolean",
"required" : true
},
"type" :
{
"type" : "string",
"required" : true
},
"width" :
{
"type" : "integer",
"required" : true
"required" : false
},
"height" :
{
"type" : "integer",
"required" : true
"required" : false
},
"frequency_Hz" :
{
@ -520,7 +525,7 @@
"required" : true
}
},
"additionalProperties" : false
"additionalProperties" : true
},
"blackborderdetector" :
{

View File

@ -68,7 +68,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
device = new LedDeviceAdalight(
deviceConfig["output"].asString(),
deviceConfig["rate"].asInt(),
deviceConfig.get("delayAfterConnect",1000).asInt()
deviceConfig.get("delayAfterConnect",500).asInt()
);
}
else if (type == "adalightapa102")
@ -76,7 +76,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
device = new LedDeviceAdalightApa102(
deviceConfig["output"].asString(),
deviceConfig["rate"].asInt(),
deviceConfig.get("delayAfterConnect",1000).asInt()
deviceConfig.get("delayAfterConnect",500).asInt()
);
}
#ifdef ENABLE_SPIDEV

View File

@ -35,6 +35,10 @@ if (ENABLE_AMLOGIC)
target_link_libraries(hyperiond amlogic-grabber)
endif ()
if (ENABLE_X11)
target_link_libraries(hyperiond x11-grabber )
endif ()
install ( TARGETS hyperiond DESTINATION "bin" COMPONENT ambilight )
install ( DIRECTORY ${CMAKE_SOURCE_DIR}/effects DESTINATION "share/hyperion/" COMPONENT ambilight )
install ( DIRECTORY ${CMAKE_SOURCE_DIR}/bin/service DESTINATION "share/hyperion/" COMPONENT ambilight )

View File

@ -1,5 +1,6 @@
#include <unistd.h>
#include <cassert>
#include <stdlib.h>
#include <QCoreApplication>
#include <QResource>
@ -36,6 +37,7 @@ HyperionDaemon::HyperionDaemon(std::string configFile, QObject *parent)
, _udpListener(nullptr)
, _v4l2Grabber(nullptr)
, _dispmanx(nullptr)
, _x11Grabber(nullptr)
, _amlGrabber(nullptr)
, _fbGrabber(nullptr)
, _osxGrabber(nullptr)
@ -92,9 +94,7 @@ void HyperionDaemon::run()
// ---- grabber -----
createGrabberV4L2();
createGrabberDispmanx();
createGrabberAmlogic();
createGrabberFramebuffer();
createSystemFrameGrabber();
#if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB)
ErrorIf(_config.isMember("framegrabber"), _log, "No grabber can be instantiated, because all grabbers have been left out from the build");
@ -255,7 +255,7 @@ void HyperionDaemon::startNetworkServices()
{
const Json::Value & boblightServerConfig = _config["boblightServer"];
_boblightServer = new BoblightServer(
boblightServerConfig.get("priority",900).asInt(),
boblightServerConfig.get("priority",899).asInt(),
boblightServerConfig["port"].asUInt()
);
Debug(_log, "Boblight server created");
@ -319,40 +319,186 @@ void HyperionDaemon::startNetworkServices()
Debug(_log, "Proto mDNS responder started");
}
void HyperionDaemon::createGrabberDispmanx()
void HyperionDaemon::createSystemFrameGrabber()
{
if (_config.isMember("framegrabber"))
{
const Json::Value & grabberConfig = _config["framegrabber"];
if (grabberConfig.get("enable", true).asBool())
{
#ifdef ENABLE_OSX
std::string type = "osx";
#else
std::string type = grabberConfig.get("type", "auto").asString();
#endif
QFile amvideo("/dev/amvideo");
// auto eval of type
if ( type == "auto" )
{
// dispmanx -> on raspi
// TODO currently a compile option
#ifdef ENABLE_DISPMANX
if (true)
#else
if (false)
#endif
{
type = "dispmanx";
}
// amlogic -> /dev/amvideo exists
else if ( amvideo.exists() )
{
type = "amlogic";
}
// x11 -> if DISPLAY is set
else if (getenv("DISPLAY") != NULL )
{
type = "x11";
}
// framebuffer -> if nothing other applies
else
{
type == "framebuffer";
}
InfoIf( type != "auto", _log, "set screen capture device to '%s'", type.c_str());
}
if (type == "framebuffer") createGrabberFramebuffer(grabberConfig);
else if (type == "dispmanx") createGrabberDispmanx(grabberConfig);
else if (type == "amlogic") createGrabberAmlogic(grabberConfig);
else if (type == "osx") createGrabberOsx(grabberConfig);
else if (type == "x11") createGrabberX11(grabberConfig);
else WarningIf( type != "", _log, "unknown framegrabber type '%s'", type.c_str());
InfoIf( type == "", _log, "screen capture device disabled");
}
}
}
void HyperionDaemon::createGrabberDispmanx(const Json::Value & grabberConfig)
{
#ifdef ENABLE_DISPMANX
// Construct and start the dispmanx grabber if the configuration is present
if (_config.isMember("framegrabber"))
{
const Json::Value & frameGrabberConfig = _config["framegrabber"];
if (frameGrabberConfig.get("enable", true).asBool())
{
_dispmanx = new DispmanxWrapper(
frameGrabberConfig["width"].asUInt(),
frameGrabberConfig["height"].asUInt(),
frameGrabberConfig["frequency_Hz"].asUInt(),
frameGrabberConfig.get("priority",900).asInt());
_dispmanx->setCropping(
frameGrabberConfig.get("cropLeft", 0).asInt(),
frameGrabberConfig.get("cropRight", 0).asInt(),
frameGrabberConfig.get("cropTop", 0).asInt(),
frameGrabberConfig.get("cropBottom", 0).asInt());
_dispmanx = new DispmanxWrapper(
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig.get("frequency_Hz",10).asUInt(),
grabberConfig.get("priority",900).asInt());
_dispmanx->setCropping(
grabberConfig.get("cropLeft", 0).asInt(),
grabberConfig.get("cropRight", 0).asInt(),
grabberConfig.get("cropTop", 0).asInt(),
grabberConfig.get("cropBottom", 0).asInt());
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _dispmanx, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _dispmanx, SLOT(setVideoMode(VideoMode)));
QObject::connect(_dispmanx, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _dispmanx, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _dispmanx, SLOT(setVideoMode(VideoMode)));
QObject::connect(_dispmanx, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
_dispmanx->start();
Info(_log, "DISPMANX frame grabber created and started");
}
}
_dispmanx->start();
Info(_log, "DISPMANX frame grabber created and started");
#else
ErrorIf(_config.isMember("framegrabber"), _log, "The dispmanx framegrabber can not be instantiated, because it has been left out from the build");
#endif
}
void HyperionDaemon::createGrabberAmlogic(const Json::Value & grabberConfig)
{
#ifdef ENABLE_AMLOGIC
// Construct and start the amlogic grabber if the configuration is present
_amlGrabber = new AmlogicWrapper(
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig.get("frequency_Hz",10).asUInt(),
grabberConfig.get("priority",900).asInt());
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _amlGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _amlGrabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_amlGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
_amlGrabber->start();
Info(_log, "AMLOGIC grabber created and started");
#else
Error( _log, "The AMLOGIC grabber can not be instantiated, because it has been left out from the build");
#endif
}
void HyperionDaemon::createGrabberX11(const Json::Value & grabberConfig)
{
#ifdef ENABLE_X11
// Construct and start the amlogic grabber if the configuration is present
_x11Grabber = new X11Wrapper(
grabberConfig.get("useXGetImage",false).asBool(),
grabberConfig.get("cropLeft", 0).asInt(),
grabberConfig.get("cropRight", 0).asInt(),
grabberConfig.get("cropTop", 0).asInt(),
grabberConfig.get("cropBottom", 0).asInt(),
grabberConfig.get("horizontalPixelDecimation", 8).asInt(),
grabberConfig.get("verticalPixelDecimation", 8).asInt(),
grabberConfig.get("frequency_Hz",10).asUInt(),
grabberConfig.get("priority",900).asInt()
);
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _x11Grabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _x11Grabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_x11Grabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
_x11Grabber->start();
Info(_log, "X11 grabber created and started");
#else
Error(_log, "The X11 grabber can not be instantiated, because it has been left out from the build");
#endif
}
void HyperionDaemon::createGrabberFramebuffer(const Json::Value & grabberConfig)
{
#ifdef ENABLE_FB
// Construct and start the framebuffer grabber if the configuration is present
_fbGrabber = new FramebufferWrapper(
grabberConfig.get("device", "/dev/fb0").asString(),
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig.get("frequency_Hz",10).asUInt(),
grabberConfig.get("priority",900).asInt());
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _fbGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _fbGrabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_fbGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
_fbGrabber->start();
Info(_log, "Framebuffer grabber created and started");
#else
Error(_log, "The framebuffer grabber can not be instantiated, because it has been left out from the build");
#endif
}
void HyperionDaemon::createGrabberOsx(const Json::Value & grabberConfig)
{
#ifdef ENABLE_OSX
// Construct and start the osx grabber if the configuration is present
_osxGrabber = new OsxWrapper(
grabberConfig.get("display", 0).asUInt(),
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig.get("frequency_Hz",10).asUInt(),
grabberConfig.get("priority",900).asInt());
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _osxGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _osxGrabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_osxGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
_osxGrabber->start();
Info(_log, "OSX grabber created and started");
#else
Error(_log, "The osx grabber can not be instantiated, because it has been left out from the build");
#endif
}
void HyperionDaemon::createGrabberV4L2()
{
// construct and start the v4l2 grabber if the configuration is present
@ -372,7 +518,7 @@ void HyperionDaemon::createGrabberV4L2()
grabberConfig.get("redSignalThreshold", 0.0).asDouble(),
grabberConfig.get("greenSignalThreshold", 0.0).asDouble(),
grabberConfig.get("blueSignalThreshold", 0.0).asDouble(),
grabberConfig.get("priority", 900).asInt());
grabberConfig.get("priority", 890).asInt());
_v4l2Grabber->set3D(parse3DMode(grabberConfig.get("mode", "2D").asString()));
_v4l2Grabber->setCropping(
grabberConfig.get("cropLeft", 0).asInt(),
@ -391,91 +537,3 @@ void HyperionDaemon::createGrabberV4L2()
ErrorIf(_config.isMember("grabber-v4l2"), _log, "The v4l2 grabber can not be instantiated, because it has been left out from the build");
#endif
}
void HyperionDaemon::createGrabberAmlogic()
{
#ifdef ENABLE_AMLOGIC
// Construct and start the amlogic grabber if the configuration is present
if (_config.isMember("amlgrabber"))
{
const Json::Value & grabberConfig = _config["amlgrabber"];
if (grabberConfig.get("enable", true).asBool())
{
_amlGrabber = new AmlogicWrapper(
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig["frequency_Hz"].asUInt(),
grabberConfig.get("priority",900).asInt());
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _amlGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _amlGrabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_amlGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
_amlGrabber->start();
Info(_log, "AMLOGIC grabber created and started");
}
}
#else
ErrorIf(_config.isMember("amlgrabber"), _log, "The AMLOGIC grabber can not be instantiated, because it has been left out from the build");
#endif
}
void HyperionDaemon::createGrabberFramebuffer()
{
#ifdef ENABLE_FB
// Construct and start the framebuffer grabber if the configuration is present
if (_config.isMember("framebuffergrabber"))
{
const Json::Value & grabberConfig = _config["framebuffergrabber"];
if (grabberConfig.get("enable", true).asBool())
{
_fbGrabber = new FramebufferWrapper(
grabberConfig.get("device", "/dev/fb0").asString(),
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig["frequency_Hz"].asUInt(),
grabberConfig.get("priority",900).asInt());
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _fbGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _fbGrabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_fbGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
_fbGrabber->start();
Info(_log, "Framebuffer grabber created and started");
}
}
#else
ErrorIf(_config.isMember("framebuffergrabber"), _log, "The framebuffer grabber can not be instantiated, because it has been left out from the build");
#endif
}
void HyperionDaemon::createGrabberOsx()
{
#ifdef ENABLE_OSX
// Construct and start the osx grabber if the configuration is present
if (_config.isMember("osxgrabber"))
{
const Json::Value & grabberConfig = _config["osxgrabber"];
if (grabberConfig.get("enable", true).asBool())
{
_osxGrabber = new OsxWrapper(
grabberConfig.get("display", 0).asUInt(),
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig["frequency_Hz"].asUInt(),
grabberConfig.get("priority",900).asInt());
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _osxGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _osxGrabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_osxGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
_osxGrabber->start();
Info(_log, "OSX grabber created and started");
}
}
#else
ErrorIf(_config.isMember("osxgrabber"), _log, "The osx grabber can not be instantiated, because it has been left out from the build");
#endif
}

View File

@ -32,6 +32,12 @@
typedef QObject OsxWrapper;
#endif
#ifdef ENABLE_X11
#include <grabber/X11Wrapper.h>
#else
typedef QObject X11Wrapper;
#endif
#include <utils/Logger.h>
#include <kodivideochecker/KODIVideoChecker.h>
@ -55,13 +61,16 @@ public:
void startNetworkServices();
// grabber creators
void createGrabberDispmanx();
void createGrabberV4L2();
void createGrabberAmlogic();
void createGrabberFramebuffer();
void createGrabberOsx();
void createSystemFrameGrabber();
private:
void createGrabberDispmanx(const Json::Value & grabberConfig);
void createGrabberAmlogic(const Json::Value & grabberConfig);
void createGrabberFramebuffer(const Json::Value & grabberConfig);
void createGrabberOsx(const Json::Value & grabberConfig);
void createGrabberX11(const Json::Value & grabberConfig);
Logger* _log;
Json::Value _config;
KODIVideoChecker* _kodiVideoChecker;
@ -71,6 +80,7 @@ private:
UDPListener* _udpListener;
V4L2Wrapper* _v4l2Grabber;
DispmanxWrapper* _dispmanx;
X11Wrapper* _x11Grabber;
AmlogicWrapper* _amlGrabber;
FramebufferWrapper* _fbGrabber;
OsxWrapper* _osxGrabber;