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
|
[ "${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
|
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}"
|
echo "compile jobs: ${JOBS:=4}"
|
||||||
make -j ${JOBS} || exit 3
|
make -j ${JOBS} || exit 3
|
||||||
|
@ -95,6 +95,9 @@ if ( "${PLATFORM}" MATCHES "-dev" )
|
|||||||
SET ( DEFAULT_TESTS ON )
|
SET ( DEFAULT_TESTS ON )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
STRING( TOUPPER "-DPLATFORM_${PLATFORM}" PLATFORM_DEFINE)
|
||||||
|
STRING( REPLACE "-DEV" "" PLATFORM_DEFINE "${PLATFORM_DEFINE}" )
|
||||||
|
ADD_DEFINITIONS( ${PLATFORM_DEFINE} )
|
||||||
|
|
||||||
# set the build options
|
# set the build options
|
||||||
option(ENABLE_AMLOGIC "Enable the AMLOGIC video grabber" ${DEFAULT_AMLOGIC} )
|
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)
|
# link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
|
||||||
#endif()
|
#endif()
|
||||||
|
|
||||||
if(ENABLE_OSX)
|
if(APPLE)
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "-framework CoreGraphics")
|
set(CMAKE_EXE_LINKER_FLAGS "-framework CoreGraphics")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -133,8 +133,8 @@
|
|||||||
"device" : "auto",
|
"device" : "auto",
|
||||||
"input" : 0,
|
"input" : 0,
|
||||||
"standard" : "PAL",
|
"standard" : "PAL",
|
||||||
"width" : -1,
|
"width" : 0,
|
||||||
"height" : -1,
|
"height" : 0,
|
||||||
"frameDecimation" : 2,
|
"frameDecimation" : 2,
|
||||||
"sizeDecimation" : 8,
|
"sizeDecimation" : 8,
|
||||||
"priority" : 240,
|
"priority" : 240,
|
||||||
|
@ -64,8 +64,8 @@
|
|||||||
"device" : "auto",
|
"device" : "auto",
|
||||||
"input" : 0,
|
"input" : 0,
|
||||||
"standard" : "PAL",
|
"standard" : "PAL",
|
||||||
"width" : -1,
|
"width" : 0,
|
||||||
"height" : -1,
|
"height" : 0,
|
||||||
"frameDecimation" : 2,
|
"frameDecimation" : 2,
|
||||||
"sizeDecimation" : 8,
|
"sizeDecimation" : 8,
|
||||||
"priority" : 240,
|
"priority" : 240,
|
||||||
|
@ -11,33 +11,37 @@ class SwitchOption: public Option
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SwitchOption(const QString &name,
|
SwitchOption(const QString &name,
|
||||||
const QString &description = QString(),
|
const QString &description = QString(),
|
||||||
const QString &valueName = QString(),
|
const QString &valueName = QString(),
|
||||||
const QString &defaultValue = QString(),
|
const QString &defaultValue = QString(),
|
||||||
const QMap<QString, T> &switches=QMap<QString, T>())
|
const QMap<QString, T> &switches=QMap<QString, T>())
|
||||||
: Option(name, description, valueName, defaultValue), _switches(switches)
|
: Option(name, description, valueName, defaultValue), _switches(switches)
|
||||||
{}
|
{}
|
||||||
SwitchOption(const QStringList &names,
|
|
||||||
const QString &description = QString(),
|
|
||||||
const QString &valueName = QString(),
|
|
||||||
const QString &defaultValue = QString(),
|
|
||||||
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;};
|
SwitchOption(const QStringList &names,
|
||||||
virtual bool validate(Parser &parser, QString &switch_) override{return hasSwitch(switch_);}
|
const QString &description = QString(),
|
||||||
bool hasSwitch(const QString &switch_){return _switches.contains(switch_.toLower());}
|
const QString &valueName = QString(),
|
||||||
void setSwitches(const QMap<QString, T> &_switches){this->_switches = _switches;}
|
const QString &defaultValue = QString(),
|
||||||
void addSwitch(const QString &switch_, T value=T()){_switches[switch_.toLower()] = value;}
|
const QMap<QString, T> &switches=QMap<QString, T>())
|
||||||
void removeSwitch(const QString &switch_){_switches.remove(switch_.toLower());}
|
: Option(names, description, valueName, defaultValue), _switches(switches)
|
||||||
T & switchValue(Parser & parser){return _switches[value(parser).toLower()];}
|
{}
|
||||||
|
|
||||||
|
SwitchOption(const QCommandLineOption &other, const QMap<QString, T> &switches)
|
||||||
|
: Option(other), _switches(switches)
|
||||||
|
{}
|
||||||
|
|
||||||
|
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:
|
protected:
|
||||||
QMap<QString, T> _switches;
|
QMap<QString, T> _switches;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,14 +29,17 @@ public:
|
|||||||
/// height)
|
/// height)
|
||||||
/// @return Zero on success else negative
|
/// @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
|
* Returns true if video is playing over the amlogic chip
|
||||||
* @return True if video is playing else false
|
* @return True if video is playing else false
|
||||||
*/
|
*/
|
||||||
bool isVideoPlaying();
|
bool isVideoPlaying();
|
||||||
private:
|
|
||||||
/** The snapshot/capture device of the amlogic video chip */
|
/** The snapshot/capture device of the amlogic video chip */
|
||||||
int _amlogicCaptureDev;
|
int _amlogicCaptureDev;
|
||||||
|
|
||||||
|
Image<ColorBgr> _image;
|
||||||
};
|
};
|
||||||
|
@ -1,16 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Utils includes
|
|
||||||
#include <utils/Image.h>
|
|
||||||
#include <utils/ColorBgr.h>
|
|
||||||
#include <utils/ColorRgb.h>
|
|
||||||
#include <utils/VideoMode.h>
|
|
||||||
#include <hyperion/GrabberWrapper.h>
|
#include <hyperion/GrabberWrapper.h>
|
||||||
|
#include <grabber/AmlogicGrabber.h>
|
||||||
// Forward class declaration
|
|
||||||
class AmlogicGrabber;
|
|
||||||
class Hyperion;
|
|
||||||
class ImageProcessor;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The DispmanxWrapper uses an instance of the DispmanxFrameGrabber to obtain ImageRgb's from the
|
/// 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.
|
/// Destructor of this dispmanx frame grabber. Releases any claimed resources.
|
||||||
///
|
///
|
||||||
virtual ~AmlogicWrapper();
|
virtual ~AmlogicWrapper() {};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
///
|
///
|
||||||
@ -42,19 +33,7 @@ public slots:
|
|||||||
///
|
///
|
||||||
virtual void action();
|
virtual void action();
|
||||||
|
|
||||||
virtual void setVideoMode(const VideoMode mode);
|
|
||||||
|
|
||||||
private:
|
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
|
/// The actual grabber
|
||||||
AmlogicGrabber * _grabber;
|
AmlogicGrabber _grabber;
|
||||||
|
|
||||||
/// The list with computed led colors
|
|
||||||
std::vector<ColorRgb> _ledColors;
|
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// BCM includes
|
// BCM includes
|
||||||
#pragma GCC system_header
|
#ifdef PLATFORM_RPI
|
||||||
#include <bcm_host.h>
|
#pragma GCC system_header
|
||||||
|
#include <bcm_host.h>
|
||||||
|
#else
|
||||||
|
#include <grabber/DispmanxFrameGrabberMock.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Utils includes
|
// Utils includes
|
||||||
|
#include <utils/Image.h>
|
||||||
#include <utils/ColorRgba.h>
|
#include <utils/ColorRgba.h>
|
||||||
#include <hyperion/Grabber.h>
|
#include <hyperion/Grabber.h>
|
||||||
|
|
||||||
@ -24,15 +29,6 @@ public:
|
|||||||
DispmanxFrameGrabber(const unsigned width, const unsigned height);
|
DispmanxFrameGrabber(const unsigned width, const unsigned height);
|
||||||
~DispmanxFrameGrabber();
|
~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
|
/// 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
|
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
||||||
/// height)
|
/// height)
|
||||||
///
|
///
|
||||||
void grabFrame(Image<ColorRgba> & image);
|
int grabFrame(Image<ColorRgb> & image);
|
||||||
|
|
||||||
private:
|
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
|
/// Handle to the display that is being captured
|
||||||
DISPMANX_DISPLAY_HANDLE_T _vc_display;
|
DISPMANX_DISPLAY_HANDLE_T _vc_display;
|
||||||
|
|
||||||
@ -63,4 +66,8 @@ private:
|
|||||||
|
|
||||||
// size of the capture buffer in Pixels
|
// size of the capture buffer in Pixels
|
||||||
unsigned _captureBufferSize;
|
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
|
#pragma once
|
||||||
|
|
||||||
// Utils includes
|
// Utils includes
|
||||||
#include <utils/Image.h>
|
|
||||||
#include <utils/ColorRgb.h>
|
|
||||||
#include <utils/ColorRgba.h>
|
#include <utils/ColorRgba.h>
|
||||||
#include <utils/GrabbingMode.h>
|
|
||||||
#include <utils/VideoMode.h>
|
|
||||||
#include <hyperion/GrabberWrapper.h>
|
#include <hyperion/GrabberWrapper.h>
|
||||||
|
#include <grabber/DispmanxFrameGrabber.h>
|
||||||
// Forward class declaration
|
|
||||||
class DispmanxFrameGrabber;
|
|
||||||
class ImageProcessor;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The DispmanxWrapper uses an instance of the DispmanxFrameGrabber to obtain ImageRgb's from the
|
/// 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.
|
/// Destructor of this dispmanx frame grabber. Releases any claimed resources.
|
||||||
///
|
///
|
||||||
virtual ~DispmanxWrapper();
|
virtual ~DispmanxWrapper() {};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
///
|
///
|
||||||
@ -42,25 +35,7 @@ public slots:
|
|||||||
///
|
///
|
||||||
virtual void action();
|
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:
|
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
|
/// The actual grabber
|
||||||
DispmanxFrameGrabber * _grabber;
|
DispmanxFrameGrabber _grabber;
|
||||||
|
|
||||||
/// The list with computed led colors
|
|
||||||
std::vector<ColorRgb> _ledColors;
|
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
||||||
/// height)
|
/// height)
|
||||||
///
|
///
|
||||||
void grabFrame(Image<ColorRgb> & image);
|
int grabFrame(Image<ColorRgb> & image);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Framebuffer file descriptor
|
/// Framebuffer file descriptor
|
||||||
|
@ -1,15 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Utils includes
|
|
||||||
#include <utils/Image.h>
|
|
||||||
#include <utils/ColorRgb.h>
|
|
||||||
#include <utils/GrabbingMode.h>
|
|
||||||
#include <utils/VideoMode.h>
|
|
||||||
#include <hyperion/GrabberWrapper.h>
|
#include <hyperion/GrabberWrapper.h>
|
||||||
|
#include <grabber/FramebufferFrameGrabber.h>
|
||||||
// Forward class declaration
|
|
||||||
class FramebufferFrameGrabber;
|
|
||||||
class ImageProcessor;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The FramebufferWrapper uses an instance of the FramebufferFrameGrabber to obtain ImageRgb's from the
|
/// 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.
|
/// Destructor of this framebuffer frame grabber. Releases any claimed resources.
|
||||||
///
|
///
|
||||||
virtual ~FramebufferWrapper();
|
virtual ~FramebufferWrapper() {};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
///
|
///
|
||||||
@ -41,23 +33,7 @@ public slots:
|
|||||||
///
|
///
|
||||||
virtual void action();
|
virtual void action();
|
||||||
|
|
||||||
///
|
|
||||||
/// Set the video mode (2D/3D)
|
|
||||||
/// @param[in] mode The new video mode
|
|
||||||
///
|
|
||||||
void setVideoMode(const VideoMode videoMode);
|
|
||||||
|
|
||||||
private:
|
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
|
/// The actual grabber
|
||||||
FramebufferFrameGrabber * _grabber;
|
FramebufferFrameGrabber _grabber;
|
||||||
|
|
||||||
/// The list with computed led colors
|
|
||||||
std::vector<ColorRgb> _ledColors;
|
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// OSX includes
|
// OSX includes
|
||||||
|
#ifdef __APPLE__
|
||||||
#include <CoreGraphics/CoreGraphics.h>
|
#include <CoreGraphics/CoreGraphics.h>
|
||||||
|
#else
|
||||||
|
#include <grabber/OsxFrameGrabberMock.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Utils includes
|
// Utils includes
|
||||||
#include <utils/ColorRgb.h>
|
#include <utils/ColorRgb.h>
|
||||||
@ -31,7 +35,7 @@ public:
|
|||||||
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
||||||
/// height)
|
/// height)
|
||||||
///
|
///
|
||||||
void grabFrame(Image<ColorRgb> & image);
|
int grabFrame(Image<ColorRgb> & image);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// display
|
/// 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
|
#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>
|
#include <hyperion/GrabberWrapper.h>
|
||||||
|
#include <grabber/OsxFrameGrabber.h>
|
||||||
// Forward class declaration
|
|
||||||
class OsxFrameGrabber;
|
|
||||||
class ImageProcessor;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The OsxWrapper uses an instance of the OsxFrameGrabber to obtain ImageRgb's from the
|
/// 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.
|
/// Destructor of this osx frame grabber. Releases any claimed resources.
|
||||||
///
|
///
|
||||||
virtual ~OsxWrapper();
|
virtual ~OsxWrapper() {};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
///
|
///
|
||||||
@ -43,23 +34,7 @@ public slots:
|
|||||||
///
|
///
|
||||||
virtual void action();
|
virtual void action();
|
||||||
|
|
||||||
///
|
|
||||||
/// Set the video mode (2D/3D)
|
|
||||||
/// @param[in] mode The new video mode
|
|
||||||
///
|
|
||||||
void setVideoMode(const VideoMode videoMode);
|
|
||||||
|
|
||||||
private:
|
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
|
/// The actual grabber
|
||||||
OsxFrameGrabber * _grabber;
|
OsxFrameGrabber _grabber;
|
||||||
|
|
||||||
/// The list with computed led colors
|
|
||||||
std::vector<ColorRgb> _ledColors;
|
|
||||||
};
|
};
|
||||||
|
@ -10,11 +10,8 @@
|
|||||||
#include <QRectF>
|
#include <QRectF>
|
||||||
|
|
||||||
// util includes
|
// util includes
|
||||||
#include <utils/ColorRgb.h>
|
|
||||||
#include <utils/PixelFormat.h>
|
#include <utils/PixelFormat.h>
|
||||||
#include <hyperion/Grabber.h>
|
#include <hyperion/Grabber.h>
|
||||||
|
|
||||||
// grabber includes
|
|
||||||
#include <grabber/VideoStandard.h>
|
#include <grabber/VideoStandard.h>
|
||||||
|
|
||||||
/// Capture class for V4L2 devices
|
/// Capture class for V4L2 devices
|
||||||
@ -28,8 +25,8 @@ public:
|
|||||||
V4L2Grabber(const QString & device,
|
V4L2Grabber(const QString & device,
|
||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard, PixelFormat pixelFormat,
|
VideoStandard videoStandard, PixelFormat pixelFormat,
|
||||||
int width,
|
unsigned width,
|
||||||
int height,
|
unsigned height,
|
||||||
int frameDecimation,
|
int frameDecimation,
|
||||||
int horizontalPixelDecimation,
|
int horizontalPixelDecimation,
|
||||||
int verticalPixelDecimation
|
int verticalPixelDecimation
|
||||||
@ -39,12 +36,9 @@ public:
|
|||||||
QRectF getSignalDetectionOffset();
|
QRectF getSignalDetectionOffset();
|
||||||
bool getSignalDetectionEnabled();
|
bool getSignalDetectionEnabled();
|
||||||
|
|
||||||
public slots:
|
int grabFrame(Image<ColorRgb> &);
|
||||||
void setCropping(int cropLeft,
|
|
||||||
int cropRight,
|
|
||||||
int cropTop,
|
|
||||||
int cropBottom);
|
|
||||||
|
|
||||||
|
public slots:
|
||||||
void setSignalThreshold(
|
void setSignalThreshold(
|
||||||
double redSignalThreshold,
|
double redSignalThreshold,
|
||||||
double greenSignalThreshold,
|
double greenSignalThreshold,
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Hyperion includes
|
|
||||||
#include <hyperion/Hyperion.h>
|
|
||||||
#include <hyperion/ImageProcessor.h>
|
|
||||||
#include <hyperion/GrabberWrapper.h>
|
#include <hyperion/GrabberWrapper.h>
|
||||||
|
|
||||||
// Grabber includes
|
|
||||||
#include <grabber/V4L2Grabber.h>
|
#include <grabber/V4L2Grabber.h>
|
||||||
|
|
||||||
class V4L2Wrapper : public GrabberWrapper
|
class V4L2Wrapper : public GrabberWrapper
|
||||||
@ -17,8 +12,8 @@ public:
|
|||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard,
|
VideoStandard videoStandard,
|
||||||
PixelFormat pixelFormat,
|
PixelFormat pixelFormat,
|
||||||
int width,
|
unsigned width,
|
||||||
int height,
|
unsigned height,
|
||||||
int frameDecimation,
|
int frameDecimation,
|
||||||
int pixelDecimation,
|
int pixelDecimation,
|
||||||
double redSignalThreshold,
|
double redSignalThreshold,
|
||||||
@ -26,7 +21,7 @@ public:
|
|||||||
double blueSignalThreshold,
|
double blueSignalThreshold,
|
||||||
const int priority,
|
const int priority,
|
||||||
bool useGrabbingMode);
|
bool useGrabbingMode);
|
||||||
virtual ~V4L2Wrapper();
|
virtual ~V4L2Wrapper() {};
|
||||||
|
|
||||||
bool getSignalDetectionEnable();
|
bool getSignalDetectionEnable();
|
||||||
|
|
||||||
@ -36,7 +31,6 @@ public slots:
|
|||||||
|
|
||||||
void setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom);
|
void setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom);
|
||||||
void setSignalDetectionOffset(double verticalMin, double horizontalMin, double verticalMax, double horizontalMax);
|
void setSignalDetectionOffset(double verticalMin, double horizontalMin, double verticalMax, double horizontalMax);
|
||||||
void setVideoMode(VideoMode mode);
|
|
||||||
void setSignalDetectionEnable(bool enable);
|
void setSignalDetectionEnable(bool enable);
|
||||||
|
|
||||||
// signals:
|
// signals:
|
||||||
@ -50,12 +44,6 @@ private slots:
|
|||||||
void checkSources();
|
void checkSources();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The timeout of the led colors [ms]
|
|
||||||
const int _timeout_ms;
|
|
||||||
|
|
||||||
/// The V4L2 grabber
|
/// The V4L2 grabber
|
||||||
V4L2Grabber _grabber;
|
V4L2Grabber _grabber;
|
||||||
|
|
||||||
/// The list with computed led colors
|
|
||||||
std::vector<ColorRgb> _ledColors;
|
|
||||||
};
|
};
|
||||||
|
@ -23,8 +23,6 @@ public:
|
|||||||
|
|
||||||
bool Setup();
|
bool Setup();
|
||||||
|
|
||||||
Image<ColorRgb> & grab();
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Captures a single snapshot of the display and writes the data to the given image. The
|
/// 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
|
/// 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
|
/// @param[out] image The snapped screenshot (should be initialized with correct width and
|
||||||
/// height)
|
/// height)
|
||||||
///
|
///
|
||||||
int grabFrame(Image<ColorRgb> & image);
|
virtual int grabFrame(Image<ColorRgb> & image, bool forceUpdate=false);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// update dimension according current screen
|
/// update dimension according current screen
|
||||||
int updateScreenDimensions();
|
int updateScreenDimensions(bool force=false);
|
||||||
|
|
||||||
|
virtual void setVideoMode(VideoMode mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _useXGetImage, _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
|
bool _useXGetImage, _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
|
||||||
@ -63,6 +63,8 @@ private:
|
|||||||
|
|
||||||
unsigned _screenWidth;
|
unsigned _screenWidth;
|
||||||
unsigned _screenHeight;
|
unsigned _screenHeight;
|
||||||
|
unsigned _src_x;
|
||||||
|
unsigned _src_y;
|
||||||
|
|
||||||
Image<ColorRgb> _image;
|
Image<ColorRgb> _image;
|
||||||
|
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Utils includes
|
|
||||||
#include <utils/Image.h>
|
|
||||||
#include <utils/ColorRgb.h>
|
|
||||||
#include <utils/VideoMode.h>
|
|
||||||
#include <hyperion/GrabberWrapper.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
|
/// 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.
|
/// Destructor of this framebuffer frame grabber. Releases any claimed resources.
|
||||||
///
|
///
|
||||||
virtual ~X11Wrapper();
|
virtual ~X11Wrapper() {};
|
||||||
|
|
||||||
public slots:
|
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
|
/// Performs a single frame grab and computes the led-colors
|
||||||
///
|
///
|
||||||
virtual void action();
|
virtual void action();
|
||||||
|
|
||||||
///
|
|
||||||
/// Set the video mode (2D/3D)
|
|
||||||
/// @param[in] mode The new video mode
|
|
||||||
///
|
|
||||||
void setVideoMode(const VideoMode videoMode);
|
|
||||||
|
|
||||||
private:
|
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
|
/// The actual grabber
|
||||||
X11Grabber * _grabber;
|
X11Grabber _grabber;
|
||||||
|
|
||||||
/// The list with computed led colors
|
|
||||||
std::vector<ColorRgb> _ledColors;
|
|
||||||
|
|
||||||
|
|
||||||
bool _init;
|
bool _init;
|
||||||
bool _x11SetupSuccess;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include <utils/ColorRgb.h>
|
||||||
#include <utils/Image.h>
|
#include <utils/Image.h>
|
||||||
#include <utils/VideoMode.h>
|
#include <utils/VideoMode.h>
|
||||||
#include <utils/GrabbingMode.h>
|
#include <utils/GrabbingMode.h>
|
||||||
@ -16,24 +17,28 @@ class Grabber : public QObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Grabber(QString grabberName, int width=0, int height=0, int cropLeft=0, int cropRight=0, int cropTop=0, int cropBottom=0);
|
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)
|
/// Set the video mode (2D/3D)
|
||||||
/// @param[in] mode The new video mode
|
/// @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
|
/// gets resulting height of image
|
||||||
const int getImageWidth() { return _width; };
|
virtual const int getImageWidth() { return _width; };
|
||||||
|
|
||||||
/// gets resulting width of image
|
/// gets resulting width of image
|
||||||
const int getImageHeight() { return _height; };
|
virtual const int getImageHeight() { return _height; };
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ImageResampler _imageResampler;
|
ImageResampler _imageResampler;
|
||||||
|
|
||||||
|
bool _useImageResampler;
|
||||||
|
|
||||||
/// the selected VideoMode
|
/// the selected VideoMode
|
||||||
VideoMode _videoMode;
|
VideoMode _videoMode;
|
||||||
|
|
||||||
|
@ -9,14 +9,20 @@
|
|||||||
#include <utils/Components.h>
|
#include <utils/Components.h>
|
||||||
#include <utils/GrabbingMode.h>
|
#include <utils/GrabbingMode.h>
|
||||||
#include <hyperion/Hyperion.h>
|
#include <hyperion/Hyperion.h>
|
||||||
|
#include <hyperion/ImageProcessor.h>
|
||||||
|
#include <utils/Image.h>
|
||||||
|
#include <utils/ColorRgb.h>
|
||||||
|
#include <utils/VideoMode.h>
|
||||||
|
|
||||||
class ImageProcessor;
|
class ImageProcessor;
|
||||||
|
class Grabber;
|
||||||
|
class DispmanxFrameGrabber;
|
||||||
|
|
||||||
class GrabberWrapper : public QObject
|
class GrabberWrapper : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
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();
|
virtual ~GrabberWrapper();
|
||||||
|
|
||||||
@ -30,8 +36,32 @@ public:
|
|||||||
///
|
///
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
|
||||||
|
void setImageProcessorEnabled(bool enable);
|
||||||
|
|
||||||
static QStringList availableGrabbers();
|
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:
|
public slots:
|
||||||
void componentStateChanged(const hyperion::Components component, bool enable);
|
void componentStateChanged(const hyperion::Components component, bool enable);
|
||||||
|
|
||||||
@ -50,8 +80,9 @@ public slots:
|
|||||||
/// Set the video mode (2D/3D)
|
/// Set the video mode (2D/3D)
|
||||||
/// @param[in] mode The new video mode
|
/// @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:
|
signals:
|
||||||
void emitImage(int priority, const Image<ColorRgb> & image, const int timeout_ms);
|
void emitImage(int priority, const Image<ColorRgb> & image, const int timeout_ms);
|
||||||
@ -59,6 +90,7 @@ signals:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
void setColors(const std::vector<ColorRgb> &ledColors, const int timeout_ms);
|
void setColors(const std::vector<ColorRgb> &ledColors, const int timeout_ms);
|
||||||
|
|
||||||
QString _grabberName;
|
QString _grabberName;
|
||||||
|
|
||||||
/// Pointer to Hyperion for writing led values
|
/// Pointer to Hyperion for writing led values
|
||||||
@ -70,6 +102,12 @@ protected:
|
|||||||
/// The timer for generating events with the specified update rate
|
/// The timer for generating events with the specified update rate
|
||||||
QTimer _timer;
|
QTimer _timer;
|
||||||
|
|
||||||
|
/// The update rate [Hz]
|
||||||
|
const int _updateInterval_ms;
|
||||||
|
|
||||||
|
/// The timeout of the led colors [ms]
|
||||||
|
const int _timeout_ms;
|
||||||
|
|
||||||
/// The Logger instance
|
/// The Logger instance
|
||||||
Logger * _log;
|
Logger * _log;
|
||||||
|
|
||||||
@ -80,4 +118,15 @@ protected:
|
|||||||
ImageProcessor * _processor;
|
ImageProcessor * _processor;
|
||||||
|
|
||||||
hyperion::Components _grabberComponentId;
|
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.
|
/// 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
|
/// Run the specified effect on the given priority channel and optionally specify a timeout
|
||||||
/// @param effectName Name of the effec to run
|
/// @param effectName Name of the effec to run
|
||||||
|
@ -42,7 +42,6 @@ public:
|
|||||||
///
|
///
|
||||||
void setSize(const unsigned width, const unsigned height);
|
void setSize(const unsigned width, const unsigned height);
|
||||||
|
|
||||||
|
|
||||||
/// Returns starte of black border detector
|
/// Returns starte of black border detector
|
||||||
bool blackBorderDetectorEnabled();
|
bool blackBorderDetectorEnabled();
|
||||||
|
|
||||||
@ -60,6 +59,19 @@ public slots:
|
|||||||
void setLedMappingType(int mapType);
|
void setLedMappingType(int mapType);
|
||||||
|
|
||||||
public:
|
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
|
/// 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.
|
/// if required and call the image-to-leds mapping to determine the mean color per led.
|
||||||
@ -71,18 +83,25 @@ public:
|
|||||||
template <typename Pixel_T>
|
template <typename Pixel_T>
|
||||||
std::vector<ColorRgb> process(const Image<Pixel_T>& image)
|
std::vector<ColorRgb> process(const Image<Pixel_T>& image)
|
||||||
{
|
{
|
||||||
// Ensure that the buffer-image is the proper size
|
|
||||||
setSize(image.width(), image.height());
|
|
||||||
|
|
||||||
// Check black border detection
|
|
||||||
verifyBorder(image);
|
|
||||||
|
|
||||||
// Create a result vector and call the 'in place' functionl
|
|
||||||
std::vector<ColorRgb> colors;
|
std::vector<ColorRgb> colors;
|
||||||
switch (_mappingType)
|
if (image.width()>0 && image.height()>0)
|
||||||
{
|
{
|
||||||
case 1: colors = _imageToLeds->getUniLedColor(image); break;
|
// Ensure that the buffer-image is the proper size
|
||||||
default: colors = _imageToLeds->getMeanLedColor(image);
|
setSize(image);
|
||||||
|
|
||||||
|
// Check black border detection
|
||||||
|
verifyBorder(image);
|
||||||
|
|
||||||
|
// Create a result vector and call the 'in place' functionl
|
||||||
|
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 the computed colors
|
||||||
@ -98,19 +117,25 @@ public:
|
|||||||
template <typename Pixel_T>
|
template <typename Pixel_T>
|
||||||
void process(const Image<Pixel_T>& image, std::vector<ColorRgb>& ledColors)
|
void process(const Image<Pixel_T>& image, std::vector<ColorRgb>& ledColors)
|
||||||
{
|
{
|
||||||
// Ensure that the buffer-image is the proper size
|
if ( image.width()>0 && image.height()>0)
|
||||||
setSize(image.width(), image.height());
|
|
||||||
|
|
||||||
// Check black border detection
|
|
||||||
verifyBorder(image);
|
|
||||||
|
|
||||||
// Determine the mean-colors of each led (using the existing mapping)
|
|
||||||
switch (_mappingType)
|
|
||||||
{
|
{
|
||||||
case 1: _imageToLeds->getUniLedColor(image, ledColors); break;
|
// Ensure that the buffer-image is the proper size
|
||||||
default: _imageToLeds->getMeanLedColor(image, ledColors);
|
setSize(image);
|
||||||
}
|
|
||||||
|
|
||||||
|
// Check black border detection
|
||||||
|
verifyBorder(image);
|
||||||
|
|
||||||
|
// Determine the mean-colors of each led (using the existing mapping)
|
||||||
|
switch (_mappingType)
|
||||||
|
{
|
||||||
|
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
|
/// 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
|
/// Updates the current time. Channels with a configured time out will be checked and cleared if
|
||||||
@ -152,5 +152,4 @@ private:
|
|||||||
|
|
||||||
QTimer _timer;
|
QTimer _timer;
|
||||||
QTimer _blockTimer;
|
QTimer _blockTimer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,7 @@ public:
|
|||||||
int cropTop,
|
int cropTop,
|
||||||
int cropBottom);
|
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;
|
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()
|
bool AmlogicGrabber::isVideoPlaying()
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO crop resulting image accroding member _videoMode
|
|
||||||
// TODO add croping
|
|
||||||
|
|
||||||
const QString videoDevice = "/dev/amvideo";
|
const QString videoDevice = "/dev/amvideo";
|
||||||
|
|
||||||
// Open the video device
|
// Open the video device
|
||||||
@ -81,13 +77,10 @@ bool AmlogicGrabber::isVideoPlaying()
|
|||||||
return videoDisabled == 0;
|
return videoDisabled == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
|
int AmlogicGrabber::grabFrame(Image<ColorRgb> & image)
|
||||||
{
|
{
|
||||||
// resize the given image if needed
|
// TODO crop resulting image accroding member _videoMode
|
||||||
if (image.width() != (unsigned)_width || image.height() != (unsigned)_height)
|
// TODO add croping
|
||||||
{
|
|
||||||
image.resize(_width, _height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure video is playing, else there is nothing to grab
|
// Make sure video is playing, else there is nothing to grab
|
||||||
if (!isVideoPlaying())
|
if (!isVideoPlaying())
|
||||||
@ -95,7 +88,6 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// If the device is not open, attempt to open it
|
// If the device is not open, attempt to open it
|
||||||
if (_amlogicCaptureDev == -1)
|
if (_amlogicCaptureDev == -1)
|
||||||
{
|
{
|
||||||
@ -121,7 +113,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the snapshot into the memory
|
// 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 bytesToRead = _width * _height * sizeof(ColorBgr);
|
||||||
|
|
||||||
const ssize_t bytesRead = pread(_amlogicCaptureDev, image_ptr, bytesToRead, 0);
|
const ssize_t bytesRead = pread(_amlogicCaptureDev, image_ptr, bytesToRead, 0);
|
||||||
@ -150,5 +142,10 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
|
|||||||
_amlogicCaptureDev = -1;
|
_amlogicCaptureDev = -1;
|
||||||
readCnt = 0;
|
readCnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_imageResampler.setHorizontalPixelDecimation(_width);
|
||||||
|
_imageResampler.setVerticalPixelDecimation(_height);
|
||||||
|
_imageResampler.processImage((const uint8_t*)image_ptr, _width, _height, 3, PIXELFORMAT_BGR24, image);
|
||||||
|
|
||||||
return 0;
|
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/AmlogicWrapper.h>
|
||||||
#include <grabber/AmlogicGrabber.h>
|
|
||||||
|
|
||||||
|
|
||||||
AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
||||||
: GrabberWrapper("AmLogic", priority)
|
: GrabberWrapper("AmLogic", &_grabber, grabWidth, grabHeight, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||||
, _updateInterval_ms(1000/updateRate_Hz)
|
, _grabber(grabWidth, grabHeight)
|
||||||
, _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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AmlogicWrapper::action()
|
void AmlogicWrapper::action()
|
||||||
{
|
{
|
||||||
// Grab frame into the allocated image
|
transferFrame(_grabber);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
# Find the BCM-package (VC control)
|
# Find the BCM-package (VC control)
|
||||||
find_package(BCM REQUIRED)
|
IF ( "${PLATFORM}" MATCHES rpi)
|
||||||
include_directories(${BCM_INCLUDE_DIRS})
|
find_package(BCM REQUIRED)
|
||||||
|
include_directories(${BCM_INCLUDE_DIRS})
|
||||||
|
ELSE()
|
||||||
|
SET(BCM_INCLUDE_DIRS "")
|
||||||
|
SET(BCM_LIBRARIES "")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
||||||
|
@ -13,7 +13,10 @@ DispmanxFrameGrabber::DispmanxFrameGrabber(const unsigned width, const unsigned
|
|||||||
, _vc_flags(0)
|
, _vc_flags(0)
|
||||||
, _captureBuffer(new ColorRgba[0])
|
, _captureBuffer(new ColorRgba[0])
|
||||||
, _captureBufferSize(0)
|
, _captureBufferSize(0)
|
||||||
|
, _image_rgba(width, height)
|
||||||
{
|
{
|
||||||
|
_useImageResampler = false;
|
||||||
|
|
||||||
// Initiase BCM
|
// Initiase BCM
|
||||||
bcm_host_init();
|
bcm_host_init();
|
||||||
|
|
||||||
@ -64,33 +67,15 @@ void DispmanxFrameGrabber::setFlags(const int vc_flags)
|
|||||||
_vc_flags = vc_flags;
|
_vc_flags = vc_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispmanxFrameGrabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
|
int DispmanxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||||
{
|
|
||||||
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 ret;
|
int ret;
|
||||||
|
|
||||||
// vc_dispmanx_resource_read_data doesn't seem to work well
|
// vc_dispmanx_resource_read_data doesn't seem to work well
|
||||||
// with arbitrary positions so we have to handle cropping by ourselves
|
// with arbitrary positions so we have to handle cropping by ourselves
|
||||||
unsigned cropLeft = _cropLeft;
|
unsigned cropLeft = _cropLeft;
|
||||||
unsigned cropRight = _cropRight;
|
unsigned cropRight = _cropRight;
|
||||||
unsigned cropTop = _cropTop;
|
unsigned cropTop = _cropTop;
|
||||||
unsigned cropBottom = _cropBottom;
|
unsigned cropBottom = _cropBottom;
|
||||||
|
|
||||||
if (_vc_flags & DISPMANX_SNAPSHOT_FILL)
|
if (_vc_flags & DISPMANX_SNAPSHOT_FILL)
|
||||||
@ -99,19 +84,19 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
|||||||
cropLeft = cropRight = cropTop = cropBottom = 0;
|
cropLeft = cropRight = cropTop = cropBottom = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned imageWidth = _width - cropLeft - cropRight;
|
unsigned imageWidth = _width - cropLeft - cropRight;
|
||||||
unsigned imageHeight = _height - cropTop - cropBottom;
|
unsigned imageHeight = _height - cropTop - cropBottom;
|
||||||
|
|
||||||
// calculate final image dimensions and adjust top/left cropping in 3D modes
|
// calculate final image dimensions and adjust top/left cropping in 3D modes
|
||||||
switch (_videoMode)
|
switch (_videoMode)
|
||||||
{
|
{
|
||||||
case VIDEO_3DSBS:
|
case VIDEO_3DSBS:
|
||||||
imageWidth = imageWidth / 2;
|
imageWidth /= 2;
|
||||||
cropLeft = cropLeft / 2;
|
cropLeft /= 2;
|
||||||
break;
|
break;
|
||||||
case VIDEO_3DTAB:
|
case VIDEO_3DTAB:
|
||||||
imageHeight = imageHeight / 2;
|
imageHeight /= 2;
|
||||||
cropTop = cropTop / 2;
|
cropTop /= 2;
|
||||||
break;
|
break;
|
||||||
case VIDEO_2D:
|
case VIDEO_2D:
|
||||||
default:
|
default:
|
||||||
@ -124,12 +109,17 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
|||||||
image.resize(imageWidth, imageHeight);
|
image.resize(imageWidth, imageHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_image_rgba.width() != imageWidth || _image_rgba.height() != imageHeight)
|
||||||
|
{
|
||||||
|
_image_rgba.resize(imageWidth, imageHeight);
|
||||||
|
}
|
||||||
|
|
||||||
// Open the connection to the display
|
// Open the connection to the display
|
||||||
_vc_display = vc_dispmanx_display_open(0);
|
_vc_display = vc_dispmanx_display_open(0);
|
||||||
if (_vc_display < 0)
|
if (_vc_display < 0)
|
||||||
{
|
{
|
||||||
Error(_log, "Cannot open display: %d", _vc_display);
|
Error(_log, "Cannot open display: %d", _vc_display);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the snapshot (incl down-scaling)
|
// Create the snapshot (incl down-scaling)
|
||||||
@ -138,11 +128,11 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
|||||||
{
|
{
|
||||||
Error(_log, "Snapshot failed: %d", ret);
|
Error(_log, "Snapshot failed: %d", ret);
|
||||||
vc_dispmanx_display_close(_vc_display);
|
vc_dispmanx_display_close(_vc_display);
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the snapshot into the memory
|
// Read the snapshot into the memory
|
||||||
void* imagePtr = image.memptr();
|
void* imagePtr = _image_rgba.memptr();
|
||||||
void* capturePtr = imagePtr;
|
void* capturePtr = imagePtr;
|
||||||
|
|
||||||
unsigned imagePitch = imageWidth * sizeof(ColorRgba);
|
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);
|
Error(_log, "vc_dispmanx_resource_read_data failed: %d", ret);
|
||||||
vc_dispmanx_display_close(_vc_display);
|
vc_dispmanx_display_close(_vc_display);
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy capture data to image if we captured to temp buffer
|
// copy capture data to image if we captured to temp buffer
|
||||||
@ -193,4 +183,9 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
|||||||
|
|
||||||
// Close the displaye
|
// Close the displaye
|
||||||
vc_dispmanx_display_close(_vc_display);
|
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/DispmanxWrapper.h>
|
||||||
#include <grabber/DispmanxFrameGrabber.h>
|
|
||||||
|
|
||||||
|
|
||||||
DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
||||||
: GrabberWrapper("Dispmanx", priority)
|
: GrabberWrapper("Dispmanx", &_grabber, grabWidth, grabHeight, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||||
, _updateInterval_ms(1000/updateRate_Hz)
|
, _grabber(grabWidth, grabHeight)
|
||||||
, _timeout_ms(2 * _updateInterval_ms)
|
|
||||||
, _image(grabWidth, grabHeight)
|
|
||||||
, _grabber(new DispmanxFrameGrabber(grabWidth, grabHeight))
|
|
||||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
|
||||||
{
|
{
|
||||||
// Configure the timer to generate events every n milliseconds
|
setImageProcessorEnabled(false);
|
||||||
_timer.setInterval(_updateInterval_ms);
|
|
||||||
|
|
||||||
_processor->setSize(grabWidth, grabHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
DispmanxWrapper::~DispmanxWrapper()
|
|
||||||
{
|
|
||||||
delete _grabber;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispmanxWrapper::action()
|
void DispmanxWrapper::action()
|
||||||
{
|
{
|
||||||
// Grab frame into the allocated image
|
transferFrame(_grabber);
|
||||||
_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);
|
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ FramebufferFrameGrabber::~FramebufferFrameGrabber()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
int FramebufferFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||||
{
|
{
|
||||||
struct fb_var_screeninfo vinfo;
|
struct fb_var_screeninfo vinfo;
|
||||||
unsigned capSize, bytesPerPixel;
|
unsigned capSize, bytesPerPixel;
|
||||||
@ -62,23 +62,15 @@ void FramebufferFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
|||||||
bytesPerPixel = vinfo.bits_per_pixel / 8;
|
bytesPerPixel = vinfo.bits_per_pixel / 8;
|
||||||
capSize = vinfo.xres * vinfo.yres * bytesPerPixel;
|
capSize = vinfo.xres * vinfo.yres * bytesPerPixel;
|
||||||
|
|
||||||
if (vinfo.bits_per_pixel == 16)
|
switch (vinfo.bits_per_pixel)
|
||||||
{
|
{
|
||||||
pixelFormat = PIXELFORMAT_BGR16;
|
case 16: pixelFormat = PIXELFORMAT_BGR16; break;
|
||||||
}
|
case 24: pixelFormat = PIXELFORMAT_BGR24; break;
|
||||||
else if (vinfo.bits_per_pixel == 24)
|
case 32: pixelFormat = PIXELFORMAT_BGR32; break;
|
||||||
{
|
default:
|
||||||
pixelFormat = PIXELFORMAT_BGR24;
|
Error(_log, "Unknown pixel format: %d bits per pixel", vinfo.bits_per_pixel);
|
||||||
}
|
close(_fbfd);
|
||||||
else if (vinfo.bits_per_pixel == 32)
|
return -1;
|
||||||
{
|
|
||||||
pixelFormat = PIXELFORMAT_BGR32;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Error(_log, "Unknown pixel format: %d bits per pixel", vinfo.bits_per_pixel);
|
|
||||||
close(_fbfd);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* map the device to memory */
|
/* map the device to memory */
|
||||||
@ -95,4 +87,6 @@ void FramebufferFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
|||||||
|
|
||||||
munmap(_fbp, capSize);
|
munmap(_fbp, capSize);
|
||||||
close(_fbfd);
|
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/FramebufferWrapper.h>
|
||||||
#include <grabber/FramebufferFrameGrabber.h>
|
|
||||||
|
|
||||||
FramebufferWrapper::FramebufferWrapper(const QString & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
FramebufferWrapper::FramebufferWrapper(const QString & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
||||||
: GrabberWrapper("FrameBuffer", priority)
|
: GrabberWrapper("FrameBuffer", &_grabber, grabWidth, grabHeight, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||||
, _updateInterval_ms(1000/updateRate_Hz)
|
, _grabber(device, grabWidth, grabHeight)
|
||||||
, _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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramebufferWrapper::action()
|
void FramebufferWrapper::action()
|
||||||
{
|
{
|
||||||
// Grab frame into the allocated image
|
transferFrame(_grabber);
|
||||||
_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);
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
Error(_log, "Display with index %d is not available. Using main display", _screenIndex);
|
||||||
_display = kCGDirectMainDisplay;
|
_display = kCGDirectMainDisplay;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_display = displays[_screenIndex];
|
_display = displays[_screenIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +37,7 @@ OsxFrameGrabber::~OsxFrameGrabber()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void OsxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
int OsxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||||
{
|
{
|
||||||
CGImageRef dispImage;
|
CGImageRef dispImage;
|
||||||
CFDataRef imgData;
|
CFDataRef imgData;
|
||||||
@ -52,12 +54,12 @@ void OsxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
|||||||
if (dispImage == NULL)
|
if (dispImage == NULL)
|
||||||
{
|
{
|
||||||
Error(_log, "No display connected...");
|
Error(_log, "No display connected...");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imgData = CGDataProviderCopyData(CGImageGetDataProvider(dispImage));
|
imgData = CGDataProviderCopyData(CGImageGetDataProvider(dispImage));
|
||||||
pImgData = (unsigned char*) CFDataGetBytePtr(imgData);
|
pImgData = (unsigned char*) CFDataGetBytePtr(imgData);
|
||||||
dspWidth = CGImageGetWidth(dispImage);
|
dspWidth = CGImageGetWidth(dispImage);
|
||||||
dspHeight = CGImageGetHeight(dispImage);
|
dspHeight = CGImageGetHeight(dispImage);
|
||||||
|
|
||||||
_imageResampler.setHorizontalPixelDecimation(dspWidth/_width);
|
_imageResampler.setHorizontalPixelDecimation(dspWidth/_width);
|
||||||
@ -71,4 +73,6 @@ void OsxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
|||||||
|
|
||||||
CFRelease(imgData);
|
CFRelease(imgData);
|
||||||
CGImageRelease(dispImage);
|
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/OsxWrapper.h>
|
||||||
#include <grabber/OsxFrameGrabber.h>
|
|
||||||
|
|
||||||
OsxWrapper::OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
OsxWrapper::OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
||||||
: GrabberWrapper("OSX FrameGrabber", priority)
|
: GrabberWrapper("OSX FrameGrabber", &_grabber, grabWidth, grabHeight, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||||
, _updateInterval_ms(1000/updateRate_Hz)
|
, _grabber(display, grabWidth, grabHeight)
|
||||||
, _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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OsxWrapper::action()
|
void OsxWrapper::action()
|
||||||
{
|
{
|
||||||
// Grab frame into the allocated image
|
transferFrame(_grabber);
|
||||||
_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);
|
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@ V4L2Grabber::V4L2Grabber(const QString & device
|
|||||||
, int input
|
, int input
|
||||||
, VideoStandard videoStandard
|
, VideoStandard videoStandard
|
||||||
, PixelFormat pixelFormat
|
, PixelFormat pixelFormat
|
||||||
, int width
|
, unsigned width
|
||||||
, int height
|
, unsigned height
|
||||||
, int frameDecimation
|
, int frameDecimation
|
||||||
, int horizontalPixelDecimation
|
, int horizontalPixelDecimation
|
||||||
, int verticalPixelDecimation
|
, 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)
|
void V4L2Grabber::setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, int noSignalCounterThreshold)
|
||||||
{
|
{
|
||||||
_noSignalThresholdColor.red = uint8_t(255*redSignalThreshold);
|
_noSignalThresholdColor.red = uint8_t(255*redSignalThreshold);
|
||||||
|
@ -8,8 +8,8 @@ V4L2Wrapper::V4L2Wrapper(const QString &device,
|
|||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard,
|
VideoStandard videoStandard,
|
||||||
PixelFormat pixelFormat,
|
PixelFormat pixelFormat,
|
||||||
int width,
|
unsigned width,
|
||||||
int height,
|
unsigned height,
|
||||||
int frameDecimation,
|
int frameDecimation,
|
||||||
int pixelDecimation,
|
int pixelDecimation,
|
||||||
double redSignalThreshold,
|
double redSignalThreshold,
|
||||||
@ -17,8 +17,7 @@ V4L2Wrapper::V4L2Wrapper(const QString &device,
|
|||||||
double blueSignalThreshold,
|
double blueSignalThreshold,
|
||||||
const int priority,
|
const int priority,
|
||||||
bool useGrabbingMode)
|
bool useGrabbingMode)
|
||||||
: GrabberWrapper("V4L2:"+device, priority, hyperion::COMP_V4L)
|
: GrabberWrapper("V4L2:"+device, &_grabber, width, height, 8, priority, hyperion::COMP_V4L)
|
||||||
, _timeout_ms(1000)
|
|
||||||
, _grabber(device,
|
, _grabber(device,
|
||||||
input,
|
input,
|
||||||
videoStandard,
|
videoStandard,
|
||||||
@ -28,10 +27,10 @@ V4L2Wrapper::V4L2Wrapper(const QString &device,
|
|||||||
frameDecimation,
|
frameDecimation,
|
||||||
pixelDecimation,
|
pixelDecimation,
|
||||||
pixelDecimation)
|
pixelDecimation)
|
||||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
|
||||||
{
|
{
|
||||||
// set the signal detection threshold of the grabber
|
// set the signal detection threshold of the grabber
|
||||||
_grabber.setSignalThreshold( redSignalThreshold, greenSignalThreshold, blueSignalThreshold, 50);
|
_grabber.setSignalThreshold( redSignalThreshold, greenSignalThreshold, blueSignalThreshold, 50);
|
||||||
|
_ggrabber = &_grabber;
|
||||||
|
|
||||||
// register the image type
|
// register the image type
|
||||||
qRegisterMetaType<Image<ColorRgb>>("Image<ColorRgb>");
|
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
|
// 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(newFrame(Image<ColorRgb>)), this, SLOT(newFrame(Image<ColorRgb>)), Qt::DirectConnection);
|
||||||
|
|
||||||
QObject::connect(&_grabber, SIGNAL(readError(const char*)), this, SLOT(readError(const char*)), Qt::DirectConnection);
|
QObject::connect(&_grabber, SIGNAL(readError(const char*)), this, SLOT(readError(const char*)), Qt::DirectConnection);
|
||||||
|
|
||||||
if (!useGrabbingMode)
|
if (!useGrabbingMode)
|
||||||
{
|
{
|
||||||
disconnect(_hyperion, SIGNAL(grabbingMode(GrabbingMode)), this, 0);
|
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);
|
_timer.setInterval(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
V4L2Wrapper::~V4L2Wrapper()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool V4L2Wrapper::start()
|
bool V4L2Wrapper::start()
|
||||||
{
|
{
|
||||||
return ( _grabber.start() && GrabberWrapper::start());
|
return ( _grabber.start() && GrabberWrapper::start());
|
||||||
@ -84,12 +69,6 @@ void V4L2Wrapper::setSignalDetectionOffset(double verticalMin, double horizontal
|
|||||||
_grabber.setSignalDetectionOffset(verticalMin, horizontalMin, verticalMax, horizontalMax);
|
_grabber.setSignalDetectionOffset(verticalMin, horizontalMin, verticalMax, horizontalMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void V4L2Wrapper::setVideoMode(VideoMode mode)
|
|
||||||
{
|
|
||||||
_grabber.setVideoMode(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void V4L2Wrapper::newFrame(const Image<ColorRgb> &image)
|
void V4L2Wrapper::newFrame(const Image<ColorRgb> &image)
|
||||||
{
|
{
|
||||||
emit emitImage(_priority, image, _timeout_ms);
|
emit emitImage(_priority, image, _timeout_ms);
|
||||||
|
@ -14,8 +14,11 @@ X11Grabber::X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropT
|
|||||||
, _verticalDecimation(verticalPixelDecimation)
|
, _verticalDecimation(verticalPixelDecimation)
|
||||||
, _screenWidth(0)
|
, _screenWidth(0)
|
||||||
, _screenHeight(0)
|
, _screenHeight(0)
|
||||||
|
, _src_x(cropLeft)
|
||||||
|
, _src_y(cropTop)
|
||||||
, _image(0,0)
|
, _image(0,0)
|
||||||
{
|
{
|
||||||
|
_useImageResampler = false;
|
||||||
_imageResampler.setCropping(0, 0, 0, 0); // cropping is performed by XRender, XShmGetImage or XGetImage
|
_imageResampler.setCropping(0, 0, 0, 0); // cropping is performed by XRender, XShmGetImage or XGetImage
|
||||||
memset(&_pictAttr, 0, sizeof(_pictAttr));
|
memset(&_pictAttr, 0, sizeof(_pictAttr));
|
||||||
_pictAttr.repeat = RepeatNone;
|
_pictAttr.repeat = RepeatNone;
|
||||||
@ -52,9 +55,7 @@ void X11Grabber::setupResources()
|
|||||||
{
|
{
|
||||||
if(_XShmAvailable && !_useXGetImage)
|
if(_XShmAvailable && !_useXGetImage)
|
||||||
{
|
{
|
||||||
_xImage = XShmCreateImage(_x11Display, _windowAttr.visual,
|
_xImage = XShmCreateImage(_x11Display, _windowAttr.visual, _windowAttr.depth, ZPixmap, NULL, &_shminfo, _width, _height);
|
||||||
_windowAttr.depth, ZPixmap, NULL, &_shminfo,
|
|
||||||
_width, _height);
|
|
||||||
_shminfo.shmid = shmget(IPC_PRIVATE, _xImage->bytes_per_line * _xImage->height, IPC_CREAT|0777);
|
_shminfo.shmid = shmget(IPC_PRIVATE, _xImage->bytes_per_line * _xImage->height, IPC_CREAT|0777);
|
||||||
_xImage->data = (char*)shmat(_shminfo.shmid,0,0);
|
_xImage->data = (char*)shmat(_shminfo.shmid,0,0);
|
||||||
_shminfo.shmaddr = _xImage->data;
|
_shminfo.shmaddr = _xImage->data;
|
||||||
@ -109,12 +110,15 @@ bool X11Grabber::Setup()
|
|||||||
_imageResampler.setHorizontalPixelDecimation(_XRenderAvailable ? 1 : _horizontalDecimation);
|
_imageResampler.setHorizontalPixelDecimation(_XRenderAvailable ? 1 : _horizontalDecimation);
|
||||||
_imageResampler.setVerticalPixelDecimation(_XRenderAvailable ? 1 : _verticalDecimation);
|
_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)
|
if (_XRenderAvailable && !_useXGetImage)
|
||||||
{
|
{
|
||||||
@ -145,19 +149,11 @@ Image<ColorRgb> & X11Grabber::grab()
|
|||||||
|
|
||||||
XRenderSetPictureTransform (_x11Display, _srcPicture, &_transform);
|
XRenderSetPictureTransform (_x11Display, _srcPicture, &_transform);
|
||||||
|
|
||||||
XRenderComposite( _x11Display, // dpy
|
// display, op, src, mask, dest, src_x = cropLeft,
|
||||||
PictOpSrc, // op
|
// src_y = cropTop, mask_x, mask_y, dest_x, dest_y, width, height
|
||||||
_srcPicture, // src
|
XRenderComposite(
|
||||||
None, // mask
|
_x11Display, PictOpSrc, _srcPicture, None, _dstPicture, ( _src_x/_horizontalDecimation),
|
||||||
_dstPicture, // dst
|
(_src_y/_verticalDecimation), 0, 0, 0, 0, _width, _height);
|
||||||
_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);
|
XSync(_x11Display, False);
|
||||||
|
|
||||||
@ -170,93 +166,15 @@ Image<ColorRgb> & X11Grabber::grab()
|
|||||||
_xImage = XGetImage(_x11Display, _pixmap, 0, 0, _width, _height, AllPlanes, ZPixmap);
|
_xImage = XGetImage(_x11Display, _pixmap, 0, 0, _width, _height, AllPlanes, ZPixmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (_XShmAvailable && !_useXGetImage)
|
||||||
{
|
{
|
||||||
if (_XShmAvailable && !_useXGetImage) {
|
// use xshm
|
||||||
XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, AllPlanes);
|
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
|
else
|
||||||
{
|
{
|
||||||
if (_XShmAvailable && !_useXGetImage) {
|
// all things done by xgetimage
|
||||||
XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, AllPlanes);
|
_xImage = XGetImage(_x11Display, _window, _src_x, _src_y, _width, _height, AllPlanes, ZPixmap);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_xImage = XGetImage(_x11Display, _window, _cropLeft, _cropTop, _width, _height, AllPlanes, ZPixmap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_xImage == nullptr)
|
if (_xImage == nullptr)
|
||||||
@ -270,7 +188,7 @@ int X11Grabber::grabFrame(Image<ColorRgb> & image)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int X11Grabber::updateScreenDimensions()
|
int X11Grabber::updateScreenDimensions(bool force)
|
||||||
{
|
{
|
||||||
const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr);
|
const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
@ -279,7 +197,7 @@ int X11Grabber::updateScreenDimensions()
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_screenWidth == unsigned(_windowAttr.width) && _screenHeight == unsigned(_windowAttr.height))
|
if (!force && _screenWidth == unsigned(_windowAttr.width) && _screenHeight == unsigned(_windowAttr.height))
|
||||||
{
|
{
|
||||||
// No update required
|
// No update required
|
||||||
return 0;
|
return 0;
|
||||||
@ -294,14 +212,16 @@ int X11Grabber::updateScreenDimensions()
|
|||||||
_screenWidth = _windowAttr.width;
|
_screenWidth = _windowAttr.width;
|
||||||
_screenHeight = _windowAttr.height;
|
_screenHeight = _windowAttr.height;
|
||||||
|
|
||||||
|
int width=0, height=0;
|
||||||
|
|
||||||
// Image scaling is performed by XRender when available, otherwise by ImageResampler
|
// Image scaling is performed by XRender when available, otherwise by ImageResampler
|
||||||
if (_XRenderAvailable && !_useXGetImage)
|
if (_XRenderAvailable && !_useXGetImage)
|
||||||
{
|
{
|
||||||
_width = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
width = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
||||||
? ((_screenWidth - _cropLeft - _cropRight) / _horizontalDecimation)
|
? ((_screenWidth - _cropLeft - _cropRight) / _horizontalDecimation)
|
||||||
: _screenWidth / _horizontalDecimation;
|
: _screenWidth / _horizontalDecimation;
|
||||||
|
|
||||||
_height = (_screenHeight > unsigned(_cropTop + _cropBottom))
|
height = (_screenHeight > unsigned(_cropTop + _cropBottom))
|
||||||
? ((_screenHeight - _cropTop - _cropBottom) / _verticalDecimation)
|
? ((_screenHeight - _cropTop - _cropBottom) / _verticalDecimation)
|
||||||
: _screenHeight / _verticalDecimation;
|
: _screenHeight / _verticalDecimation;
|
||||||
|
|
||||||
@ -309,19 +229,52 @@ int X11Grabber::updateScreenDimensions()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_width = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
width = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
||||||
? (_screenWidth - _cropLeft - _cropRight)
|
? (_screenWidth - _cropLeft - _cropRight)
|
||||||
: _screenWidth;
|
: _screenWidth;
|
||||||
|
|
||||||
_height = (_screenHeight > unsigned(_cropTop + _cropBottom))
|
height = (_screenHeight > unsigned(_cropTop + _cropBottom))
|
||||||
? (_screenHeight - _cropTop - _cropBottom)
|
? (_screenHeight - _cropTop - _cropBottom)
|
||||||
: _screenHeight;
|
: _screenHeight;
|
||||||
|
|
||||||
Info(_log, "Using XGetImage for grabbing");
|
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);
|
_image.resize(_width, _height);
|
||||||
setupResources();
|
setupResources();
|
||||||
|
|
||||||
return 1;
|
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/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)
|
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)
|
: GrabberWrapper("X11", &_grabber, 0, 0, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||||
, _updateInterval_ms(1000/updateRate_Hz)
|
, _grabber(useXGetImage, cropLeft, cropRight, cropTop, cropBottom, horizontalPixelDecimation, verticalPixelDecimation)
|
||||||
, _timeout_ms(2 * _updateInterval_ms)
|
|
||||||
, _grabber(new X11Grabber(useXGetImage, cropLeft, cropRight, cropTop, cropBottom, horizontalPixelDecimation, verticalPixelDecimation))
|
|
||||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
|
||||||
, _init(false)
|
, _init(false)
|
||||||
, _x11SetupSuccess(false)
|
{}
|
||||||
{
|
|
||||||
// Configure the timer to generate events every n milliseconds
|
|
||||||
_timer.setInterval(_updateInterval_ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
X11Wrapper::~X11Wrapper()
|
void X11Wrapper::action()
|
||||||
{
|
|
||||||
delete _grabber;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool X11Wrapper::start()
|
|
||||||
{
|
{
|
||||||
if (! _init )
|
if (! _init )
|
||||||
{
|
{
|
||||||
_init = true;
|
_init = true;
|
||||||
_x11SetupSuccess = _grabber->Setup();
|
if ( ! _grabber.Setup() )
|
||||||
if ( _x11SetupSuccess )
|
|
||||||
{
|
{
|
||||||
_x11SetupSuccess = (_grabber->updateScreenDimensions() >= 0);
|
stop();
|
||||||
_processor->setSize(_grabber->getImageWidth(), _grabber->getImageHeight());
|
|
||||||
_image.resize(_grabber->getImageWidth(), _grabber->getImageHeight());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Start the timer with the pre configured interval
|
|
||||||
if ( _x11SetupSuccess )
|
if (_grabber.updateScreenDimensions() >= 0 )
|
||||||
{
|
{
|
||||||
GrabberWrapper::start();
|
transferFrame(_grabber);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,19 @@
|
|||||||
|
|
||||||
Grabber::Grabber(QString grabberName, int width, int height, int cropLeft, int cropRight, int cropTop, int cropBottom)
|
Grabber::Grabber(QString grabberName, int width, int height, int cropLeft, int cropRight, int cropTop, int cropBottom)
|
||||||
: _imageResampler()
|
: _imageResampler()
|
||||||
|
, _useImageResampler(true)
|
||||||
, _videoMode(VIDEO_2D)
|
, _videoMode(VIDEO_2D)
|
||||||
, _width(width)
|
, _width(width)
|
||||||
, _height(height)
|
, _height(height)
|
||||||
, _cropLeft(cropLeft)
|
, _cropLeft(0)
|
||||||
, _cropRight(cropRight)
|
, _cropRight(0)
|
||||||
, _cropTop(cropTop)
|
, _cropTop(0)
|
||||||
, _cropBottom(cropBottom)
|
, _cropBottom(0)
|
||||||
, _log(Logger::getInstance(grabberName))
|
, _log(Logger::getInstance(grabberName))
|
||||||
|
|
||||||
{
|
{
|
||||||
|
setVideoMode(VIDEO_2D);
|
||||||
|
setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
Grabber::~Grabber()
|
Grabber::~Grabber()
|
||||||
@ -22,6 +25,41 @@ Grabber::~Grabber()
|
|||||||
|
|
||||||
void Grabber::setVideoMode(VideoMode mode)
|
void Grabber::setVideoMode(VideoMode mode)
|
||||||
{
|
{
|
||||||
|
Debug(_log,"setvideomode %d", mode);
|
||||||
_videoMode = 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/ImageProcessorFactory.h>
|
||||||
#include <hyperion/ImageProcessor.h>
|
#include <hyperion/ImageProcessor.h>
|
||||||
#include <hyperion/GrabberWrapper.h>
|
#include <hyperion/GrabberWrapper.h>
|
||||||
|
#include <hyperion/Grabber.h>
|
||||||
#include <HyperionConfig.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)
|
: _grabberName(grabberName)
|
||||||
, _hyperion(Hyperion::getInstance())
|
, _hyperion(Hyperion::getInstance())
|
||||||
, _priority(priority)
|
, _priority(priority)
|
||||||
, _timer()
|
, _timer()
|
||||||
|
, _updateInterval_ms(1000/updateRate_Hz)
|
||||||
|
, _timeout_ms(2 * _updateInterval_ms)
|
||||||
, _log(Logger::getInstance(grabberName))
|
, _log(Logger::getInstance(grabberName))
|
||||||
, _forward(true)
|
, _forward(true)
|
||||||
, _processor(ImageProcessorFactory::getInstance().newImageProcessor())
|
, _processor(ImageProcessorFactory::getInstance().newImageProcessor())
|
||||||
, _grabberComponentId(grabberComponentId)
|
, _grabberComponentId(grabberComponentId)
|
||||||
|
, _ggrabber(ggrabber)
|
||||||
|
, _image(0,0)
|
||||||
|
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
||||||
|
, _imageProcessorEnabled(true)
|
||||||
{
|
{
|
||||||
_timer.setSingleShot(false);
|
_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();
|
_forward = _hyperion->getForwarder()->protoForwardingEnabled();
|
||||||
_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_BLACKBORDER, _processor->blackBorderDetectorEnabled());
|
_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(_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(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()));
|
connect(&_timer, SIGNAL(timeout()), this, SLOT(action()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GrabberWrapper::~GrabberWrapper()
|
GrabberWrapper::~GrabberWrapper()
|
||||||
@ -139,3 +152,24 @@ QStringList GrabberWrapper::availableGrabbers()
|
|||||||
|
|
||||||
return grabbers;
|
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)
|
void Hyperion::freeObjects(bool emitCloseSignal)
|
||||||
{
|
{
|
||||||
|
// switch off all leds
|
||||||
|
clearall(true);
|
||||||
|
_device->switchOff();
|
||||||
|
|
||||||
if (emitCloseSignal)
|
if (emitCloseSignal)
|
||||||
{
|
{
|
||||||
emit closing();
|
emit closing();
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch off all leds
|
|
||||||
clearall();
|
|
||||||
_device->switchOff();
|
|
||||||
|
|
||||||
// delete components on exit of hyperion core
|
// delete components on exit of hyperion core
|
||||||
delete _effectEngine;
|
delete _effectEngine;
|
||||||
@ -740,9 +741,9 @@ void Hyperion::clear(int priority)
|
|||||||
_effectEngine->channelCleared(priority);
|
_effectEngine->channelCleared(priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hyperion::clearall()
|
void Hyperion::clearall(bool forceClearAll)
|
||||||
{
|
{
|
||||||
_muxer.clearAll();
|
_muxer.clearAll(forceClearAll);
|
||||||
setSourceAutoSelectEnabled(true);
|
setSourceAutoSelectEnabled(true);
|
||||||
|
|
||||||
// update leds
|
// update leds
|
||||||
|
@ -44,7 +44,7 @@ void ImageProcessor::setSize(const unsigned width, const unsigned height)
|
|||||||
delete _imageToLeds;
|
delete _imageToLeds;
|
||||||
|
|
||||||
// Construct a new buffer and mapping
|
// 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)
|
void ImageProcessor::enableBlackBorderDetector(bool enable)
|
||||||
|
@ -17,6 +17,8 @@ ImageToLedsMap::ImageToLedsMap(
|
|||||||
// Sanity check of the size of the borders (and width and height)
|
// Sanity check of the size of the borders (and width and height)
|
||||||
Q_ASSERT(_width > 2*_verticalBorder);
|
Q_ASSERT(_width > 2*_verticalBorder);
|
||||||
Q_ASSERT(_height > 2*_horizontalBorder);
|
Q_ASSERT(_height > 2*_horizontalBorder);
|
||||||
|
Q_ASSERT(_width < 10000);
|
||||||
|
Q_ASSERT(_height < 10000);
|
||||||
|
|
||||||
// Reserve enough space in the map for the leds
|
// Reserve enough space in the map for the leds
|
||||||
_colorsMap.reserve(leds.size());
|
_colorsMap.reserve(leds.size());
|
||||||
|
@ -78,13 +78,22 @@ void PriorityMuxer::clearInput(const int priority)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PriorityMuxer::clearAll()
|
void PriorityMuxer::clearAll(bool forceClearAll)
|
||||||
{
|
{
|
||||||
for(auto key : _activeInputs.keys())
|
if (forceClearAll)
|
||||||
{
|
{
|
||||||
if (key < LOWEST_PRIORITY-1)
|
_activeInputs.clear();
|
||||||
|
_currentPriority = LOWEST_PRIORITY;
|
||||||
|
_activeInputs[_currentPriority] = _lowestPriorityInfo;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(auto key : _activeInputs.keys())
|
||||||
{
|
{
|
||||||
_activeInputs.remove(key);
|
if (key < LOWEST_PRIORITY-1)
|
||||||
|
{
|
||||||
|
_activeInputs.remove(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,8 @@
|
|||||||
{
|
{
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"title" : "edt_conf_v4l2_width_title",
|
"title" : "edt_conf_v4l2_width_title",
|
||||||
"minimum" : -1,
|
"minimum" : 0,
|
||||||
"default" : -1,
|
"default" : 0,
|
||||||
"append" : "edt_append_pixel",
|
"append" : "edt_append_pixel",
|
||||||
"propertyOrder" : 5
|
"propertyOrder" : 5
|
||||||
},
|
},
|
||||||
@ -55,8 +55,8 @@
|
|||||||
{
|
{
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"title" : "edt_conf_v4l2_height_title",
|
"title" : "edt_conf_v4l2_height_title",
|
||||||
"minimum" : -1,
|
"minimum" : 0,
|
||||||
"default" : -1,
|
"default" : 0,
|
||||||
"append" : "edt_append_pixel",
|
"append" : "edt_append_pixel",
|
||||||
"propertyOrder" : 6
|
"propertyOrder" : 6
|
||||||
},
|
},
|
||||||
|
@ -19,6 +19,8 @@ add_library(protoserver
|
|||||||
${ProtoServer_PROTO_SRCS}
|
${ProtoServer_PROTO_SRCS}
|
||||||
${ProtoServer_PROTO_HDRS}
|
${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
|
target_link_libraries(protoserver
|
||||||
hyperion
|
hyperion
|
||||||
|
@ -30,22 +30,22 @@ void ImageResampler::setVerticalPixelDecimation(int decimator)
|
|||||||
|
|
||||||
void ImageResampler::setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom)
|
void ImageResampler::setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom)
|
||||||
{
|
{
|
||||||
_cropLeft = cropLeft;
|
_cropLeft = cropLeft;
|
||||||
_cropRight = cropRight;
|
_cropRight = cropRight;
|
||||||
_cropTop = cropTop;
|
_cropTop = cropTop;
|
||||||
_cropBottom = cropBottom;
|
_cropBottom = cropBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageResampler::set3D(VideoMode mode)
|
void ImageResampler::setVideoMode(VideoMode mode)
|
||||||
{
|
{
|
||||||
_videoMode = mode;
|
_videoMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageResampler::processImage(const uint8_t * data, int width, int height, int lineLength, PixelFormat pixelFormat, Image<ColorRgb> &outputImage) const
|
void ImageResampler::processImage(const uint8_t * data, int width, int height, int lineLength, PixelFormat pixelFormat, Image<ColorRgb> &outputImage) const
|
||||||
{
|
{
|
||||||
int cropLeft = _cropLeft;
|
int cropLeft = _cropLeft;
|
||||||
int cropRight = _cropRight;
|
int cropRight = _cropRight;
|
||||||
int cropTop = _cropTop;
|
int cropTop = _cropTop;
|
||||||
int cropBottom = _cropBottom;
|
int cropBottom = _cropBottom;
|
||||||
|
|
||||||
// handle 3D mode
|
// handle 3D mode
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
"tan" : {
|
"tan" : {
|
||||||
"type" : "integer"
|
"type" : "integer"
|
||||||
},
|
},
|
||||||
"mappingType": {
|
"videoMode": {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"enum" : ["2D", "3DSBS", "3DTAB"]
|
"enum" : ["2D", "3DSBS", "3DTAB"]
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeig
|
|||||||
const Image<ColorRgb> & AmlogicWrapper::getScreenshot()
|
const Image<ColorRgb> & AmlogicWrapper::getScreenshot()
|
||||||
{
|
{
|
||||||
capture();
|
capture();
|
||||||
return _screenshot_rgb;
|
return _screenshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmlogicWrapper::start()
|
void AmlogicWrapper::start()
|
||||||
@ -32,7 +32,5 @@ void AmlogicWrapper::stop()
|
|||||||
void AmlogicWrapper::capture()
|
void AmlogicWrapper::capture()
|
||||||
{
|
{
|
||||||
_grabber.grabFrame(_screenshot);
|
_grabber.grabFrame(_screenshot);
|
||||||
_screenshot.toRgb(_screenshot_rgb);
|
emit sig_screenshot(_screenshot);
|
||||||
|
|
||||||
emit sig_screenshot(_screenshot_rgb);
|
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ private:
|
|||||||
AmlogicGrabber _grabber;
|
AmlogicGrabber _grabber;
|
||||||
|
|
||||||
// image buffers
|
// image buffers
|
||||||
Image<ColorRgb> _screenshot_rgb;
|
Image<ColorRgb> _screenshot;
|
||||||
Image<ColorBgr> _screenshot;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,12 @@ cmake_minimum_required(VERSION 2.8.12)
|
|||||||
project(hyperion-dispmanx)
|
project(hyperion-dispmanx)
|
||||||
|
|
||||||
find_package(Qt5Widgets REQUIRED)
|
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(
|
include_directories(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/protoserver
|
${CMAKE_CURRENT_BINARY_DIR}/../../libsrc/protoserver
|
||||||
|
@ -22,7 +22,7 @@ DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHe
|
|||||||
const Image<ColorRgb> & DispmanxWrapper::getScreenshot()
|
const Image<ColorRgb> & DispmanxWrapper::getScreenshot()
|
||||||
{
|
{
|
||||||
capture();
|
capture();
|
||||||
return _screenshot_rgb;
|
return _screenshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispmanxWrapper::start()
|
void DispmanxWrapper::start()
|
||||||
@ -38,7 +38,5 @@ void DispmanxWrapper::stop()
|
|||||||
void DispmanxWrapper::capture()
|
void DispmanxWrapper::capture()
|
||||||
{
|
{
|
||||||
_grabber.grabFrame(_screenshot);
|
_grabber.grabFrame(_screenshot);
|
||||||
_screenshot.toRgb(_screenshot_rgb);
|
emit sig_screenshot(_screenshot);
|
||||||
|
|
||||||
emit sig_screenshot(_screenshot_rgb);
|
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,5 @@ private:
|
|||||||
|
|
||||||
/// The grabber for creating screenshots
|
/// The grabber for creating screenshots
|
||||||
DispmanxFrameGrabber _grabber;
|
DispmanxFrameGrabber _grabber;
|
||||||
Image<ColorRgb> _screenshot_rgb;
|
Image<ColorRgb> _screenshot;
|
||||||
Image<ColorRgba> _screenshot;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,8 @@ X11Wrapper::X11Wrapper(int grabInterval, bool useXGetImage, int cropLeft, int cr
|
|||||||
|
|
||||||
const Image<ColorRgb> & X11Wrapper::getScreenshot()
|
const Image<ColorRgb> & X11Wrapper::getScreenshot()
|
||||||
{
|
{
|
||||||
const Image<ColorRgb> & screenshot = _grabber.grab();
|
_grabber.grabFrame(_screenshot, true);
|
||||||
return screenshot;
|
return _screenshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Wrapper::start()
|
void X11Wrapper::start()
|
||||||
@ -36,8 +36,8 @@ bool X11Wrapper::displayInit()
|
|||||||
|
|
||||||
void X11Wrapper::capture()
|
void X11Wrapper::capture()
|
||||||
{
|
{
|
||||||
const Image<ColorRgb> & screenshot = _grabber.grab();
|
_grabber.grabFrame(_screenshot, true);
|
||||||
emit sig_screenshot(screenshot);
|
emit sig_screenshot(_screenshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Wrapper::setGrabbingMode(const GrabbingMode mode)
|
void X11Wrapper::setGrabbingMode(const GrabbingMode mode)
|
||||||
|
@ -55,4 +55,6 @@ private:
|
|||||||
|
|
||||||
/// The grabber for creating screenshots
|
/// The grabber for creating screenshots
|
||||||
X11Grabber _grabber;
|
X11Grabber _grabber;
|
||||||
|
|
||||||
|
Image<ColorRgb> _screenshot;
|
||||||
};
|
};
|
||||||
|
@ -98,7 +98,7 @@ int main(int argc, char ** argv)
|
|||||||
catch (const std::runtime_error & e)
|
catch (const std::runtime_error & e)
|
||||||
{
|
{
|
||||||
// An error occured. Display error and quit
|
// An error occured. Display error and quit
|
||||||
Error(Logger::getInstance("X11GRABBER"), "%s", e.what());
|
Error(Logger::getInstance("X11GRABBER"), "%s", e.what());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ HyperionDaemon::~HyperionDaemon()
|
|||||||
|
|
||||||
void HyperionDaemon::freeObjects()
|
void HyperionDaemon::freeObjects()
|
||||||
{
|
{
|
||||||
|
_hyperion->clearall(true);
|
||||||
Debug(_log, "destroy grabbers and network stuff");
|
Debug(_log, "destroy grabbers and network stuff");
|
||||||
delete _amlGrabber;
|
delete _amlGrabber;
|
||||||
delete _dispmanx;
|
delete _dispmanx;
|
||||||
@ -117,7 +118,6 @@ void HyperionDaemon::freeObjects()
|
|||||||
|
|
||||||
void HyperionDaemon::run()
|
void HyperionDaemon::run()
|
||||||
{
|
{
|
||||||
startInitialEffect();
|
|
||||||
createKODIVideoChecker();
|
createKODIVideoChecker();
|
||||||
|
|
||||||
// ---- network services -----
|
// ---- network services -----
|
||||||
@ -133,6 +133,8 @@ void HyperionDaemon::run()
|
|||||||
Info(_log, "Hyperion started");
|
Info(_log, "Hyperion started");
|
||||||
|
|
||||||
connect(_hyperion,SIGNAL(closing()),this,SLOT(freeObjects()));
|
connect(_hyperion,SIGNAL(closing()),this,SLOT(freeObjects()));
|
||||||
|
|
||||||
|
startInitialEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyperionDaemon::loadConfig(const QString & configFile)
|
void HyperionDaemon::loadConfig(const QString & configFile)
|
||||||
@ -499,6 +501,7 @@ void HyperionDaemon::createGrabberX11(const QJsonObject & grabberConfig)
|
|||||||
grabberConfig["horizontalPixelDecimation"].toInt(8),
|
grabberConfig["horizontalPixelDecimation"].toInt(8),
|
||||||
grabberConfig["verticalPixelDecimation"].toInt(8),
|
grabberConfig["verticalPixelDecimation"].toInt(8),
|
||||||
_grabber_frequency, _grabber_priority );
|
_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)) );
|
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(
|
_fbGrabber = new FramebufferWrapper(
|
||||||
grabberConfig["device"].toString("/dev/fb0"),
|
grabberConfig["device"].toString("/dev/fb0"),
|
||||||
_grabber_width, _grabber_height, _grabber_frequency, _grabber_priority);
|
_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)) );
|
QObject::connect(_fbGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
||||||
|
|
||||||
_fbGrabber->start();
|
_fbGrabber->start();
|
||||||
@ -570,8 +573,8 @@ void HyperionDaemon::createGrabberV4L2()
|
|||||||
grabberConfig["input"].toInt(0),
|
grabberConfig["input"].toInt(0),
|
||||||
parseVideoStandard(grabberConfig["standard"].toString("no-change")),
|
parseVideoStandard(grabberConfig["standard"].toString("no-change")),
|
||||||
parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")),
|
parsePixelFormat(grabberConfig["pixelFormat"].toString("no-change")),
|
||||||
grabberConfig["width"].toInt(-1),
|
grabberConfig["width"].toInt(0),
|
||||||
grabberConfig["height"].toInt(-1),
|
grabberConfig["height"].toInt(0),
|
||||||
grabberConfig["frameDecimation"].toInt(2),
|
grabberConfig["frameDecimation"].toInt(2),
|
||||||
grabberConfig["sizeDecimation"].toInt(8),
|
grabberConfig["sizeDecimation"].toInt(8),
|
||||||
grabberConfig["redSignalThreshold"].toDouble(0.0)/100.0,
|
grabberConfig["redSignalThreshold"].toDouble(0.0)/100.0,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#ifdef ENABLE_DISPMANX
|
#ifdef ENABLE_DISPMANX
|
||||||
#include <grabber/DispmanxWrapper.h>
|
#include <grabber/DispmanxWrapper.h>
|
||||||
@ -46,7 +47,7 @@
|
|||||||
#include <boblightserver/BoblightServer.h>
|
#include <boblightserver/BoblightServer.h>
|
||||||
#include <udplistener/UDPListener.h>
|
#include <udplistener/UDPListener.h>
|
||||||
#include <utils/Stats.h>
|
#include <utils/Stats.h>
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
class SysTray;
|
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)
|
add_definitions(${QT_DEFINITIONS})
|
||||||
find_package(BCM REQUIRED)
|
link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
|
||||||
include_directories(${BCM_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
add_definitions(${QT_DEFINITIONS})
|
add_executable(dispmanx2png
|
||||||
link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
|
|
||||||
|
|
||||||
|
|
||||||
add_executable(dispmanx2png
|
|
||||||
dispmanx2png.cpp)
|
dispmanx2png.cpp)
|
||||||
|
|
||||||
target_link_libraries(dispmanx2png
|
target_link_libraries(dispmanx2png
|
||||||
dispmanx-grabber
|
dispmanx-grabber
|
||||||
Qt5::Gui)
|
Qt5::Gui)
|
||||||
|
ENDIF()
|
||||||
|
Loading…
Reference in New Issue
Block a user