use struct member width_set/height_set to replace static width/height.
[platform/upstream/opencv.git] / modules / videoio / src / cap_v4l.cpp
1 /* This is the contributed code:
2
3 File:             cvcap_v4l.cpp
4 Current Location: ../opencv-0.9.6/otherlibs/videoio
5
6 Original Version: 2003-03-12  Magnus Lundin lundin@mlu.mine.nu
7 Original Comments:
8
9 ML:This set of files adds support for firevre and usb cameras.
10 First it tries to install a firewire camera,
11 if that fails it tries a v4l/USB camera
12 It has been tested with the motempl sample program
13
14 First Patch:  August 24, 2004 Travis Wood   TravisOCV@tkwood.com
15 For Release:  OpenCV-Linux Beta4  opencv-0.9.6
16 Tested On:    LMLBT44 with 8 video inputs
17 Problems?     Post your questions at answers.opencv.org,
18               Report bugs at code.opencv.org,
19               Submit your fixes at https://github.com/opencv/opencv/
20 Patched Comments:
21
22 TW: The cv cam utils that came with the initial release of OpenCV for LINUX Beta4
23 were not working.  I have rewritten them so they work for me. At the same time, trying
24 to keep the original code as ML wrote it as unchanged as possible.  No one likes to debug
25 someone elses code, so I resisted changes as much as possible.  I have tried to keep the
26 same "ideas" where applicable, that is, where I could figure out what the previous author
27 intended. Some areas I just could not help myself and had to "spiffy-it-up" my way.
28
29 These drivers should work with other V4L frame capture cards other then my bttv
30 driven frame capture card.
31
32 Re Written driver for standard V4L mode. Tested using LMLBT44 video capture card.
33 Standard bttv drivers are on the LMLBT44 with up to 8 Inputs.
34
35 This utility was written with the help of the document:
36 http://pages.cpsc.ucalgary.ca/~sayles/VFL_HowTo
37 as a general guide for interfacing into the V4l standard.
38
39 Made the index value passed for icvOpenCAM_V4L(index) be the number of the
40 video device source in the /dev tree. The -1 uses original /dev/video.
41
42 Index  Device
43   0    /dev/video0
44   1    /dev/video1
45   2    /dev/video2
46   3    /dev/video3
47   ...
48   7    /dev/video7
49 with
50   -1   /dev/video
51
52 TW: You can select any video source, but this package was limited from the start to only
53 ONE camera opened at any ONE time.
54 This is an original program limitation.
55 If you are interested, I will make my version available to other OpenCV users.  The big
56 difference in mine is you may pass the camera number as part of the cv argument, but this
57 convention is non standard for current OpenCV calls and the camera number is not currently
58 passed into the called routine.
59
60 Second Patch:   August 28, 2004 Sfuncia Fabio fiblan@yahoo.it
61 For Release:  OpenCV-Linux Beta4 Opencv-0.9.6
62
63 FS: this patch fix not sequential index of device (unplugged device), and real numCameras.
64     for -1 index (icvOpenCAM_V4L) I don't use /dev/video but real device available, because
65     if /dev/video is a link to /dev/video0 and i unplugged device on /dev/video0, /dev/video
66     is a bad link. I search the first available device with indexList.
67
68 Third Patch:   December 9, 2004 Frederic Devernay Frederic.Devernay@inria.fr
69 For Release:  OpenCV-Linux Beta4 Opencv-0.9.6
70
71 [FD] I modified the following:
72  - handle YUV420P, YUV420, and YUV411P palettes (for many webcams) without using floating-point
73  - cvGrabFrame should not wait for the end of the first frame, and should return quickly
74    (see videoio doc)
75  - cvRetrieveFrame should in turn wait for the end of frame capture, and should not
76    trigger the capture of the next frame (the user choses when to do it using GrabFrame)
77    To get the old behavior, re-call cvRetrieveFrame just after cvGrabFrame.
78  - having global bufferIndex and FirstCapture variables makes the code non-reentrant
79  (e.g. when using several cameras), put these in the CvCapture struct.
80  - according to V4L HowTo, incrementing the buffer index must be done before VIDIOCMCAPTURE.
81  - the VID_TYPE_SCALES stuff from V4L HowTo is wrong: image size can be changed
82    even if the hardware does not support scaling (e.g. webcams can have several
83    resolutions available). Just don't try to set the size at 640x480 if the hardware supports
84    scaling: open with the default (probably best) image size, and let the user scale it
85    using SetProperty.
86  - image size can be changed by two subsequent calls to SetProperty (for width and height)
87  - bug fix: if the image size changes, realloc the new image only when it is grabbed
88  - issue errors only when necessary, fix error message formatting.
89
90 Fourth Patch: Sept 7, 2005 Csaba Kertesz sign@freemail.hu
91 For Release:  OpenCV-Linux Beta5 OpenCV-0.9.7
92
93 I modified the following:
94   - Additional Video4Linux2 support :)
95   - Use mmap functions (v4l2)
96   - New methods are internal:
97     try_palette_v4l2 -> rewrite try_palette for v4l2
98     mainloop_v4l2, read_image_v4l2 -> this methods are moved from official v4l2 capture.c example
99     try_init_v4l -> device v4l initialisation
100     try_init_v4l2 -> device v4l2 initialisation
101     autosetup_capture_mode_v4l -> autodetect capture modes for v4l
102     autosetup_capture_mode_v4l2 -> autodetect capture modes for v4l2
103   - Modifications are according with Video4Linux old codes
104   - Video4Linux handling is automatically if it does not recognize a Video4Linux2 device
105   - Tested successfully with Logitech Quickcam Express (V4L), Creative Vista (V4L) and Genius VideoCam Notebook (V4L2)
106   - Correct source lines with compiler warning messages
107   - Information message from v4l/v4l2 detection
108
109 Fifth Patch: Sept 7, 2005 Csaba Kertesz sign@freemail.hu
110 For Release:  OpenCV-Linux Beta5 OpenCV-0.9.7
111
112 I modified the following:
113   - SN9C10x chip based webcams support
114   - New methods are internal:
115     bayer2rgb24, sonix_decompress -> decoder routines for SN9C10x decoding from Takafumi Mizuno <taka-qce@ls-a.jp> with his pleasure :)
116   - Tested successfully with Genius VideoCam Notebook (V4L2)
117
118 Sixth Patch: Sept 10, 2005 Csaba Kertesz sign@freemail.hu
119 For Release:  OpenCV-Linux Beta5 OpenCV-0.9.7
120
121 I added the following:
122   - Add capture control support (hue, saturation, brightness, contrast, gain)
123   - Get and change V4L capture controls (hue, saturation, brightness, contrast)
124   - New method is internal:
125     icvSetControl -> set capture controls
126   - Tested successfully with Creative Vista (V4L)
127
128 Seventh Patch: Sept 10, 2005 Csaba Kertesz sign@freemail.hu
129 For Release:  OpenCV-Linux Beta5 OpenCV-0.9.7
130
131 I added the following:
132   - Detect, get and change V4L2 capture controls (hue, saturation, brightness, contrast, gain)
133   - New methods are internal:
134     v4l2_scan_controls_enumerate_menu, v4l2_scan_controls -> detect capture control intervals
135   - Tested successfully with Genius VideoCam Notebook (V4L2)
136
137 8th patch: Jan 5, 2006, Olivier.Bornet@idiap.ch
138 Add support of V4L2_PIX_FMT_YUYV and V4L2_PIX_FMT_MJPEG.
139 With this patch, new webcams of Logitech, like QuickCam Fusion works.
140 Note: For use these webcams, look at the UVC driver at
141 http://linux-uvc.berlios.de/
142
143 9th patch: Mar 4, 2006, Olivier.Bornet@idiap.ch
144 - try V4L2 before V4L, because some devices are V4L2 by default,
145   but they try to implement the V4L compatibility layer.
146   So, I think this is better to support V4L2 before V4L.
147 - better separation between V4L2 and V4L initialization. (this was needed to support
148   some drivers working, but not fully with V4L2. (so, we do not know when we
149   need to switch from V4L2 to V4L.
150
151 10th patch: July 02, 2008, Mikhail Afanasyev fopencv@theamk.com
152 Fix reliability problems with high-resolution UVC cameras on linux
153 the symptoms were damaged image and 'Corrupt JPEG data: premature end of data segment' on stderr
154 - V4L_ABORT_BADJPEG detects JPEG warnings and turns them into errors, so bad images
155   could be filtered out
156 - USE_TEMP_BUFFER fixes the main problem (improper buffer management) and
157   prevents bad images in the first place
158
159 11th patch: April 2, 2013, Forrest Reiling forrest.reiling@gmail.com
160 Added v4l2 support for getting capture property CV_CAP_PROP_POS_MSEC.
161 Returns the millisecond timestamp of the last frame grabbed or 0 if no frames have been grabbed
162 Used to successfully synchronize 2 Logitech C310 USB webcams to within 16 ms of one another
163
164 12th patch: March 9, 2018, Taylor Lanclos <tlanclos@live.com>
165  added support for CV_CAP_PROP_BUFFERSIZE
166
167 make & enjoy!
168
169 */
170
171 /*M///////////////////////////////////////////////////////////////////////////////////////
172 //
173 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
174 //
175 //  By downloading, copying, installing or using the software you agree to this license.
176 //  If you do not agree to this license, do not download, install,
177 //  copy or use the software.
178 //
179 //
180 //                        Intel License Agreement
181 //                For Open Source Computer Vision Library
182 //
183 // Copyright (C) 2000, Intel Corporation, all rights reserved.
184 // Third party copyrights are property of their respective owners.
185 //
186 // Redistribution and use in source and binary forms, with or without modification,
187 // are permitted provided that the following conditions are met:
188 //
189 //   * Redistribution's of source code must retain the above copyright notice,
190 //     this list of conditions and the following disclaimer.
191 //
192 //   * Redistribution's in binary form must reproduce the above copyright notice,
193 //     this list of conditions and the following disclaimer in the documentation
194 //     and/or other materials provided with the distribution.
195 //
196 //   * The name of Intel Corporation may not be used to endorse or promote products
197 //     derived from this software without specific prior written permission.
198 //
199 // This software is provided by the copyright holders and contributors "as is" and
200 // any express or implied warranties, including, but not limited to, the implied
201 // warranties of merchantability and fitness for a particular purpose are disclaimed.
202 // In no event shall the Intel Corporation or contributors be liable for any direct,
203 // indirect, incidental, special, exemplary, or consequential damages
204 // (including, but not limited to, procurement of substitute goods or services;
205 // loss of use, data, or profits; or business interruption) however caused
206 // and on any theory of liability, whether in contract, strict liability,
207 // or tort (including negligence or otherwise) arising in any way out of
208 // the use of this software, even if advised of the possibility of such damage.
209 //
210 //M*/
211
212 #include "precomp.hpp"
213
214 #if !defined _WIN32 && (defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO)
215
216 #include <stdio.h>
217 #include <unistd.h>
218 #include <fcntl.h>
219 #include <errno.h>
220 #include <sys/ioctl.h>
221 #include <sys/types.h>
222 #include <sys/mman.h>
223
224 #include <string.h>
225 #include <stdlib.h>
226 #include <assert.h>
227 #include <sys/stat.h>
228 #include <sys/ioctl.h>
229
230 #ifdef HAVE_CAMV4L2
231 #include <asm/types.h>          /* for videodev2.h */
232 #include <linux/videodev2.h>
233 #endif
234
235 #ifdef HAVE_VIDEOIO
236 // NetBSD compatibility layer with V4L2
237 #include <sys/videoio.h>
238 #endif
239
240 /* Defaults - If your board can do better, set it here.  Set for the most common type inputs. */
241 #define DEFAULT_V4L_WIDTH  640
242 #define DEFAULT_V4L_HEIGHT 480
243 #define DEFAULT_V4L_FPS 30
244
245 #define CHANNEL_NUMBER 1
246 #define MAX_CAMERAS 8
247
248
249 // default and maximum number of V4L buffers, not including last, 'special' buffer
250 #define MAX_V4L_BUFFERS 10
251 #define DEFAULT_V4L_BUFFERS 4
252
253 // if enabled, then bad JPEG warnings become errors and cause NULL returned instead of image
254 #define V4L_ABORT_BADJPEG
255
256 #define MAX_DEVICE_DRIVER_NAME 80
257
258 namespace cv {
259
260 /* Device Capture Objects */
261 /* V4L2 structure */
262 struct buffer
263 {
264     void *  start;
265     size_t  length;
266 };
267
268 struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
269 {
270     int deviceHandle;
271     int bufferIndex;
272     int FirstCapture;
273     String deviceName;
274
275     char *memoryMap;
276     IplImage frame;
277
278     __u32 palette;
279     int width, height;
280     int width_set, height_set;
281     int bufferSize;
282     __u32 fps;
283     bool convert_rgb;
284     bool frame_allocated;
285     bool returnFrame;
286
287     /* V4L2 variables */
288     buffer buffers[MAX_V4L_BUFFERS + 1];
289     v4l2_capability cap;
290     v4l2_input inp;
291     v4l2_format form;
292     v4l2_crop crop;
293     v4l2_cropcap cropcap;
294     v4l2_requestbuffers req;
295     v4l2_buf_type type;
296     v4l2_queryctrl queryctrl;
297
298     timeval timestamp;
299
300     /* V4L2 control variables */
301     Range focus, brightness, contrast, saturation, hue, gain, exposure;
302
303     bool open(int _index);
304     bool open(const char* deviceName);
305
306     virtual double getProperty(int) const CV_OVERRIDE;
307     virtual bool setProperty(int, double) CV_OVERRIDE;
308     virtual bool grabFrame() CV_OVERRIDE;
309     virtual IplImage* retrieveFrame(int) CV_OVERRIDE;
310
311     Range getRange(int property_id) const {
312         switch (property_id) {
313         case CV_CAP_PROP_BRIGHTNESS:
314             return brightness;
315         case CV_CAP_PROP_CONTRAST:
316             return contrast;
317         case CV_CAP_PROP_SATURATION:
318             return saturation;
319         case CV_CAP_PROP_HUE:
320             return hue;
321         case CV_CAP_PROP_GAIN:
322             return gain;
323         case CV_CAP_PROP_EXPOSURE:
324             return exposure;
325         case CV_CAP_PROP_FOCUS:
326             return focus;
327         case CV_CAP_PROP_AUTOFOCUS:
328             return Range(0, 1);
329         case CV_CAP_PROP_AUTO_EXPOSURE:
330             return Range(0, 4);
331         default:
332             return Range(0, 255);
333         }
334     }
335
336     virtual ~CvCaptureCAM_V4L();
337 };
338
339 static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture );
340
341 static bool icvGrabFrameCAM_V4L( CvCaptureCAM_V4L* capture );
342 static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int );
343
344 static double icvGetPropertyCAM_V4L( const CvCaptureCAM_V4L* capture, int property_id );
345 static int    icvSetPropertyCAM_V4L( CvCaptureCAM_V4L* capture, int property_id, double value );
346
347 /***********************   Implementations  ***************************************/
348
349 CvCaptureCAM_V4L::~CvCaptureCAM_V4L() {
350     icvCloseCAM_V4L(this);
351 }
352
353 static bool try_palette_v4l2(CvCaptureCAM_V4L* capture)
354 {
355     capture->form = v4l2_format();
356     capture->form.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
357     capture->form.fmt.pix.pixelformat = capture->palette;
358     capture->form.fmt.pix.field       = V4L2_FIELD_ANY;
359     capture->form.fmt.pix.width       = capture->width;
360     capture->form.fmt.pix.height      = capture->height;
361
362     if (-1 == ioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form))
363         return false;
364
365     return capture->palette == capture->form.fmt.pix.pixelformat;
366 }
367
368 static int try_init_v4l2(CvCaptureCAM_V4L* capture, const char *deviceName)
369 {
370     // Test device for V4L2 compatibility
371     // Return value:
372     // -1 then unable to open device
373     //  0 then detected nothing
374     //  1 then V4L2 device
375
376     int deviceIndex;
377
378     /* Open and test V4L2 device */
379     capture->deviceHandle = open (deviceName, O_RDWR /* required */ | O_NONBLOCK, 0);
380     if (-1 == capture->deviceHandle)
381     {
382 #ifndef NDEBUG
383         fprintf(stderr, "(DEBUG) try_init_v4l2 open \"%s\": %s\n", deviceName, strerror(errno));
384 #endif
385         icvCloseCAM_V4L(capture);
386         return -1;
387     }
388
389     capture->cap = v4l2_capability();
390     if (-1 == ioctl (capture->deviceHandle, VIDIOC_QUERYCAP, &capture->cap))
391     {
392 #ifndef NDEBUG
393         fprintf(stderr, "(DEBUG) try_init_v4l2 VIDIOC_QUERYCAP \"%s\": %s\n", deviceName, strerror(errno));
394 #endif
395         icvCloseCAM_V4L(capture);
396         return 0;
397     }
398
399     /* Query channels number */
400     if (-1 == ioctl (capture->deviceHandle, VIDIOC_G_INPUT, &deviceIndex))
401     {
402 #ifndef NDEBUG
403         fprintf(stderr, "(DEBUG) try_init_v4l2 VIDIOC_G_INPUT \"%s\": %s\n", deviceName, strerror(errno));
404 #endif
405         icvCloseCAM_V4L(capture);
406         return 0;
407     }
408
409     /* Query information about current input */
410     capture->inp = v4l2_input();
411     capture->inp.index = deviceIndex;
412     if (-1 == ioctl (capture->deviceHandle, VIDIOC_ENUMINPUT, &capture->inp))
413     {
414 #ifndef NDEBUG
415         fprintf(stderr, "(DEBUG) try_init_v4l2 VIDIOC_ENUMINPUT \"%s\": %s\n", deviceName, strerror(errno));
416 #endif
417         icvCloseCAM_V4L(capture);
418         return 0;
419     }
420
421     return 1;
422
423 }
424
425 static int autosetup_capture_mode_v4l2(CvCaptureCAM_V4L* capture) {
426     //in case palette is already set and works, no need to setup.
427     if(capture->palette != 0 and try_palette_v4l2(capture)){
428         return 0;
429     }
430     __u32 try_order[] = {
431             V4L2_PIX_FMT_BGR24,
432             V4L2_PIX_FMT_RGB24,
433             V4L2_PIX_FMT_YVU420,
434             V4L2_PIX_FMT_YUV411P,
435             V4L2_PIX_FMT_YUYV,
436             V4L2_PIX_FMT_UYVY,
437             V4L2_PIX_FMT_SBGGR8,
438             V4L2_PIX_FMT_SGBRG8,
439             V4L2_PIX_FMT_SN9C10X,
440 #ifdef HAVE_JPEG
441             V4L2_PIX_FMT_MJPEG,
442             V4L2_PIX_FMT_JPEG,
443 #endif
444             V4L2_PIX_FMT_Y16
445     };
446
447     for (size_t i = 0; i < sizeof(try_order) / sizeof(__u32); i++) {
448         capture->palette = try_order[i];
449         if (try_palette_v4l2(capture)) {
450             return 0;
451         }
452     }
453
454     fprintf(stderr,
455             "VIDEOIO ERROR: V4L2: Pixel format of incoming image is unsupported by OpenCV\n");
456     icvCloseCAM_V4L(capture);
457     return -1;
458 }
459
460 static void v4l2_control_range(CvCaptureCAM_V4L* cap, __u32 id)
461 {
462     cap->queryctrl= v4l2_queryctrl();
463     cap->queryctrl.id = id;
464
465     if(0 != ioctl(cap->deviceHandle, VIDIOC_QUERYCTRL, &cap->queryctrl))
466     {
467         if (errno != EINVAL)
468             perror ("VIDIOC_QUERYCTRL");
469         return;
470     }
471
472     if (cap->queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
473         return;
474
475     Range range(cap->queryctrl.minimum, cap->queryctrl.maximum);
476
477     switch(cap->queryctrl.id) {
478     case V4L2_CID_BRIGHTNESS:
479         cap->brightness = range;
480         break;
481     case V4L2_CID_CONTRAST:
482         cap->contrast = range;
483         break;
484     case V4L2_CID_SATURATION:
485         cap->saturation = range;
486         break;
487     case V4L2_CID_HUE:
488         cap->hue = range;
489         break;
490     case V4L2_CID_GAIN:
491         cap->gain = range;
492         break;
493     case V4L2_CID_EXPOSURE_ABSOLUTE:
494         cap->exposure = range;
495         break;
496     case V4L2_CID_FOCUS_ABSOLUTE:
497         cap->focus = range;
498         break;
499     }
500 }
501
502 static void v4l2_scan_controls(CvCaptureCAM_V4L* capture)
503 {
504
505     __u32 ctrl_id;
506
507     for (ctrl_id = V4L2_CID_BASE; ctrl_id < V4L2_CID_LASTP1; ctrl_id++)
508     {
509         v4l2_control_range(capture, ctrl_id);
510     }
511
512     for (ctrl_id = V4L2_CID_PRIVATE_BASE;;ctrl_id++)
513     {
514         v4l2_control_range(capture, ctrl_id);
515
516         if (errno == EINVAL)
517             break;
518     }
519
520     v4l2_control_range(capture, V4L2_CID_FOCUS_ABSOLUTE);
521 }
522
523 static int v4l2_set_fps(CvCaptureCAM_V4L* capture) {
524     v4l2_streamparm setfps = v4l2_streamparm();
525     setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
526     setfps.parm.capture.timeperframe.numerator = 1;
527     setfps.parm.capture.timeperframe.denominator = capture->fps;
528     return ioctl (capture->deviceHandle, VIDIOC_S_PARM, &setfps);
529 }
530
531 static int v4l2_num_channels(__u32 palette) {
532     switch(palette) {
533     case V4L2_PIX_FMT_YVU420:
534     case V4L2_PIX_FMT_MJPEG:
535     case V4L2_PIX_FMT_JPEG:
536     case V4L2_PIX_FMT_Y16:
537         return 1;
538     case V4L2_PIX_FMT_YUYV:
539     case V4L2_PIX_FMT_UYVY:
540         return 2;
541     case V4L2_PIX_FMT_BGR24:
542     case V4L2_PIX_FMT_RGB24:
543         return 3;
544     default:
545         return 0;
546     }
547 }
548
549 static void v4l2_create_frame(CvCaptureCAM_V4L *capture) {
550     CvSize size(capture->form.fmt.pix.width, capture->form.fmt.pix.height);
551     int channels = 3;
552     int depth = IPL_DEPTH_8U;
553
554     if (!capture->convert_rgb) {
555         channels = v4l2_num_channels(capture->palette);
556
557         switch(capture->palette) {
558         case V4L2_PIX_FMT_MJPEG:
559         case V4L2_PIX_FMT_JPEG:
560             size = CvSize(capture->buffers[capture->bufferIndex].length, 1);
561             break;
562         case V4L2_PIX_FMT_YVU420:
563             size.height = size.height * 3 / 2; // "1.5" channels
564             break;
565         case V4L2_PIX_FMT_Y16:
566             if(!capture->convert_rgb){
567                 depth = IPL_DEPTH_16U;
568             }
569             break;
570         }
571     }
572
573     /* Set up Image data */
574     cvInitImageHeader(&capture->frame, size, depth, channels);
575
576     /* Allocate space for pixelformat we convert to.
577      * If we do not convert frame is just points to the buffer
578      */
579     if(capture->convert_rgb) {
580         capture->frame.imageData = (char*)cvAlloc(capture->frame.imageSize);
581     }
582
583     capture->frame_allocated = capture->convert_rgb;
584 }
585
586 static int _capture_V4L2 (CvCaptureCAM_V4L *capture)
587 {
588     const char* deviceName = capture->deviceName.c_str();
589     if (try_init_v4l2(capture, deviceName) != 1) {
590         /* init of the v4l2 device is not OK */
591         return -1;
592     }
593
594     /* V4L2 control variables are zero (memset above) */
595
596     /* Scan V4L2 controls */
597     v4l2_scan_controls(capture);
598
599     if ((capture->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
600         /* Nope. */
601         fprintf( stderr, "VIDEOIO ERROR: V4L2: device %s is unable to capture video memory.\n",deviceName);
602         icvCloseCAM_V4L(capture);
603         return -1;
604     }
605
606     /* The following code sets the CHANNEL_NUMBER of the video input.  Some video sources
607     have sub "Channel Numbers".  For a typical V4L TV capture card, this is usually 1.
608     I myself am using a simple NTSC video input capture card that uses the value of 1.
609     If you are not in North America or have a different video standard, you WILL have to change
610     the following settings and recompile/reinstall.  This set of settings is based on
611     the most commonly encountered input video source types (like my bttv card) */
612
613     if(capture->inp.index > 0) {
614         capture->inp = v4l2_input();
615         capture->inp.index = CHANNEL_NUMBER;
616         /* Set only channel number to CHANNEL_NUMBER */
617         /* V4L2 have a status field from selected video mode */
618         if (-1 == ioctl (capture->deviceHandle, VIDIOC_ENUMINPUT, &capture->inp))
619         {
620             fprintf (stderr, "VIDEOIO ERROR: V4L2: Aren't able to set channel number\n");
621             icvCloseCAM_V4L (capture);
622             return -1;
623         }
624     } /* End if */
625
626     /* Find Window info */
627     capture->form = v4l2_format();
628     capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
629
630     if (-1 == ioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) {
631         fprintf( stderr, "VIDEOIO ERROR: V4L2: Could not obtain specifics of capture window.\n\n");
632         icvCloseCAM_V4L(capture);
633         return -1;
634     }
635
636     if (autosetup_capture_mode_v4l2(capture) == -1)
637         return -1;
638
639     /* try to set framerate */
640     v4l2_set_fps(capture);
641
642     unsigned int min;
643
644     /* Buggy driver paranoia. */
645     min = capture->form.fmt.pix.width * 2;
646
647     if (capture->form.fmt.pix.bytesperline < min)
648         capture->form.fmt.pix.bytesperline = min;
649
650     min = capture->form.fmt.pix.bytesperline * capture->form.fmt.pix.height;
651
652     if (capture->form.fmt.pix.sizeimage < min)
653         capture->form.fmt.pix.sizeimage = min;
654
655     capture->req = v4l2_requestbuffers();
656
657     unsigned int buffer_number = capture->bufferSize;
658
659 try_again:
660
661     capture->req.count = buffer_number;
662     capture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
663     capture->req.memory = V4L2_MEMORY_MMAP;
664
665     if (-1 == ioctl (capture->deviceHandle, VIDIOC_REQBUFS, &capture->req))
666     {
667         if (EINVAL == errno)
668         {
669             fprintf (stderr, "%s does not support memory mapping\n", deviceName);
670         } else {
671             perror ("VIDIOC_REQBUFS");
672         }
673         /* free capture, and returns an error code */
674         icvCloseCAM_V4L (capture);
675         return -1;
676     }
677
678     if (capture->req.count < buffer_number)
679     {
680         if (buffer_number == 1)
681         {
682             fprintf (stderr, "Insufficient buffer memory on %s\n", deviceName);
683
684             /* free capture, and returns an error code */
685             icvCloseCAM_V4L (capture);
686             return -1;
687         } else {
688             buffer_number--;
689             fprintf (stderr, "Insufficient buffer memory on %s -- decreaseing buffers\n", deviceName);
690
691             goto try_again;
692         }
693     }
694
695     for (unsigned int n_buffers = 0; n_buffers < capture->req.count; ++n_buffers)
696     {
697         v4l2_buffer buf = v4l2_buffer();
698         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
699         buf.memory = V4L2_MEMORY_MMAP;
700         buf.index = n_buffers;
701
702         if (-1 == ioctl (capture->deviceHandle, VIDIOC_QUERYBUF, &buf)) {
703             perror ("VIDIOC_QUERYBUF");
704
705             /* free capture, and returns an error code */
706             icvCloseCAM_V4L (capture);
707             return -1;
708         }
709
710         capture->buffers[n_buffers].length = buf.length;
711         capture->buffers[n_buffers].start =
712                 mmap (NULL /* start anywhere */,
713                         buf.length,
714                         PROT_READ | PROT_WRITE /* required */,
715                         MAP_SHARED /* recommended */,
716                         capture->deviceHandle, buf.m.offset);
717
718         if (MAP_FAILED == capture->buffers[n_buffers].start) {
719             perror ("mmap");
720
721             /* free capture, and returns an error code */
722             icvCloseCAM_V4L (capture);
723             return -1;
724         }
725
726         if (n_buffers == 0) {
727             capture->buffers[MAX_V4L_BUFFERS].start = malloc( buf.length );
728             capture->buffers[MAX_V4L_BUFFERS].length = buf.length;
729         }
730     }
731
732     v4l2_create_frame(capture);
733
734     // reinitialize buffers
735     capture->FirstCapture = 1;
736
737     return 1;
738 }; /* End _capture_V4L2 */
739
740 /**
741  * some properties can not be changed while the device is in streaming mode.
742  * this method closes and re-opens the device to re-start the stream.
743  * this also causes buffers to be reallocated if the frame size was changed.
744  */
745 static bool v4l2_reset( CvCaptureCAM_V4L* capture) {
746     String deviceName = capture->deviceName;
747     icvCloseCAM_V4L(capture);
748     capture->deviceName = deviceName;
749     return _capture_V4L2(capture) == 1;
750 }
751
752 bool CvCaptureCAM_V4L::open(int _index)
753 {
754     cv::String name;
755     /* Select camera, or rather, V4L video source */
756     if (_index < 0) // Asking for the first device available
757     {
758         for (int autoindex = 0; autoindex < MAX_CAMERAS; ++autoindex)
759         {
760             name = cv::format("/dev/video%d", autoindex);
761             /* Test using an open to see if this new device name really does exists. */
762             int h = ::open(name.c_str(), O_RDONLY);
763             if (h != -1)
764             {
765                 ::close(h);
766                 _index = autoindex;
767                 break;
768             }
769         }
770         if (_index < 0)
771         {
772             fprintf(stderr, "VIDEOIO ERROR: V4L: can't find camera device\n");
773             name.clear();
774             return false;
775         }
776     }
777     else
778     {
779         name = cv::format("/dev/video%d", _index);
780     }
781
782     /* Print the CameraNumber at the end of the string with a width of one character */
783     bool res = open(name.c_str());
784     if (!res)
785     {
786         fprintf(stderr, "VIDEOIO ERROR: V4L: can't open camera by index %d\n", _index);
787     }
788     return res;
789 }
790
791 bool CvCaptureCAM_V4L::open(const char* _deviceName)
792 {
793 #ifndef NDEBUG
794     fprintf(stderr, "(DEBUG) V4L: opening %s\n", _deviceName);
795 #endif
796     FirstCapture = 1;
797     width = DEFAULT_V4L_WIDTH;
798     height = DEFAULT_V4L_HEIGHT;
799     width_set = height_set = 0;
800     bufferSize = DEFAULT_V4L_BUFFERS;
801     fps = DEFAULT_V4L_FPS;
802     convert_rgb = true;
803     deviceName = _deviceName;
804     returnFrame = true;
805
806     return _capture_V4L2(this) == 1;
807 }
808
809 static int read_frame_v4l2(CvCaptureCAM_V4L* capture) {
810     v4l2_buffer buf = v4l2_buffer();
811
812     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
813     buf.memory = V4L2_MEMORY_MMAP;
814
815     if (-1 == ioctl (capture->deviceHandle, VIDIOC_DQBUF, &buf)) {
816         switch (errno) {
817         case EAGAIN:
818             return 0;
819
820         case EIO:
821             if (!(buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)))
822             {
823                 if (ioctl(capture->deviceHandle, VIDIOC_QBUF, &buf) == -1)
824                 {
825                     return 0;
826                 }
827             }
828             return 0;
829
830         default:
831             /* display the error and stop processing */
832             capture->returnFrame = false;
833             perror ("VIDIOC_DQBUF");
834             return -1;
835         }
836     }
837
838     assert(buf.index < capture->req.count);
839
840     memcpy(capture->buffers[MAX_V4L_BUFFERS].start,
841             capture->buffers[buf.index].start,
842             capture->buffers[MAX_V4L_BUFFERS].length );
843     capture->bufferIndex = MAX_V4L_BUFFERS;
844     //printf("got data in buff %d, len=%d, flags=0x%X, seq=%d, used=%d)\n",
845     //    buf.index, buf.length, buf.flags, buf.sequence, buf.bytesused);
846
847     //set timestamp in capture struct to be timestamp of most recent frame
848     capture->timestamp = buf.timestamp;
849
850     if (-1 == ioctl (capture->deviceHandle, VIDIOC_QBUF, &buf))
851         perror ("VIDIOC_QBUF");
852
853     return 1;
854 }
855
856 static int mainloop_v4l2(CvCaptureCAM_V4L* capture) {
857     unsigned int count;
858
859     count = 1;
860
861     while (count-- > 0) {
862         for (;;) {
863             fd_set fds;
864             struct timeval tv;
865             int r;
866
867             FD_ZERO (&fds);
868             FD_SET (capture->deviceHandle, &fds);
869
870             /* Timeout. */
871             tv.tv_sec = 10;
872             tv.tv_usec = 0;
873
874             r = select (capture->deviceHandle+1, &fds, NULL, NULL, &tv);
875
876             if (-1 == r) {
877                 if (EINTR == errno)
878                     continue;
879
880                 perror ("select");
881             }
882
883             if (0 == r) {
884                 fprintf (stderr, "select timeout\n");
885
886                 /* end the infinite loop */
887                 break;
888             }
889
890             int returnCode = read_frame_v4l2 (capture);
891             if(returnCode == -1)
892                 return -1;
893             if(returnCode == 1)
894                 return 1;
895         }
896     }
897     return 0;
898 }
899
900 static bool icvGrabFrameCAM_V4L(CvCaptureCAM_V4L* capture) {
901     if (capture->FirstCapture) {
902         /* Some general initialization must take place the first time through */
903
904         /* This is just a technicality, but all buffers must be filled up before any
905          staggered SYNC is applied.  SO, filler up. (see V4L HowTo) */
906
907         {
908
909             for (capture->bufferIndex = 0;
910                     capture->bufferIndex < ((int)capture->req.count);
911                     ++capture->bufferIndex)
912             {
913
914                 v4l2_buffer buf = v4l2_buffer();
915
916                 buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
917                 buf.memory      = V4L2_MEMORY_MMAP;
918                 buf.index       = (unsigned long)capture->bufferIndex;
919
920                 if (-1 == ioctl (capture->deviceHandle, VIDIOC_QBUF, &buf)) {
921                     perror ("VIDIOC_QBUF");
922                     return false;
923                 }
924             }
925
926             /* enable the streaming */
927             capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
928             if (-1 == ioctl (capture->deviceHandle, VIDIOC_STREAMON,
929                     &capture->type)) {
930                 /* error enabling the stream */
931                 perror ("VIDIOC_STREAMON");
932                 return false;
933             }
934         }
935
936 #if defined(V4L_ABORT_BADJPEG)
937         // skip first frame. it is often bad -- this is unnotied in traditional apps,
938         //  but could be fatal if bad jpeg is enabled
939         if(mainloop_v4l2(capture) != 1)
940             return false;
941 #endif
942
943         /* preparation is ok */
944         capture->FirstCapture = 0;
945     }
946
947     if(mainloop_v4l2(capture) != 1) return false;
948
949     return true;
950 }
951
952 /*
953  * Turn a YUV4:2:0 block into an RGB block
954  *
955  * Video4Linux seems to use the blue, green, red channel
956  * order convention-- rgb[0] is blue, rgb[1] is green, rgb[2] is red.
957  *
958  * Color space conversion coefficients taken from the excellent
959  * http://www.inforamp.net/~poynton/ColorFAQ.html
960  * In his terminology, this is a CCIR 601.1 YCbCr -> RGB.
961  * Y values are given for all 4 pixels, but the U (Pb)
962  * and V (Pr) are assumed constant over the 2x2 block.
963  *
964  * To avoid floating point arithmetic, the color conversion
965  * coefficients are scaled into 16.16 fixed-point integers.
966  * They were determined as follows:
967  *
968  *  double brightness = 1.0;  (0->black; 1->full scale)
969  *  double saturation = 1.0;  (0->greyscale; 1->full color)
970  *  double fixScale = brightness * 256 * 256;
971  *  int rvScale = (int)(1.402 * saturation * fixScale);
972  *  int guScale = (int)(-0.344136 * saturation * fixScale);
973  *  int gvScale = (int)(-0.714136 * saturation * fixScale);
974  *  int buScale = (int)(1.772 * saturation * fixScale);
975  *  int yScale = (int)(fixScale);
976  */
977
978 /* LIMIT: convert a 16.16 fixed-point value to a byte, with clipping. */
979 #define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))
980
981 static inline void
982 move_411_block(int yTL, int yTR, int yBL, int yBR, int u, int v,
983         int /*rowPixels*/, unsigned char * rgb)
984 {
985     const int rvScale = 91881;
986     const int guScale = -22553;
987     const int gvScale = -46801;
988     const int buScale = 116129;
989     const int yScale  = 65536;
990     int r, g, b;
991
992     g = guScale * u + gvScale * v;
993     //  if (force_rgb) {
994     //      r = buScale * u;
995     //      b = rvScale * v;
996     //  } else {
997     r = rvScale * v;
998     b = buScale * u;
999     //  }
1000
1001     yTL *= yScale; yTR *= yScale;
1002     yBL *= yScale; yBR *= yScale;
1003
1004     /* Write out top two first pixels */
1005     rgb[0] = LIMIT(b+yTL); rgb[1] = LIMIT(g+yTL);
1006     rgb[2] = LIMIT(r+yTL);
1007
1008     rgb[3] = LIMIT(b+yTR); rgb[4] = LIMIT(g+yTR);
1009     rgb[5] = LIMIT(r+yTR);
1010
1011     /* Write out top two last pixels */
1012     rgb += 6;
1013     rgb[0] = LIMIT(b+yBL); rgb[1] = LIMIT(g+yBL);
1014     rgb[2] = LIMIT(r+yBL);
1015
1016     rgb[3] = LIMIT(b+yBR); rgb[4] = LIMIT(g+yBR);
1017     rgb[5] = LIMIT(r+yBR);
1018 }
1019
1020 /* Converts from planar YUV420P to RGB24. */
1021 static inline void
1022 yuv420p_to_rgb24(int width, int height, uchar* src, uchar* dst)
1023 {
1024     cvtColor(Mat(height * 3 / 2, width, CV_8U, src), Mat(height, width, CV_8UC3, dst),
1025             COLOR_YUV2BGR_YV12);
1026 }
1027
1028 // Consider a YUV411P image of 8x2 pixels.
1029 //
1030 // A plane of Y values as before.
1031 //
1032 // A plane of U values    1       2
1033 //                        3       4
1034 //
1035 // A plane of V values    1       2
1036 //                        3       4
1037 //
1038 // The U1/V1 samples correspond to the ABCD pixels.
1039 //     U2/V2 samples correspond to the EFGH pixels.
1040 //
1041 /* Converts from planar YUV411P to RGB24. */
1042 /* [FD] untested... */
1043 static void
1044 yuv411p_to_rgb24(int width, int height,
1045         unsigned char *pIn0, unsigned char *pOut0)
1046 {
1047     const int numpix = width * height;
1048     const int bytes = 24 >> 3;
1049     int i, j, y00, y01, y10, y11, u, v;
1050     unsigned char *pY = pIn0;
1051     unsigned char *pU = pY + numpix;
1052     unsigned char *pV = pU + numpix / 4;
1053     unsigned char *pOut = pOut0;
1054
1055     for (j = 0; j <= height; j++) {
1056         for (i = 0; i <= width - 4; i += 4) {
1057             y00 = *pY;
1058             y01 = *(pY + 1);
1059             y10 = *(pY + 2);
1060             y11 = *(pY + 3);
1061             u = (*pU++) - 128;
1062             v = (*pV++) - 128;
1063
1064             move_411_block(y00, y01, y10, y11, u, v,
1065                     width, pOut);
1066
1067             pY += 4;
1068             pOut += 4 * bytes;
1069
1070         }
1071     }
1072 }
1073
1074 /* convert from 4:2:2 YUYV interlaced to RGB24 */
1075 static void
1076 yuyv_to_rgb24(int width, int height, unsigned char* src, unsigned char* dst) {
1077     cvtColor(Mat(height, width, CV_8UC2, src), Mat(height, width, CV_8UC3, dst),
1078             COLOR_YUV2BGR_YUYV);
1079 }
1080
1081 static inline void
1082 uyvy_to_rgb24 (int width, int height, unsigned char *src, unsigned char *dst)
1083 {
1084     cvtColor(Mat(height, width, CV_8UC2, src), Mat(height, width, CV_8UC3, dst),
1085             COLOR_YUV2BGR_UYVY);
1086 }
1087
1088 static inline void
1089 y16_to_rgb24 (int width, int height, unsigned char* src, unsigned char* dst)
1090 {
1091     Mat gray8;
1092     Mat(height, width, CV_16UC1, src).convertTo(gray8, CV_8U, 0.00390625);
1093     cvtColor(gray8,Mat(height, width, CV_8UC3, dst),COLOR_GRAY2BGR);
1094 }
1095
1096 #ifdef HAVE_JPEG
1097
1098 /* convert from mjpeg to rgb24 */
1099 static bool
1100 mjpeg_to_rgb24(int width, int height, unsigned char* src, int length, IplImage* dst) {
1101     Mat temp = cvarrToMat(dst);
1102     imdecode(Mat(1, length, CV_8U, src), IMREAD_COLOR, &temp);
1103     return temp.data && temp.cols == width && temp.rows == height;
1104 }
1105
1106 #endif
1107
1108 /*
1109  * BAYER2RGB24 ROUTINE TAKEN FROM:
1110  *
1111  * Sonix SN9C10x based webcam basic I/F routines
1112  * Takafumi Mizuno <taka-qce@ls-a.jp>
1113  *
1114  */
1115 static void bayer2rgb24(long int WIDTH, long int HEIGHT, unsigned char *src, unsigned char *dst)
1116 {
1117     long int i;
1118     unsigned char *rawpt, *scanpt;
1119     long int size;
1120
1121     rawpt = src;
1122     scanpt = dst;
1123     size = WIDTH*HEIGHT;
1124
1125     for ( i = 0; i < size; i++ ) {
1126         if ( (i/WIDTH) % 2 == 0 ) {
1127             if ( (i % 2) == 0 ) {
1128                 /* B */
1129                 if ( (i > WIDTH) && ((i % WIDTH) > 0) ) {
1130                     *scanpt++ = (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+
1131                             *(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4;  /* R */
1132                     *scanpt++ = (*(rawpt-1)+*(rawpt+1)+
1133                             *(rawpt+WIDTH)+*(rawpt-WIDTH))/4;      /* G */
1134                     *scanpt++ = *rawpt;                                     /* B */
1135                 } else {
1136                     /* first line or left column */
1137                     *scanpt++ = *(rawpt+WIDTH+1);           /* R */
1138                     *scanpt++ = (*(rawpt+1)+*(rawpt+WIDTH))/2;      /* G */
1139                     *scanpt++ = *rawpt;                             /* B */
1140                 }
1141             } else {
1142                 /* (B)G */
1143                 if ( (i > WIDTH) && ((i % WIDTH) < (WIDTH-1)) ) {
1144                     *scanpt++ = (*(rawpt+WIDTH)+*(rawpt-WIDTH))/2;  /* R */
1145                     *scanpt++ = *rawpt;                                     /* G */
1146                     *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2;          /* B */
1147                 } else {
1148                     /* first line or right column */
1149                     *scanpt++ = *(rawpt+WIDTH);     /* R */
1150                     *scanpt++ = *rawpt;             /* G */
1151                     *scanpt++ = *(rawpt-1); /* B */
1152                 }
1153             }
1154         } else {
1155             if ( (i % 2) == 0 ) {
1156                 /* G(R) */
1157                 if ( (i < (WIDTH*(HEIGHT-1))) && ((i % WIDTH) > 0) ) {
1158                     *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2;          /* R */
1159                     *scanpt++ = *rawpt;                                     /* G */
1160                     *scanpt++ = (*(rawpt+WIDTH)+*(rawpt-WIDTH))/2;  /* B */
1161                 } else {
1162                     /* bottom line or left column */
1163                     *scanpt++ = *(rawpt+1);         /* R */
1164                     *scanpt++ = *rawpt;                     /* G */
1165                     *scanpt++ = *(rawpt-WIDTH);             /* B */
1166                 }
1167             } else {
1168                 /* R */
1169                 if ( i < (WIDTH*(HEIGHT-1)) && ((i % WIDTH) < (WIDTH-1)) ) {
1170                     *scanpt++ = *rawpt;                                     /* R */
1171                     *scanpt++ = (*(rawpt-1)+*(rawpt+1)+
1172                             *(rawpt-WIDTH)+*(rawpt+WIDTH))/4;      /* G */
1173                     *scanpt++ = (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+
1174                             *(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4;  /* B */
1175                 } else {
1176                     /* bottom line or right column */
1177                     *scanpt++ = *rawpt;                             /* R */
1178                     *scanpt++ = (*(rawpt-1)+*(rawpt-WIDTH))/2;      /* G */
1179                     *scanpt++ = *(rawpt-WIDTH-1);           /* B */
1180                 }
1181             }
1182         }
1183         rawpt++;
1184     }
1185
1186 }
1187
1188 // SGBRG to RGB24
1189 // for some reason, red and blue needs to be swapped
1190 // at least for  046d:092f Logitech, Inc. QuickCam Express Plus to work
1191 //see: http://www.siliconimaging.com/RGB%20Bayer.htm
1192 //and 4.6 at http://tldp.org/HOWTO/html_single/libdc1394-HOWTO/
1193 static void sgbrg2rgb24(long int WIDTH, long int HEIGHT, unsigned char *src, unsigned char *dst)
1194 {
1195     long int i;
1196     unsigned char *rawpt, *scanpt;
1197     long int size;
1198
1199     rawpt = src;
1200     scanpt = dst;
1201     size = WIDTH*HEIGHT;
1202
1203     for ( i = 0; i < size; i++ )
1204     {
1205         if ( (i/WIDTH) % 2 == 0 ) //even row
1206         {
1207             if ( (i % 2) == 0 ) //even pixel
1208             {
1209                 if ( (i > WIDTH) && ((i % WIDTH) > 0) )
1210                 {
1211                     *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2;       /* R */
1212                     *scanpt++ = *(rawpt);                        /* G */
1213                     *scanpt++ = (*(rawpt-WIDTH) + *(rawpt+WIDTH))/2;      /* B */
1214                 } else
1215                 {
1216                     /* first line or left column */
1217
1218                     *scanpt++ = *(rawpt+1);           /* R */
1219                     *scanpt++ = *(rawpt);             /* G */
1220                     *scanpt++ =  *(rawpt+WIDTH);      /* B */
1221                 }
1222             } else //odd pixel
1223             {
1224                 if ( (i > WIDTH) && ((i % WIDTH) < (WIDTH-1)) )
1225                 {
1226                     *scanpt++ = *(rawpt);       /* R */
1227                     *scanpt++ = (*(rawpt-1)+*(rawpt+1)+*(rawpt-WIDTH)+*(rawpt+WIDTH))/4; /* G */
1228                     *scanpt++ = (*(rawpt-WIDTH-1) + *(rawpt-WIDTH+1) + *(rawpt+WIDTH-1) + *(rawpt+WIDTH+1))/4;      /* B */
1229                 } else
1230                 {
1231                     /* first line or right column */
1232
1233                     *scanpt++ = *(rawpt);       /* R */
1234                     *scanpt++ = (*(rawpt-1)+*(rawpt+WIDTH))/2; /* G */
1235                     *scanpt++ = *(rawpt+WIDTH-1);      /* B */
1236                 }
1237             }
1238         } else
1239         { //odd row
1240             if ( (i % 2) == 0 ) //even pixel
1241             {
1242                 if ( (i < (WIDTH*(HEIGHT-1))) && ((i % WIDTH) > 0) )
1243                 {
1244                     *scanpt++ =  (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+*(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4;          /* R */
1245                     *scanpt++ =  (*(rawpt-1)+*(rawpt+1)+*(rawpt-WIDTH)+*(rawpt+WIDTH))/4;      /* G */
1246                     *scanpt++ =  *(rawpt); /* B */
1247                 } else
1248                 {
1249                     /* bottom line or left column */
1250
1251                     *scanpt++ =  *(rawpt-WIDTH+1);          /* R */
1252                     *scanpt++ =  (*(rawpt+1)+*(rawpt-WIDTH))/2;      /* G */
1253                     *scanpt++ =  *(rawpt); /* B */
1254                 }
1255             } else
1256             { //odd pixel
1257                 if ( i < (WIDTH*(HEIGHT-1)) && ((i % WIDTH) < (WIDTH-1)) )
1258                 {
1259                     *scanpt++ = (*(rawpt-WIDTH)+*(rawpt+WIDTH))/2;  /* R */
1260                     *scanpt++ = *(rawpt);      /* G */
1261                     *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* B */
1262                 } else
1263                 {
1264                     /* bottom line or right column */
1265
1266                     *scanpt++ = (*(rawpt-WIDTH));  /* R */
1267                     *scanpt++ = *(rawpt);      /* G */
1268                     *scanpt++ = (*(rawpt-1)); /* B */
1269                 }
1270             }
1271         }
1272         rawpt++;
1273     }
1274 }
1275
1276 static inline void
1277 rgb24_to_rgb24 (int width, int height, unsigned char *src, unsigned char *dst)
1278 {
1279     cvtColor(Mat(height, width, CV_8UC3, src), Mat(height, width, CV_8UC3, dst), COLOR_RGB2BGR);
1280 }
1281
1282 #define CLAMP(x)        ((x)<0?0:((x)>255)?255:(x))
1283
1284 typedef struct {
1285     int is_abs;
1286     int len;
1287     int val;
1288 } code_table_t;
1289
1290
1291 /* local storage */
1292 static code_table_t table[256];
1293 static int init_done = 0;
1294
1295
1296 /*
1297   sonix_decompress_init
1298   =====================
1299     pre-calculates a locally stored table for efficient huffman-decoding.
1300
1301   Each entry at index x in the table represents the codeword
1302   present at the MSB of byte x.
1303
1304  */
1305 static void sonix_decompress_init(void)
1306 {
1307     int i;
1308     int is_abs, val, len;
1309
1310     for (i = 0; i < 256; i++) {
1311         is_abs = 0;
1312         val = 0;
1313         len = 0;
1314         if ((i & 0x80) == 0) {
1315             /* code 0 */
1316             val = 0;
1317             len = 1;
1318         }
1319         else if ((i & 0xE0) == 0x80) {
1320             /* code 100 */
1321             val = +4;
1322             len = 3;
1323         }
1324         else if ((i & 0xE0) == 0xA0) {
1325             /* code 101 */
1326             val = -4;
1327             len = 3;
1328         }
1329         else if ((i & 0xF0) == 0xD0) {
1330             /* code 1101 */
1331             val = +11;
1332             len = 4;
1333         }
1334         else if ((i & 0xF0) == 0xF0) {
1335             /* code 1111 */
1336             val = -11;
1337             len = 4;
1338         }
1339         else if ((i & 0xF8) == 0xC8) {
1340             /* code 11001 */
1341             val = +20;
1342             len = 5;
1343         }
1344         else if ((i & 0xFC) == 0xC0) {
1345             /* code 110000 */
1346             val = -20;
1347             len = 6;
1348         }
1349         else if ((i & 0xFC) == 0xC4) {
1350             /* code 110001xx: unknown */
1351             val = 0;
1352             len = 8;
1353         }
1354         else if ((i & 0xF0) == 0xE0) {
1355             /* code 1110xxxx */
1356             is_abs = 1;
1357             val = (i & 0x0F) << 4;
1358             len = 8;
1359         }
1360         table[i].is_abs = is_abs;
1361         table[i].val = val;
1362         table[i].len = len;
1363     }
1364
1365     init_done = 1;
1366 }
1367
1368
1369 /*
1370   sonix_decompress
1371   ================
1372     decompresses an image encoded by a SN9C101 camera controller chip.
1373
1374   IN    width
1375     height
1376     inp         pointer to compressed frame (with header already stripped)
1377   OUT   outp    pointer to decompressed frame
1378
1379   Returns 0 if the operation was successful.
1380   Returns <0 if operation failed.
1381
1382  */
1383 static int sonix_decompress(int width, int height, unsigned char *inp, unsigned char *outp)
1384 {
1385     int row, col;
1386     int val;
1387     int bitpos;
1388     unsigned char code;
1389     unsigned char *addr;
1390
1391     if (!init_done) {
1392         /* do sonix_decompress_init first! */
1393         return -1;
1394     }
1395
1396     bitpos = 0;
1397     for (row = 0; row < height; row++) {
1398
1399         col = 0;
1400
1401
1402
1403         /* first two pixels in first two rows are stored as raw 8-bit */
1404         if (row < 2) {
1405             addr = inp + (bitpos >> 3);
1406             code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
1407             bitpos += 8;
1408             *outp++ = code;
1409
1410             addr = inp + (bitpos >> 3);
1411             code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
1412             bitpos += 8;
1413             *outp++ = code;
1414
1415             col += 2;
1416         }
1417
1418         while (col < width) {
1419             /* get bitcode from bitstream */
1420             addr = inp + (bitpos >> 3);
1421             code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
1422
1423             /* update bit position */
1424             bitpos += table[code].len;
1425
1426             /* calculate pixel value */
1427             val = table[code].val;
1428             if (!table[code].is_abs) {
1429                 /* value is relative to top and left pixel */
1430                 if (col < 2) {
1431                     /* left column: relative to top pixel */
1432                     val += outp[-2*width];
1433                 }
1434                 else if (row < 2) {
1435                     /* top row: relative to left pixel */
1436                     val += outp[-2];
1437                 }
1438                 else {
1439                     /* main area: average of left pixel and top pixel */
1440                     val += (outp[-2] + outp[-2*width]) / 2;
1441                 }
1442             }
1443
1444             /* store pixel */
1445             *outp++ = CLAMP(val);
1446             col++;
1447         }
1448     }
1449
1450     return 0;
1451 }
1452
1453 static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) {
1454     /* Now get what has already been captured as a IplImage return */
1455     // we need memory iff convert_rgb is true
1456     bool recreate_frame = capture->frame_allocated != capture->convert_rgb;
1457
1458     if (!capture->convert_rgb) {
1459         // for mjpeg streams the size might change in between, so we have to change the header
1460         recreate_frame += capture->frame.imageSize != (int)capture->buffers[capture->bufferIndex].length;
1461     }
1462
1463     if(recreate_frame) {
1464         // printf("realloc %d %zu\n", capture->frame.imageSize, capture->buffers[capture->bufferIndex].length);
1465         if(capture->frame_allocated)
1466             cvFree(&capture->frame.imageData);
1467         v4l2_create_frame(capture);
1468     }
1469
1470     if(!capture->convert_rgb) {
1471         capture->frame.imageData = (char*)capture->buffers[capture->bufferIndex].start;
1472         return &capture->frame;
1473     }
1474
1475     switch (capture->palette)
1476     {
1477     case V4L2_PIX_FMT_BGR24:
1478         memcpy((char *)capture->frame.imageData,
1479                 (char *)capture->buffers[capture->bufferIndex].start,
1480                 capture->frame.imageSize);
1481         break;
1482
1483     case V4L2_PIX_FMT_YVU420:
1484         yuv420p_to_rgb24(capture->form.fmt.pix.width,
1485                 capture->form.fmt.pix.height,
1486                 (unsigned char*)(capture->buffers[capture->bufferIndex].start),
1487                 (unsigned char*)capture->frame.imageData);
1488         break;
1489
1490     case V4L2_PIX_FMT_YUV411P:
1491         yuv411p_to_rgb24(capture->form.fmt.pix.width,
1492                 capture->form.fmt.pix.height,
1493                 (unsigned char*)(capture->buffers[capture->bufferIndex].start),
1494                 (unsigned char*)capture->frame.imageData);
1495         break;
1496 #ifdef HAVE_JPEG
1497     case V4L2_PIX_FMT_MJPEG:
1498     case V4L2_PIX_FMT_JPEG:
1499         if (!mjpeg_to_rgb24(capture->form.fmt.pix.width,
1500                 capture->form.fmt.pix.height,
1501                 (unsigned char*)(capture->buffers[capture->bufferIndex]
1502                                                   .start),
1503                                                   capture->buffers[capture->bufferIndex].length,
1504                                                   &capture->frame))
1505             return 0;
1506         break;
1507 #endif
1508
1509     case V4L2_PIX_FMT_YUYV:
1510         yuyv_to_rgb24(capture->form.fmt.pix.width,
1511                 capture->form.fmt.pix.height,
1512                 (unsigned char*)(capture->buffers[capture->bufferIndex].start),
1513                 (unsigned char*)capture->frame.imageData);
1514         break;
1515     case V4L2_PIX_FMT_UYVY:
1516         uyvy_to_rgb24(capture->form.fmt.pix.width,
1517                 capture->form.fmt.pix.height,
1518                 (unsigned char*)(capture->buffers[capture->bufferIndex].start),
1519                 (unsigned char*)capture->frame.imageData);
1520         break;
1521     case V4L2_PIX_FMT_SBGGR8:
1522         bayer2rgb24(capture->form.fmt.pix.width,
1523                 capture->form.fmt.pix.height,
1524                 (unsigned char*)capture->buffers[capture->bufferIndex].start,
1525                 (unsigned char*)capture->frame.imageData);
1526         break;
1527
1528     case V4L2_PIX_FMT_SN9C10X:
1529         sonix_decompress_init();
1530         sonix_decompress(capture->form.fmt.pix.width,
1531                 capture->form.fmt.pix.height,
1532                 (unsigned char*)capture->buffers[capture->bufferIndex].start,
1533                 (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start);
1534
1535         bayer2rgb24(capture->form.fmt.pix.width,
1536                 capture->form.fmt.pix.height,
1537                 (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start,
1538                 (unsigned char*)capture->frame.imageData);
1539         break;
1540
1541     case V4L2_PIX_FMT_SGBRG8:
1542         sgbrg2rgb24(capture->form.fmt.pix.width,
1543                 capture->form.fmt.pix.height,
1544                 (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start,
1545                 (unsigned char*)capture->frame.imageData);
1546         break;
1547     case V4L2_PIX_FMT_RGB24:
1548         rgb24_to_rgb24(capture->form.fmt.pix.width,
1549                 capture->form.fmt.pix.height,
1550                 (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start,
1551                 (unsigned char*)capture->frame.imageData);
1552         break;
1553     case V4L2_PIX_FMT_Y16:
1554         if(capture->convert_rgb){
1555             y16_to_rgb24(capture->form.fmt.pix.width,
1556                     capture->form.fmt.pix.height,
1557                     (unsigned char*)capture->buffers[capture->bufferIndex].start,
1558                     (unsigned char*)capture->frame.imageData);
1559         }else{
1560             memcpy((char *)capture->frame.imageData,
1561                     (char *)capture->buffers[capture->bufferIndex].start,
1562                     capture->frame.imageSize);
1563         }
1564         break;
1565     }
1566
1567     if (capture->returnFrame)
1568         return(&capture->frame);
1569     else
1570         return 0;
1571 }
1572
1573 static inline __u32 capPropertyToV4L2(int prop) {
1574     switch (prop) {
1575     case CV_CAP_PROP_BRIGHTNESS:
1576         return V4L2_CID_BRIGHTNESS;
1577     case CV_CAP_PROP_CONTRAST:
1578         return V4L2_CID_CONTRAST;
1579     case CV_CAP_PROP_SATURATION:
1580         return V4L2_CID_SATURATION;
1581     case CV_CAP_PROP_HUE:
1582         return V4L2_CID_HUE;
1583     case CV_CAP_PROP_GAIN:
1584         return V4L2_CID_GAIN;
1585     case CV_CAP_PROP_AUTO_EXPOSURE:
1586         return V4L2_CID_EXPOSURE_AUTO;
1587     case CV_CAP_PROP_EXPOSURE:
1588         return V4L2_CID_EXPOSURE_ABSOLUTE;
1589     case CV_CAP_PROP_AUTOFOCUS:
1590         return V4L2_CID_FOCUS_AUTO;
1591     case CV_CAP_PROP_FOCUS:
1592         return V4L2_CID_FOCUS_ABSOLUTE;
1593     default:
1594         return -1;
1595     }
1596 }
1597
1598 static double icvGetPropertyCAM_V4L (const CvCaptureCAM_V4L* capture,
1599         int property_id ) {
1600     {
1601         v4l2_format form;
1602         memset(&form, 0, sizeof(v4l2_format));
1603         form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1604         if (-1 == ioctl (capture->deviceHandle, VIDIOC_G_FMT, &form)) {
1605             /* display an error message, and return an error code */
1606             perror ("VIDIOC_G_FMT");
1607             return -1;
1608         }
1609
1610         switch (property_id) {
1611         case CV_CAP_PROP_FRAME_WIDTH:
1612             return form.fmt.pix.width;
1613         case CV_CAP_PROP_FRAME_HEIGHT:
1614             return form.fmt.pix.height;
1615         case CV_CAP_PROP_FOURCC:
1616         case CV_CAP_PROP_MODE:
1617             return capture->palette;
1618         case CV_CAP_PROP_FORMAT:
1619             return CV_MAKETYPE(IPL2CV_DEPTH(capture->frame.depth), capture->frame.nChannels);
1620         case CV_CAP_PROP_CONVERT_RGB:
1621             return capture->convert_rgb;
1622         case CV_CAP_PROP_BUFFERSIZE:
1623             return capture->bufferSize;
1624         }
1625
1626         if(property_id == CV_CAP_PROP_FPS) {
1627             v4l2_streamparm sp = v4l2_streamparm();
1628             sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1629             if (ioctl(capture->deviceHandle, VIDIOC_G_PARM, &sp) < 0){
1630                 fprintf(stderr, "VIDEOIO ERROR: V4L: Unable to get camera FPS\n");
1631                 return -1;
1632             }
1633
1634             return sp.parm.capture.timeperframe.denominator / (double)sp.parm.capture.timeperframe.numerator;
1635         }
1636
1637         /* initialize the control structure */
1638
1639         if(property_id == CV_CAP_PROP_POS_MSEC) {
1640             if (capture->FirstCapture) {
1641                 return 0;
1642             } else {
1643                 return 1000 * capture->timestamp.tv_sec + ((double) capture->timestamp.tv_usec) / 1000;
1644             }
1645         }
1646
1647         __u32 v4l2id = capPropertyToV4L2(property_id);
1648
1649         if(v4l2id == __u32(-1)) {
1650             fprintf(stderr,
1651                     "VIDEOIO ERROR: V4L2: getting property #%d is not supported\n",
1652                     property_id);
1653             return -1;
1654         }
1655
1656         v4l2_control control = {v4l2id, 0};
1657
1658         if (-1 == ioctl (capture->deviceHandle, VIDIOC_G_CTRL,
1659                 &control)) {
1660
1661             fprintf( stderr, "VIDEOIO ERROR: V4L2: ");
1662             switch (property_id) {
1663             case CV_CAP_PROP_BRIGHTNESS:
1664                 fprintf (stderr, "Brightness");
1665                 break;
1666             case CV_CAP_PROP_CONTRAST:
1667                 fprintf (stderr, "Contrast");
1668                 break;
1669             case CV_CAP_PROP_SATURATION:
1670                 fprintf (stderr, "Saturation");
1671                 break;
1672             case CV_CAP_PROP_HUE:
1673                 fprintf (stderr, "Hue");
1674                 break;
1675             case CV_CAP_PROP_GAIN:
1676                 fprintf (stderr, "Gain");
1677                 break;
1678             case CV_CAP_PROP_AUTO_EXPOSURE:
1679                 fprintf (stderr, "Auto Exposure");
1680                 break;
1681             case CV_CAP_PROP_EXPOSURE:
1682                 fprintf (stderr, "Exposure");
1683                 break;
1684             case CV_CAP_PROP_AUTOFOCUS:
1685                 fprintf (stderr, "Autofocus");
1686                 break;
1687             case CV_CAP_PROP_FOCUS:
1688                 fprintf (stderr, "Focus");
1689                 break;
1690             }
1691             fprintf (stderr, " is not supported by your device\n");
1692
1693             return -1;
1694         }
1695
1696         /* get the min/max values */
1697         Range range = capture->getRange(property_id);
1698
1699         /* all was OK, so convert to 0.0 - 1.0 range, and return the value */
1700         return ((double)control.value - range.start) / range.size();
1701
1702     }
1703 };
1704
1705 static bool icvSetControl (CvCaptureCAM_V4L* capture,
1706         int property_id, double value) {
1707
1708     /* limitation of the input value */
1709     if (value < 0.0) {
1710         value = 0.0;
1711     } else if (value > 1.0) {
1712         value = 1.0;
1713     }
1714
1715     /* initialisations */
1716     __u32 v4l2id = capPropertyToV4L2(property_id);
1717
1718     if(v4l2id == __u32(-1)) {
1719         fprintf(stderr,
1720                 "VIDEOIO ERROR: V4L2: setting property #%d is not supported\n",
1721                 property_id);
1722         return -1;
1723     }
1724
1725     /* get the min/max values */
1726     Range range = capture->getRange(property_id);
1727
1728     /* scale the value we want to set */
1729     value = value * range.size() + range.start;
1730
1731     /* set which control we want to set */
1732     v4l2_control control = {v4l2id, int(value)};
1733
1734     /* The driver may clamp the value or return ERANGE, ignored here */
1735     if (-1 == ioctl(capture->deviceHandle, VIDIOC_S_CTRL, &control) && errno != ERANGE) {
1736         perror ("VIDIOC_S_CTRL");
1737         return false;
1738     }
1739
1740     if(control.id == V4L2_CID_EXPOSURE_AUTO && control.value == V4L2_EXPOSURE_MANUAL) {
1741         // update the control range for expose after disabling autoexposure
1742         // as it is not read correctly at startup
1743         // TODO check this again as it might be fixed with Linux 4.5
1744         v4l2_control_range(capture, V4L2_CID_EXPOSURE_ABSOLUTE);
1745     }
1746
1747     /* all was OK */
1748     return true;
1749 }
1750
1751 static int icvSetPropertyCAM_V4L( CvCaptureCAM_V4L* capture,
1752         int property_id, double value ){
1753     bool retval = false;
1754     bool possible;
1755
1756     /* two subsequent calls setting WIDTH and HEIGHT will change
1757        the video size */
1758
1759     switch (property_id) {
1760     case CV_CAP_PROP_FRAME_WIDTH:
1761     {
1762         int& width = capture->width_set;
1763         int& height = capture->height_set;
1764         width = cvRound(value);
1765         retval = width != 0;
1766         if(width !=0 && height != 0) {
1767             capture->width = width;
1768             capture->height = height;
1769             retval = v4l2_reset(capture);
1770             width = height = 0;
1771         }
1772     }
1773     break;
1774     case CV_CAP_PROP_FRAME_HEIGHT:
1775     {
1776         int& width = capture->width_set;
1777         int& height = capture->height_set;
1778         height = cvRound(value);
1779         retval = height != 0;
1780         if(width !=0 && height != 0) {
1781             capture->width = width;
1782             capture->height = height;
1783             retval = v4l2_reset(capture);
1784             width = height = 0;
1785         }
1786     }
1787     break;
1788     case CV_CAP_PROP_FPS:
1789         capture->fps = value;
1790         retval = v4l2_reset(capture);
1791         break;
1792     case CV_CAP_PROP_CONVERT_RGB:
1793         // returns "0" for formats we do not know how to map to IplImage
1794         possible = v4l2_num_channels(capture->palette);
1795         capture->convert_rgb = bool(value) && possible;
1796         retval = possible || !bool(value);
1797         break;
1798     case CV_CAP_PROP_FOURCC:
1799     {
1800         __u32 old_palette = capture->palette;
1801         __u32 new_palette = static_cast<__u32>(value);
1802         capture->palette = new_palette;
1803         if (v4l2_reset(capture)) {
1804             retval = true;
1805         } else {
1806             capture->palette = old_palette;
1807             v4l2_reset(capture);
1808             retval = false;
1809         }
1810     }
1811     break;
1812     case CV_CAP_PROP_BUFFERSIZE:
1813         if ((int)value > MAX_V4L_BUFFERS || (int)value < 1) {
1814             fprintf(stderr, "V4L: Bad buffer size %d, buffer size must be from 1 to %d\n", (int)value, MAX_V4L_BUFFERS);
1815             retval = false;
1816         } else {
1817             capture->bufferSize = (int)value;
1818             if (capture->bufferIndex > capture->bufferSize) {
1819                 capture->bufferIndex = 0;
1820             }
1821             retval = v4l2_reset(capture);
1822         }
1823         break;
1824     default:
1825         retval = icvSetControl(capture, property_id, value);
1826         break;
1827     }
1828
1829     /* return the the status */
1830     return retval;
1831 }
1832
1833 static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ){
1834     /* Deallocate space - Hopefully, no leaks */
1835
1836     if (!capture->deviceName.empty())
1837     {
1838         if (capture->deviceHandle != -1)
1839         {
1840             capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1841             if (-1 == ioctl(capture->deviceHandle, VIDIOC_STREAMOFF, &capture->type)) {
1842                 perror ("Unable to stop the stream");
1843             }
1844
1845             for (unsigned int n_buffers = 0; n_buffers < MAX_V4L_BUFFERS; ++n_buffers)
1846             {
1847                 if (capture->buffers[n_buffers].start) {
1848                     if (-1 == munmap (capture->buffers[n_buffers].start, capture->buffers[n_buffers].length)) {
1849                         perror ("munmap");
1850                     } else {
1851                         capture->buffers[n_buffers].start = 0;
1852                     }
1853                 }
1854             }
1855
1856             if (capture->buffers[MAX_V4L_BUFFERS].start)
1857             {
1858                 free(capture->buffers[MAX_V4L_BUFFERS].start);
1859                 capture->buffers[MAX_V4L_BUFFERS].start = 0;
1860             }
1861         }
1862
1863         if (capture->deviceHandle != -1)
1864             close(capture->deviceHandle);
1865
1866         if (capture->frame_allocated && capture->frame.imageData)
1867             cvFree(&capture->frame.imageData);
1868
1869         capture->deviceName.clear(); // flag that the capture is closed
1870     }
1871 };
1872
1873 bool CvCaptureCAM_V4L::grabFrame()
1874 {
1875     return icvGrabFrameCAM_V4L( this );
1876 }
1877
1878 IplImage* CvCaptureCAM_V4L::retrieveFrame(int)
1879 {
1880     return icvRetrieveFrameCAM_V4L( this, 0 );
1881 }
1882
1883 double CvCaptureCAM_V4L::getProperty( int propId ) const
1884 {
1885     return icvGetPropertyCAM_V4L( this, propId );
1886 }
1887
1888 bool CvCaptureCAM_V4L::setProperty( int propId, double value )
1889 {
1890     return icvSetPropertyCAM_V4L( this, propId, value );
1891 }
1892
1893 } // end namespace cv
1894
1895 CvCapture* cvCreateCameraCapture_V4L( int index )
1896 {
1897     cv::CvCaptureCAM_V4L* capture = new cv::CvCaptureCAM_V4L();
1898
1899     if(capture->open(index))
1900         return capture;
1901
1902     delete capture;
1903     return NULL;
1904 }
1905
1906 CvCapture* cvCreateCameraCapture_V4L( const char * deviceName )
1907 {
1908     cv::CvCaptureCAM_V4L* capture = new cv::CvCaptureCAM_V4L();
1909
1910     if(capture->open( deviceName ))
1911         return capture;
1912
1913     delete capture;
1914     return NULL;
1915 }
1916
1917 #endif