Skip to content
This repository was archived by the owner on May 6, 2021. It is now read-only.

Commit e7d892a

Browse files
committed
Merge branch 'add_rgb32_for_v4l2'
2 parents 83a1865 + 6a02b86 commit e7d892a

File tree

10 files changed

+166
-35
lines changed

10 files changed

+166
-35
lines changed

include/grabber/PixelFormat.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <algorithm>
5+
6+
/**
7+
* Enumeration of the possible pixel formats the grabber can be set to
8+
*/
9+
enum PixelFormat {
10+
PIXELFORMAT_YUYV,
11+
PIXELFORMAT_UYVY,
12+
PIXELFORMAT_RGB32,
13+
PIXELFORMAT_NO_CHANGE
14+
};
15+
16+
inline PixelFormat parsePixelFormat(std::string pixelFormat)
17+
{
18+
// convert to lower case
19+
std::transform(pixelFormat.begin(), pixelFormat.end(), pixelFormat.begin(), ::tolower);
20+
21+
if (pixelFormat == "yuyv")
22+
{
23+
return PIXELFORMAT_YUYV;
24+
}
25+
else if (pixelFormat == "uyvy")
26+
{
27+
return PIXELFORMAT_UYVY;
28+
}
29+
else if (pixelFormat == "rgb32")
30+
{
31+
return PIXELFORMAT_RGB32;
32+
}
33+
34+
// return the default NO_CHANGE
35+
return PIXELFORMAT_NO_CHANGE;
36+
}

include/grabber/V4L2Grabber.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
// grabber includes
1717
#include <grabber/VideoStandard.h>
18+
#include <grabber/PixelFormat.h>
1819

