mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
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:
parent
01ec4a3655
commit
30b9c20611
@ -19,10 +19,10 @@ SET ( HYPERION_VERSION_PATCH 0 )
|
|||||||
|
|
||||||
SET ( DEFAULT_AMLOGIC OFF )
|
SET ( DEFAULT_AMLOGIC OFF )
|
||||||
SET ( DEFAULT_DISPMANX OFF )
|
SET ( DEFAULT_DISPMANX OFF )
|
||||||
SET ( DEFAULT_FB OFF )
|
SET ( DEFAULT_FB ON )
|
||||||
SET ( DEFAULT_OSX OFF )
|
SET ( DEFAULT_OSX OFF )
|
||||||
SET ( DEFAULT_X11 OFF )
|
SET ( DEFAULT_X11 OFF )
|
||||||
SET ( DEFAULT_SPIDEV OFF )
|
SET ( DEFAULT_SPIDEV ON )
|
||||||
SET ( DEFAULT_WS2812BPWM OFF )
|
SET ( DEFAULT_WS2812BPWM OFF )
|
||||||
SET ( DEFAULT_WS281XPWM OFF )
|
SET ( DEFAULT_WS281XPWM OFF )
|
||||||
SET ( DEFAULT_V4L2 ON )
|
SET ( DEFAULT_V4L2 ON )
|
||||||
@ -30,8 +30,10 @@ SET ( DEFAULT_USE_SHARED_AVAHI_LIBS OFF )
|
|||||||
SET ( DEFAULT_TESTS OFF )
|
SET ( DEFAULT_TESTS OFF )
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
SET ( DEFAULT_OSX ON )
|
SET ( DEFAULT_OSX ON )
|
||||||
SET ( DEFAULT_V4l2 OFF )
|
SET ( DEFAULT_V4l2 OFF )
|
||||||
|
SET ( DEFAULT_SPIDEV OFF )
|
||||||
|
SET ( DEFAULT_FB OFF )
|
||||||
else ()
|
else ()
|
||||||
if ( NOT DEFINED PLATFORM )
|
if ( NOT DEFINED PLATFORM )
|
||||||
if ( "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86" )
|
if ( "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86" )
|
||||||
@ -56,24 +58,18 @@ else ()
|
|||||||
|
|
||||||
if ( "${PLATFORM}" STREQUAL "rpi" )
|
if ( "${PLATFORM}" STREQUAL "rpi" )
|
||||||
SET ( DEFAULT_DISPMANX ON )
|
SET ( DEFAULT_DISPMANX ON )
|
||||||
SET ( DEFAULT_SPIDEV ON )
|
|
||||||
elseif ( "${PLATFORM}" STREQUAL "rpi-pwm" )
|
elseif ( "${PLATFORM}" STREQUAL "rpi-pwm" )
|
||||||
SET ( DEFAULT_DISPMANX ON )
|
SET ( DEFAULT_DISPMANX ON )
|
||||||
SET ( DEFAULT_WS2812BPWM ON )
|
SET ( DEFAULT_WS2812BPWM ON )
|
||||||
SET ( DEFAULT_WS281XPWM ON )
|
SET ( DEFAULT_WS281XPWM ON )
|
||||||
SET ( DEFAULT_SPIDEV ON )
|
|
||||||
elseif ( "${PLATFORM}" STREQUAL "wetek" )
|
elseif ( "${PLATFORM}" STREQUAL "wetek" )
|
||||||
SET ( DEFAULT_AMLOGIC ON )
|
SET ( DEFAULT_AMLOGIC ON )
|
||||||
SET ( DEFAULT_FB ON )
|
|
||||||
elseif ( "${PLATFORM}" STREQUAL "x86" )
|
elseif ( "${PLATFORM}" STREQUAL "x86" )
|
||||||
SET ( DEFAULT_X11 ON )
|
SET ( DEFAULT_X11 ON )
|
||||||
SET ( DEFAULT_FB ON )
|
|
||||||
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
|
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
|
||||||
elseif ( "${PLATFORM}" STREQUAL "x86-dev" )
|
elseif ( "${PLATFORM}" STREQUAL "x86-dev" )
|
||||||
SET ( DEFAULT_X11 ON )
|
SET ( DEFAULT_X11 ON )
|
||||||
SET ( DEFAULT_FB ON )
|
|
||||||
SET ( DEFAULT_AMLOGIC ON)
|
SET ( DEFAULT_AMLOGIC ON)
|
||||||
SET ( DEFAULT_SPIDEV ON )
|
|
||||||
SET ( DEFAULT_WS281XPWM ON )
|
SET ( DEFAULT_WS281XPWM ON )
|
||||||
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
|
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
|
||||||
SET ( DEFAULT_TESTS 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})
|
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_BIN_DIR ${CMAKE_BINARY_DIR}/proto )
|
||||||
SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )
|
SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )
|
||||||
|
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
// Define to enable the osx grabber
|
// Define to enable the osx grabber
|
||||||
#cmakedefine ENABLE_OSX
|
#cmakedefine ENABLE_OSX
|
||||||
|
|
||||||
|
// Define to enable the x11 grabber
|
||||||
|
#cmakedefine ENABLE_X11
|
||||||
|
|
||||||
// Define to enable profiler for development purpose
|
// Define to enable profiler for development purpose
|
||||||
#cmakedefine ENABLE_PROFILER
|
#cmakedefine ENABLE_PROFILER
|
||||||
|
|
||||||
|
@ -44,11 +44,11 @@ void setup() {
|
|||||||
|
|
||||||
// initial RGB flash
|
// initial RGB flash
|
||||||
LEDS.showColor(CRGB(255, 0, 0));
|
LEDS.showColor(CRGB(255, 0, 0));
|
||||||
delay(500);
|
delay(250);
|
||||||
LEDS.showColor(CRGB(0, 255, 0));
|
LEDS.showColor(CRGB(0, 255, 0));
|
||||||
delay(500);
|
delay(250);
|
||||||
LEDS.showColor(CRGB(0, 0, 255));
|
LEDS.showColor(CRGB(0, 0, 255));
|
||||||
delay(500);
|
delay(250);
|
||||||
LEDS.showColor(CRGB(0, 0, 0));
|
LEDS.showColor(CRGB(0, 0, 0));
|
||||||
|
|
||||||
Serial.begin(serialRate);
|
Serial.begin(serialRate);
|
||||||
|
@ -172,7 +172,7 @@
|
|||||||
"height" : -1,
|
"height" : -1,
|
||||||
"frameDecimation" : 2,
|
"frameDecimation" : 2,
|
||||||
"sizeDecimation" : 8,
|
"sizeDecimation" : 8,
|
||||||
"priority" : 900,
|
"priority" : 890,
|
||||||
"mode" : "2D",
|
"mode" : "2D",
|
||||||
"cropLeft" : 0,
|
"cropLeft" : 0,
|
||||||
"cropRight" : 0,
|
"cropRight" : 0,
|
||||||
@ -185,6 +185,7 @@
|
|||||||
|
|
||||||
/// The configuration for the frame-grabber, contains the following items:
|
/// The configuration for the frame-grabber, contains the following items:
|
||||||
/// * enable : true if the framegrabber (platform grabber) should be activated
|
/// * 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]
|
/// * width : The width of the grabbed frames [pixels]
|
||||||
/// * height : The height of the grabbed frames [pixels]
|
/// * height : The height of the grabbed frames [pixels]
|
||||||
/// * frequency_Hz : The frequency of the frame grab [Hz]
|
/// * 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!
|
/// * ATTENTION : Power-of-Two resolution is not supported and leads to unexpected behaviour!
|
||||||
"framegrabber" :
|
"framegrabber" :
|
||||||
{
|
{
|
||||||
|
// for all type of grabbers
|
||||||
"enable" : true,
|
"enable" : true,
|
||||||
|
"type" : "framebuffer",
|
||||||
|
"frequency_Hz" : 10,
|
||||||
|
"priority" : 890,
|
||||||
|
|
||||||
|
// valid for grabber: osx|dispmanx|amlogic|framebuffer
|
||||||
"width" : 96,
|
"width" : 96,
|
||||||
"height" : 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:
|
/// The black border configuration, contains the following items:
|
||||||
|
@ -102,7 +102,7 @@
|
|||||||
"height" : -1,
|
"height" : -1,
|
||||||
"frameDecimation" : 2,
|
"frameDecimation" : 2,
|
||||||
"sizeDecimation" : 8,
|
"sizeDecimation" : 8,
|
||||||
"priority" : 900,
|
"priority" : 890,
|
||||||
"mode" : "2D",
|
"mode" : "2D",
|
||||||
"cropLeft" : 0,
|
"cropLeft" : 0,
|
||||||
"cropRight" : 0,
|
"cropRight" : 0,
|
||||||
@ -116,6 +116,7 @@
|
|||||||
"framegrabber" :
|
"framegrabber" :
|
||||||
{
|
{
|
||||||
"enable" : true,
|
"enable" : true,
|
||||||
|
"type" : "auto",
|
||||||
"width" : 96,
|
"width" : 96,
|
||||||
"height" : 96,
|
"height" : 96,
|
||||||
"frequency_Hz" : 10.0,
|
"frequency_Hz" : 10.0,
|
||||||
|
@ -28,6 +28,26 @@ public:
|
|||||||
bool Setup();
|
bool Setup();
|
||||||
|
|
||||||
Image<ColorRgb> & grab();
|
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:
|
private:
|
||||||
ImageResampler _imageResampler;
|
ImageResampler _imageResampler;
|
||||||
@ -63,7 +83,6 @@ private:
|
|||||||
void freeResources();
|
void freeResources();
|
||||||
void setupResources();
|
void setupResources();
|
||||||
|
|
||||||
int updateScreenDimensions();
|
|
||||||
|
|
||||||
Logger * _log;
|
Logger * _log;
|
||||||
};
|
};
|
||||||
|
100
include/grabber/X11Wrapper.h
Normal file
100
include/grabber/X11Wrapper.h
Normal 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;
|
||||||
|
};
|
||||||
|
|
@ -80,11 +80,24 @@ bool V4L2Grabber::init()
|
|||||||
if (! _initialized)
|
if (! _initialized)
|
||||||
{
|
{
|
||||||
getV4Ldevices();
|
getV4Ldevices();
|
||||||
if ( _deviceName == "auto" )
|
std::string v4lDevices_str;
|
||||||
|
|
||||||
|
// show list only once
|
||||||
|
if ( ! QString(_deviceName.c_str()).startsWith("/dev/") )
|
||||||
{
|
{
|
||||||
for (auto& dev: _v4lDevices)
|
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;
|
_deviceName = dev.first;
|
||||||
if ( init() )
|
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
|
else
|
||||||
{
|
{
|
||||||
Info(_log, "configured v4l device: %s", _deviceName.c_str());
|
Info(_log, "configured v4l device: %s", _deviceName.c_str());
|
||||||
|
@ -9,6 +9,9 @@ include_directories(
|
|||||||
${QT_INCLUDES}
|
${QT_INCLUDES}
|
||||||
${X11_INCLUDES}
|
${X11_INCLUDES}
|
||||||
)
|
)
|
||||||
|
SET(X11_QT_HEADERS
|
||||||
|
${CURRENT_HEADER_DIR}/X11Wrapper.h
|
||||||
|
)
|
||||||
|
|
||||||
SET(X11_HEADERS
|
SET(X11_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/X11Grabber.h
|
${CURRENT_HEADER_DIR}/X11Grabber.h
|
||||||
@ -16,6 +19,7 @@ SET(X11_HEADERS
|
|||||||
|
|
||||||
SET(X11_SOURCES
|
SET(X11_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/X11Grabber.cpp
|
${CURRENT_SOURCE_DIR}/X11Grabber.cpp
|
||||||
|
${CURRENT_SOURCE_DIR}/X11Wrapper.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
QT5_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
|
QT5_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
|
||||||
@ -29,5 +33,7 @@ add_library(x11-grabber
|
|||||||
|
|
||||||
target_link_libraries(x11-grabber
|
target_link_libraries(x11-grabber
|
||||||
hyperion
|
hyperion
|
||||||
${QT_LIBRARIES}
|
${X11_LIBRARIES}
|
||||||
|
${X11_Xrender_LIB}
|
||||||
|
${QT_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
@ -162,6 +162,49 @@ Image<ColorRgb> & X11Grabber::grab()
|
|||||||
return _image;
|
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()
|
int X11Grabber::updateScreenDimensions()
|
||||||
{
|
{
|
||||||
const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr);
|
const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr);
|
||||||
@ -176,18 +219,15 @@ int X11Grabber::updateScreenDimensions()
|
|||||||
// No update required
|
// No update required
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info(_log, "Update of screen resolution: [%dx%d]", _screenWidth, _screenHeight);
|
|
||||||
|
|
||||||
if (_screenWidth || _screenHeight) {
|
if (_screenWidth || _screenHeight) {
|
||||||
freeResources();
|
freeResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info(_log, "Update of screen resolution: [%dx%d] to [%dx%d]", _screenWidth, _screenHeight, _windowAttr.width, _windowAttr.height);
|
||||||
_screenWidth = _windowAttr.width;
|
_screenWidth = _windowAttr.width;
|
||||||
_screenHeight = _windowAttr.height;
|
_screenHeight = _windowAttr.height;
|
||||||
|
|
||||||
Info(_log, " to [%dx%d]", _screenWidth, _screenHeight);
|
|
||||||
|
|
||||||
_croppedWidth = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
_croppedWidth = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
||||||
? (_screenWidth - _cropLeft - _cropRight)
|
? (_screenWidth - _cropLeft - _cropRight)
|
||||||
: _screenWidth;
|
: _screenWidth;
|
||||||
@ -204,5 +244,5 @@ int X11Grabber::updateScreenDimensions()
|
|||||||
|
|
||||||
setupResources();
|
setupResources();
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
111
libsrc/grabber/x11/X11Wrapper.cpp
Normal file
111
libsrc/grabber/x11/X11Wrapper.cpp
Normal 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);
|
||||||
|
}
|
@ -499,15 +499,20 @@
|
|||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
|
"type" :
|
||||||
|
{
|
||||||
|
"type" : "string",
|
||||||
|
"required" : true
|
||||||
|
},
|
||||||
"width" :
|
"width" :
|
||||||
{
|
{
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : false
|
||||||
},
|
},
|
||||||
"height" :
|
"height" :
|
||||||
{
|
{
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : false
|
||||||
},
|
},
|
||||||
"frequency_Hz" :
|
"frequency_Hz" :
|
||||||
{
|
{
|
||||||
@ -520,7 +525,7 @@
|
|||||||
"required" : true
|
"required" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : true
|
||||||
},
|
},
|
||||||
"blackborderdetector" :
|
"blackborderdetector" :
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
|||||||
device = new LedDeviceAdalight(
|
device = new LedDeviceAdalight(
|
||||||
deviceConfig["output"].asString(),
|
deviceConfig["output"].asString(),
|
||||||
deviceConfig["rate"].asInt(),
|
deviceConfig["rate"].asInt(),
|
||||||
deviceConfig.get("delayAfterConnect",1000).asInt()
|
deviceConfig.get("delayAfterConnect",500).asInt()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (type == "adalightapa102")
|
else if (type == "adalightapa102")
|
||||||
@ -76,7 +76,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
|||||||
device = new LedDeviceAdalightApa102(
|
device = new LedDeviceAdalightApa102(
|
||||||
deviceConfig["output"].asString(),
|
deviceConfig["output"].asString(),
|
||||||
deviceConfig["rate"].asInt(),
|
deviceConfig["rate"].asInt(),
|
||||||
deviceConfig.get("delayAfterConnect",1000).asInt()
|
deviceConfig.get("delayAfterConnect",500).asInt()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_SPIDEV
|
#ifdef ENABLE_SPIDEV
|
||||||
|
@ -35,6 +35,10 @@ if (ENABLE_AMLOGIC)
|
|||||||
target_link_libraries(hyperiond amlogic-grabber)
|
target_link_libraries(hyperiond amlogic-grabber)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (ENABLE_X11)
|
||||||
|
target_link_libraries(hyperiond x11-grabber )
|
||||||
|
endif ()
|
||||||
|
|
||||||
install ( TARGETS hyperiond DESTINATION "bin" COMPONENT ambilight )
|
install ( TARGETS hyperiond DESTINATION "bin" COMPONENT ambilight )
|
||||||
install ( DIRECTORY ${CMAKE_SOURCE_DIR}/effects DESTINATION "share/hyperion/" 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 )
|
install ( DIRECTORY ${CMAKE_SOURCE_DIR}/bin/service DESTINATION "share/hyperion/" COMPONENT ambilight )
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QResource>
|
#include <QResource>
|
||||||
@ -36,6 +37,7 @@ HyperionDaemon::HyperionDaemon(std::string configFile, QObject *parent)
|
|||||||
, _udpListener(nullptr)
|
, _udpListener(nullptr)
|
||||||
, _v4l2Grabber(nullptr)
|
, _v4l2Grabber(nullptr)
|
||||||
, _dispmanx(nullptr)
|
, _dispmanx(nullptr)
|
||||||
|
, _x11Grabber(nullptr)
|
||||||
, _amlGrabber(nullptr)
|
, _amlGrabber(nullptr)
|
||||||
, _fbGrabber(nullptr)
|
, _fbGrabber(nullptr)
|
||||||
, _osxGrabber(nullptr)
|
, _osxGrabber(nullptr)
|
||||||
@ -92,9 +94,7 @@ void HyperionDaemon::run()
|
|||||||
|
|
||||||
// ---- grabber -----
|
// ---- grabber -----
|
||||||
createGrabberV4L2();
|
createGrabberV4L2();
|
||||||
createGrabberDispmanx();
|
createSystemFrameGrabber();
|
||||||
createGrabberAmlogic();
|
|
||||||
createGrabberFramebuffer();
|
|
||||||
|
|
||||||
#if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB)
|
#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");
|
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"];
|
const Json::Value & boblightServerConfig = _config["boblightServer"];
|
||||||
_boblightServer = new BoblightServer(
|
_boblightServer = new BoblightServer(
|
||||||
boblightServerConfig.get("priority",900).asInt(),
|
boblightServerConfig.get("priority",899).asInt(),
|
||||||
boblightServerConfig["port"].asUInt()
|
boblightServerConfig["port"].asUInt()
|
||||||
);
|
);
|
||||||
Debug(_log, "Boblight server created");
|
Debug(_log, "Boblight server created");
|
||||||
@ -319,40 +319,186 @@ void HyperionDaemon::startNetworkServices()
|
|||||||
Debug(_log, "Proto mDNS responder started");
|
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
|
#ifdef ENABLE_DISPMANX
|
||||||
// Construct and start the dispmanx grabber if the configuration is present
|
// Construct and start the dispmanx grabber if the configuration is present
|
||||||
if (_config.isMember("framegrabber"))
|
_dispmanx = new DispmanxWrapper(
|
||||||
{
|
grabberConfig["width"].asUInt(),
|
||||||
const Json::Value & frameGrabberConfig = _config["framegrabber"];
|
grabberConfig["height"].asUInt(),
|
||||||
if (frameGrabberConfig.get("enable", true).asBool())
|
grabberConfig.get("frequency_Hz",10).asUInt(),
|
||||||
{
|
grabberConfig.get("priority",900).asInt());
|
||||||
_dispmanx = new DispmanxWrapper(
|
_dispmanx->setCropping(
|
||||||
frameGrabberConfig["width"].asUInt(),
|
grabberConfig.get("cropLeft", 0).asInt(),
|
||||||
frameGrabberConfig["height"].asUInt(),
|
grabberConfig.get("cropRight", 0).asInt(),
|
||||||
frameGrabberConfig["frequency_Hz"].asUInt(),
|
grabberConfig.get("cropTop", 0).asInt(),
|
||||||
frameGrabberConfig.get("priority",900).asInt());
|
grabberConfig.get("cropBottom", 0).asInt());
|
||||||
_dispmanx->setCropping(
|
|
||||||
frameGrabberConfig.get("cropLeft", 0).asInt(),
|
|
||||||
frameGrabberConfig.get("cropRight", 0).asInt(),
|
|
||||||
frameGrabberConfig.get("cropTop", 0).asInt(),
|
|
||||||
frameGrabberConfig.get("cropBottom", 0).asInt());
|
|
||||||
|
|
||||||
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _dispmanx, SLOT(setGrabbingMode(GrabbingMode)));
|
QObject::connect(_kodiVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _dispmanx, SLOT(setGrabbingMode(GrabbingMode)));
|
||||||
QObject::connect(_kodiVideoChecker, SIGNAL(videoMode(VideoMode)), _dispmanx, SLOT(setVideoMode(VideoMode)));
|
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(_dispmanx, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
||||||
|
|
||||||
_dispmanx->start();
|
_dispmanx->start();
|
||||||
Info(_log, "DISPMANX frame grabber created and started");
|
Info(_log, "DISPMANX frame grabber created and started");
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
ErrorIf(_config.isMember("framegrabber"), _log, "The dispmanx framegrabber can not be instantiated, because it has been left out from the build");
|
ErrorIf(_config.isMember("framegrabber"), _log, "The dispmanx framegrabber can not be instantiated, because it has been left out from the build");
|
||||||
#endif
|
#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()
|
void HyperionDaemon::createGrabberV4L2()
|
||||||
{
|
{
|
||||||
// construct and start the v4l2 grabber if the configuration is present
|
// 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("redSignalThreshold", 0.0).asDouble(),
|
||||||
grabberConfig.get("greenSignalThreshold", 0.0).asDouble(),
|
grabberConfig.get("greenSignalThreshold", 0.0).asDouble(),
|
||||||
grabberConfig.get("blueSignalThreshold", 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->set3D(parse3DMode(grabberConfig.get("mode", "2D").asString()));
|
||||||
_v4l2Grabber->setCropping(
|
_v4l2Grabber->setCropping(
|
||||||
grabberConfig.get("cropLeft", 0).asInt(),
|
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");
|
ErrorIf(_config.isMember("grabber-v4l2"), _log, "The v4l2 grabber can not be instantiated, because it has been left out from the build");
|
||||||
#endif
|
#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
|
|
||||||
}
|
|
||||||
|
@ -32,6 +32,12 @@
|
|||||||
typedef QObject OsxWrapper;
|
typedef QObject OsxWrapper;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_X11
|
||||||
|
#include <grabber/X11Wrapper.h>
|
||||||
|
#else
|
||||||
|
typedef QObject X11Wrapper;
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <utils/Logger.h>
|
#include <utils/Logger.h>
|
||||||
|
|
||||||
#include <kodivideochecker/KODIVideoChecker.h>
|
#include <kodivideochecker/KODIVideoChecker.h>
|
||||||
@ -55,13 +61,16 @@ public:
|
|||||||
void startNetworkServices();
|
void startNetworkServices();
|
||||||
|
|
||||||
// grabber creators
|
// grabber creators
|
||||||
void createGrabberDispmanx();
|
|
||||||
void createGrabberV4L2();
|
void createGrabberV4L2();
|
||||||
void createGrabberAmlogic();
|
void createSystemFrameGrabber();
|
||||||
void createGrabberFramebuffer();
|
|
||||||
void createGrabberOsx();
|
|
||||||
|
|
||||||
private:
|
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;
|
Logger* _log;
|
||||||
Json::Value _config;
|
Json::Value _config;
|
||||||
KODIVideoChecker* _kodiVideoChecker;
|
KODIVideoChecker* _kodiVideoChecker;
|
||||||
@ -71,6 +80,7 @@ private:
|
|||||||
UDPListener* _udpListener;
|
UDPListener* _udpListener;
|
||||||
V4L2Wrapper* _v4l2Grabber;
|
V4L2Wrapper* _v4l2Grabber;
|
||||||
DispmanxWrapper* _dispmanx;
|
DispmanxWrapper* _dispmanx;
|
||||||
|
X11Wrapper* _x11Grabber;
|
||||||
AmlogicWrapper* _amlGrabber;
|
AmlogicWrapper* _amlGrabber;
|
||||||
FramebufferWrapper* _fbGrabber;
|
FramebufferWrapper* _fbGrabber;
|
||||||
OsxWrapper* _osxGrabber;
|
OsxWrapper* _osxGrabber;
|
||||||
|
Loading…
Reference in New Issue
Block a user