mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Use ImageResampler in V4L2 grabber
Former-commit-id: c6ec92c17b07444a49a303cdced6f59347f98f76
This commit is contained in:
parent
e608b11caa
commit
2b6d485ea7
@ -13,6 +13,7 @@
|
|||||||
#include <utils/ColorRgb.h>
|
#include <utils/ColorRgb.h>
|
||||||
#include <utils/PixelFormat.h>
|
#include <utils/PixelFormat.h>
|
||||||
#include <utils/VideoMode.h>
|
#include <utils/VideoMode.h>
|
||||||
|
#include <utils/ImageResampler.h>
|
||||||
|
|
||||||
// grabber includes
|
// grabber includes
|
||||||
#include <grabber/VideoStandard.h>
|
#include <grabber/VideoStandard.h>
|
||||||
@ -108,22 +109,17 @@ private:
|
|||||||
PixelFormat _pixelFormat;
|
PixelFormat _pixelFormat;
|
||||||
int _width;
|
int _width;
|
||||||
int _height;
|
int _height;
|
||||||
|
int _lineLength;
|
||||||
int _frameByteSize;
|
int _frameByteSize;
|
||||||
int _cropLeft;
|
|
||||||
int _cropRight;
|
|
||||||
int _cropTop;
|
|
||||||
int _cropBottom;
|
|
||||||
int _frameDecimation;
|
int _frameDecimation;
|
||||||
int _horizontalPixelDecimation;
|
|
||||||
int _verticalPixelDecimation;
|
|
||||||
int _noSignalCounterThreshold;
|
int _noSignalCounterThreshold;
|
||||||
|
|
||||||
ColorRgb _noSignalThresholdColor;
|
ColorRgb _noSignalThresholdColor;
|
||||||
|
|
||||||
VideoMode _mode3D;
|
|
||||||
|
|
||||||
int _currentFrame;
|
int _currentFrame;
|
||||||
int _noSignalCounter;
|
int _noSignalCounter;
|
||||||
|
|
||||||
QSocketNotifier * _streamNotifier;
|
QSocketNotifier * _streamNotifier;
|
||||||
|
|
||||||
|
ImageResampler _imageResampler;
|
||||||
};
|
};
|
||||||
|
@ -18,24 +18,6 @@
|
|||||||
|
|
||||||
#define CLEAR(x) memset(&(x), 0, sizeof(x))
|
#define CLEAR(x) memset(&(x), 0, sizeof(x))
|
||||||
|
|
||||||
static inline uint8_t clamp(int x)
|
|
||||||
{
|
|
||||||
return (x<0) ? 0 : ((x>255) ? 255 : uint8_t(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t & r, uint8_t & g, uint8_t & b)
|
|
||||||
{
|
|
||||||
// see: http://en.wikipedia.org/wiki/YUV#Y.27UV444_to_RGB888_conversion
|
|
||||||
int c = y - 16;
|
|
||||||
int d = u - 128;
|
|
||||||
int e = v - 128;
|
|
||||||
|
|
||||||
r = clamp((298 * c + 409 * e + 128) >> 8);
|
|
||||||
g = clamp((298 * c - 100 * d - 208 * e + 128) >> 8);
|
|
||||||
b = clamp((298 * c + 516 * d + 128) >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
V4L2Grabber::V4L2Grabber(const std::string & device,
|
V4L2Grabber::V4L2Grabber(const std::string & device,
|
||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard,
|
VideoStandard videoStandard,
|
||||||
@ -52,21 +34,19 @@ V4L2Grabber::V4L2Grabber(const std::string & device,
|
|||||||
_pixelFormat(pixelFormat),
|
_pixelFormat(pixelFormat),
|
||||||
_width(width),
|
_width(width),
|
||||||
_height(height),
|
_height(height),
|
||||||
|
_lineLength(-1),
|
||||||
_frameByteSize(-1),
|
_frameByteSize(-1),
|
||||||
_cropLeft(0),
|
|
||||||
_cropRight(0),
|
|
||||||
_cropTop(0),
|
|
||||||
_cropBottom(0),
|
|
||||||
_frameDecimation(std::max(1, frameDecimation)),
|
_frameDecimation(std::max(1, frameDecimation)),
|
||||||
_horizontalPixelDecimation(std::max(1, horizontalPixelDecimation)),
|
|
||||||
_verticalPixelDecimation(std::max(1, verticalPixelDecimation)),
|
|
||||||
_noSignalCounterThreshold(50),
|
_noSignalCounterThreshold(50),
|
||||||
_noSignalThresholdColor(ColorRgb{0,0,0}),
|
_noSignalThresholdColor(ColorRgb{0,0,0}),
|
||||||
_mode3D(VIDEO_2D),
|
|
||||||
_currentFrame(0),
|
_currentFrame(0),
|
||||||
_noSignalCounter(0),
|
_noSignalCounter(0),
|
||||||
_streamNotifier(nullptr)
|
_streamNotifier(nullptr),
|
||||||
|
_imageResampler()
|
||||||
{
|
{
|
||||||
|
_imageResampler.setHorizontalPixelDecimation(std::max(1, horizontalPixelDecimation));
|
||||||
|
_imageResampler.setVerticalPixelDecimation(std::max(1, verticalPixelDecimation));
|
||||||
|
|
||||||
open_device();
|
open_device();
|
||||||
init_device(videoStandard, input);
|
init_device(videoStandard, input);
|
||||||
}
|
}
|
||||||
@ -81,15 +61,12 @@ V4L2Grabber::~V4L2Grabber()
|
|||||||
|
|
||||||
void V4L2Grabber::setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom)
|
void V4L2Grabber::setCropping(int cropLeft, int cropRight, int cropTop, int cropBottom)
|
||||||
{
|
{
|
||||||
_cropLeft = cropLeft;
|
_imageResampler.setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||||
_cropRight = cropRight;
|
|
||||||
_cropTop = cropTop;
|
|
||||||
_cropBottom = cropBottom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void V4L2Grabber::set3D(VideoMode mode)
|
void V4L2Grabber::set3D(VideoMode mode)
|
||||||
{
|
{
|
||||||
_mode3D = mode;
|
_imageResampler.set3D(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void V4L2Grabber::setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, int noSignalCounterThreshold)
|
void V4L2Grabber::setSignalThreshold(double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, int noSignalCounterThreshold)
|
||||||
@ -414,6 +391,9 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set the line length
|
||||||
|
_lineLength = fmt.fmt.pix.bytesperline;
|
||||||
|
|
||||||
// set the settings
|
// set the settings
|
||||||
if (-1 == xioctl(VIDIOC_S_FMT, &fmt))
|
if (-1 == xioctl(VIDIOC_S_FMT, &fmt))
|
||||||
{
|
{
|
||||||
@ -688,71 +668,8 @@ bool V4L2Grabber::process_image(const void *p, int size)
|
|||||||
|
|
||||||
void V4L2Grabber::process_image(const uint8_t * data)
|
void V4L2Grabber::process_image(const uint8_t * data)
|
||||||
{
|
{
|
||||||
int width = _width;
|
Image<ColorRgb> image(0, 0);
|
||||||
int height = _height;
|
_imageResampler.processImage(data, _width, _height, _lineLength, _pixelFormat, image);
|
||||||
|
|
||||||
switch (_mode3D)
|
|
||||||
{
|
|
||||||
case VIDEO_3DSBS:
|
|
||||||
width = _width/2;
|
|
||||||
break;
|
|
||||||
case VIDEO_3DTAB:
|
|
||||||
height = _height/2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create output structure
|
|
||||||
int outputWidth = (width - _cropLeft - _cropRight + _horizontalPixelDecimation/2) / _horizontalPixelDecimation;
|
|
||||||
int outputHeight = (height - _cropTop - _cropBottom + _verticalPixelDecimation/2) / _verticalPixelDecimation;
|
|
||||||
|
|
||||||
// TODO: should this be the following (like X11):
|
|
||||||
//int outputWidth = (width - _cropLeft - _cropRight + _horizontalPixelDecimation/2 - 1) / _horizontalPixelDecimation + 1;
|
|
||||||
//int outputHeight = (height - _cropTop - _cropBottom + _verticalPixelDecimation/2 - 1) / _verticalPixelDecimation + 1;
|
|
||||||
|
|
||||||
Image<ColorRgb> image(outputWidth, outputHeight);
|
|
||||||
|
|
||||||
for (int ySource = _cropTop + _verticalPixelDecimation/2, yDest = 0; ySource < height - _cropBottom; ySource += _verticalPixelDecimation, ++yDest)
|
|
||||||
{
|
|
||||||
for (int xSource = _cropLeft + _horizontalPixelDecimation/2, xDest = 0; xSource < width - _cropRight; xSource += _horizontalPixelDecimation, ++xDest)
|
|
||||||
{
|
|
||||||
ColorRgb & rgb = image(xDest, yDest);
|
|
||||||
|
|
||||||
switch (_pixelFormat)
|
|
||||||
{
|
|
||||||
case PIXELFORMAT_UYVY:
|
|
||||||
{
|
|
||||||
int index = (_width * ySource + xSource) * 2;
|
|
||||||
uint8_t y = data[index+1];
|
|
||||||
uint8_t u = (xSource%2 == 0) ? data[index ] : data[index-2];
|
|
||||||
uint8_t v = (xSource%2 == 0) ? data[index+2] : data[index ];
|
|
||||||
yuv2rgb(y, u, v, rgb.red, rgb.green, rgb.blue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PIXELFORMAT_YUYV:
|
|
||||||
{
|
|
||||||
int index = (_width * ySource + xSource) * 2;
|
|
||||||
uint8_t y = data[index];
|
|
||||||
uint8_t u = (xSource%2 == 0) ? data[index+1] : data[index-1];
|
|
||||||
uint8_t v = (xSource%2 == 0) ? data[index+3] : data[index+1];
|
|
||||||
yuv2rgb(y, u, v, rgb.red, rgb.green, rgb.blue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PIXELFORMAT_RGB32:
|
|
||||||
{
|
|
||||||
int index = (_width * ySource + xSource) * 4;
|
|
||||||
rgb.red = data[index ];
|
|
||||||
rgb.green = data[index+1];
|
|
||||||
rgb.blue = data[index+2];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// this should not be possible
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check signal (only in center of the resulting image, because some grabbers have noise values along the borders)
|
// check signal (only in center of the resulting image, because some grabbers have noise values along the borders)
|
||||||
bool noSignal = true;
|
bool noSignal = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user