mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00: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:
@@ -1,6 +1,11 @@
|
||||
# Find the BCM-package (VC control)
|
||||
find_package(BCM REQUIRED)
|
||||
include_directories(${BCM_INCLUDE_DIRS})
|
||||
IF ( "${PLATFORM}" MATCHES rpi)
|
||||
find_package(BCM REQUIRED)
|
||||
include_directories(${BCM_INCLUDE_DIRS})
|
||||
ELSE()
|
||||
SET(BCM_INCLUDE_DIRS "")
|
||||
SET(BCM_LIBRARIES "")
|
||||
ENDIF()
|
||||
|
||||
# Define the current source locations
|
||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
||||
|
@@ -13,7 +13,10 @@ DispmanxFrameGrabber::DispmanxFrameGrabber(const unsigned width, const unsigned
|
||||
, _vc_flags(0)
|
||||
, _captureBuffer(new ColorRgba[0])
|
||||
, _captureBufferSize(0)
|
||||
, _image_rgba(width, height)
|
||||
{
|
||||
_useImageResampler = false;
|
||||
|
||||
// Initiase BCM
|
||||
bcm_host_init();
|
||||
|
||||
@@ -64,33 +67,15 @@ void DispmanxFrameGrabber::setFlags(const int vc_flags)
|
||||
_vc_flags = vc_flags;
|
||||
}
|
||||
|
||||
void DispmanxFrameGrabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
|
||||
{
|
||||
if (cropLeft + cropRight >= (unsigned)_width || cropTop + cropBottom >= (unsigned)_height)
|
||||
{
|
||||
Error(_log, "Rejecting invalid crop values: left: %d, right: %d, top: %d, bottom: %d", cropLeft, cropRight, cropTop, cropBottom);
|
||||
return;
|
||||
}
|
||||
_cropLeft = cropLeft;
|
||||
_cropRight = cropRight;
|
||||
_cropTop = cropTop;
|
||||
_cropBottom = cropBottom;
|
||||
|
||||
if (cropLeft > 0 || cropRight > 0 || cropTop > 0 || cropBottom > 0)
|
||||
{
|
||||
Info(_log, "Cropping image: width=%d height=%d; crop: left=%d right=%d top=%d bottom=%d ", _width, _height, cropLeft, cropRight, cropTop, cropBottom);
|
||||
}
|
||||
}
|
||||
|
||||
void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
int DispmanxFrameGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
{
|
||||
int ret;
|
||||
|
||||
// vc_dispmanx_resource_read_data doesn't seem to work well
|
||||
// with arbitrary positions so we have to handle cropping by ourselves
|
||||
unsigned cropLeft = _cropLeft;
|
||||
unsigned cropRight = _cropRight;
|
||||
unsigned cropTop = _cropTop;
|
||||
unsigned cropLeft = _cropLeft;
|
||||
unsigned cropRight = _cropRight;
|
||||
unsigned cropTop = _cropTop;
|
||||
unsigned cropBottom = _cropBottom;
|
||||
|
||||
if (_vc_flags & DISPMANX_SNAPSHOT_FILL)
|
||||
@@ -99,19 +84,19 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
cropLeft = cropRight = cropTop = cropBottom = 0;
|
||||
}
|
||||
|
||||
unsigned imageWidth = _width - cropLeft - cropRight;
|
||||
unsigned imageWidth = _width - cropLeft - cropRight;
|
||||
unsigned imageHeight = _height - cropTop - cropBottom;
|
||||
|
||||
// calculate final image dimensions and adjust top/left cropping in 3D modes
|
||||
switch (_videoMode)
|
||||
{
|
||||
case VIDEO_3DSBS:
|
||||
imageWidth = imageWidth / 2;
|
||||
cropLeft = cropLeft / 2;
|
||||
imageWidth /= 2;
|
||||
cropLeft /= 2;
|
||||
break;
|
||||
case VIDEO_3DTAB:
|
||||
imageHeight = imageHeight / 2;
|
||||
cropTop = cropTop / 2;
|
||||
imageHeight /= 2;
|
||||
cropTop /= 2;
|
||||
break;
|
||||
case VIDEO_2D:
|
||||
default:
|
||||
@@ -124,12 +109,17 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
image.resize(imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
if (_image_rgba.width() != imageWidth || _image_rgba.height() != imageHeight)
|
||||
{
|
||||
_image_rgba.resize(imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
// Open the connection to the display
|
||||
_vc_display = vc_dispmanx_display_open(0);
|
||||
if (_vc_display < 0)
|
||||
{
|
||||
Error(_log, "Cannot open display: %d", _vc_display);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create the snapshot (incl down-scaling)
|
||||
@@ -138,11 +128,11 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
{
|
||||
Error(_log, "Snapshot failed: %d", ret);
|
||||
vc_dispmanx_display_close(_vc_display);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Read the snapshot into the memory
|
||||
void* imagePtr = image.memptr();
|
||||
void* imagePtr = _image_rgba.memptr();
|
||||
void* capturePtr = imagePtr;
|
||||
|
||||
unsigned imagePitch = imageWidth * sizeof(ColorRgba);
|
||||
@@ -172,7 +162,7 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
{
|
||||
Error(_log, "vc_dispmanx_resource_read_data failed: %d", ret);
|
||||
vc_dispmanx_display_close(_vc_display);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// copy capture data to image if we captured to temp buffer
|
||||
@@ -193,4 +183,9 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||
|
||||
// Close the displaye
|
||||
vc_dispmanx_display_close(_vc_display);
|
||||
|
||||
// image to output image
|
||||
_image_rgba.toRgb(image);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
107
libsrc/grabber/dispmanx/DispmanxFrameGrabberMock.cpp
Normal file
107
libsrc/grabber/dispmanx/DispmanxFrameGrabberMock.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#ifndef PLATFORM_RPI
|
||||
|
||||
#include <grabber/DispmanxFrameGrabberMock.h>
|
||||
|
||||
unsigned __bcm_frame_counter = 0;
|
||||
const int __screenWidth = 800;
|
||||
const int __screenHeight = 600;
|
||||
|
||||
void bcm_host_init()
|
||||
{
|
||||
}
|
||||
|
||||
void bcm_host_deinit()
|
||||
{
|
||||
}
|
||||
|
||||
int vc_dispmanx_display_open(int)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void vc_dispmanx_display_close(int)
|
||||
{
|
||||
}
|
||||
|
||||
int vc_dispmanx_display_get_info(int, DISPMANX_MODEINFO_T *vc_info)
|
||||
{
|
||||
vc_info->width = __screenWidth;
|
||||
vc_info->height = __screenHeight;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DISPMANX_RESOURCE_HANDLE_T vc_dispmanx_resource_create(int,int width,int height, uint32_t *)
|
||||
{
|
||||
return new DISPMANX_RESOURCE(width,height);
|
||||
}
|
||||
|
||||
void vc_dispmanx_resource_delete(DISPMANX_RESOURCE_HANDLE_T resource)
|
||||
{
|
||||
delete resource;
|
||||
}
|
||||
|
||||
int vc_dispmanx_resource_read_data(DISPMANX_RESOURCE_HANDLE_T resource, VC_RECT_T *rectangle, void* capturePtr, unsigned capturePitch)
|
||||
{
|
||||
memcpy(capturePtr, resource->memptr(), resource->height()*resource->width() * sizeof(ColorRgba));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vc_dispmanx_rect_set(VC_RECT_T *rectangle, int left, int top, int width, int height)
|
||||
{
|
||||
rectangle->width = width;
|
||||
rectangle->height = height;
|
||||
rectangle->left = left;
|
||||
rectangle->top = top;
|
||||
}
|
||||
|
||||
int vc_dispmanx_snapshot(int, DISPMANX_RESOURCE_HANDLE_T resource, int vc_flags)
|
||||
{
|
||||
__bcm_frame_counter++;
|
||||
if (__bcm_frame_counter > 100)
|
||||
{
|
||||
__bcm_frame_counter = 0;
|
||||
}
|
||||
|
||||
ColorRgba color[4] = {ColorRgba::RED, ColorRgba::BLUE, ColorRgba::GREEN, ColorRgba::WHITE};
|
||||
if (__bcm_frame_counter < 25)
|
||||
{
|
||||
color[0] = ColorRgba::WHITE;
|
||||
color[1] = ColorRgba::RED;
|
||||
color[2] = ColorRgba::BLUE;
|
||||
color[3] = ColorRgba::GREEN;
|
||||
}
|
||||
else if(__bcm_frame_counter < 50)
|
||||
{
|
||||
color[1] = ColorRgba::WHITE;
|
||||
color[2] = ColorRgba::RED;
|
||||
color[3] = ColorRgba::BLUE;
|
||||
color[0] = ColorRgba::GREEN;
|
||||
}
|
||||
else if(__bcm_frame_counter < 75)
|
||||
{
|
||||
color[2] = ColorRgba::WHITE;
|
||||
color[3] = ColorRgba::RED;
|
||||
color[0] = ColorRgba::BLUE;
|
||||
color[1] = ColorRgba::GREEN;
|
||||
}
|
||||
|
||||
unsigned w = resource->width();
|
||||
unsigned h = resource->height();
|
||||
for (unsigned y=0; y<h; y++)
|
||||
{
|
||||
for (unsigned x=0; x<w; x++)
|
||||
{
|
||||
unsigned id = 0;
|
||||
if (x < w/2 && y < h/2) id = 1;
|
||||
if (x < w/2 && y >= h/2) id = 2;
|
||||
if (x >= w/2 && y < h/2) id = 3;
|
||||
|
||||
resource->memptr()[y*w + x] = color[id];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,56 +1,13 @@
|
||||
// QT includes
|
||||
#include <QDateTime>
|
||||
|
||||
// Hyperion includes
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
|
||||
// Dispmanx grabber includes
|
||||
#include <grabber/DispmanxWrapper.h>
|
||||
#include <grabber/DispmanxFrameGrabber.h>
|
||||
|
||||
|
||||
DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, const int priority)
|
||||
: GrabberWrapper("Dispmanx", priority)
|
||||
, _updateInterval_ms(1000/updateRate_Hz)
|
||||
, _timeout_ms(2 * _updateInterval_ms)
|
||||
, _image(grabWidth, grabHeight)
|
||||
, _grabber(new DispmanxFrameGrabber(grabWidth, grabHeight))
|
||||
, _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb{0,0,0})
|
||||
: GrabberWrapper("Dispmanx", &_grabber, grabWidth, grabHeight, updateRate_Hz, priority, hyperion::COMP_GRABBER)
|
||||
, _grabber(grabWidth, grabHeight)
|
||||
{
|
||||
// Configure the timer to generate events every n milliseconds
|
||||
_timer.setInterval(_updateInterval_ms);
|
||||
|
||||
_processor->setSize(grabWidth, grabHeight);
|
||||
}
|
||||
|
||||
DispmanxWrapper::~DispmanxWrapper()
|
||||
{
|
||||
delete _grabber;
|
||||
setImageProcessorEnabled(false);
|
||||
}
|
||||
|
||||
void DispmanxWrapper::action()
|
||||
{
|
||||
// Grab frame into the allocated image
|
||||
_grabber->grabFrame(_image);
|
||||
|
||||
Image<ColorRgb> image_rgb;
|
||||
_image.toRgb(image_rgb);
|
||||
emit emitImage(_priority, image_rgb, _timeout_ms);
|
||||
|
||||
_processor->process(_image, _ledColors);
|
||||
setColors(_ledColors, _timeout_ms);
|
||||
}
|
||||
|
||||
|
||||
void DispmanxWrapper::setVideoMode(const VideoMode mode)
|
||||
{
|
||||
_grabber->setVideoMode(mode);
|
||||
}
|
||||
|
||||
void DispmanxWrapper::setCropping(const unsigned cropLeft, const unsigned cropRight,
|
||||
const unsigned cropTop, const unsigned cropBottom)
|
||||
{
|
||||
_grabber->setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||
transferFrame(_grabber);
|
||||
}
|
||||
|
Reference in New Issue
Block a user