1920
/// Capture class for V4L2 devices
2021
///
@@ -26,7 +27,7 @@ class V4L2Grabber : public QObject
2627
public:
2728
V4L2Grabber(const std::string & device,
2829
int input,
29-
VideoStandard videoStandard,
30+
VideoStandard videoStandard, PixelFormat pixelFormat,
3031
int width,
3132
int height,
3233
int frameDecimation,
@@ -104,7 +105,7 @@ private slots:
104105
int _fileDescriptor;
105106
std::vector<buffer> _buffers;
106107

107-
uint32_t _pixelFormat;
108+
PixelFormat _pixelFormat;
108109
int _width;
109110
int _height;
110111
int _cropLeft;

include/grabber/V4L2Wrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class V4L2Wrapper : public QObject
1818
V4L2Wrapper(const std::string & device,
1919
int input,
2020
VideoStandard videoStandard,
21+
PixelFormat pixelFormat,
2122
int width,
2223
int height,
2324
int frameDecimation,

libsrc/grabber/v4l2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ SET(V4L2_QT_HEADERS
99

1010
SET(V4L2_HEADERS
1111
${CURRENT_HEADER_DIR}/VideoStandard.h
12+
${CURRENT_HEADER_DIR}/PixelFormat.h
1213
)
1314

1415
SET(V4L2_SOURCES

libsrc/grabber/v4l2/V4L2Grabber.cpp

Lines changed: 74 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ static void yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t & r, uint8_t & g, u
3939
V4L2Grabber::V4L2Grabber(const std::string & device,
4040
int input,
4141
VideoStandard videoStandard,
42+
PixelFormat pixelFormat,
4243
int width,
4344
int height,
4445
int frameDecimation,
@@ -48,7 +49,7 @@ V4L2Grabber::V4L2Grabber(const std::string & device,
4849
_ioMethod(IO_METHOD_MMAP),
4950
_fileDescriptor(-1),
5051
_buffers(),
51-
_pixelFormat(0),
52+
_pixelFormat(pixelFormat),
5253
_width(width),
5354
_height(height),
5455
_cropLeft(0),
@@ -380,17 +381,25 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input)
380381
throw_errno_exception("VIDIOC_G_FMT");
381382
}
382383

383-
// check pixel format
384-
switch (fmt.fmt.pix.pixelformat)
384+
// set the requested pixel format
385+
switch (_pixelFormat)
385386
{
386-
case V4L2_PIX_FMT_UYVY:
387-
case V4L2_PIX_FMT_YUYV:
388-
_pixelFormat = fmt.fmt.pix.pixelformat;
387+
case PIXELFORMAT_UYVY:
388+
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
389+
break;
390+
case PIXELFORMAT_YUYV:
391+
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
389392
break;
393+
case PIXELFORMAT_RGB32:
394+
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32;
395+
break;
396+
case PIXELFORMAT_NO_CHANGE:
390397
default:
391-
throw_exception("Only pixel formats UYVY and YUYV are supported");
398+
// No change to device settings
399+
break;
392400
}
393401

402+
// set the requested withd and height
394403
if (_width > 0 || _height > 0)
395404
{
396405
if (_width > 0)
@@ -402,19 +411,38 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input)
402411
{
403412
fmt.fmt.pix.height = _height;
404413
}
414+
}
405415

406-
// set the settings
407-
if (-1 == xioctl(VIDIOC_S_FMT, &fmt))
408-
{
409-
throw_errno_exception("VIDIOC_S_FMT");
410-
}
416+
// set the settings
417+
if (-1 == xioctl(VIDIOC_S_FMT, &fmt))
418+
{
419+
throw_errno_exception("VIDIOC_S_FMT");
420+
}
411421

412-
// get the format settings again
413-
// (the size may not have been accepted without an error)
414-
if (-1 == xioctl(VIDIOC_G_FMT, &fmt))
415-
{
416-
throw_errno_exception("VIDIOC_G_FMT");
417-
}
422+
// get the format settings again
423+
// (the size may not have been accepted without an error)
424+
if (-1 == xioctl(VIDIOC_G_FMT, &fmt))
425+
{
426+
throw_errno_exception("VIDIOC_G_FMT");
427+
}
428+
429+
// check pixel format
430+
switch (fmt.fmt.pix.pixelformat)
431+
{
432+
case V4L2_PIX_FMT_UYVY:
433+
_pixelFormat = PIXELFORMAT_UYVY;
434+
std::cout << "V4L2 pixel format=UYVY" << std::endl;
435+
break;
436+
case V4L2_PIX_FMT_YUYV:
437+
_pixelFormat = PIXELFORMAT_YUYV;
438+
std::cout << "V4L2 pixel format=YUYV" << std::endl;
439+
break;
440+
case V4L2_PIX_FMT_RGB32:
441+
_pixelFormat = PIXELFORMAT_RGB32;
442+
std::cout << "V4L2 pixel format=RGB32" << std::endl;
443+
break;
444+
default:
445+
throw_exception("Only pixel formats UYVY, YUYV, and RGB32 are supported");
418446
}
419447

420448
// store width & height
@@ -680,27 +708,40 @@ void V4L2Grabber::process_image(const uint8_t * data)
680708
{
681709
for (int xSource = _cropLeft + _horizontalPixelDecimation/2, xDest = 0; xSource < width - _cropRight; xSource += _horizontalPixelDecimation, ++xDest)
682710
{
683-
int index = (_width * ySource + xSource) * 2;
684-
uint8_t y = 0;
685-
uint8_t u = 0;
686-
uint8_t v = 0;
711+
ColorRgb & rgb = image(xDest, yDest);
687712

688713
switch (_pixelFormat)
689714
{
690-
case V4L2_PIX_FMT_UYVY:
691-
y = data[index+1];
692-
u = (xSource%2 == 0) ? data[index ] : data[index-2];
693-
v = (xSource%2 == 0) ? data[index+2] : data[index ];
715+
case PIXELFORMAT_UYVY:
716+
{
717+
int index = (_width * ySource + xSource) * 2;
718+
uint8_t y = data[index+1];
719+
uint8_t u = (xSource%2 == 0) ? data[index ] : data[index-2];
720+
uint8_t v = (xSource%2 == 0) ? data[index+2] : data[index ];
721+
yuv2rgb(y, u, v, rgb.red, rgb.green, rgb.blue);
722+
}
723+
break;
724+
case PIXELFORMAT_YUYV:
725+
{
726+
int index = (_width * ySource + xSource) * 2;
727+
uint8_t y = data[index];
728+
uint8_t u = (xSource%2 == 0) ? data[index+1] : data[index-1];
729+
uint8_t v = (xSource%2 == 0) ? data[index+3] : data[index+1];
730+
yuv2rgb(y, u, v, rgb.red, rgb.green, rgb.blue);
731+
}
694732
break;
695-
case V4L2_PIX_FMT_YUYV:
696-
y = data[index];
697-
u = (xSource%2 == 0) ? data[index+1] : data[index-1];
698-
v = (xSource%2 == 0) ? data[index+3] : data[index+1];
733+
case PIXELFORMAT_RGB32:
734+
{
735+
int index = (_width * ySource + xSource) * 4;
736+
rgb.red = data[index+1];
737+
rgb.green = data[index+2];
738+
rgb.blue = data[index+3];
739+
}
740+
break;
741+
default:
742+
// this should not be possible
699743
break;
700744
}
701-
702-
ColorRgb & rgb = image(xDest, yDest);
703-
yuv2rgb(y, u, v, rgb.red, rgb.green, rgb.blue);
704745
}
705746
}
706747

libsrc/grabber/v4l2/V4L2Wrapper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
V4L2Wrapper::V4L2Wrapper(const std::string &device,
88
int input,
99
VideoStandard videoStandard,
10+
PixelFormat pixelFormat,
1011
int width,
1112
int height,
1213
int frameDecimation,
@@ -21,6 +22,7 @@ V4L2Wrapper::V4L2Wrapper(const std::string &device,
2122
_grabber(device,
2223
input,
2324
videoStandard,
25+
pixelFormat,
2426
width,
2527
height,
2628
frameDecimation,

src/hyperion-v4l2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ set(Hyperion_V4L2_QT_HEADERS
2121

2222
set(Hyperion_V4L2_HEADERS
2323
VideoStandardParameter.h
24+
PixelFormatParameter.h
2425
ProtoConnection.h
2526
)
2627

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// getoptPlusPLus includes
2+
#include <getoptPlusPlus/getoptpp.h>
3+
4+
// grabber includes
5+
#include <grabber/PixelFormat.h>
6+
7+
using namespace vlofgren;
8+
9+
/// Data parameter for the pixel format
10+
typedef vlofgren::PODParameter<PixelFormat> PixelFormatParameter;
11+
12+
namespace vlofgren {
13+
/// Translates a string (as passed on the commandline) to a pixel format
14+
///
15+
/// @param[in] s The string (as passed on the commandline)
16+
/// @return The pixel format
17+
/// @throws Parameter::ParameterRejected If the string did not result in a pixel format
18+
template<>
19+
PixelFormat PixelFormatParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
20+
{
21+
QString input = QString::fromStdString(s).toLower();
22+
23+
if (input == "yuyv")
24+
{
25+
return PIXELFORMAT_YUYV;
26+
}
27+
else if (input == "uyvy")
28+
{
29+
return PIXELFORMAT_UYVY;
30+
}
31+
else if (input == "rgb32")
32+
{
33+
return PIXELFORMAT_RGB32;
34+
}
35+
else if (input == "no-change")
36+
{
37+
return PIXELFORMAT_NO_CHANGE;
38+
}
39+
40+
throw Parameter::ParameterRejected("Invalid value for pixel format. Valid values are: YUYV, UYVY, RGB32, and NO-CHANGE");
41+
return PIXELFORMAT_NO_CHANGE;
42+
}
43+
}

src/hyperion-v4l2/hyperion-v4l2.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
// hyperion-v4l2 includes
1919
#include "ProtoConnection.h"
2020
#include "VideoStandardParameter.h"
21+
#include "PixelFormatParameter.h"
2122
#include "ImageHandler.h"
2223
#include "ScreenshotHandler.h"
2324

@@ -50,6 +51,7 @@ int main(int argc, char** argv)
5051

5152
StringParameter & argDevice = parameters.add<StringParameter> ('d', "device", "The device to use [default=/dev/video0]");
5253
VideoStandardParameter & argVideoStandard = parameters.add<VideoStandardParameter>('v', "video-standard", "The used video standard. Valid values are PAL or NTSC (optional)");
54+
PixelFormatParameter & argPixelFormat = parameters.add<PixelFormatParameter> (0x0, "pixel-format", "The use pixel format. Valid values are YUYV, UYVY, and RGB32 (optional)");
5355
IntParameter & argInput = parameters.add<IntParameter> (0x0, "input", "Input channel (optional)");
5456
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "Try to set the width of the video input (optional)");
5557
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)
7678
// set defaults
7779
argDevice.setDefault("/dev/video0");
7880
argVideoStandard.setDefault(VIDEOSTANDARD_NO_CHANGE);
81+
argPixelFormat.setDefault(PIXELFORMAT_NO_CHANGE);
7982
argInput.setDefault(-1);
8083
argWidth.setDefault(-1);
8184
argHeight.setDefault(-1);
@@ -107,6 +110,7 @@ int main(int argc, char** argv)
107110
argDevice.getValue(),
108111
argInput.getValue(),
109112
argVideoStandard.getValue(),
113+
argPixelFormat.getValue(),
110114
argWidth.getValue(),
111115
argHeight.getValue(),
112116
std::max(1, argFrameDecimation.getValue()),

src/hyperiond/hyperiond.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ int main(int argc, char** argv)
180180
grabberConfig.get("device", "/dev/video0").asString(),
181181
grabberConfig.get("input", 0).asInt(),
182182
parseVideoStandard(grabberConfig.get("standard", "no-change").asString()),
183+
parsePixelFormat(grabberConfig.get("pixelFormat", "no-change").asString()),
183184
grabberConfig.get("width", -1).asInt(),
184185
grabberConfig.get("height", -1).asInt(),
185186
grabberConfig.get("frameDecimation", 2).asInt(),

0 commit comments

Comments
 (0)