18
18
19
19
#define CLEAR (x ) memset(&(x), 0 , sizeof (x))
20
20
21
- static inline uint8_t clamp (int x)
22
- {
23
- return (x<0 ) ? 0 : ((x>255 ) ? 255 : uint8_t (x));
24
- }
25
-
26
- static void yuv2rgb (uint8_t y, uint8_t u, uint8_t v, uint8_t & r, uint8_t & g, uint8_t & b)
27
- {
28
- // see: http://en.wikipedia.org/wiki/YUV#Y.27UV444_to_RGB888_conversion
29
- int c = y - 16 ;
30
- int d = u - 128 ;
31
- int e = v - 128 ;
32
-
33
- r = clamp ((298 * c + 409 * e + 128 ) >> 8 );
34
- g = clamp ((298 * c - 100 * d - 208 * e + 128 ) >> 8 );
35
- b = clamp ((298 * c + 516 * d + 128 ) >> 8 );
36
- }
37
-
38
-
39
21
V4L2Grabber::V4L2Grabber (const std::string & device,
40
22
int input,
41
23
VideoStandard videoStandard,
@@ -52,21 +34,19 @@ V4L2Grabber::V4L2Grabber(const std::string & device,
52
34
_pixelFormat(pixelFormat),
53
35
_width(width),
54
36
_height(height),
37
+ _lineLength(-1 ),
55
38
_frameByteSize(-1 ),
56
- _cropLeft(0 ),
57
- _cropRight(0 ),
58
- _cropTop(0 ),
59
- _cropBottom(0 ),
60
39
_frameDecimation(std::max(1 , frameDecimation)),
61
- _horizontalPixelDecimation(std::max(1 , horizontalPixelDecimation)),
62
- _verticalPixelDecimation(std::max(1 , verticalPixelDecimation)),
63
40
_noSignalCounterThreshold(50 ),
64
41
_noSignalThresholdColor(ColorRgb{0 ,0 ,0 }),
65
- _mode3D(VIDEO_2D),
66
42
_currentFrame(0 ),
67
43
_noSignalCounter(0 ),
68
- _streamNotifier(nullptr )
44
+ _streamNotifier(nullptr ),
45
+ _imageResampler()
69
46
{
47
+ _imageResampler.setHorizontalPixelDecimation (std::max (1 , horizontalPixelDecimation));
48
+ _imageResampler.setVerticalPixelDecimation (std::max (1 , verticalPixelDecimation));
49
+
70
50
open_device ();
71
51
init_device (videoStandard, input);
72
52
}
@@ -81,15 +61,12 @@ V4L2Grabber::~V4L2Grabber()
81
61
82
62
void V4L2Grabber::setCropping (int cropLeft, int cropRight, int cropTop, int cropBottom)
83
63
{
84
- _cropLeft = cropLeft;
85
- _cropRight = cropRight;
86
- _cropTop = cropTop;
87
- _cropBottom = cropBottom;
64
+ _imageResampler.setCropping (cropLeft, cropRight, cropTop, cropBottom);
88
65
}
89
66
90
67
void V4L2Grabber::set3D (VideoMode mode)
91
68
{
92
- _mode3D = mode;
69
+ _imageResampler. set3D ( mode) ;
93
70
}
94
71
95
72
void V4L2Grabber::setSignalThreshold (double redSignalThreshold, double greenSignalThreshold, double blueSignalThreshold, int noSignalCounterThreshold)
@@ -414,6 +391,9 @@ void V4L2Grabber::init_device(VideoStandard videoStandard, int input)
414
391
}
415
392
}
416
393
394
+ // set the line length
395
+ _lineLength = fmt.fmt .pix .bytesperline ;
396
+
417
397
// set the settings
418
398
if (-1 == xioctl (VIDIOC_S_FMT, &fmt))
419
399
{
@@ -688,71 +668,8 @@ bool V4L2Grabber::process_image(const void *p, int size)
688
668
689
669
void V4L2Grabber::process_image (const uint8_t * data)
690
670
{
691
- int width = _width;
692
- int height = _height;
693
-
694
- switch (_mode3D)
695
- {
696
- case VIDEO_3DSBS:
697
- width = _width/2 ;
698
- break ;
699
- case VIDEO_3DTAB:
700
- height = _height/2 ;
701
- break ;
702
- default :
703
- break ;
704
- }
705
-
706
- // create output structure
707
- int outputWidth = (width - _cropLeft - _cropRight + _horizontalPixelDecimation/2 ) / _horizontalPixelDecimation;
708
- int outputHeight = (height - _cropTop - _cropBottom + _verticalPixelDecimation/2 ) / _verticalPixelDecimation;
709
-
710
- // TODO: should this be the following (like X11):
711
- // int outputWidth = (width - _cropLeft - _cropRight + _horizontalPixelDecimation/2 - 1) / _horizontalPixelDecimation + 1;
712
- // int outputHeight = (height - _cropTop - _cropBottom + _verticalPixelDecimation/2 - 1) / _verticalPixelDecimation + 1;
713
-
714
- Image<ColorRgb> image (outputWidth, outputHeight);
715
-
716
- for (int ySource = _cropTop + _verticalPixelDecimation/2 , yDest = 0 ; ySource < height - _cropBottom; ySource += _verticalPixelDecimation, ++yDest)
717
- {
718
- for (int xSource = _cropLeft + _horizontalPixelDecimation/2 , xDest = 0 ; xSource < width - _cropRight; xSource += _horizontalPixelDecimation, ++xDest)
719
- {
720
- ColorRgb & rgb = image (xDest, yDest);
721
-
722
- switch (_pixelFormat)
723
- {
724
- case PIXELFORMAT_UYVY:
725
- {
726
- int index = (_width * ySource + xSource) * 2 ;
727
- uint8_t y = data[index+1 ];
728
- uint8_t u = (xSource%2 == 0 ) ? data[index ] : data[index-2 ];
729
- uint8_t v = (xSource%2 == 0 ) ? data[index+2 ] : data[index ];
730
- yuv2rgb (y, u, v, rgb.red , rgb.green , rgb.blue );
731
- }
732
- break ;
733
- case PIXELFORMAT_YUYV:
734
- {
735
- int index = (_width * ySource + xSource) * 2 ;
736
- uint8_t y = data[index];
737
- uint8_t u = (xSource%2 == 0 ) ? data[index+1 ] : data[index-1 ];
738
- uint8_t v = (xSource%2 == 0 ) ? data[index+3 ] : data[index+1 ];
739
- yuv2rgb (y, u, v, rgb.red , rgb.green , rgb.blue );
740
- }
741
- break ;
742
- case PIXELFORMAT_RGB32:
743
- {
744
- int index = (_width * ySource + xSource) * 4 ;
745
- rgb.red = data[index ];
746
- rgb.green = data[index+1 ];
747
- rgb.blue = data[index+2 ];
748
- }
749
- break ;
750
- default :
751
- // this should not be possible
752
- break ;
753
- }
754
- }
755
- }
671
+ Image<ColorRgb> image (0 , 0 );
672
+ _imageResampler.processImage (data, _width, _height, _lineLength, _pixelFormat, image);
756
673
757
674
// check signal (only in center of the resulting image, because some grabbers have noise values along the borders)
758
675
bool noSignal = true ;
0 commit comments