mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Merge branch 'add_rgb32_for_v4l2'
Former-commit-id: e7d892ab8ab1bb3aeed6ef3238f7d999dfd19013
This commit is contained in:
commit
fbb60d2006
36
include/grabber/PixelFormat.h
Normal file
36
include/grabber/PixelFormat.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration of the possible pixel formats the grabber can be set to
|
||||||
|
*/
|
||||||
|
enum PixelFormat {
|
||||||
|
PIXELFORMAT_YUYV,
|
||||||
|
PIXELFORMAT_UYVY,
|
||||||
|
PIXELFORMAT_RGB32,
|
||||||
|
PIXELFORMAT_NO_CHANGE
|
||||||
|
};
|
||||||
|
|
||||||
|
inline PixelFormat parsePixelFormat(std::string pixelFormat)
|
||||||
|
{
|
||||||
|
// convert to lower case
|
||||||
|
std::transform(pixelFormat.begin(), pixelFormat.end(), pixelFormat.begin(), ::tolower);
|
||||||
|
|
||||||
|
if (pixelFormat == "yuyv")
|
||||||
|
{
|
||||||
|
return PIXELFORMAT_YUYV;
|
||||||
|
}
|
||||||
|
else if (pixelFormat == "uyvy")
|
||||||
|
{
|
||||||
|
return PIXELFORMAT_UYVY;
|
||||||
|
}
|
||||||
|
else if (pixelFormat == "rgb32")
|
||||||
|
{
|
||||||
|
return PIXELFORMAT_RGB32;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the default NO_CHANGE
|
||||||
|
return PIXELFORMAT_NO_CHANGE;
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
// grabber includes
|
// grabber includes
|
||||||
#include <grabber/VideoStandard.h>
|
#include <grabber/VideoStandard.h>
|
||||||
|
#include <grabber/PixelFormat.h>
|
||||||
|
|
||||||
/// Capture class for V4L2 devices
|
/// Capture class for V4L2 devices
|
||||||
///
|
///
|
||||||
@ -26,7 +27,7 @@ class V4L2Grabber : public QObject
|
|||||||
public:
|
public:
|
||||||
V4L2Grabber(const std::string & device,
|
V4L2Grabber(const std::string & device,
|
||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard,
|
VideoStandard videoStandard, PixelFormat pixelFormat,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int frameDecimation,
|
int frameDecimation,
|
||||||
@ -104,7 +105,7 @@ private:
|
|||||||
int _fileDescriptor;
|
int _fileDescriptor;
|
||||||
std::vector<buffer> _buffers;
|
std::vector<buffer> _buffers;
|
||||||
|
|
||||||
uint32_t _pixelFormat;
|
PixelFormat _pixelFormat;
|
||||||
int _width;
|
int _width;
|
||||||
int _height;
|
int _height;
|
||||||
int _cropLeft;
|
int _cropLeft;
|
||||||
|
@ -18,6 +18,7 @@ public:
|
|||||||
V4L2Wrapper(const std::string & device,
|
V4L2Wrapper(const std::string & device,
|
||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard,
|
VideoStandard videoStandard,
|
||||||
|
PixelFormat pixelFormat,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int frameDecimation,
|
int frameDecimation,
|
||||||
|
@ -9,6 +9,7 @@ SET(V4L2_QT_HEADERS
|
|||||||
|
|
||||||
SET(V4L2_HEADERS
|
SET(V4L2_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/VideoStandard.h
|
${CURRENT_HEADER_DIR}/VideoStandard.h
|
||||||
|
${CURRENT_HEADER_DIR}/PixelFormat.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(V4L2_SOURCES
|
SET(V4L2_SOURCES
|
||||||
|
@ -39,6 +39,7 @@ static void yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t & r, uint8_t & g, u
|
|||||||
V4L2Grabber::V4L2Grabber(const std::string & device,
|
V4L2Grabber::V4L2Grabber(const std::string & device,
|
||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard,
|
VideoStandard videoStandard,
|
||||||
|
PixelFormat pixelFormat,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int frameDecimation,
|
int frameDecimation,
|
||||||
@ -48,7 +49,7 @@ V4L2Grabber::V4L2Grabber(const std::string & device,
|
|||||||
_ioMethod(IO_METHOD_MMAP),
|
_ioMethod(IO_METHOD_MMAP),
|
||||||
_fileDescriptor(-1),
|
_fileDescriptor(-1),
|
||||||
_buffers(),
|
_buffers(),
|
||||||
_pixelFormat(0),
|
_pixelFormat(pixelFormat),
|
||||||
_width(width),
|
_width(width),
|
||||||
_height(height),
|
_height(height),
|
||||||
_cropLeft(0),
|
_cropLeft(0),
|
||||||
@ -380,17 +381,25 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input)
|
|||||||
throw_errno_exception("VIDIOC_G_FMT");
|
throw_errno_exception("VIDIOC_G_FMT");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check pixel format
|
// set the requested pixel format
|
||||||
switch (fmt.fmt.pix.pixelformat)
|
switch (_pixelFormat)
|
||||||
{
|
{
|
||||||
case V4L2_PIX_FMT_UYVY:
|
case PIXELFORMAT_UYVY:
|
||||||
case V4L2_PIX_FMT_YUYV:
|
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
|
||||||
_pixelFormat = fmt.fmt.pix.pixelformat;
|
|
||||||
break;
|
break;
|
||||||
|
case PIXELFORMAT_YUYV:
|
||||||
|
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
|
||||||
|
break;
|
||||||
|
case PIXELFORMAT_RGB32:
|
||||||
|
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32;
|
||||||
|
break;
|
||||||
|
case PIXELFORMAT_NO_CHANGE:
|
||||||
default:
|
default:
|
||||||
throw_exception("Only pixel formats UYVY and YUYV are supported");
|
// No change to device settings
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set the requested withd and height
|
||||||
if (_width > 0 || _height > 0)
|
if (_width > 0 || _height > 0)
|
||||||
{
|
{
|
||||||
if (_width > 0)
|
if (_width > 0)
|
||||||
@ -402,6 +411,7 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input)
|
|||||||
{
|
{
|
||||||
fmt.fmt.pix.height = _height;
|
fmt.fmt.pix.height = _height;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set the settings
|
// set the settings
|
||||||
if (-1 == xioctl(VIDIOC_S_FMT, &fmt))
|
if (-1 == xioctl(VIDIOC_S_FMT, &fmt))
|
||||||
@ -415,6 +425,24 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input)
|
|||||||
{
|
{
|
||||||
throw_errno_exception("VIDIOC_G_FMT");
|
throw_errno_exception("VIDIOC_G_FMT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check pixel format
|
||||||
|
switch (fmt.fmt.pix.pixelformat)
|
||||||
|
{
|
||||||
|
case V4L2_PIX_FMT_UYVY:
|
||||||
|
_pixelFormat = PIXELFORMAT_UYVY;
|
||||||
|
std::cout << "V4L2 pixel format=UYVY" << std::endl;
|
||||||
|
break;
|
||||||
|
case V4L2_PIX_FMT_YUYV:
|
||||||
|
_pixelFormat = PIXELFORMAT_YUYV;
|
||||||
|
std::cout << "V4L2 pixel format=YUYV" << std::endl;
|
||||||
|
break;
|
||||||
|
case V4L2_PIX_FMT_RGB32:
|
||||||
|
_pixelFormat = PIXELFORMAT_RGB32;
|
||||||
|
std::cout << "V4L2 pixel format=RGB32" << std::endl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw_exception("Only pixel formats UYVY, YUYV, and RGB32 are supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
// store width & height
|
// store width & height
|
||||||
@ -680,27 +708,40 @@ void V4L2Grabber::process_image(const uint8_t * data)
|
|||||||
{
|
{
|
||||||
for (int xSource = _cropLeft + _horizontalPixelDecimation/2, xDest = 0; xSource < width - _cropRight; xSource += _horizontalPixelDecimation, ++xDest)
|
for (int xSource = _cropLeft + _horizontalPixelDecimation/2, xDest = 0; xSource < width - _cropRight; xSource += _horizontalPixelDecimation, ++xDest)
|
||||||
{
|
{
|
||||||
int index = (_width * ySource + xSource) * 2;
|
ColorRgb & rgb = image(xDest, yDest);
|
||||||
uint8_t y = 0;
|
|
||||||
uint8_t u = 0;
|
|
||||||
uint8_t v = 0;
|
|
||||||
|
|
||||||
switch (_pixelFormat)
|
switch (_pixelFormat)
|
||||||
{
|
{
|
||||||
case V4L2_PIX_FMT_UYVY:
|
case PIXELFORMAT_UYVY:
|
||||||
y = data[index+1];
|
{
|
||||||
u = (xSource%2 == 0) ? data[index ] : data[index-2];
|
int index = (_width * ySource + xSource) * 2;
|
||||||
v = (xSource%2 == 0) ? data[index+2] : data[index ];
|
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;
|
break;
|
||||||
case V4L2_PIX_FMT_YUYV:
|
case PIXELFORMAT_YUYV:
|
||||||
y = data[index];
|
{
|
||||||
u = (xSource%2 == 0) ? data[index+1] : data[index-1];
|
int index = (_width * ySource + xSource) * 2;
|
||||||
v = (xSource%2 == 0) ? data[index+3] : data[index+1];
|
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+1];
|
||||||
|
rgb.green = data[index+2];
|
||||||
|
rgb.blue = data[index+3];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// this should not be possible
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorRgb & rgb = image(xDest, yDest);
|
|
||||||
yuv2rgb(y, u, v, rgb.red, rgb.green, rgb.blue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
V4L2Wrapper::V4L2Wrapper(const std::string &device,
|
V4L2Wrapper::V4L2Wrapper(const std::string &device,
|
||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard,
|
VideoStandard videoStandard,
|
||||||
|
PixelFormat pixelFormat,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int frameDecimation,
|
int frameDecimation,
|
||||||
@ -21,6 +22,7 @@ V4L2Wrapper::V4L2Wrapper(const std::string &device,
|
|||||||
_grabber(device,
|
_grabber(device,
|
||||||
input,
|
input,
|
||||||
videoStandard,
|
videoStandard,
|
||||||
|
pixelFormat,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
frameDecimation,
|
frameDecimation,
|
||||||
|
@ -21,6 +21,7 @@ set(Hyperion_V4L2_QT_HEADERS
|
|||||||
|
|
||||||
set(Hyperion_V4L2_HEADERS
|
set(Hyperion_V4L2_HEADERS
|
||||||
VideoStandardParameter.h
|
VideoStandardParameter.h
|
||||||
|
PixelFormatParameter.h
|
||||||
ProtoConnection.h
|
ProtoConnection.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
43
src/hyperion-v4l2/PixelFormatParameter.h
Normal file
43
src/hyperion-v4l2/PixelFormatParameter.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// getoptPlusPLus includes
|
||||||
|
#include <getoptPlusPlus/getoptpp.h>
|
||||||
|
|
||||||
|
// grabber includes
|
||||||
|
#include <grabber/PixelFormat.h>
|
||||||
|
|
||||||
|
using namespace vlofgren;
|
||||||
|
|
||||||
|
/// Data parameter for the pixel format
|
||||||
|
typedef vlofgren::PODParameter<PixelFormat> PixelFormatParameter;
|
||||||
|
|
||||||
|
namespace vlofgren {
|
||||||
|
/// Translates a string (as passed on the commandline) to a pixel format
|
||||||
|
///
|
||||||
|
/// @param[in] s The string (as passed on the commandline)
|
||||||
|
/// @return The pixel format
|
||||||
|
/// @throws Parameter::ParameterRejected If the string did not result in a pixel format
|
||||||
|
template<>
|
||||||
|
PixelFormat PixelFormatParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
|
||||||
|
{
|
||||||
|
QString input = QString::fromStdString(s).toLower();
|
||||||
|
|
||||||
|
if (input == "yuyv")
|
||||||
|
{
|
||||||
|
return PIXELFORMAT_YUYV;
|
||||||
|
}
|
||||||
|
else if (input == "uyvy")
|
||||||
|
{
|
||||||
|
return PIXELFORMAT_UYVY;
|
||||||
|
}
|
||||||
|
else if (input == "rgb32")
|
||||||
|
{
|
||||||
|
return PIXELFORMAT_RGB32;
|
||||||
|
}
|
||||||
|
else if (input == "no-change")
|
||||||
|
{
|
||||||
|
return PIXELFORMAT_NO_CHANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Parameter::ParameterRejected("Invalid value for pixel format. Valid values are: YUYV, UYVY, RGB32, and NO-CHANGE");
|
||||||
|
return PIXELFORMAT_NO_CHANGE;
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@
|
|||||||
// hyperion-v4l2 includes
|
// hyperion-v4l2 includes
|
||||||
#include "ProtoConnection.h"
|
#include "ProtoConnection.h"
|
||||||
#include "VideoStandardParameter.h"
|
#include "VideoStandardParameter.h"
|
||||||
|
#include "PixelFormatParameter.h"
|
||||||
#include "ImageHandler.h"
|
#include "ImageHandler.h"
|
||||||
#include "ScreenshotHandler.h"
|
#include "ScreenshotHandler.h"
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
StringParameter & argDevice = parameters.add<StringParameter> ('d', "device", "The device to use [default=/dev/video0]");
|
StringParameter & argDevice = parameters.add<StringParameter> ('d', "device", "The device to use [default=/dev/video0]");
|
||||||
VideoStandardParameter & argVideoStandard = parameters.add<VideoStandardParameter>('v', "video-standard", "The used video standard. Valid values are PAL or NTSC (optional)");
|
VideoStandardParameter & argVideoStandard = parameters.add<VideoStandardParameter>('v', "video-standard", "The used video standard. Valid values are PAL or NTSC (optional)");
|
||||||
|
PixelFormatParameter & argPixelFormat = parameters.add<PixelFormatParameter> (0x0, "pixel-format", "The use pixel format. Valid values are YUYV, UYVY, and RGB32 (optional)");
|
||||||
IntParameter & argInput = parameters.add<IntParameter> (0x0, "input", "Input channel (optional)");
|
IntParameter & argInput = parameters.add<IntParameter> (0x0, "input", "Input channel (optional)");
|
||||||
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "Try to set the width of the video input (optional)");
|
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "Try to set the width of the video input (optional)");
|
||||||
IntParameter & argHeight = parameters.add<IntParameter> (0x0, "height", "Try to set the height of the video input (optional)");
|
IntParameter & argHeight = parameters.add<IntParameter> (0x0, "height", "Try to set the height of the video input (optional)");
|
||||||
@ -76,6 +78,7 @@ int main(int argc, char** argv)
|
|||||||
// set defaults
|
// set defaults
|
||||||
argDevice.setDefault("/dev/video0");
|
argDevice.setDefault("/dev/video0");
|
||||||
argVideoStandard.setDefault(VIDEOSTANDARD_NO_CHANGE);
|
argVideoStandard.setDefault(VIDEOSTANDARD_NO_CHANGE);
|
||||||
|
argPixelFormat.setDefault(PIXELFORMAT_NO_CHANGE);
|
||||||
argInput.setDefault(-1);
|
argInput.setDefault(-1);
|
||||||
argWidth.setDefault(-1);
|
argWidth.setDefault(-1);
|
||||||
argHeight.setDefault(-1);
|
argHeight.setDefault(-1);
|
||||||
@ -107,6 +110,7 @@ int main(int argc, char** argv)
|
|||||||
argDevice.getValue(),
|
argDevice.getValue(),
|
||||||
argInput.getValue(),
|
argInput.getValue(),
|
||||||
argVideoStandard.getValue(),
|
argVideoStandard.getValue(),
|
||||||
|
argPixelFormat.getValue(),
|
||||||
argWidth.getValue(),
|
argWidth.getValue(),
|
||||||
argHeight.getValue(),
|
argHeight.getValue(),
|
||||||
std::max(1, argFrameDecimation.getValue()),
|
std::max(1, argFrameDecimation.getValue()),
|
||||||
|
@ -180,6 +180,7 @@ int main(int argc, char** argv)
|
|||||||
grabberConfig.get("device", "/dev/video0").asString(),
|
grabberConfig.get("device", "/dev/video0").asString(),
|
||||||
grabberConfig.get("input", 0).asInt(),
|
grabberConfig.get("input", 0).asInt(),
|
||||||
parseVideoStandard(grabberConfig.get("standard", "no-change").asString()),
|
parseVideoStandard(grabberConfig.get("standard", "no-change").asString()),
|
||||||
|
parsePixelFormat(grabberConfig.get("pixelFormat", "no-change").asString()),
|
||||||
grabberConfig.get("width", -1).asInt(),
|
grabberConfig.get("width", -1).asInt(),
|
||||||
grabberConfig.get("height", -1).asInt(),
|
grabberConfig.get("height", -1).asInt(),
|
||||||
grabberConfig.get("frameDecimation", 2).asInt(),
|
grabberConfig.get("frameDecimation", 2).asInt(),
|
||||||
|
Loading…
Reference in New Issue
Block a user