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

Commit ca3a959

Browse files
committed
color decoding added; size decimation added
1 parent 8f7eb09 commit ca3a959

File tree

2 files changed

+90
-14
lines changed

2 files changed

+90
-14
lines changed

test/v4l2png/V4L2Grabber.cpp

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,33 @@
1919

2020
#define CLEAR(x) memset(&(x), 0, sizeof(x))
2121

22+
static inline uint8_t clamp(int x)
23+
{
24+
return (x<0) ? 0 : ((x>255) ? 255 : uint8_t(x));
25+
}
26+
27+
static void yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t & r, uint8_t & g, uint8_t & b)
28+
{
29+
// see: http://en.wikipedia.org/wiki/YUV#Y.27UV444_to_RGB888_conversion
30+
int c = y - 16;
31+
int d = u - 128;
32+
int e = v - 128;
33+
34+
r = clamp((298 * c + 409 * e + 128) >> 8);
35+
g = clamp((298 * c - 100 * d - 208 * e + 128) >> 8);
36+
b = clamp((298 * c + 516 * d + 128) >> 8);
37+
}
38+
39+
2240
V4L2Grabber::V4L2Grabber(const std::string &device, int input, VideoStandard videoStandard, int frameDecimation, int pixelDecimation) :
2341
_deviceName(device),
2442
_ioMethod(IO_METHOD_MMAP),
2543
_fileDescriptor(-1),
2644
_buffers(),
2745
_width(0),
2846
_height(0),
29-
_frameDecimation(frameDecimation),
30-
_pixelDecimation(pixelDecimation),
47+
_frameDecimation(std::max(1, frameDecimation)),
48+
_pixelDecimation(std::max(1, pixelDecimation)),
3149
_currentFrame(0)
3250
{
3351
open_device();
@@ -569,15 +587,24 @@ void V4L2Grabber::process_image(const uint8_t * data)
569587
{
570588
std::cout << "process image" << std::endl;
571589

572-
QImage image(_width, _height, QImage::Format_RGB888);
590+
int width = (_width + _pixelDecimation/2) / _pixelDecimation;
591+
int height = (_height + _pixelDecimation/2) / _pixelDecimation;
592+
593+
QImage image(width, height, QImage::Format_RGB888);
573594

574-
for (int y = 0; y < image.height(); ++y)
595+
for (int ySource = _pixelDecimation/2, yDest = 0; ySource < _height; ySource += _pixelDecimation, ++yDest)
575596
{
576-
for (int x = 0; x < image.width(); ++x)
597+
for (int xSource = _pixelDecimation/2, xDest = 0; xSource < _width; xSource += _pixelDecimation, ++xDest)
577598
{
578-
uint8_t value = data[(image.width() * y + x) * 2 + 1];
579-
//std::cout << "data = " << int(value) << std::endl;
580-
image.setPixel(x, y, qRgb(value, value, value));
599+
int index = (_width * ySource + xSource) * 2;
600+
uint8_t y = data[index+1];
601+
uint8_t u = (xSource%2 == 0) ? data[index] : data[index-2];
602+
uint8_t v = (xSource%2 == 0) ? data[index+2] : data[index];
603+
604+
uint8_t r, g, b;
605+
yuv2rgb(y, u, v, r, g, b);
606+
607+
image.setPixel(xDest, yDest, qRgb(r, g, b));
581608
}
582609
}
583610

test/v4l2png/v4l2png.cpp

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,39 @@
1313

1414
using namespace vlofgren;
1515

16+
/// Data parameter for the video standard
17+
typedef vlofgren::PODParameter<V4L2Grabber::VideoStandard> VideoStandardParameter;
18+
19+
namespace vlofgren {
20+
/// Translates a string (as passed on the commandline) to a color standard
21+
///
22+
/// @param[in] s The string (as passed on the commandline)
23+
/// @return The color standard
24+
/// @throws Parameter::ParameterRejected If the string did not result in a video standard
25+
template<>
26+
V4L2Grabber::VideoStandard VideoStandardParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
27+
{
28+
QString input = QString::fromStdString(s).toLower();
29+
30+
if (input == "pal")
31+
{
32+
return V4L2Grabber::PAL;
33+
}
34+
else if (input == "ntsc")
35+
{
36+
return V4L2Grabber::NTSC;
37+
}
38+
else if (input == "no-change")
39+
{
40+
return V4L2Grabber::NO_CHANGE;
41+
}
42+
43+
throw Parameter::ParameterRejected("Invalid value for video standard. Valid values are: PAL, NTSC, and NO-CHANGE");
44+
return V4L2Grabber::NO_CHANGE;
45+
}
46+
}
47+
48+
1649
int main(int argc, char** argv)
1750
{
1851
try
@@ -21,7 +54,17 @@ int main(int argc, char** argv)
2154
OptionsParser optionParser("Simple application to send a command to hyperion using the Json interface");
2255
ParameterSet & parameters = optionParser.getParameters();
2356

24-
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<> >('h', "help", "Show this help message and exit");
57+
StringParameter & argDevice = parameters.add<StringParameter> ('d', "device", "The device to use [default=/dev/video0]");
58+
VideoStandardParameter & argVideoStandard = parameters.add<VideoStandardParameter>('v', "video-standard", "The used video standard. Valid values are PAL. NYSC, or NO-CHANGE [default=PAL]");
59+
IntParameter & argInput = parameters.add<IntParameter> ('i', "input", "Input channel [default=0]");
60+
IntParameter & argSizeDecimation = parameters.add<IntParameter> ('s', "size-decimator", "Decimation factor for the output size [default=1]");
61+
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<> > ('h', "help", "Show this help message and exit");
62+
63+
// set defaults
64+
argDevice.setDefault("/dev/video0");
65+
argVideoStandard.setDefault(V4L2Grabber::PAL);
66+
argInput.setDefault(0);
67+
argSizeDecimation.setDefault(1);
2568

2669
// parse all options
2770
optionParser.parse(argc, const_cast<const char **>(argv));
@@ -32,6 +75,17 @@ int main(int argc, char** argv)
3275
optionParser.usage();
3376
return 0;
3477
}
78+
79+
V4L2Grabber grabber(
80+
argDevice.getValue(),
81+
argInput.getValue(),
82+
argVideoStandard.getValue(),
83+
1,
84+
argSizeDecimation.getValue());
85+
86+
grabber.start();
87+
grabber.capture(1);
88+
grabber.stop();
3589
}
3690
catch (const std::runtime_error & e)
3791
{
@@ -40,10 +94,5 @@ int main(int argc, char** argv)
4094
return 1;
4195
}
4296

43-
V4L2Grabber grabber("/dev/video0", 0, V4L2Grabber::PAL, 25, 8);
44-
grabber.start();
45-
grabber.capture(250);
46-
grabber.stop();
47-
4897
return 0;
4998
}

0 commit comments

Comments
 (0)