mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
grabber api and feature unification (#462)
* move setvideomode to common place * implement more croping and 3d support * more api unification * more refactoring * osx fix * next step * add a mock for osx grabber. Now it is possible to test compile on none osx platforms. * more unifications ... * remove obsolete includes and grabbers are not dyn allocated. dispmanx needs rework an probaly not work atm * first version of dispmanx mock. it compiles, but outputs a black image * now dispmanx mock works! * activate mocks in travis linux build prepare dispmanx to rgb image out * dispmanx now with image rgb output fix deadlock with w/h -1 in grabber v4l cleanups * fix json * fix some runtime stuff * Update FramebufferWrapper.cpp fix missing code * unify grabframe * 3d and croping for amlogic * fix setimage not working * make use of templates save some codelines * save more code lines
This commit is contained in:
parent
317a903b14
commit
9eff6384cc
@ -30,6 +30,11 @@ cd build
|
||||
[ "${TRAVIS_EVENT_TYPE:-}" != 'cron' -a -z "${TRAVIS_TAG:-}" ] && PLATFORM=${PLATFORM}-dev
|
||||
|
||||
cmake -DPLATFORM=$PLATFORM -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX=/usr .. || exit 2
|
||||
if [[ "$TRAVIS_OS_NAME" == 'linux' ]]
|
||||
then
|
||||
# activate dispmanx and osx mocks
|
||||
cmake -DENABLE_OSX=ON -DENABLE_DISPMANX=ON .. || exit 5
|
||||
fi
|
||||
|
||||
echo "compile jobs: ${JOBS:=4}"
|
||||
make -j ${JOBS} || exit 3
|
||||
|
@ -95,6 +95,9 @@ if ( "${PLATFORM}" MATCHES "-dev" )
|
||||
SET ( DEFAULT_TESTS ON )
|
||||
endif()
|
||||
|
||||
STRING( TOUPPER "-DPLATFORM_${PLATFORM}" PLATFORM_DEFINE)
|
||||
STRING( REPLACE "-DEV" "" PLATFORM_DEFINE "${PLATFORM_DEFINE}" )
|
||||
ADD_DEFINITIONS( ${PLATFORM_DEFINE} )
|
||||
|
||||
# set the build options
|
||||
option(ENABLE_AMLOGIC "Enable the AMLOGIC video grabber" ${DEFAULT_AMLOGIC} )
|
||||
@ -240,7 +243,7 @@ add_definitions(${QT_DEFINITIONS})
|
||||
# link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
|
||||
#endif()
|
||||
|
||||
if(ENABLE_OSX)
|
||||
if(APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-framework CoreGraphics")
|
||||
endif()
|
||||
|
||||
|
@ -133,8 +133,8 @@
|
||||
"device" : "auto",
|
||||
"input" : 0,
|
||||
"standard" : "PAL",
|
||||
"width" : -1,
|
||||
"height" : -1,
|
||||
"width" : 0,
|
||||
"height" : 0,
|
||||
"frameDecimation" : 2,
|
||||
"sizeDecimation" : 8,
|
||||
"priority" : 240,
|
||||
|
@ -64,8 +64,8 @@
|
||||
"device" : "auto",
|
||||
"input" : 0,
|
||||
"standard" : "PAL",
|
||||
"width" : -1,
|
||||
"height" : -1,
|
||||
"width" : 0,
|
||||
"height" : 0,
|
||||
"frameDecimation" : 2,
|
||||
"sizeDecimation" : 8,
|
||||
"priority" : 240,
|
||||
|
@ -17,6 +17,7 @@ public:
|
||||
const QMap<QString, T> &switches=QMap<QString, T>())
|
||||
: Option(name, description, valueName, defaultValue), _switches(switches)
|
||||
{}
|
||||
|
||||
SwitchOption(const QStringList &names,
|
||||
const QString &description = QString(),
|
||||
const QString &valueName = QString(),
|
||||
@ -24,17 +25,20 @@ public:
|
||||
const QMap<QString, T> &switches=QMap<QString, T>())
|
||||
: Option(names, description, valueName, defaultValue), _switches(switches)
|
||||
{}
|
||||
|
||||
SwitchOption(const QCommandLineOption &other, const QMap<QString, T> &switches)
|
||||
: Option(other), _switches(switches)
|
||||
{}
|
||||
|
||||
const QMap<QString, T> &getSwitches() const{return _switches;};
|
||||
virtual bool validate(Parser &parser, QString &switch_) override{return hasSwitch(switch_);}
|
||||
bool hasSwitch(const QString &switch_){return _switches.contains(switch_.toLower());}
|
||||
void setSwitches(const QMap<QString, T> &_switches){this->_switches = _switches;}
|
||||
void addSwitch(const QString &switch_, T value=T()){_switches[switch_.toLower()] = value;}
|
||||
void removeSwitch(const QString &switch_){_switches.remove(switch_.toLower());}
|
||||
T & switchValue(Parser & parser){return _switches[value(parser).toLower()];}
|
||||
virtual ~SwitchOption() {}
|
||||
|
||||
const QMap<QString, T> &getSwitches() const { return _switches; }
|
||||
virtual bool validate(Parser &parser, QString &switch_) override { return hasSwitch(switch_); }
|
||||
bool hasSwitch(const QString &switch_) { return _switches.contains(switch_.toLower()); }
|
||||
void setSwitches(const QMap<QString, T> &_switches) { this->_switches = _switches; }
|
||||
void addSwitch(const QString &switch_, T value=T()) { _switches[switch_.toLower()] = value; }
|
||||
void removeSwitch(const QString &switch_) { _switches.remove(switch_.toLower()); }
|
||||
T & switchValue(Parser & parser) { return _switches[value(parser).toLower()]; }
|
||||
|
||||
protected:
|
||||
QMap<QString, T> _switches;
|
||||
|
@ -29,14 +29,17 @@ public:
|
||||
/// height)
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
int grabFrame(Image<ColorBgr> & image);
|
||||
int grabFrame(Image<ColorRgb> & image);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Returns true if video is playing over the amlogic chip
|
||||
* @return True if video is playing else false
|
||||
*/
|
||||
bool isVideoPlaying();
|
||||
private:
|
||||
|
||||
/** The snapshot/capture device of the amlogic video chip */
|
||||
int _amlogicCaptureDev;
|
||||
|
||||
Image<ColorBgr> _image;
|
||||
};
|
||||
|
@ -1,16 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
// Utils includes
|
||||
#include <utils/Image.h>
|
||||
#include <utils/ColorBgr.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <utils/VideoMode.h>
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
|
||||
// Forward class declaration
|
||||
class AmlogicGrabber;
|
||||
class Hyperion;
|
||||
class ImageProcessor;
|
||||
#include <grabber/AmlogicGrabber.h>
|
||||
|
||||
///
|
||||
/// The DispmanxWrapper uses an instance of the DispmanxFrameGrabber to obtain ImageRgb's from the
|
||||
@ -34,7 +25,7 @@ public:
|
||||
///
|
||||
/// Destructor of this dispmanx frame grabber. Releases any claimed resources.
|
||||
///
|
||||
virtual ~AmlogicWrapper();
|
||||
virtual ~AmlogicWrapper() {};
|
||||
|
||||
public slots:
|
||||
///
|
||||
@ -42,19 +33,7 @@ public slots:
|
||||
///
|
||||
virtual void action();
|
||||
|
||||
virtual void setVideoMode(const VideoMode mode);
|
||||
|
||||
private:
|
||||
/// The update rate [Hz]
|
||||
const int _updateInterval_ms;
|
||||
/// The timeout of the led colors [ms]
|
||||
const int _timeout_ms;
|
||||
|
||||
/// The image used for grabbing frames
|
||||
Image<ColorBgr> _image;
|
||||
/// The actual grabber
|
||||
AmlogicGrabber * _grabber;
|
||||
|
||||
/// The list with computed led colors
|
||||
std::vector<ColorRgb> _ledColors;
|
||||
AmlogicGrabber _grabber;
|
||||
};
|
||||
|
@ -1,10 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
// BCM includes
|
||||
#pragma GCC system_header
|
||||
#include <bcm_host.h>
|
||||
#ifdef PLATFORM_RPI
|
||||
#pragma GCC system_header
|
||||
#include <bcm_host.h>
|
||||
#else
|
||||
#include <grabber/DispmanxFrameGrabberMock.h>
|
||||
#endif
|
||||
|
||||
// Utils includes
|
||||
#include <utils/Image.h>
|
||||
#include <utils/ColorRgba.h>
|
||||
#include <hyperion/Grabber.h>
|
||||
|
||||
@ -24,15 +29,6 @@ public:
|
||||
DispmanxFrameGrabber(const unsigned width, const unsigned height);
|
||||
~DispmanxFrameGrabber();
|
||||
|
||||
///
|
||||
/// Updates the frame-grab flags as used by the VC library for frame grabbing
|
||||
///
|
||||
/// @param vc_flags The snapshot grabbing mask
|
||||
///
|
||||
void setFlags(const int vc_flags);
|
||||
|
||||
void setCropping(const unsigned cropLeft, const unsigned cropRight,
|
||||
const unsigned cropTop, const unsigned cropBottom);
|
||||
|
||||
///
|
||||
/// Captures a single snapshot of the display and writes the data to the given image. The
|
||||
@ -42,9 +38,16 @@ public:
|
||||
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
||||
/// height)
|
||||
///
|
||||
void grabFrame(Image<ColorRgba> & image);
|
||||
int grabFrame(Image<ColorRgb> & image);
|
||||
|
||||
private:
|
||||
///
|
||||
/// Updates the frame-grab flags as used by the VC library for frame grabbing
|
||||
///
|
||||
/// @param vc_flags The snapshot grabbing mask
|
||||
///
|
||||
void setFlags(const int vc_flags);
|
||||
|
||||
/// Handle to the display that is being captured
|
||||
DISPMANX_DISPLAY_HANDLE_T _vc_display;
|
||||
|
||||
@ -63,4 +66,8 @@ private:
|
||||
|
||||
// size of the capture buffer in Pixels
|
||||
unsigned _captureBufferSize;
|
||||
|
||||
// rgba output buffer
|
||||
Image<ColorRgba> _image_rgba;
|
||||
|
||||
};
|
||||
|
40
include/grabber/DispmanxFrameGrabberMock.h
Normal file
40
include/grabber/DispmanxFrameGrabberMock.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#ifndef PLATFORM_RPI
|
||||
|
||||
#include <QRect>
|
||||
#include <utils/Image.h>
|
||||
#include <utils/ColorRgba.h>
|
||||
|
||||
typedef int DISPMANX_DISPLAY_HANDLE_T;
|
||||
typedef Image<ColorRgba> DISPMANX_RESOURCE;
|
||||
typedef DISPMANX_RESOURCE* DISPMANX_RESOURCE_HANDLE_T;
|
||||
const int VC_IMAGE_RGBA32 = 1;
|
||||
const int DISPMANX_SNAPSHOT_FILL = 1;
|
||||
typedef int DISPMANX_TRANSFORM_T;
|
||||
|
||||
|
||||
struct DISPMANX_MODEINFO_T {
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct VC_RECT_T {
|
||||
int left;
|
||||
int top;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
void bcm_host_init();
|
||||
void bcm_host_deinit();
|
||||
int vc_dispmanx_display_open(int);
|
||||
void vc_dispmanx_display_close(int);
|
||||
int vc_dispmanx_display_get_info(int, DISPMANX_MODEINFO_T *vc_info);
|
||||
DISPMANX_RESOURCE_HANDLE_T vc_dispmanx_resource_create(int,int width,int height, uint32_t *);
|
||||
void vc_dispmanx_resource_delete(DISPMANX_RESOURCE_HANDLE_T resource);
|
||||
int vc_dispmanx_resource_read_data(DISPMANX_RESOURCE_HANDLE_T vc_resource, VC_RECT_T *rectangle, void* capturePtr, unsigned capturePitch);
|
||||
void vc_dispmanx_rect_set(VC_RECT_T *rectangle, int left, int top, int width, int height);
|
||||
int vc_dispmanx_snapshot(int, DISPMANX_RESOURCE_HANDLE_T resource, int vc_flags);
|
||||
|
||||
|
||||
#endif
|
@ -1,16 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
// Utils includes
|
||||
#include <utils/Image.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <utils/ColorRgba.h>
|
||||
#include <utils/GrabbingMode.h>
|
||||
#include <utils/VideoMode.h>
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
|
||||
// Forward class declaration
|
||||
class DispmanxFrameGrabber;
|
||||
class ImageProcessor;
|
||||
#include <grabber/DispmanxFrameGrabber.h>
|
||||
|
||||
///
|
||||
/// The DispmanxWrapper uses an instance of the DispmanxFrameGrabber to obtain ImageRgb's from the
|
||||
@ -34,7 +27,7 @@ public:
|
||||
///
|
||||
/// Destructor of this dispmanx frame grabber. Releases any claimed resources.
|
||||
///
|
||||
virtual ~DispmanxWrapper();
|
||||
virtual ~DispmanxWrapper() {};
|
||||
|
||||
public slots:
|
||||
///
|
||||
@ -42,25 +35,7 @@ public slots:
|
||||
///
|
||||
virtual void action();
|
||||
|
||||
void setCropping(const unsigned cropLeft, const unsigned cropRight, const unsigned cropTop, const unsigned cropBottom);
|
||||
|
||||
///
|
||||
/// Set the video mode (2D/3D)
|
||||
/// @param[in] mode The new video mode
|
||||
///
|
||||
void setVideoMode(const VideoMode videoMode);
|
||||
|
||||
private:
|
||||
/// The update rate [Hz]
|
||||
const int _updateInterval_ms;
|
||||
/// The timeout of the led colors [ms]
|
||||
const int _timeout_ms;
|
||||
|
||||
/// The image used for grabbing frames
|
||||
Image<ColorRgba> _image;
|
||||
/// The actual grabber
|
||||
DispmanxFrameGrabber * _grabber;
|
||||
|
||||
/// The list with computed led colors
|
||||
std::vector<ColorRgb> _ledColors;
|
||||
DispmanxFrameGrabber _grabber;
|
||||
};
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
||||
/// height)
|
||||
///
|
||||
void grabFrame(Image<ColorRgb> & image);
|
||||
int grabFrame(Image<ColorRgb> & image);
|
||||
|
||||
private:
|
||||
/// Framebuffer file descriptor
|
||||
|
@ -1,15 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
// Utils includes
|
||||
#include <utils/Image.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <utils/GrabbingMode.h>
|
||||
#include <utils/VideoMode.h>
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
|
||||
// Forward class declaration
|
||||
class FramebufferFrameGrabber;
|
||||
class ImageProcessor;
|
||||
#include <grabber/FramebufferFrameGrabber.h>
|
||||
|
||||
///
|
||||
/// The FramebufferWrapper uses an instance of the FramebufferFrameGrabber to obtain ImageRgb's from the
|
||||
@ -33,7 +25,7 @@ public:
|
||||
///
|
||||
/// Destructor of this framebuffer frame grabber. Releases any claimed resources.
|
||||
///
|
||||
virtual ~FramebufferWrapper();
|
||||
virtual ~FramebufferWrapper() {};
|
||||
|
||||
public slots:
|
||||
///
|
||||
@ -41,23 +33,7 @@ public slots:
|
||||
///
|
||||
virtual void action();
|
||||
|
||||
///
|
||||
/// Set the video mode (2D/3D)
|
||||
/// @param[in] mode The new video mode
|
||||
///
|
||||
void setVideoMode(const VideoMode videoMode);
|
||||
|
||||
private:
|
||||
/// The update rate [Hz]
|
||||
const int _updateInterval_ms;
|
||||
/// The timeout of the led colors [ms]
|
||||
const int _timeout_ms;
|
||||
|
||||
/// The image used for grabbing frames
|
||||
Image<ColorRgb> _image;
|
||||
/// The actual grabber
|
||||
FramebufferFrameGrabber * _grabber;
|
||||
|
||||
/// The list with computed led colors
|
||||
std::vector<ColorRgb> _ledColors;
|
||||
FramebufferFrameGrabber _grabber;
|
||||
};
|
||||
|
@ -1,7 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// OSX includes
|
||||
#ifdef __APPLE__
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#else
|
||||
#include <grabber/OsxFrameGrabberMock.h>
|
||||
#endif
|
||||
|
||||
// Utils includes
|
||||
#include <utils/ColorRgb.h>
|
||||
@ -31,7 +35,7 @@ public:
|
||||
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
||||
/// height)
|
||||
///
|
||||
void grabFrame(Image<ColorRgb> & image);
|
||||
int grabFrame(Image<ColorRgb> & image);
|
||||
|
||||
private:
|
||||
/// display
|
||||
|
34
include/grabber/OsxFrameGrabberMock.h
Normal file
34
include/grabber/OsxFrameGrabberMock.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#ifndef __APPLE__
|
||||
|
||||
/*
|
||||
* this is a mock up for compiling and testing osx wrapper on no osx platform.
|
||||
* this will show a test image and rotate the colors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <utils/Image.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
|
||||
typedef int CGDirectDisplayID;
|
||||
typedef Image<ColorRgb> CGImage;
|
||||
typedef CGImage* CGImageRef;
|
||||
typedef unsigned char CFData;
|
||||
typedef CFData* CFDataRef;
|
||||
typedef unsigned CGDisplayCount;
|
||||
|
||||
const int kCGDirectMainDisplay = 0;
|
||||
|
||||
void CGGetActiveDisplayList(int max, CGDirectDisplayID *displays, CGDisplayCount *displayCount);
|
||||
CGImageRef CGDisplayCreateImage(CGDirectDisplayID display);
|
||||
void CGImageRelease(CGImageRef image);
|
||||
CGImageRef CGImageGetDataProvider(CGImageRef image);
|
||||
CFDataRef CGDataProviderCopyData(CGImageRef image);
|
||||
unsigned char* CFDataGetBytePtr(CFDataRef imgData);
|
||||
unsigned CGImageGetWidth(CGImageRef image);
|
||||
unsigned CGImageGetHeight(CGImageRef image);
|
||||
unsigned CGImageGetBitsPerPixel(CGImageRef image);
|
||||
unsigned CGImageGetBytesPerRow(CGImageRef image);
|
||||
void CFRelease(CFDataRef imgData);
|
||||
|
||||
#endif
|
@ -1,16 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
// Utils includes
|
||||
#include <utils/Image.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <utils/ColorRgba.h>
|
||||
#include <utils/GrabbingMode.h>
|
||||
#include <utils/VideoMode.h>
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
|
||||
// Forward class declaration
|
||||
class OsxFrameGrabber;
|
||||
class ImageProcessor;
|
||||
#include <grabber/OsxFrameGrabber.h>
|
||||
|
||||
///
|
||||
/// The OsxWrapper uses an instance of the OsxFrameGrabber to obtain ImageRgb's from the
|
||||
@ -35,7 +26,7 @@ public:
|
||||
///
|
||||
/// Destructor of this osx frame grabber. Releases any claimed resources.
|
||||
///
|
||||
virtual ~OsxWrapper();
|
||||
virtual ~OsxWrapper() {};
|
||||
|
||||
public slots:
|
||||
///
|
||||
@ -43,23 +34,7 @@ public slots:
|
||||
///
|
||||
virtual void action();
|
||||
|
||||
///
|
||||
/// Set the video mode (2D/3D)
|
||||
/// @param[in] mode The new video mode
|
||||
///
|
||||
void setVideoMode(const VideoMode videoMode);
|
||||
|
||||
private:
|
||||
/// The update rate [Hz]
|
||||
const int _updateInterval_ms;
|
||||
/// The timeout of the led colors [ms]
|
||||
const int _timeout_ms;
|
||||
|
||||
/// The image used for grabbing frames
|
||||
Image<ColorRgb> _image;
|
||||
/// The actual grabber
|
||||
OsxFrameGrabber * _grabber;
|
||||
|
||||
/// The list with computed led colors
|
||||
std::vector<ColorRgb> _ledColors;
|
||||
OsxFrameGrabber _grabber;
|
||||
};
|
||||
|
@ -10,11 +10,8 @@
|
||||
#include <QRectF>
|
||||
|
||||
// util includes
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <utils/PixelFormat.h>
|
||||
#include <hyperion/Grabber.h>
|
||||
|
||||
// grabber includes
|
||||
#include <grabber/VideoStandard.h>
|
||||
|
||||
/// Capture class for V4L2 devices
|
||||
@ -28,8 +25,8 @@ public:
|
||||
V4L2Grabber(const QString & device,
|
||||
int input,
|
||||
VideoStandard videoStandard, PixelFormat pixelFormat,
|
||||
int width,
|
||||
int height,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
int frameDecimation,
|
||||
int horizontalPixelDecimation,
|
||||
int verticalPixelDecimation
|
||||
@ -39,12 +36,9 @@ public:
|
||||
QRectF getSignalDetectionOffset();
|
||||
bool getSignalDetectionEnabled();
|
||||
|
||||
public slots:
|
||||
void setCropping(int cropLeft,
|
||||
int cropRight,
|
||||
int cropTop,
|
||||
int cropBottom);
|
||||
int grabFrame(Image<ColorRgb> &);
|
||||
|
||||
public slots:
|
||||
void setSignalThreshold(
|
||||
double redSignalThreshold,
|
||||
double greenSignalThreshold,
|
||||
|
@ -1,11 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
|
||||
// Grabber includes
|
||||
#include <grabber/V4L2Grabber.h>
|
||||
|
||||
class V4L2Wrapper : public GrabberWrapper
|
||||
@ -17,8 +12,8 @@ public:
|
||||
int input,
|
||||
VideoStandard videoStandard,
|
||||
PixelFormat pixelFormat,
|
||||
int width,
|
||||
int height,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
int frameDecimation,
|
||||
int pixelDecimation,
|
||||
double redSignalThreshold,
|
||||
@ -26,7 +21,7 @@ public:
|
||||
double blueSignalThreshold,
|
||||
const int priority,
|
||||
bool useGrabbingMode);
|
||||
virtual ~V4L2Wrapper();
|
||||
virtual ~V4L2Wrapper() {};
|
||||
|
||||
bool getSignalDetectionEnable();
|
||||
|
||||
@ -36,7 +31,6 @@ public slots:
|
||||
|
||||
void setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom);
|
||||
void setSignalDetectionOffset(double verticalMin, double horizontalMin, double verticalMax, double horizontalMax);
|
||||
void setVideoMode(VideoMode mode);
|
||||
void setSignalDetectionEnable(bool enable);
|
||||
|
||||
// signals:
|
||||
@ -50,12 +44,6 @@ private slots:
|
||||
void checkSources();
|
||||
|
||||
private:
|
||||
/// The timeout of the led colors [ms]
|
||||
const int _timeout_ms;
|
||||
|
||||
/// The V4L2 grabber
|
||||
V4L2Grabber _grabber;
|
||||
|
||||
/// The list with computed led colors
|
||||
std::vector<ColorRgb> _ledColors;
|
||||
};
|
||||
|
@ -23,8 +23,6 @@ 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
|
||||
@ -33,11 +31,13 @@ public:
|
||||
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
||||
/// height)
|
||||
///
|
||||
int grabFrame(Image<ColorRgb> & image);
|
||||
virtual int grabFrame(Image<ColorRgb> & image, bool forceUpdate=false);
|
||||
|
||||
///
|
||||
/// update dimension according current screen
|
||||
int updateScreenDimensions();
|
||||
int updateScreenDimensions(bool force=false);
|
||||
|
||||
virtual void setVideoMode(VideoMode mode);
|
||||
|
||||
private:
|
||||
bool _useXGetImage, _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
|
||||
@ -63,6 +63,8 @@ private:
|
||||
|
||||
unsigned _screenWidth;
|
||||
unsigned _screenHeight;
|
||||
unsigned _src_x;
|
||||
unsigned _src_y;
|
||||
|
||||
Image<ColorRgb> _image;
|
||||
|
||||
|
@ -1,14 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
// Utils includes
|
||||
#include <utils/Image.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <utils/VideoMode.h>
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
#include <grabber/X11Grabber.h>
|
||||
// some include of xorg defines "None" this is also used by QT and has to be undefined to avoid collisions
|
||||
#ifdef None
|
||||
#undef None
|
||||
#endif
|
||||
|
||||
// Forward class declaration
|
||||
class X11Grabber;
|
||||
class ImageProcessor;
|
||||
|
||||
///
|
||||
/// The X11Wrapper uses an instance of the X11Grabber to obtain ImageRgb's from the
|
||||
@ -31,42 +29,18 @@ public:
|
||||
///
|
||||
/// Destructor of this framebuffer frame grabber. Releases any claimed resources.
|
||||
///
|
||||
virtual ~X11Wrapper();
|
||||
virtual ~X11Wrapper() {};
|
||||
|
||||
public slots:
|
||||
///
|
||||
/// Starts the grabber wich produces led values with the specified update rate
|
||||
///
|
||||
bool start();
|
||||
|
||||
///
|
||||
/// Performs a single frame grab and computes the led-colors
|
||||
///
|
||||
virtual void action();
|
||||
|
||||
///
|
||||
/// Set the video mode (2D/3D)
|
||||
/// @param[in] mode The new video mode
|
||||
///
|
||||
void setVideoMode(const VideoMode videoMode);
|
||||
|
||||
private:
|
||||
/// The update rate [Hz]
|
||||
const int _updateInterval_ms;
|
||||
/// The timeout of the led colors [ms]
|
||||
const int _timeout_ms;
|
||||
|
||||
/// The image used for grabbing frames
|
||||
Image<ColorRgb> _image;
|
||||
|
||||
/// The actual grabber
|
||||
X11Grabber * _grabber;
|
||||
|
||||
/// The list with computed led colors
|
||||
std::vector<ColorRgb> _ledColors;
|
||||
|
||||
X11Grabber _grabber;
|
||||
|
||||
bool _init;
|
||||
bool _x11SetupSuccess;
|
||||
};
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <QObject>
|
||||
#include <cstdint>
|
||||
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <utils/Image.h>
|
||||
#include <utils/VideoMode.h>
|
||||
#include <utils/GrabbingMode.h>
|
||||
@ -16,24 +17,28 @@ class Grabber : public QObject
|
||||
|
||||
public:
|
||||
Grabber(QString grabberName, int width=0, int height=0, int cropLeft=0, int cropRight=0, int cropTop=0, int cropBottom=0);
|
||||
~Grabber();
|
||||
virtual ~Grabber();
|
||||
|
||||
///
|
||||
/// Set the video mode (2D/3D)
|
||||
/// @param[in] mode The new video mode
|
||||
///
|
||||
void setVideoMode(VideoMode mode);
|
||||
virtual void setVideoMode(VideoMode mode);
|
||||
|
||||
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
|
||||
|
||||
/// gets resulting height of image
|
||||
const int getImageWidth() { return _width; };
|
||||
virtual const int getImageWidth() { return _width; };
|
||||
|
||||
/// gets resulting width of image
|
||||
const int getImageHeight() { return _height; };
|
||||
virtual const int getImageHeight() { return _height; };
|
||||
|
||||
|
||||
protected:
|
||||
ImageResampler _imageResampler;
|
||||
|
||||
bool _useImageResampler;
|
||||
|
||||
/// the selected VideoMode
|
||||
VideoMode _videoMode;
|
||||
|
||||
|
@ -9,14 +9,20 @@
|
||||
#include <utils/Components.h>
|
||||
#include <utils/GrabbingMode.h>
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
#include <utils/Image.h>
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <utils/VideoMode.h>
|
||||
|
||||
class ImageProcessor;
|
||||
class Grabber;
|
||||
class DispmanxFrameGrabber;
|
||||
|
||||
class GrabberWrapper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GrabberWrapper(QString grabberName, const int priority, hyperion::Components grabberComponentId=hyperion::COMP_GRABBER);
|
||||
GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned width, unsigned height, const unsigned updateRate_Hz, const int priority, hyperion::Components grabberComponentId=hyperion::COMP_GRABBER);
|
||||
|
||||
virtual ~GrabberWrapper();
|
||||
|
||||
@ -30,8 +36,32 @@ public:
|
||||
///
|
||||
virtual void stop();
|
||||
|
||||
void setImageProcessorEnabled(bool enable);
|
||||
|
||||
static QStringList availableGrabbers();
|
||||
|
||||
|
||||
public:
|
||||
template <typename Grabber_T>
|
||||
void transferFrame(Grabber_T &grabber)
|
||||
{
|
||||
unsigned w = grabber.getImageWidth();
|
||||
unsigned h = grabber.getImageHeight();
|
||||
if (_imageProcessorEnabled && ( _image.width() != w || _image.height() != h))
|
||||
{
|
||||
_processor->setSize(w, h);
|
||||
_image.resize(w, h);
|
||||
}
|
||||
|
||||
if (grabber.grabFrame(_image) >= 0)
|
||||
{
|
||||
emit emitImage(_priority, _image, _timeout_ms);
|
||||
_processor->process(_image, _ledColors);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public slots:
|
||||
void componentStateChanged(const hyperion::Components component, bool enable);
|
||||
|
||||
@ -50,8 +80,9 @@ public slots:
|
||||
/// Set the video mode (2D/3D)
|
||||
/// @param[in] mode The new video mode
|
||||
///
|
||||
virtual void setVideoMode(const VideoMode videoMode) = 0;
|
||||
virtual void setVideoMode(const VideoMode videoMode);
|
||||
|
||||
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
|
||||
|
||||
signals:
|
||||
void emitImage(int priority, const Image<ColorRgb> & image, const int timeout_ms);
|
||||
@ -59,6 +90,7 @@ signals:
|
||||
protected:
|
||||
|
||||
void setColors(const std::vector<ColorRgb> &ledColors, const int timeout_ms);
|
||||
|
||||
QString _grabberName;
|
||||
|
||||
/// Pointer to Hyperion for writing led values
|
||||
@ -70,6 +102,12 @@ protected:
|
||||
/// The timer for generating events with the specified update rate
|
||||
QTimer _timer;
|
||||
|
||||
/// The update rate [Hz]
|
||||
const int _updateInterval_ms;
|
||||
|
||||
/// The timeout of the led colors [ms]
|
||||
const int _timeout_ms;
|
||||
|
||||
/// The Logger instance
|
||||
Logger * _log;
|
||||
|
||||
@ -80,4 +118,15 @@ protected:
|
||||
ImageProcessor * _processor;
|
||||
|
||||
hyperion::Components _grabberComponentId;
|
||||
|
||||
Grabber *_ggrabber;
|
||||
|
||||
/// The image used for grabbing frames
|
||||
Image<ColorRgb> _image;
|
||||
|
||||
/// The list with computed led colors
|
||||
std::vector<ColorRgb> _ledColors;
|
||||
|
||||
bool _imageProcessorEnabled;
|
||||
};
|
||||
|
||||
|
@ -260,7 +260,7 @@ public slots:
|
||||
///
|
||||
/// Clears all priority channels. This will switch the leds off until a new priority is written.
|
||||
///
|
||||
void clearall();
|
||||
void clearall(bool forceClearAll=false);
|
||||
|
||||
/// Run the specified effect on the given priority channel and optionally specify a timeout
|
||||
/// @param effectName Name of the effec to run
|
||||
|
@ -42,7 +42,6 @@ public:
|
||||
///
|
||||
void setSize(const unsigned width, const unsigned height);
|
||||
|
||||
|
||||
/// Returns starte of black border detector
|
||||
bool blackBorderDetectorEnabled();
|
||||
|
||||
@ -60,6 +59,19 @@ public slots:
|
||||
void setLedMappingType(int mapType);
|
||||
|
||||
public:
|
||||
///
|
||||
/// Specifies the width and height of 'incomming' images. This will resize the buffer-image to
|
||||
/// match the given size.
|
||||
/// NB All earlier obtained references will be invalid.
|
||||
///
|
||||
/// @param[in] image The dimensions taken from image
|
||||
///
|
||||
template <typename Pixel_T>
|
||||
void setSize(const Image<Pixel_T> &image)
|
||||
{
|
||||
setSize(image.width(), image.height());
|
||||
}
|
||||
|
||||
///
|
||||
/// Processes the image to a list of led colors. This will update the size of the buffer-image
|
||||
/// if required and call the image-to-leds mapping to determine the mean color per led.
|
||||
@ -70,20 +82,27 @@ public:
|
||||
///
|
||||
template <typename Pixel_T>
|
||||
std::vector<ColorRgb> process(const Image<Pixel_T>& image)
|
||||
{
|
||||
std::vector<ColorRgb> colors;
|
||||
if (image.width()>0 && image.height()>0)
|
||||
{
|
||||
// Ensure that the buffer-image is the proper size
|
||||
setSize(image.width(), image.height());
|
||||
setSize(image);
|
||||
|
||||
// Check black border detection
|
||||
verifyBorder(image);
|
||||
|
||||
// Create a result vector and call the 'in place' functionl
|
||||
std::vector<ColorRgb> colors;
|
||||
switch (_mappingType)
|
||||
{
|
||||
case 1: colors = _imageToLeds->getUniLedColor(image); break;
|
||||
default: colors = _imageToLeds->getMeanLedColor(image);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning(_log, "ImageProcessor::process called without image size 0");
|
||||
}
|
||||
|
||||
// return the computed colors
|
||||
return colors;
|
||||
@ -97,9 +116,11 @@ public:
|
||||
///
|
||||
template <typename Pixel_T>
|
||||
void process(const Image<Pixel_T>& image, std::vector<ColorRgb>& ledColors)
|
||||
{
|
||||
if ( image.width()>0 && image.height()>0)
|
||||
{
|
||||
// Ensure that the buffer-image is the proper size
|
||||
setSize(image.width(), image.height());
|
||||
setSize(image);
|
||||
|
||||
// Check black border detection
|
||||
verifyBorder(image);
|
||||
@ -110,7 +131,11 @@ public:
|
||||
case 1: _imageToLeds->getUniLedColor(image, ledColors); break;
|
||||
default: _imageToLeds->getMeanLedColor(image, ledColors);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning(_log, "ImageProcessor::process called without image size 0");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -118,7 +118,7 @@ public:
|
||||
///
|
||||
/// Clears all priority channels
|
||||
///
|
||||
void clearAll();
|
||||
void clearAll(bool forceClearAll=false);
|
||||
|
||||
///
|
||||
/// Updates the current time. Channels with a configured time out will be checked and cleared if
|
||||
@ -152,5 +152,4 @@ private:
|
||||
|
||||
QTimer _timer;
|
||||
QTimer _blockTimer;
|
||||
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
int cropTop,
|
||||
int cropBottom);
|
||||
|
||||
void set3D(VideoMode mode);
|
||||
void setVideoMode(VideoMode mode);
|
||||
|
||||
void processImage(const uint8_t * data, int width, int height, int lineLength, PixelFormat pixelFormat, Image<ColorRgb> & outputImage) const;
|
||||
|
||||
|
@ -52,10 +52,6 @@ AmlogicGrabber::~AmlogicGrabber()
|
||||
|
||||
bool AmlogicGrabber::isVideoPlaying()
|
||||
{
|
||||
|
||||
// TODO crop resulting image accroding member _videoMode
|
||||
// TODO add croping
|
||||
|
||||
const QString videoDevice = "/dev/amvideo";
|
||||
|
||||
// Open the video device
|
||||
@ -81,13 +77,10 @@ bool AmlogicGrabber::isVideoPlaying()
|
||||
return videoDisabled == 0;
|
||||
}
|
||||
|
||||
int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
|
||||
int AmlogicGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
{
|
||||
// resize the given image if needed
|
||||
if (image.width() != (unsigned)_width || image.height() != (unsigned)_height)
|
||||
{
|
||||
image.resize(_width, _height);
|
||||
}
|
||||
// TODO crop resulting image accroding member _videoMode
|
||||
// TODO add croping
|
||||
|
||||
// Make sure video is playing, else there is nothing to grab
|
||||
if (!isVideoPlaying())
|
||||
@ -95,7 +88,6 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// If the device is not open, attempt to open it
|
||||
if (_amlogicCaptureDev == -1)
|
||||
{
|
||||
@ -121,7 +113,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
|
||||
}
|
||||
|
||||
// Read the snapshot into the memory
|
||||
void * image_ptr = image.memptr();
|
||||
void * image_ptr = _image.memptr();
|
||||
const ssize_t bytesToRead = _width * _height * sizeof(ColorBgr);
|
||||
|
||||
const ssize_t bytesRead = pread(_amlogicCaptureDev, image_ptr, bytesToRead, 0);
|
||||
@ -150,5 +142,10 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
|
||||
_amlogicCaptureDev = -1;
|
||||
readCnt = 0;
|
||||
}
|
||||
|
||||
_imageResampler.setHorizontalPixelDecimation(_width);
|
||||
_imageResampler.setVerticalPixelDecimation(_height);
|
||||
_imageResampler.processImage((const uint8_t*)image_ptr, _width, _height, 3, PIXELFORMAT_BGR24, image);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,53 +1,11 @@
|
||||
// QT includes
|
||||
#include <QDateTime>
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
|
||||
// Amlogic grabber includes
|
||||
#include <grabber/AmlogicWrapper.h>
|
||||
#include <grabber/AmlogicGrabber.h>
|
||||
|
||||
|
||||
AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
||||
: GrabberWrapper("AmLogic", priority)
|
||||
, _updateInterval_ms(1000/updateRate_Hz)
|
||||
, _timeout_ms(2 * _updateInterval_ms)
|
||||
, _image(grabWidth, grabHeight)
|
||||
, _grabber(new AmlogicGrabber(grabWidth, grabHeight))
|
||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
||||
{
|
||||
// Configure the timer to generate events every n milliseconds
|
||||
_timer.setInterval(_updateInterval_ms);
|
||||
|
||||
_processor->setSize(grabWidth, grabHeight);
|
||||
}
|
||||
|
||||
AmlogicWrapper::~AmlogicWrapper()
|
||||
{
|
||||
delete _grabber;
|
||||
}
|
||||
: GrabberWrapper("AmLogic", &_grabber, grabWidth, grabHeight, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||
, _grabber(grabWidth, grabHeight)
|
||||
{}
|
||||
|
||||
void AmlogicWrapper::action()
|
||||
{
|
||||
// Grab frame into the allocated image
|
||||
if (_grabber->grabFrame(_image) < 0)
|
||||
{
|
||||
// Frame grab failed, maybe nothing playing or ....
|
||||
return;
|
||||
}
|
||||
|
||||
Image<ColorRgb> image_rgb;
|
||||
_image.toRgb(image_rgb);
|
||||
emit emitImage(_priority, image_rgb, _timeout_ms);
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
void AmlogicWrapper::setVideoMode(const VideoMode mode)
|
||||
{
|
||||
_grabber->setVideoMode(mode);
|
||||
transferFrame(_grabber);
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
# Find the BCM-package (VC control)
|
||||
find_package(BCM REQUIRED)
|
||||
include_directories(${BCM_INCLUDE_DIRS})
|
||||
IF ( "${PLATFORM}" MATCHES rpi)
|
||||
find_package(BCM REQUIRED)
|
||||
include_directories(${BCM_INCLUDE_DIRS})
|
||||
ELSE()
|
||||
SET(BCM_INCLUDE_DIRS "")
|
||||
SET(BCM_LIBRARIES "")
|
||||
ENDIF()
|
||||
|
||||
# Define the current source locations
|
||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
||||
|
@ -13,7 +13,10 @@ DispmanxFrameGrabber::DispmanxFrameGrabber(const unsigned width, const unsigned
|
||||
, _vc_flags(0)
|
||||
, _captureBuffer(new ColorRgba[0])
|
||||
, _captureBufferSize(0)
|
||||
, _image_rgba(width, height)
|
||||
{
|
||||
_useImageResampler = false;
|
||||
|
||||
// Initiase BCM
|
||||
bcm_host_init();
|
||||
|
||||
@ -64,25 +67,7 @@ void DispmanxFrameGrabber::setFlags(const int vc_flags)
|
||||
_vc_flags = vc_flags;
|
||||
}
|
||||
|
||||
void DispmanxFrameGrabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
|
||||
{
|
||||
if (cropLeft + cropRight >= (unsigned)_width || cropTop + cropBottom >= (unsigned)_height)
|
||||
{
|
||||
Error(_log, "Rejecting invalid crop values: left: %d, right: %d, top: %d, bottom: %d", cropLeft, cropRight, cropTop, cropBottom);
|
||||
return;
|
||||
}
|
||||
_cropLeft = cropLeft;
|
||||
_cropRight = cropRight;
|
||||
_cropTop = cropTop;
|
||||
_cropBottom = cropBottom;
|
||||
|
||||
if (cropLeft > 0 || cropRight > 0 || cropTop > 0 || cropBottom > 0)
|
||||
{
|
||||
Info(_log, "Cropping image: width=%d height=%d; crop: left=%d right=%d top=%d bottom=%d ", _width, _height, cropLeft, cropRight, cropTop, cropBottom);
|
||||
}
|
||||
}
|
||||
|
||||
void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
int DispmanxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -106,12 +91,12 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
switch (_videoMode)
|
||||
{
|
||||
case VIDEO_3DSBS:
|
||||
imageWidth = imageWidth / 2;
|
||||
cropLeft = cropLeft / 2;
|
||||
imageWidth /= 2;
|
||||
cropLeft /= 2;
|
||||
break;
|
||||
case VIDEO_3DTAB:
|
||||
imageHeight = imageHeight / 2;
|
||||
cropTop = cropTop / 2;
|
||||
imageHeight /= 2;
|
||||
cropTop /= 2;
|
||||
break;
|
||||
case VIDEO_2D:
|
||||
default:
|
||||
@ -124,12 +109,17 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
image.resize(imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
if (_image_rgba.width() != imageWidth || _image_rgba.height() != imageHeight)
|
||||
{
|
||||
_image_rgba.resize(imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
// Open the connection to the display
|
||||
_vc_display = vc_dispmanx_display_open(0);
|
||||
if (_vc_display < 0)
|
||||
{
|
||||
Error(_log, "Cannot open display: %d", _vc_display);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create the snapshot (incl down-scaling)
|
||||
@ -138,11 +128,11 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
{
|
||||
Error(_log, "Snapshot failed: %d", ret);
|
||||
vc_dispmanx_display_close(_vc_display);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Read the snapshot into the memory
|
||||
void* imagePtr = image.memptr();
|
||||
void* imagePtr = _image_rgba.memptr();
|
||||
void* capturePtr = imagePtr;
|
||||
|
||||
unsigned imagePitch = imageWidth * sizeof(ColorRgba);
|
||||
@ -172,7 +162,7 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
{
|
||||
Error(_log, "vc_dispmanx_resource_read_data failed: %d", ret);
|
||||
vc_dispmanx_display_close(_vc_display);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// copy capture data to image if we captured to temp buffer
|
||||
@ -193,4 +183,9 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
|
||||
// Close the displaye
|
||||
vc_dispmanx_display_close(_vc_display);
|
||||
|
||||
// image to output image
|
||||
_image_rgba.toRgb(image);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
107
libsrc/grabber/dispmanx/DispmanxFrameGrabberMock.cpp
Normal file
107
libsrc/grabber/dispmanx/DispmanxFrameGrabberMock.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef PLATFORM_RPI
|
||||
|
||||
#include <grabber/DispmanxFrameGrabberMock.h>
|
||||
|
||||
unsigned __bcm_frame_counter = 0;
|
||||
const int __screenWidth = 800;
|
||||
const int __screenHeight = 600;
|
||||
|
||||
void bcm_host_init()
|
||||
{
|
||||
}
|
||||
|
||||
void bcm_host_deinit()
|
||||
{
|
||||
}
|
||||
|
||||
int vc_dispmanx_display_open(int)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void vc_dispmanx_display_close(int)
|
||||
{
|
||||
}
|
||||
|
||||
int vc_dispmanx_display_get_info(int, DISPMANX_MODEINFO_T *vc_info)
|
||||
{
|
||||
vc_info->width = __screenWidth;
|
||||
vc_info->height = __screenHeight;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DISPMANX_RESOURCE_HANDLE_T vc_dispmanx_resource_create(int,int width,int height, uint32_t *)
|
||||
{
|
||||
return new DISPMANX_RESOURCE(width,height);
|
||||
}
|
||||
|
||||
void vc_dispmanx_resource_delete(DISPMANX_RESOURCE_HANDLE_T resource)
|
||||
{
|
||||
delete resource;
|
||||
}
|
||||
|
||||
int vc_dispmanx_resource_read_data(DISPMANX_RESOURCE_HANDLE_T resource, VC_RECT_T *rectangle, void* capturePtr, unsigned capturePitch)
|
||||
{
|
||||
memcpy(capturePtr, resource->memptr(), resource->height()*resource->width() * sizeof(ColorRgba));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vc_dispmanx_rect_set(VC_RECT_T *rectangle, int left, int top, int width, int height)
|
||||
{
|
||||
rectangle->width = width;
|
||||
rectangle->height = height;
|
||||
rectangle->left = left;
|
||||
rectangle->top = top;
|
||||
}
|
||||
|
||||
int vc_dispmanx_snapshot(int, DISPMANX_RESOURCE_HANDLE_T resource, int vc_flags)
|
||||
{
|
||||
__bcm_frame_counter++;
|
||||
if (__bcm_frame_counter > 100)
|
||||
{
|
||||
__bcm_frame_counter = 0;
|
||||
}
|
||||
|
||||
ColorRgba color[4] = {ColorRgba::RED, ColorRgba::BLUE, ColorRgba::GREEN, ColorRgba::WHITE};
|
||||
if (__bcm_frame_counter < 25)
|
||||
{
|
||||
color[0] = ColorRgba::WHITE;
|
||||
color[1] = ColorRgba::RED;
|
||||
color[2] = ColorRgba::BLUE;
|
||||
color[3] = ColorRgba::GREEN;
|
||||
}
|
||||
else if(__bcm_frame_counter < 50)
|
||||
{
|
||||
color[1] = ColorRgba::WHITE;
|
||||
color[2] = ColorRgba::RED;
|
||||
color[3] = ColorRgba::BLUE;
|
||||
color[0] = ColorRgba::GREEN;
|
||||
}
|
||||
else if(__bcm_frame_counter < 75)
|
||||
{
|
||||
color[2] = ColorRgba::WHITE;
|
||||
color[3] = ColorRgba::RED;
|
||||
color[0] = ColorRgba::BLUE;
|
||||
color[1] = ColorRgba::GREEN;
|
||||
}
|
||||
|
||||
unsigned w = resource->width();
|
||||
unsigned h = resource->height();
|
||||
for (unsigned y=0; y<h; y++)
|
||||
{
|
||||
for (unsigned x=0; x<w; x++)
|
||||
{
|
||||
unsigned id = 0;
|
||||
if (x < w/2 && y < h/2) id = 1;
|
||||
if (x < w/2 && y >= h/2) id = 2;
|
||||
if (x >= w/2 && y < h/2) id = 3;
|
||||
|
||||
resource->memptr()[y*w + x] = color[id];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,56 +1,13 @@
|
||||
// QT includes
|
||||
#include <QDateTime>
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
|
||||
// Dispmanx grabber includes
|
||||
#include <grabber/DispmanxWrapper.h>
|
||||
#include <grabber/DispmanxFrameGrabber.h>
|
||||
|
||||
|
||||
DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
||||
: GrabberWrapper("Dispmanx", priority)
|
||||
, _updateInterval_ms(1000/updateRate_Hz)
|
||||
, _timeout_ms(2 * _updateInterval_ms)
|
||||
, _image(grabWidth, grabHeight)
|
||||
, _grabber(new DispmanxFrameGrabber(grabWidth, grabHeight))
|
||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
||||
: GrabberWrapper("Dispmanx", &_grabber, grabWidth, grabHeight, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||
, _grabber(grabWidth, grabHeight)
|
||||
{
|
||||
// Configure the timer to generate events every n milliseconds
|
||||
_timer.setInterval(_updateInterval_ms);
|
||||
|
||||
_processor->setSize(grabWidth, grabHeight);
|
||||
}
|
||||
|
||||
DispmanxWrapper::~DispmanxWrapper()
|
||||
{
|
||||
delete _grabber;
|
||||
setImageProcessorEnabled(false);
|
||||
}
|
||||
|
||||
void DispmanxWrapper::action()
|
||||
{
|
||||
// Grab frame into the allocated image
|
||||
_grabber->grabFrame(_image);
|
||||
|
||||
Image<ColorRgb> image_rgb;
|
||||
_image.toRgb(image_rgb);
|
||||
emit emitImage(_priority, image_rgb, _timeout_ms);
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
|
||||
void DispmanxWrapper::setVideoMode(const VideoMode mode)
|
||||
{
|
||||
_grabber->setVideoMode(mode);
|
||||
}
|
||||
|
||||
void DispmanxWrapper::setCropping(const unsigned cropLeft, const unsigned cropRight,
|
||||
const unsigned cropTop, const unsigned cropBottom)
|
||||
{
|
||||
_grabber->setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||
transferFrame(_grabber);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ FramebufferFrameGrabber::~FramebufferFrameGrabber()
|
||||
{
|
||||
}
|
||||
|
||||
void FramebufferFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
int FramebufferFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
{
|
||||
struct fb_var_screeninfo vinfo;
|
||||
unsigned capSize, bytesPerPixel;
|
||||
@ -62,23 +62,15 @@ void FramebufferFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
bytesPerPixel = vinfo.bits_per_pixel / 8;
|
||||
capSize = vinfo.xres * vinfo.yres * bytesPerPixel;
|
||||
|
||||
if (vinfo.bits_per_pixel == 16)
|
||||
{
|
||||
pixelFormat = PIXELFORMAT_BGR16;
|
||||
}
|
||||
else if (vinfo.bits_per_pixel == 24)
|
||||
{
|
||||
pixelFormat = PIXELFORMAT_BGR24;
|
||||
}
|
||||
else if (vinfo.bits_per_pixel == 32)
|
||||
{
|
||||
pixelFormat = PIXELFORMAT_BGR32;
|
||||
}
|
||||
else
|
||||
switch (vinfo.bits_per_pixel)
|
||||
{
|
||||
case 16: pixelFormat = PIXELFORMAT_BGR16; break;
|
||||
case 24: pixelFormat = PIXELFORMAT_BGR24; break;
|
||||
case 32: pixelFormat = PIXELFORMAT_BGR32; break;
|
||||
default:
|
||||
Error(_log, "Unknown pixel format: %d bits per pixel", vinfo.bits_per_pixel);
|
||||
close(_fbfd);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* map the device to memory */
|
||||
@ -95,4 +87,6 @@ void FramebufferFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
|
||||
munmap(_fbp, capSize);
|
||||
close(_fbfd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,43 +1,11 @@
|
||||
// Hyperion includes
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
|
||||
// Framebuffer grabber includes
|
||||
#include <grabber/FramebufferWrapper.h>
|
||||
#include <grabber/FramebufferFrameGrabber.h>
|
||||
|
||||
FramebufferWrapper::FramebufferWrapper(const QString & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
||||
: GrabberWrapper("FrameBuffer", priority)
|
||||
, _updateInterval_ms(1000/updateRate_Hz)
|
||||
, _timeout_ms(2 * _updateInterval_ms)
|
||||
, _image(grabWidth, grabHeight)
|
||||
, _grabber(new FramebufferFrameGrabber(device, grabWidth, grabHeight))
|
||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
||||
{
|
||||
// Configure the timer to generate events every n milliseconds
|
||||
_timer.setInterval(_updateInterval_ms);
|
||||
|
||||
_processor->setSize(grabWidth, grabHeight);
|
||||
}
|
||||
|
||||
FramebufferWrapper::~FramebufferWrapper()
|
||||
{
|
||||
delete _grabber;
|
||||
}
|
||||
: GrabberWrapper("FrameBuffer", &_grabber, grabWidth, grabHeight, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||
, _grabber(device, grabWidth, grabHeight)
|
||||
{}
|
||||
|
||||
void FramebufferWrapper::action()
|
||||
{
|
||||
// Grab frame into the allocated image
|
||||
_grabber->grabFrame(_image);
|
||||
|
||||
emit emitImage(_priority, _image, _timeout_ms);
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
void FramebufferWrapper::setVideoMode(const VideoMode mode)
|
||||
{
|
||||
_grabber->setVideoMode(mode);
|
||||
transferFrame(_grabber);
|
||||
}
|
||||
|
@ -19,7 +19,9 @@ OsxFrameGrabber::OsxFrameGrabber(const unsigned display, const unsigned width, c
|
||||
{
|
||||
Error(_log, "Display with index %d is not available. Using main display", _screenIndex);
|
||||
_display = kCGDirectMainDisplay;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_display = displays[_screenIndex];
|
||||
}
|
||||
|
||||
@ -35,7 +37,7 @@ OsxFrameGrabber::~OsxFrameGrabber()
|
||||
{
|
||||
}
|
||||
|
||||
void OsxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
int OsxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
{
|
||||
CGImageRef dispImage;
|
||||
CFDataRef imgData;
|
||||
@ -52,7 +54,7 @@ void OsxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
if (dispImage == NULL)
|
||||
{
|
||||
Error(_log, "No display connected...");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
imgData = CGDataProviderCopyData(CGImageGetDataProvider(dispImage));
|
||||
@ -71,4 +73,6 @@ void OsxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
|
||||
CFRelease(imgData);
|
||||
CGImageRelease(dispImage);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
126
libsrc/grabber/osx/OsxFrameGrabberMock.cpp
Normal file
126
libsrc/grabber/osx/OsxFrameGrabberMock.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#ifndef __APPLE__
|
||||
#include <grabber/OsxFrameGrabberMock.h>
|
||||
|
||||
unsigned __osx_frame_counter = 0;
|
||||
const int __screenWidth = 800;
|
||||
const int __screenHeight = 600;
|
||||
|
||||
void CGGetActiveDisplayList(int max, CGDirectDisplayID *displays, CGDisplayCount *displayCount)
|
||||
{
|
||||
*displayCount = 1;
|
||||
displays[0] = 1;
|
||||
}
|
||||
|
||||
CGImageRef CGDisplayCreateImage(CGDirectDisplayID display)
|
||||
{
|
||||
CGImageRef image = new CGImage(__screenWidth, __screenHeight);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void CGImageRelease(CGImageRef image)
|
||||
{
|
||||
delete image;
|
||||
}
|
||||
|
||||
CGImageRef CGImageGetDataProvider(CGImageRef image)
|
||||
{
|
||||
__osx_frame_counter++;
|
||||
if (__osx_frame_counter > 100)
|
||||
{
|
||||
__osx_frame_counter = 0;
|
||||
}
|
||||
|
||||
ColorRgb color[4] = {ColorRgb::RED, ColorRgb::BLUE, ColorRgb::GREEN, ColorRgb::WHITE};
|
||||
if (__osx_frame_counter < 25)
|
||||
{
|
||||
color[0] = ColorRgb::WHITE;
|
||||
color[1] = ColorRgb::RED;
|
||||
color[2] = ColorRgb::BLUE;
|
||||
color[3] = ColorRgb::GREEN;
|
||||
}
|
||||
else if(__osx_frame_counter < 50)
|
||||
{
|
||||
color[1] = ColorRgb::WHITE;
|
||||
color[2] = ColorRgb::RED;
|
||||
color[3] = ColorRgb::BLUE;
|
||||
color[0] = ColorRgb::GREEN;
|
||||
}
|
||||
else if(__osx_frame_counter < 75)
|
||||
{
|
||||
color[2] = ColorRgb::WHITE;
|
||||
color[3] = ColorRgb::RED;
|
||||
color[0] = ColorRgb::BLUE;
|
||||
color[1] = ColorRgb::GREEN;
|
||||
}
|
||||
unsigned w = image->width();
|
||||
unsigned h = image->height();
|
||||
|
||||
for (unsigned y=0; y<h; y++)
|
||||
{
|
||||
for (unsigned x=0; x<w; x++)
|
||||
{
|
||||
unsigned id = 0;
|
||||
if (x < w/2 && y < h/2) id = 1;
|
||||
if (x < w/2 && y >= h/2) id = 2;
|
||||
if (x >= w/2 && y < h/2) id = 3;
|
||||
|
||||
image->memptr()[y*w + x] = color[id];
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
CFDataRef CGDataProviderCopyData(CGImageRef image)
|
||||
{
|
||||
const unsigned indexMax = image->width() * image->height() * CGImageGetBitsPerPixel(image);
|
||||
CFDataRef data = new CFData[indexMax];
|
||||
int lineLength = CGImageGetBytesPerRow(image);
|
||||
|
||||
for (unsigned y=0; y<image->height(); y++)
|
||||
{
|
||||
for (unsigned x=0; x<image->width(); x++)
|
||||
{
|
||||
int index = lineLength * y + x * CGImageGetBitsPerPixel(image);
|
||||
|
||||
data[index ] = (*image)(x,y).blue;
|
||||
data[index+1] = (*image)(x,y).green;
|
||||
data[index+2] = (*image)(x,y).red;
|
||||
data[index+3] = 0;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
unsigned char* CFDataGetBytePtr(CFDataRef imgData)
|
||||
{
|
||||
return imgData;
|
||||
}
|
||||
|
||||
unsigned CGImageGetWidth(CGImageRef image)
|
||||
{
|
||||
return image->width();
|
||||
}
|
||||
|
||||
unsigned CGImageGetHeight(CGImageRef image)
|
||||
{
|
||||
return image->height();
|
||||
}
|
||||
|
||||
unsigned CGImageGetBytesPerRow(CGImageRef image)
|
||||
{
|
||||
return image->width()*CGImageGetBitsPerPixel(image);
|
||||
}
|
||||
|
||||
unsigned CGImageGetBitsPerPixel(CGImageRef)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
void CFRelease(CFDataRef imgData)
|
||||
{
|
||||
delete imgData;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,44 +1,11 @@
|
||||
// Hyperion includes
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
|
||||
// Osx grabber includes
|
||||
#include <grabber/OsxWrapper.h>
|
||||
#include <grabber/OsxFrameGrabber.h>
|
||||
|
||||
OsxWrapper::OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
||||
: GrabberWrapper("OSX FrameGrabber", priority)
|
||||
, _updateInterval_ms(1000/updateRate_Hz)
|
||||
, _timeout_ms(2 * _updateInterval_ms)
|
||||
, _image(grabWidth, grabHeight)
|
||||
, _grabber(new OsxFrameGrabber(display, grabWidth, grabHeight))
|
||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
||||
{
|
||||
// Configure the timer to generate events every n milliseconds
|
||||
_timer.setInterval(_updateInterval_ms);
|
||||
|
||||
_processor->setSize(grabWidth, grabHeight);
|
||||
}
|
||||
|
||||
OsxWrapper::~OsxWrapper()
|
||||
{
|
||||
delete _grabber;
|
||||
}
|
||||
: GrabberWrapper("OSX FrameGrabber", &_grabber, grabWidth, grabHeight, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||
, _grabber(display, grabWidth, grabHeight)
|
||||
{}
|
||||
|
||||
void OsxWrapper::action()
|
||||
{
|
||||
// Grab frame into the allocated image
|
||||
_grabber->grabFrame(_image);
|
||||
|
||||
emit emitImage(_priority, _image, _timeout_ms);
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
|
||||
void OsxWrapper::setVideoMode(const VideoMode mode)
|
||||
{
|
||||
_grabber->setVideoMode(mode);
|
||||
transferFrame(_grabber);
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ V4L2Grabber::V4L2Grabber(const QString & device
|
||||
, int input
|
||||
, VideoStandard videoStandard
|
||||
, PixelFormat pixelFormat
|
||||
, int width
|
||||
, int height
|
||||
, unsigned width
|
||||
, unsigned height
|
||||
, int frameDecimation
|
||||
, int horizontalPixelDecimation
|
||||
, int verticalPixelDecimation
|
||||
@ -180,11 +180,6 @@ void V4L2Grabber::getV4Ldevices()
|
||||
}
|
||||
}
|
||||
|
||||
void V4L2Grabber::setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom)
|
||||
{
|
||||
_imageResampler.setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||
}
|
||||
|
||||
void V4L2Grabber::setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, int noSignalCounterThreshold)
|
||||
{
|
||||
_noSignalThresholdColor.red = uint8_t(255*redSignalThreshold);
|
||||
|
@ -8,8 +8,8 @@ V4L2Wrapper::V4L2Wrapper(const QString &device,
|
||||
int input,
|
||||
VideoStandard videoStandard,
|
||||
PixelFormat pixelFormat,
|
||||
int width,
|
||||
int height,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
int frameDecimation,
|
||||
int pixelDecimation,
|
||||
double redSignalThreshold,
|
||||
@ -17,8 +17,7 @@ V4L2Wrapper::V4L2Wrapper(const QString &device,
|
||||
double blueSignalThreshold,
|
||||
const int priority,
|
||||
bool useGrabbingMode)
|
||||
: GrabberWrapper("V4L2:"+device, priority, hyperion::COMP_V4L)
|
||||
, _timeout_ms(1000)
|
||||
: GrabberWrapper("V4L2:"+device, &_grabber, width, height, 8, priority, hyperion::COMP_V4L)
|
||||
, _grabber(device,
|
||||
input,
|
||||
videoStandard,
|
||||
@ -28,10 +27,10 @@ V4L2Wrapper::V4L2Wrapper(const QString &device,
|
||||
frameDecimation,
|
||||
pixelDecimation,
|
||||
pixelDecimation)
|
||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
||||
{
|
||||
// set the signal detection threshold of the grabber
|
||||
_grabber.setSignalThreshold( redSignalThreshold, greenSignalThreshold, blueSignalThreshold, 50);
|
||||
_ggrabber = &_grabber;
|
||||
|
||||
// register the image type
|
||||
qRegisterMetaType<Image<ColorRgb>>("Image<ColorRgb>");
|
||||
@ -40,29 +39,15 @@ V4L2Wrapper::V4L2Wrapper(const QString &device,
|
||||
|
||||
// Handle the image in the captured thread using a direct connection
|
||||
QObject::connect(&_grabber, SIGNAL(newFrame(Image<ColorRgb>)), this, SLOT(newFrame(Image<ColorRgb>)), Qt::DirectConnection);
|
||||
|
||||
QObject::connect(&_grabber, SIGNAL(readError(const char*)), this, SLOT(readError(const char*)), Qt::DirectConnection);
|
||||
|
||||
if (!useGrabbingMode)
|
||||
{
|
||||
disconnect(_hyperion, SIGNAL(grabbingMode(GrabbingMode)), this, 0);
|
||||
}
|
||||
// send color data to Hyperion using a queued connection to handle the data over to the main event loop
|
||||
// QObject::connect(
|
||||
// this, SIGNAL(emitColors(int,std::vector<ColorRgb>,int)),
|
||||
// _hyperion, SLOT(setColors(int,std::vector<ColorRgb>,int)),
|
||||
// Qt::QueuedConnection);
|
||||
|
||||
|
||||
// setup the higher prio source checker
|
||||
// this will disable the v4l2 grabber when a source with higher priority is active
|
||||
_timer.setInterval(500);
|
||||
}
|
||||
|
||||
V4L2Wrapper::~V4L2Wrapper()
|
||||
{
|
||||
}
|
||||
|
||||
bool V4L2Wrapper::start()
|
||||
{
|
||||
return ( _grabber.start() && GrabberWrapper::start());
|
||||
@ -84,12 +69,6 @@ void V4L2Wrapper::setSignalDetectionOffset(double verticalMin, double horizontal
|
||||
_grabber.setSignalDetectionOffset(verticalMin, horizontalMin, verticalMax, horizontalMax);
|
||||
}
|
||||
|
||||
|
||||
void V4L2Wrapper::setVideoMode(VideoMode mode)
|
||||
{
|
||||
_grabber.setVideoMode(mode);
|
||||
}
|
||||
|
||||
void V4L2Wrapper::newFrame(const Image<ColorRgb> &image)
|
||||
{
|
||||
emit emitImage(_priority, image, _timeout_ms);
|
||||
|
@ -14,8 +14,11 @@ X11Grabber::X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropT
|
||||
, _verticalDecimation(verticalPixelDecimation)
|
||||
, _screenWidth(0)
|
||||
, _screenHeight(0)
|
||||
, _src_x(cropLeft)
|
||||
, _src_y(cropTop)
|
||||
, _image(0,0)
|
||||
{
|
||||
_useImageResampler = false;
|
||||
_imageResampler.setCropping(0, 0, 0, 0); // cropping is performed by XRender, XShmGetImage or XGetImage
|
||||
memset(&_pictAttr, 0, sizeof(_pictAttr));
|
||||
_pictAttr.repeat = RepeatNone;
|
||||
@ -52,9 +55,7 @@ void X11Grabber::setupResources()
|
||||
{
|
||||
if(_XShmAvailable && !_useXGetImage)
|
||||
{
|
||||
_xImage = XShmCreateImage(_x11Display, _windowAttr.visual,
|
||||
_windowAttr.depth, ZPixmap, NULL, &_shminfo,
|
||||
_width, _height);
|
||||
_xImage = XShmCreateImage(_x11Display, _windowAttr.visual, _windowAttr.depth, ZPixmap, NULL, &_shminfo, _width, _height);
|
||||
_shminfo.shmid = shmget(IPC_PRIVATE, _xImage->bytes_per_line * _xImage->height, IPC_CREAT|0777);
|
||||
_xImage->data = (char*)shmat(_shminfo.shmid,0,0);
|
||||
_shminfo.shmaddr = _xImage->data;
|
||||
@ -109,12 +110,15 @@ bool X11Grabber::Setup()
|
||||
_imageResampler.setHorizontalPixelDecimation(_XRenderAvailable ? 1 : _horizontalDecimation);
|
||||
_imageResampler.setVerticalPixelDecimation(_XRenderAvailable ? 1 : _verticalDecimation);
|
||||
|
||||
return true;
|
||||
bool result = (updateScreenDimensions(true) >=0);
|
||||
ErrorIf(!result, _log, "X11 Grabber start failed");
|
||||
return result;
|
||||
}
|
||||
|
||||
Image<ColorRgb> & X11Grabber::grab()
|
||||
int X11Grabber::grabFrame(Image<ColorRgb> & image, bool forceUpdate)
|
||||
{
|
||||
updateScreenDimensions();
|
||||
if (forceUpdate)
|
||||
updateScreenDimensions(forceUpdate);
|
||||
|
||||
if (_XRenderAvailable && !_useXGetImage)
|
||||
{
|
||||
@ -145,19 +149,11 @@ Image<ColorRgb> & X11Grabber::grab()
|
||||
|
||||
XRenderSetPictureTransform (_x11Display, _srcPicture, &_transform);
|
||||
|
||||
XRenderComposite( _x11Display, // dpy
|
||||
PictOpSrc, // op
|
||||
_srcPicture, // src
|
||||
None, // mask
|
||||
_dstPicture, // dst
|
||||
_cropLeft / _horizontalDecimation, // src_x _cropLeft
|
||||
_cropTop / _verticalDecimation, // src_y _cropTop
|
||||
0, // mask_x
|
||||
0, // mask_y
|
||||
0, // dst_x
|
||||
0, // dst_y
|
||||
_width, // width
|
||||
_height); // height
|
||||
// display, op, src, mask, dest, src_x = cropLeft,
|
||||
// src_y = cropTop, mask_x, mask_y, dest_x, dest_y, width, height
|
||||
XRenderComposite(
|
||||
_x11Display, PictOpSrc, _srcPicture, None, _dstPicture, ( _src_x/_horizontalDecimation),
|
||||
(_src_y/_verticalDecimation), 0, 0, 0, 0, _width, _height);
|
||||
|
||||
XSync(_x11Display, False);
|
||||
|
||||
@ -170,93 +166,15 @@ Image<ColorRgb> & X11Grabber::grab()
|
||||
_xImage = XGetImage(_x11Display, _pixmap, 0, 0, _width, _height, AllPlanes, ZPixmap);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (_XShmAvailable && !_useXGetImage)
|
||||
{
|
||||
if (_XShmAvailable && !_useXGetImage) {
|
||||
XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, AllPlanes);
|
||||
// use xshm
|
||||
XShmGetImage(_x11Display, _window, _xImage, _src_x, _src_y, AllPlanes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_xImage = XGetImage(_x11Display, _window, _cropLeft, _cropTop, _width, _height, AllPlanes, ZPixmap);
|
||||
}
|
||||
}
|
||||
|
||||
if (_xImage == nullptr)
|
||||
{
|
||||
Error(_log, "Grab Failed!");
|
||||
return _image;
|
||||
}
|
||||
|
||||
_imageResampler.processImage(reinterpret_cast<const uint8_t *>(_xImage->data), _xImage->width, _xImage->height, _xImage->bytes_per_line, PIXELFORMAT_BGR32, _image);
|
||||
|
||||
return _image;
|
||||
}
|
||||
|
||||
int X11Grabber::grabFrame(Image<ColorRgb> & image)
|
||||
{
|
||||
if (_XRenderAvailable && !_useXGetImage)
|
||||
{
|
||||
double scale_x = static_cast<double>(_windowAttr.width / _horizontalDecimation) / static_cast<double>(_windowAttr.width);
|
||||
double scale_y = static_cast<double>(_windowAttr.height / _verticalDecimation) / static_cast<double>(_windowAttr.height);
|
||||
double scale = qMin(scale_y, scale_x);
|
||||
|
||||
_transform =
|
||||
{
|
||||
{
|
||||
{
|
||||
XDoubleToFixed(1),
|
||||
XDoubleToFixed(0),
|
||||
XDoubleToFixed(0)
|
||||
},
|
||||
{
|
||||
XDoubleToFixed(0),
|
||||
XDoubleToFixed(1),
|
||||
XDoubleToFixed(0)
|
||||
},
|
||||
{
|
||||
XDoubleToFixed(0),
|
||||
XDoubleToFixed(0),
|
||||
XDoubleToFixed(scale)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
XRenderSetPictureTransform (_x11Display, _srcPicture, &_transform);
|
||||
|
||||
XRenderComposite( _x11Display, // dpy
|
||||
PictOpSrc, // op
|
||||
_srcPicture, // src
|
||||
None, // mask
|
||||
_dstPicture, // dst
|
||||
_cropLeft / _horizontalDecimation, // src_x _cropLeft
|
||||
_cropTop / _verticalDecimation, // src_y _cropTop
|
||||
0, // mask_x
|
||||
0, // mask_y
|
||||
0, // dst_x
|
||||
0, // dst_y
|
||||
_width, // width
|
||||
_height); // height
|
||||
|
||||
XSync(_x11Display, False);
|
||||
|
||||
if (_XShmAvailable)
|
||||
{
|
||||
XShmGetImage(_x11Display, _pixmap, _xImage, 0, 0, AllPlanes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_xImage = XGetImage(_x11Display, _pixmap, 0, 0, _width, _height, AllPlanes, ZPixmap);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_XShmAvailable && !_useXGetImage) {
|
||||
XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, AllPlanes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_xImage = XGetImage(_x11Display, _window, _cropLeft, _cropTop, _width, _height, AllPlanes, ZPixmap);
|
||||
}
|
||||
// all things done by xgetimage
|
||||
_xImage = XGetImage(_x11Display, _window, _src_x, _src_y, _width, _height, AllPlanes, ZPixmap);
|
||||
}
|
||||
|
||||
if (_xImage == nullptr)
|
||||
@ -270,7 +188,7 @@ int X11Grabber::grabFrame(Image<ColorRgb> & image)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int X11Grabber::updateScreenDimensions()
|
||||
int X11Grabber::updateScreenDimensions(bool force)
|
||||
{
|
||||
const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr);
|
||||
if (status == 0)
|
||||
@ -279,7 +197,7 @@ int X11Grabber::updateScreenDimensions()
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_screenWidth == unsigned(_windowAttr.width) && _screenHeight == unsigned(_windowAttr.height))
|
||||
if (!force && _screenWidth == unsigned(_windowAttr.width) && _screenHeight == unsigned(_windowAttr.height))
|
||||
{
|
||||
// No update required
|
||||
return 0;
|
||||
@ -294,14 +212,16 @@ int X11Grabber::updateScreenDimensions()
|
||||
_screenWidth = _windowAttr.width;
|
||||
_screenHeight = _windowAttr.height;
|
||||
|
||||
int width=0, height=0;
|
||||
|
||||
// Image scaling is performed by XRender when available, otherwise by ImageResampler
|
||||
if (_XRenderAvailable && !_useXGetImage)
|
||||
{
|
||||
_width = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
||||
width = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
||||
? ((_screenWidth - _cropLeft - _cropRight) / _horizontalDecimation)
|
||||
: _screenWidth / _horizontalDecimation;
|
||||
|
||||
_height = (_screenHeight > unsigned(_cropTop + _cropBottom))
|
||||
height = (_screenHeight > unsigned(_cropTop + _cropBottom))
|
||||
? ((_screenHeight - _cropTop - _cropBottom) / _verticalDecimation)
|
||||
: _screenHeight / _verticalDecimation;
|
||||
|
||||
@ -309,19 +229,52 @@ int X11Grabber::updateScreenDimensions()
|
||||
}
|
||||
else
|
||||
{
|
||||
_width = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
||||
width = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
||||
? (_screenWidth - _cropLeft - _cropRight)
|
||||
: _screenWidth;
|
||||
|
||||
_height = (_screenHeight > unsigned(_cropTop + _cropBottom))
|
||||
height = (_screenHeight > unsigned(_cropTop + _cropBottom))
|
||||
? (_screenHeight - _cropTop - _cropBottom)
|
||||
: _screenHeight;
|
||||
|
||||
Info(_log, "Using XGetImage for grabbing");
|
||||
}
|
||||
|
||||
// calculate final image dimensions and adjust top/left cropping in 3D modes
|
||||
switch (_videoMode)
|
||||
{
|
||||
case VIDEO_3DSBS:
|
||||
_width = width /2;
|
||||
_height = height;
|
||||
_src_x = _cropLeft / 2;
|
||||
_src_y = _cropTop;
|
||||
break;
|
||||
case VIDEO_3DTAB:
|
||||
_width = width;
|
||||
_height = height / 2;
|
||||
_src_x = _cropLeft;
|
||||
_src_y = _cropTop / 2;
|
||||
break;
|
||||
case VIDEO_2D:
|
||||
default:
|
||||
_width = width;
|
||||
_height = height;
|
||||
_src_x = _cropLeft;
|
||||
_src_y = _cropTop;
|
||||
break;
|
||||
}
|
||||
|
||||
Info(_log, "Update output image resolution: [%dx%d] to [%dx%d]", _image.width(), _image.height(), _width, _height);
|
||||
|
||||
_image.resize(_width, _height);
|
||||
setupResources();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void X11Grabber::setVideoMode(VideoMode mode)
|
||||
{
|
||||
Info(_log, "a %d", mode);
|
||||
Grabber::setVideoMode(mode);
|
||||
updateScreenDimensions(true);
|
||||
}
|
||||
|
@ -1,78 +1,24 @@
|
||||
|
||||
// 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)
|
||||
: GrabberWrapper("X11", priority)
|
||||
, _updateInterval_ms(1000/updateRate_Hz)
|
||||
, _timeout_ms(2 * _updateInterval_ms)
|
||||
, _grabber(new X11Grabber(useXGetImage, cropLeft, cropRight, cropTop, cropBottom, horizontalPixelDecimation, verticalPixelDecimation))
|
||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
||||
: GrabberWrapper("X11", &_grabber, 0, 0, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||
, _grabber(useXGetImage, cropLeft, cropRight, cropTop, cropBottom, horizontalPixelDecimation, verticalPixelDecimation)
|
||||
, _init(false)
|
||||
, _x11SetupSuccess(false)
|
||||
{
|
||||
// Configure the timer to generate events every n milliseconds
|
||||
_timer.setInterval(_updateInterval_ms);
|
||||
}
|
||||
{}
|
||||
|
||||
X11Wrapper::~X11Wrapper()
|
||||
{
|
||||
delete _grabber;
|
||||
}
|
||||
|
||||
bool X11Wrapper::start()
|
||||
void X11Wrapper::action()
|
||||
{
|
||||
if (! _init )
|
||||
{
|
||||
_init = true;
|
||||
_x11SetupSuccess = _grabber->Setup();
|
||||
if ( _x11SetupSuccess )
|
||||
if ( ! _grabber.Setup() )
|
||||
{
|
||||
_x11SetupSuccess = (_grabber->updateScreenDimensions() >= 0);
|
||||
_processor->setSize(_grabber->getImageWidth(), _grabber->getImageHeight());
|
||||
_image.resize(_grabber->getImageWidth(), _grabber->getImageHeight());
|
||||
stop();
|
||||
}
|
||||
}
|
||||
// Start the timer with the pre configured interval
|
||||
if ( _x11SetupSuccess )
|
||||
{
|
||||
GrabberWrapper::start();
|
||||
}
|
||||
|
||||
ErrorIf( ! _x11SetupSuccess, _log, "X11 Grabber start failed");
|
||||
return _x11SetupSuccess;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
|
||||
void X11Wrapper::setVideoMode(const VideoMode mode)
|
||||
{
|
||||
_grabber->setVideoMode(mode);
|
||||
if (_grabber.updateScreenDimensions() >= 0 )
|
||||
{
|
||||
transferFrame(_grabber);
|
||||
}
|
||||
}
|
||||
|
@ -3,16 +3,19 @@
|
||||
|
||||
Grabber::Grabber(QString grabberName, int width, int height, int cropLeft, int cropRight, int cropTop, int cropBottom)
|
||||
: _imageResampler()
|
||||
, _useImageResampler(true)
|
||||
, _videoMode(VIDEO_2D)
|
||||
, _width(width)
|
||||
, _height(height)
|
||||
, _cropLeft(cropLeft)
|
||||
, _cropRight(cropRight)
|
||||
, _cropTop(cropTop)
|
||||
, _cropBottom(cropBottom)
|
||||
, _cropLeft(0)
|
||||
, _cropRight(0)
|
||||
, _cropTop(0)
|
||||
, _cropBottom(0)
|
||||
, _log(Logger::getInstance(grabberName))
|
||||
|
||||
{
|
||||
setVideoMode(VIDEO_2D);
|
||||
setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||
}
|
||||
|
||||
Grabber::~Grabber()
|
||||
@ -22,6 +25,41 @@ Grabber::~Grabber()
|
||||
|
||||
void Grabber::setVideoMode(VideoMode mode)
|
||||
{
|
||||
Debug(_log,"setvideomode %d", mode);
|
||||
_videoMode = mode;
|
||||
_imageResampler.set3D(_videoMode);
|
||||
if ( _useImageResampler )
|
||||
{
|
||||
_imageResampler.setVideoMode(_videoMode);
|
||||
}
|
||||
}
|
||||
|
||||
void Grabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
|
||||
{
|
||||
if (_width>0 && _height>0)
|
||||
{
|
||||
if (cropLeft + cropRight >= (unsigned)_width || cropTop + cropBottom >= (unsigned)_height)
|
||||
{
|
||||
Error(_log, "Rejecting invalid crop values: left: %d, right: %d, top: %d, bottom: %d", cropLeft, cropRight, cropTop, cropBottom);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_cropLeft = cropLeft;
|
||||
_cropRight = cropRight;
|
||||
_cropTop = cropTop;
|
||||
_cropBottom = cropBottom;
|
||||
|
||||
if ( _useImageResampler )
|
||||
{
|
||||
_imageResampler.setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
_imageResampler.setCropping(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (cropLeft > 0 || cropRight > 0 || cropTop > 0 || cropBottom > 0)
|
||||
{
|
||||
Info(_log, "Cropping image: width=%d height=%d; crop: left=%d right=%d top=%d bottom=%d ", _width, _height, cropLeft, cropRight, cropTop, cropBottom);
|
||||
}
|
||||
}
|
||||
|
@ -2,19 +2,31 @@
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
#include <hyperion/Grabber.h>
|
||||
#include <HyperionConfig.h>
|
||||
|
||||
GrabberWrapper::GrabberWrapper(QString grabberName, const int priority, hyperion::Components grabberComponentId)
|
||||
GrabberWrapper::GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned width, unsigned height, const unsigned updateRate_Hz, const int priority, hyperion::Components grabberComponentId)
|
||||
: _grabberName(grabberName)
|
||||
, _hyperion(Hyperion::getInstance())
|
||||
, _priority(priority)
|
||||
, _timer()
|
||||
, _updateInterval_ms(1000/updateRate_Hz)
|
||||
, _timeout_ms(2 * _updateInterval_ms)
|
||||
, _log(Logger::getInstance(grabberName))
|
||||
, _forward(true)
|
||||
, _processor(ImageProcessorFactory::getInstance().newImageProcessor())
|
||||
, _grabberComponentId(grabberComponentId)
|
||||
, _ggrabber(ggrabber)
|
||||
, _image(0,0)
|
||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
||||
, _imageProcessorEnabled(true)
|
||||
{
|
||||
_timer.setSingleShot(false);
|
||||
// Configure the timer to generate events every n milliseconds
|
||||
_timer.setInterval(_updateInterval_ms);
|
||||
|
||||
_image.resize(width, height);
|
||||
_processor->setSize(width, height);
|
||||
|
||||
_forward = _hyperion->getForwarder()->protoForwardingEnabled();
|
||||
_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_BLACKBORDER, _processor->blackBorderDetectorEnabled());
|
||||
@ -26,6 +38,7 @@ GrabberWrapper::GrabberWrapper(QString grabberName, const int priority, hyperion
|
||||
connect(_hyperion, SIGNAL(videoMode(VideoMode)), this, SLOT(setVideoMode(VideoMode)));
|
||||
connect(this, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _hyperion, SLOT(setImage(int, const Image<ColorRgb>&, const int)) );
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(action()));
|
||||
|
||||
}
|
||||
|
||||
GrabberWrapper::~GrabberWrapper()
|
||||
@ -139,3 +152,24 @@ QStringList GrabberWrapper::availableGrabbers()
|
||||
|
||||
return grabbers;
|
||||
}
|
||||
|
||||
|
||||
void GrabberWrapper::setVideoMode(const VideoMode mode)
|
||||
{
|
||||
if (_ggrabber != nullptr)
|
||||
{
|
||||
Info(_log,"setvideomode");
|
||||
_ggrabber->setVideoMode(mode);
|
||||
}
|
||||
}
|
||||
|
||||
void GrabberWrapper::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
|
||||
{
|
||||
_ggrabber->setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||
}
|
||||
|
||||
void GrabberWrapper::setImageProcessorEnabled(bool enable)
|
||||
{
|
||||
_imageProcessorEnabled = enable;
|
||||
}
|
||||
|
||||
|
@ -487,14 +487,15 @@ unsigned Hyperion::addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequ
|
||||
|
||||
void Hyperion::freeObjects(bool emitCloseSignal)
|
||||
{
|
||||
// switch off all leds
|
||||
clearall(true);
|
||||
_device->switchOff();
|
||||
|
||||
if (emitCloseSignal)
|
||||
{
|
||||
emit closing();
|
||||
}
|
||||
|
||||
// switch off all leds
|
||||
clearall();
|
||||
_device->switchOff();
|
||||
|
||||
// delete components on exit of hyperion core
|
||||
delete _effectEngine;
|
||||
@ -740,9 +741,9 @@ void Hyperion::clear(int priority)
|
||||
_effectEngine->channelCleared(priority);
|
||||
}
|
||||
|
||||
void Hyperion::clearall()
|
||||
void Hyperion::clearall(bool forceClearAll)
|
||||
{
|
||||
_muxer.clearAll();
|
||||
_muxer.clearAll(forceClearAll);
|
||||
setSourceAutoSelectEnabled(true);
|
||||
|
||||
// update leds
|
||||
|
@ -44,7 +44,7 @@ void ImageProcessor::setSize(const unsigned width, const unsigned height)
|
||||
delete _imageToLeds;
|
||||
|
||||
// Construct a new buffer and mapping
|
||||
_imageToLeds = new ImageToLedsMap(width, height, 0, 0, _ledString.leds());
|
||||
_imageToLeds = (width>0 && height>0) ? (new ImageToLedsMap(width, height, 0, 0, _ledString.leds())) : nullptr;
|
||||
}
|
||||
|
||||
void ImageProcessor::enableBlackBorderDetector(bool enable)
|
||||
|
@ -17,6 +17,8 @@ ImageToLedsMap::ImageToLedsMap(
|
||||
// Sanity check of the size of the borders (and width and height)
|
||||
Q_ASSERT(_width > 2*_verticalBorder);
|
||||
Q_ASSERT(_height > 2*_horizontalBorder);
|
||||
Q_ASSERT(_width < 10000);
|
||||
Q_ASSERT(_height < 10000);
|
||||
|
||||
// Reserve enough space in the map for the leds
|
||||
_colorsMap.reserve(leds.size());
|
||||
|
@ -78,8 +78,16 @@ void PriorityMuxer::clearInput(const int priority)
|
||||
}
|
||||
}
|
||||
|
||||
void PriorityMuxer::clearAll()
|
||||
void PriorityMuxer::clearAll(bool forceClearAll)
|
||||
{
|
||||
if (forceClearAll)
|
||||
{
|
||||
_activeInputs.clear();
|
||||
_currentPriority = LOWEST_PRIORITY;
|
||||
_activeInputs[_currentPriority] = _lowestPriorityInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto key : _activeInputs.keys())
|
||||
{
|
||||
if (key < LOWEST_PRIORITY-1)
|
||||
@ -87,6 +95,7 @@ void PriorityMuxer::clearAll()
|
||||
_activeInputs.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PriorityMuxer::setCurrentTime(const int64_t& now)
|
||||
|
@ -46,8 +46,8 @@
|
||||
{
|
||||
"type" : "integer",
|
||||
"title" : "edt_conf_v4l2_width_title",
|
||||
"minimum" : -1,
|
||||
"default" : -1,
|
||||
"minimum" : 0,
|
||||
"default" : 0,
|
||||
"append" : "edt_append_pixel",
|
||||
"propertyOrder" : 5
|
||||
},
|
||||
@ -55,8 +55,8 @@
|
||||
{
|
||||
"type" : "integer",
|
||||
"title" : "edt_conf_v4l2_height_title",
|
||||
"minimum" : -1,
|
||||
"default" : -1,
|
||||
"minimum" : 0,
|
||||
"default" : 0,
|
||||
"append" : "edt_append_pixel",
|
||||
"propertyOrder" : 6
|
||||
},
|
||||
|
@ -19,6 +19,8 @@ add_library(protoserver
|
||||
${ProtoServer_PROTO_SRCS}
|
||||
${ProtoServer_PROTO_HDRS}
|
||||
)
|
||||
# disable warnings for auto generatet proto files, we can't change the files ....
|
||||
SET_SOURCE_FILES_PROPERTIES ( ${ProtoServer_PROTO_SRCS} ${ProtoServer_PROTO_HDRS} ${ProtoServer_PROTOS} PROPERTIES COMPILE_FLAGS -w )
|
||||
|
||||
target_link_libraries(protoserver
|
||||
hyperion
|
||||
|
@ -36,7 +36,7 @@ void ImageResampler::setCropping(int cropLeft, int cropRight, int cropTop, int c
|
||||
_cropBottom = cropBottom;
|
||||
}
|
||||
|
||||
void ImageResampler::set3D(VideoMode mode)
|
||||
void ImageResampler::setVideoMode(VideoMode mode)
|
||||
{
|
||||
_videoMode = mode;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
"tan" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"mappingType": {
|
||||
"videoMode": {
|
||||
"type" : "string",
|
||||
"enum" : ["2D", "3DSBS", "3DTAB"]
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeig
|
||||
const Image<ColorRgb> & AmlogicWrapper::getScreenshot()
|
||||
{
|
||||
capture();
|
||||
return _screenshot_rgb;
|
||||
return _screenshot;
|
||||
}
|
||||
|
||||
void AmlogicWrapper::start()
|
||||
@ -32,7 +32,5 @@ void AmlogicWrapper::stop()
|
||||
void AmlogicWrapper::capture()
|
||||
{
|
||||
_grabber.grabFrame(_screenshot);
|
||||
_screenshot.toRgb(_screenshot_rgb);
|
||||
|
||||
emit sig_screenshot(_screenshot_rgb);
|
||||
emit sig_screenshot(_screenshot);
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ private:
|
||||
AmlogicGrabber _grabber;
|
||||
|
||||
// image buffers
|
||||
Image<ColorRgb> _screenshot_rgb;
|
||||
Image<ColorBgr> _screenshot;
|
||||
Image<ColorRgb> _screenshot;
|
||||
|
||||
};
|
||||
|
@ -2,7 +2,12 @@ cmake_minimum_required(VERSION 2.8.12)
|
||||
project(hyperion-dispmanx)
|
||||
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(BCM REQUIRED)
|
||||
IF ( "${PLATFORM}" MATCHES rpi)
|
||||
find_package(BCM REQUIRED)
|
||||
ELSE()
|
||||
SET(BCM_INCLUDE_DIRS "")
|
||||
SET(BCM_LIBRARIES "")
|
||||
ENDIF()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/protoserver
|
||||
|
@ -22,7 +22,7 @@ DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHe
|
||||
const Image<ColorRgb> & DispmanxWrapper::getScreenshot()
|
||||
{
|
||||
capture();
|
||||
return _screenshot_rgb;
|
||||
return _screenshot;
|
||||
}
|
||||
|
||||
void DispmanxWrapper::start()
|
||||
@ -38,7 +38,5 @@ void DispmanxWrapper::stop()
|
||||
void DispmanxWrapper::capture()
|
||||
{
|
||||
_grabber.grabFrame(_screenshot);
|
||||
_screenshot.toRgb(_screenshot_rgb);
|
||||
|
||||
emit sig_screenshot(_screenshot_rgb);
|
||||
emit sig_screenshot(_screenshot);
|
||||
}
|
||||
|
@ -40,7 +40,5 @@ private:
|
||||
|
||||
/// The grabber for creating screenshots
|
||||
DispmanxFrameGrabber _grabber;
|
||||
Image<ColorRgb> _screenshot_rgb;
|
||||
Image<ColorRgba> _screenshot;
|
||||
|
||||
Image<ColorRgb> _screenshot;
|
||||
};
|
||||
|
@ -15,8 +15,8 @@ X11Wrapper::X11Wrapper(int grabInterval, bool useXGetImage, int cropLeft, int cr
|
||||
|
||||
const Image<ColorRgb> & X11Wrapper::getScreenshot()
|
||||
{
|
||||
const Image<ColorRgb> & screenshot = _grabber.grab();
|
||||
return screenshot;
|
||||
_grabber.grabFrame(_screenshot, true);
|
||||
return _screenshot;
|
||||
}
|
||||
|
||||
void X11Wrapper::start()
|
||||
@ -36,8 +36,8 @@ bool X11Wrapper::displayInit()
|
||||
|
||||
void X11Wrapper::capture()
|
||||
{
|
||||
const Image<ColorRgb> & screenshot = _grabber.grab();
|
||||
emit sig_screenshot(screenshot);
|
||||
_grabber.grabFrame(_screenshot, true);
|
||||
emit sig_screenshot(_screenshot);
|
||||
}
|
||||
|
||||
void X11Wrapper::setGrabbingMode(const GrabbingMode mode)
|
||||
|
@ -55,4 +55,6 @@ private:
|
||||
|
||||
/// The grabber for creating screenshots
|
||||
X11Grabber _grabber;
|
||||
|
||||
Image<ColorRgb> _screenshot;
|
||||
};
|
||||
|
@ -86,6 +86,7 @@ HyperionDaemon::~HyperionDaemon()
|
||||
|
||||
void HyperionDaemon::freeObjects()
|
||||
{
|
||||
_hyperion->clearall(true);
|
||||
Debug(_log, "destroy grabbers and network stuff");
|
||||
delete _amlGrabber;
|
||||
delete _dispmanx;
|
||||
@ -117,7 +118,6 @@ void HyperionDaemon::freeObjects()
|
||||
|
||||
void HyperionDaemon::run()
|
||||
{
|
||||
startInitialEffect();
|
||||
createKODIVideoChecker();
|
||||
|
||||
// ---- network services -----
|
||||
@ -133,6 +133,8 @@ void HyperionDaemon::run()
|
||||
Info(_log, "Hyperion started");
|
||||
|
||||
connect(_hyperion,SIGNAL(closing()),this,SLOT(freeObjects()));
|
||||
|
||||
startInitialEffect();
|
||||
}
|
||||
|
||||
void HyperionDaemon::loadConfig(const QString & configFile)
|
||||
@ -499,6 +501,7 @@ void HyperionDaemon::createGrabberX11(const QJsonObject & grabberConfig)
|
||||
grabberConfig["horizontalPixelDecimation"].toInt(8),
|
||||
grabberConfig["verticalPixelDecimation"].toInt(8),
|
||||
_grabber_frequency, _grabber_priority );
|
||||
_x11Grabber->setCropping(_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom);
|
||||
|
||||
QObject::connect(_x11Grabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
||||
|
||||
@ -517,7 +520,7 @@ void HyperionDaemon::createGrabberFramebuffer(const QJsonObject & grabberConfig)
|
||||
_fbGrabber = new FramebufferWrapper(
|
||||
grabberConfig["device"].toString("/dev/fb0"),
|
||||
_grabber_width, _grabber_height, _grabber_frequency, _grabber_priority);
|
||||
|
||||
_fbGrabber->setCropping(_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom);
|
||||
QObject::connect(_fbGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
||||
|
||||
_fbGrabber->start();
|
||||
@ -570,8 +573,8 @@ void HyperionDaemon::createGrabberV4L2()
|
||||
grabberConfig["input"].toInt(0),
|
||||
parseVideoStandard(grabberConfig["standard"].toString("no-change")),
|
||||
parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")),
|
||||
grabberConfig["width"].toInt(-1),
|
||||
grabberConfig["height"].toInt(-1),
|
||||
grabberConfig["width"].toInt(0),
|
||||
grabberConfig["height"].toInt(0),
|
||||
grabberConfig["frameDecimation"].toInt(2),
|
||||
grabberConfig["sizeDecimation"].toInt(8),
|
||||
grabberConfig["redSignalThreshold"].toDouble(0.0)/100.0,
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QJsonObject>
|
||||
|
||||
#ifdef ENABLE_DISPMANX
|
||||
#include <grabber/DispmanxWrapper.h>
|
||||
@ -46,7 +47,7 @@
|
||||
#include <boblightserver/BoblightServer.h>
|
||||
#include <udplistener/UDPListener.h>
|
||||
#include <utils/Stats.h>
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
class SysTray;
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
# this is only available on real pi
|
||||
IF ( "${PLATFORM}" MATCHES rpi)
|
||||
# Find the BCM-package (VC control)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
|
||||
# Find the BCM-package (VC control)
|
||||
find_package(BCM REQUIRED)
|
||||
include_directories(${BCM_INCLUDE_DIRS})
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
|
||||
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
|
||||
|
||||
|
||||
add_executable(dispmanx2png
|
||||
add_executable(dispmanx2png
|
||||
dispmanx2png.cpp)
|
||||
|
||||
target_link_libraries(dispmanx2png
|
||||
target_link_libraries(dispmanx2png
|
||||
dispmanx-grabber
|
||||
Qt5::Gui)
|
||||
ENDIF()
|
||||
|
Loading…
Reference in New Issue
Block a user