1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* This is the contributed code: 2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 3793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFile: cvcap_v4l.cpp 4793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCurrent Location: ../opencv-0.9.6/otherlibs/videoio 5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 6793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerOriginal Version: 2003-03-12 Magnus Lundin lundin@mlu.mine.nu 7793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerOriginal Comments: 8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 9793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerML:This set of files adds support for firevre and usb cameras. 10793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFirst it tries to install a firewire camera, 11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerif that fails it tries a v4l/USB camera 12793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerIt has been tested with the motempl sample program 13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 14793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFirst Patch: August 24, 2004 Travis Wood TravisOCV@tkwood.com 15793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFor Release: OpenCV-Linux Beta4 opencv-0.9.6 16793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTested On: LMLBT44 with 8 video inputs 17793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerProblems? Post your questions at answers.opencv.org, 18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Report bugs at code.opencv.org, 19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Submit your fixes at https://github.com/Itseez/opencv/ 20793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPatched Comments: 21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 22793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTW: The cv cam utils that came with the initial release of OpenCV for LINUX Beta4 23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerwere not working. I have rewritten them so they work for me. At the same time, trying 24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerto keep the original code as ML wrote it as unchanged as possible. No one likes to debug 25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslersomeone elses code, so I resisted changes as much as possible. I have tried to keep the 26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslersame "ideas" where applicable, that is, where I could figure out what the previous author 27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerintended. Some areas I just could not help myself and had to "spiffy-it-up" my way. 28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 29793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerThese drivers should work with other V4L frame capture cards other then my bttv 30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerdriven frame capture card. 31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 32793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerRe Written driver for standard V4L mode. Tested using LMLBT44 video capture card. 33793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerStandard bttv drivers are on the LMLBT44 with up to 8 Inputs. 34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 35793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerThis utility was written with the help of the document: 36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerhttp://pages.cpsc.ucalgary.ca/~sayles/VFL_HowTo 37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presleras a general guide for interfacing into the V4l standard. 38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 39793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMade the index value passed for icvOpenCAM_V4L(index) be the number of the 40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervideo device source in the /dev tree. The -1 uses original /dev/video. 41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 42793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerIndex Device 43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 0 /dev/video0 44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1 /dev/video1 45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2 /dev/video2 46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 3 /dev/video3 47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ... 48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 7 /dev/video7 49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerwith 50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler -1 /dev/video 51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 52793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTW: You can select any video source, but this package was limited from the start to only 53793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerONE camera opened at any ONE time. 54793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerThis is an original program limitation. 55793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerIf you are interested, I will make my version available to other OpenCV users. The big 56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerdifference in mine is you may pass the camera number as part of the cv argument, but this 57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconvention is non standard for current OpenCV calls and the camera number is not currently 58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpassed into the called routine. 59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 60793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerSecond Patch: August 28, 2004 Sfuncia Fabio fiblan@yahoo.it 61793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFor Release: OpenCV-Linux Beta4 Opencv-0.9.6 62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 63793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFS: this patch fix not sequential index of device (unplugged device), and real numCameras. 64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for -1 index (icvOpenCAM_V4L) i dont use /dev/video but real device available, because 65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if /dev/video is a link to /dev/video0 and i unplugged device on /dev/video0, /dev/video 66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler is a bad link. I search the first available device with indexList. 67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 68793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerThird Patch: December 9, 2004 Frederic Devernay Frederic.Devernay@inria.fr 69793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFor Release: OpenCV-Linux Beta4 Opencv-0.9.6 70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler[FD] I modified the following: 72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - handle YUV420P, YUV420, and YUV411P palettes (for many webcams) without using floating-point 73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - cvGrabFrame should not wait for the end of the first frame, and should return quickly 74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (see videoio doc) 75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - cvRetrieveFrame should in turn wait for the end of frame capture, and should not 76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trigger the capture of the next frame (the user choses when to do it using GrabFrame) 77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler To get the old behavior, re-call cvRetrieveFrame just after cvGrabFrame. 78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - having global bufferIndex and FirstCapture variables makes the code non-reentrant 79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (e.g. when using several cameras), put these in the CvCapture struct. 80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - according to V4L HowTo, incrementing the buffer index must be done before VIDIOCMCAPTURE. 81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - the VID_TYPE_SCALES stuff from V4L HowTo is wrong: image size can be changed 82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler even if the hardware does not support scaling (e.g. webcams can have several 83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler resolutions available). Just don't try to set the size at 640x480 if the hardware supports 84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler scaling: open with the default (probably best) image size, and let the user scale it 85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler using SetProperty. 86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - image size can be changed by two subsequent calls to SetProperty (for width and height) 87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - bug fix: if the image size changes, realloc the new image only when it is grabbed 88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - issue errors only when necessary, fix error message formatting. 89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 90793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFourth Patch: Sept 7, 2005 Csaba Kertesz sign@freemail.hu 91793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFor Release: OpenCV-Linux Beta5 OpenCV-0.9.7 92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 93793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerI modified the following: 94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Additional Video4Linux2 support :) 95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Use mmap functions (v4l2) 96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - New methods are internal: 97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler try_palette_v4l2 -> rewrite try_palette for v4l2 98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mainloop_v4l2, read_image_v4l2 -> this methods are moved from official v4l2 capture.c example 99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler try_init_v4l -> device v4l initialisation 100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler try_init_v4l2 -> device v4l2 initialisation 101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler autosetup_capture_mode_v4l -> autodetect capture modes for v4l 102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler autosetup_capture_mode_v4l2 -> autodetect capture modes for v4l2 103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Modifications are according with Video4Linux old codes 104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Video4Linux handling is automatically if it does not recognize a Video4Linux2 device 105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Tested successfully with Logitech Quickcam Express (V4L), Creative Vista (V4L) and Genius VideoCam Notebook (V4L2) 106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Correct source lines with compiler warning messages 107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Information message from v4l/v4l2 detection 108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 109793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFifth Patch: Sept 7, 2005 Csaba Kertesz sign@freemail.hu 110793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFor Release: OpenCV-Linux Beta5 OpenCV-0.9.7 111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 112793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerI modified the following: 113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - SN9C10x chip based webcams support 114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - New methods are internal: 115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bayer2rgb24, sonix_decompress -> decoder routines for SN9C10x decoding from Takafumi Mizuno <taka-qce@ls-a.jp> with his pleasure :) 116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Tested successfully with Genius VideoCam Notebook (V4L2) 117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 118793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerSixth Patch: Sept 10, 2005 Csaba Kertesz sign@freemail.hu 119793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFor Release: OpenCV-Linux Beta5 OpenCV-0.9.7 120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 121793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerI added the following: 122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Add capture control support (hue, saturation, brightness, contrast, gain) 123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Get and change V4L capture controls (hue, saturation, brightness, contrast) 124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - New method is internal: 125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvSetControl -> set capture controls 126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Tested successfully with Creative Vista (V4L) 127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 128793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerSeventh Patch: Sept 10, 2005 Csaba Kertesz sign@freemail.hu 129793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFor Release: OpenCV-Linux Beta5 OpenCV-0.9.7 130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 131793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerI added the following: 132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Detect, get and change V4L2 capture controls (hue, saturation, brightness, contrast, gain) 133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - New methods are internal: 134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_scan_controls_enumerate_menu, v4l2_scan_controls -> detect capture control intervals 135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Tested successfully with Genius VideoCam Notebook (V4L2) 136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler8th patch: Jan 5, 2006, Olivier.Bornet@idiap.ch 138793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerAdd support of V4L2_PIX_FMT_YUYV and V4L2_PIX_FMT_MJPEG. 139793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerWith this patch, new webcams of Logitech, like QuickCam Fusion works. 140793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerNote: For use these webcams, look at the UVC driver at 141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerhttp://linux-uvc.berlios.de/ 142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler9th patch: Mar 4, 2006, Olivier.Bornet@idiap.ch 144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- try V4L2 before V4L, because some devices are V4L2 by default, 145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler but they try to implement the V4L compatibility layer. 146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler So, I think this is better to support V4L2 before V4L. 147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- better separation between V4L2 and V4L initialization. (this was needed to support 148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler some drivers working, but not fully with V4L2. (so, we do not know when we 149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler need to switch from V4L2 to V4L. 150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler10th patch: July 02, 2008, Mikhail Afanasyev fopencv@theamk.com 152793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFix reliability problems with high-resolution UVC cameras on linux 153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerthe symptoms were damaged image and 'Corrupt JPEG data: premature end of data segment' on stderr 154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- V4L_ABORT_BADJPEG detects JPEG warnings and turns them into errors, so bad images 155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler could be filtered out 156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- USE_TEMP_BUFFER fixes the main problem (improper buffer management) and 157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler prevents bad images in the first place 158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler11th patch: Apr 13, 2010, Filipe Almeida filipe.almeida@ist.utl.pt 160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Tries to setup all properties first through v4l2_ioctl call. 161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Allows setting up all Video4Linux properties through cvSetCaptureProperty instead of only CV_CAP_PROP_BRIGHTNESS, CV_CAP_PROP_CONTRAST, CV_CAP_PROP_SATURATION, CV_CAP_PROP_HUE, CV_CAP_PROP_GAIN and CV_CAP_PROP_EXPOSURE. 162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler12th patch: Apr 16, 2010, Filipe Almeida filipe.almeida@ist.utl.pt 164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- CvCaptureCAM_V4L structure cleanup (no longer needs <PROPERTY>_{min,max,} variables) 165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Introduction of v4l2_ctrl_range - minimum and maximum allowed values for v4l controls 166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Allows setting up all Video4Linux properties through cvSetCaptureProperty using input values between 0.0 and 1.0 167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Gets v4l properties first through v4l2_ioctl call (ignores capture->is_v4l2_device) 168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- cvGetCaptureProperty adjusted to support the changes 169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Returns device properties to initial values after device closes 170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler13th patch: Apr 27, 2010, Filipe Almeida filipe.almeida@ist.utl.pt 172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Solved problem mmaping the device using uvcvideo driver (use o v4l2_mmap instead of mmap) 173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslermake & enjoy! 174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler14th patch: May 10, 2010, Filipe Almeida filipe.almeida@ist.utl.pt 176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Bug #142: Solved/Workaround "setting frame width and height does not work" 177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler There was a problem setting up the size when the input is a v4l2 device 178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler The workaround closes the camera and reopens it with the new definition 179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Planning for future rewrite of this whole library (July/August 2010) 180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler15th patch: May 12, 2010, Filipe Almeida filipe.almeida@ist.utl.pt 182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Broken compile of library (include "_videoio.h") 183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler16th patch: Dec 16, 2014, Joseph Howse josephhowse@nummist.com 185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Allow getting/setting CV_CAP_PROP_MODE. These values are supported: 186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - CV_CAP_MODE_BGR : BGR24 (default) 187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - CV_CAP_MODE_RGB : RGB24 188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - CV_CAP_MODE_GRAY : Y8, extracted from YUV420 189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler- Tested successfully on these cameras: 190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - PlayStation 3 Eye 191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Logitech C920 192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler - Odroid USB-CAM 720P 193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler17th patch: May 9, 2015, Matt Sandler 195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler added supported for CV_CAP_PROP_POS_MSEC, CV_CAP_PROP_POS_FRAMES, CV_CAP_PROP_FPS 196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler*/ 198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*M/////////////////////////////////////////////////////////////////////////////////////// 200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// By downloading, copying, installing or using the software you agree to this license. 204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// If you do not agree to this license, do not download, install, 205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// copy or use the software. 206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Intel License Agreement 209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// For Open Source Computer Vision Library 210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Copyright (C) 2000, Intel Corporation, all rights reserved. 212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Third party copyrights are property of their respective owners. 213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Redistribution and use in source and binary forms, with or without modification, 215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// are permitted provided that the following conditions are met: 216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// * Redistribution's of source code must retain the above copyright notice, 218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// this list of conditions and the following disclaimer. 219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// * Redistribution's in binary form must reproduce the above copyright notice, 221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// this list of conditions and the following disclaimer in the documentation 222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// and/or other materials provided with the distribution. 223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// * The name of Intel Corporation may not be used to endorse or promote products 225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// derived from this software without specific prior written permission. 226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// This software is provided by the copyright holders and contributors "as is" and 228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// any express or implied warranties, including, but not limited to, the implied 229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// warranties of merchantability and fitness for a particular purpose are disclaimed. 230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// In no event shall the Intel Corporation or contributors be liable for any direct, 231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// indirect, incidental, special, exemplary, or consequential damages 232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// (including, but not limited to, procurement of substitute goods or services; 233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// loss of use, data, or profits; or business interruption) however caused 234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// and on any theory of liability, whether in contract, strict liability, 235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// or tort (including negligence or otherwise) arising in any way out of 236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// the use of this software, even if advised of the possibility of such damage. 237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//M*/ 239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "precomp.hpp" 241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#if !defined WIN32 && defined HAVE_LIBV4L 243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define CLEAR(x) memset (&(x), 0, sizeof (x)) 245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <stdio.h> 247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <unistd.h> 248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <fcntl.h> 249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <errno.h> 250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <sys/types.h> 251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <sys/mman.h> 252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <string.h> 253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <stdlib.h> 254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <asm/types.h> /* for videodev2.h */ 255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <assert.h> 256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <sys/stat.h> 257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <sys/ioctl.h> 258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_CAMV4L 260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <linux/videodev.h> 261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_CAMV4L2 263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <linux/videodev2.h> 264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <libv4l1.h> 267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <libv4l2.h> 268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Defaults - If your board can do better, set it here. Set for the most common type inputs. */ 270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define DEFAULT_V4L_WIDTH 640 271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define DEFAULT_V4L_HEIGHT 480 272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define CHANNEL_NUMBER 1 274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define MAX_CAMERAS 8 275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// default and maximum number of V4L buffers, not including last, 'special' buffer 278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define MAX_V4L_BUFFERS 10 279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define DEFAULT_V4L_BUFFERS 4 280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// if enabled, copies data from the buffer. this uses a bit more memory, 282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// but much more reliable for some UVC cameras 283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define USE_TEMP_BUFFER 284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define MAX_DEVICE_DRIVER_NAME 80 286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Device Capture Objects */ 288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* V4L2 structure */ 289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstruct buffer 290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler void * start; 292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t length; 293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}; 294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic unsigned int n_buffers = 0; 295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* TODO: Dilemas: */ 297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* TODO: Consider drop the use of this data structure and perform ioctl to obtain needed values */ 298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* TODO: Consider at program exit return controls to the initial values - See v4l2_free_ranges function */ 299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* TODO: Consider at program exit reset the device to default values - See v4l2_free_ranges function */ 300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertypedef struct v4l2_ctrl_range { 301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler __u32 ctrl_id; 302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler __s32 initial_value; 303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler __s32 current_value; 304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler __s32 minimum; 305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler __s32 maximum; 306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler __s32 default_value; 307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} v4l2_ctrl_range; 308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertypedef struct CvCaptureCAM_V4L 310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char* deviceName; 312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int deviceHandle; 313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int bufferIndex; 314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int FirstCapture; 315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int width; int height; 317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int mode; 318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct video_capability capability; 320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct video_window captureWindow; 321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct video_picture imageProperties; 322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct video_mbuf memoryBuffer; 323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct video_mmap *mmaps; 324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char *memoryMap; 325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler IplImage frame; 326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* V4L2 variables */ 328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buffer buffers[MAX_V4L_BUFFERS + 1]; 329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_capability cap; 330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_input inp; 331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_format form; 332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_crop crop; 333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_cropcap cropcap; 334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_requestbuffers req; 335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_jpegcompression compr; 336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_control control; 337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler enum v4l2_buf_type type; 338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_queryctrl queryctrl; 339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct timeval timestamp; 341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /** value set the buffer of V4L*/ 343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int sequence; 344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* V4L2 control variables */ 346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_ctrl_range** v4l2_ctrl_ranges; 347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int v4l2_ctrl_count; 348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int is_v4l2_device; 350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 351793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCvCaptureCAM_V4L; 352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ); 354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvGrabFrameCAM_V4L( CvCaptureCAM_V4L* capture ); 356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int ); 357793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCvCapture* cvCreateCameraCapture_V4L( int index ); 358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic double icvGetPropertyCAM_V4L( CvCaptureCAM_V4L* capture, int property_id ); 360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvSetPropertyCAM_V4L( CvCaptureCAM_V4L* capture, int property_id, double value ); 361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h); 363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*********************** Implementations ***************************************/ 365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int numCameras = 0; 367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int indexList = 0; 368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// IOCTL handling for V4L2 370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_IOCTL_ULONG 371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int xioctl( int fd, unsigned long request, void *arg) 372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else 373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int xioctl( int fd, int request, void *arg) 374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int r; 378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do r = v4l2_ioctl (fd, request, arg); 381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (-1 == r && EINTR == errno); 382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return r; 384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Simple test program: Find number of Video Sources available. 389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Start from 0 and go to MAX_CAMERAS while checking for the device with that name. 390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler If it fails on the first attempt of /dev/video0, then check if /dev/video is valid. 391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Returns the global numCameras with the correct value (we hope) */ 392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void icvInitCapture_V4L() { 394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int deviceHandle; 395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int CameraNumber; 396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char deviceName[MAX_DEVICE_DRIVER_NAME]; 397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CameraNumber = 0; 399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while(CameraNumber < MAX_CAMERAS) { 400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Print the CameraNumber at the end of the string with a width of one character */ 401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(deviceName, "/dev/video%1d", CameraNumber); 402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Test using an open to see if this new device name really does exists. */ 403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler deviceHandle = open(deviceName, O_RDONLY); 404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (deviceHandle != -1) { 405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* This device does indeed exist - add it to the total so far */ 406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // add indexList 407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler indexList|=(1 << CameraNumber); 408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler numCameras++; 409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (deviceHandle != -1) 411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler close(deviceHandle); 412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Set up to test the next /dev/video source in line */ 413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CameraNumber++; 414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* End while */ 415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}; /* End icvInitCapture_V4L */ 417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName) 420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // if detect = -1 then unable to open device 424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // if detect = 0 then detected nothing 425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // if detect = 1 then V4L device 426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int detect = 0; 427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Test device for V4L compability 430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Test using an open to see if this new device name really does exists. */ 432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* No matter what the name - it still must be opened! */ 433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->deviceHandle = v4l1_open(deviceName, O_RDWR); 434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->deviceHandle == 0) 437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detect = -1; 439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (detect == 0) 444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Query the newly opened device for its capabilities */ 446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl(capture->deviceHandle, VIDIOCGCAP, &capture->capability) < 0) 447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detect = 0; 449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detect = 1; 455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return detect; 459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName) 464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // if detect = -1 then unable to open device 467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // if detect = 0 then detected nothing 468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // if detect = 1 then V4L2 device 469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int detect = 0; 470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Test device for V4L2 compability 473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Open and test V4L2 device */ 475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->deviceHandle = v4l2_open (deviceName, O_RDWR /* required */ | O_NONBLOCK, 0); 476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->deviceHandle == 0) 480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detect = -1; 482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (detect == 0) 487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->cap); 489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYCAP, &capture->cap)) 490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detect = 0; 492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->capability); 498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->capability.type = capture->cap.capabilities; 499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Query channels number */ 501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 != xioctl (capture->deviceHandle, VIDIOC_G_INPUT, &capture->capability.channels)) 502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detect = 1; 504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return detect; 509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void v4l2_free_ranges(CvCaptureCAM_V4L* capture) { 514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int i; 515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->v4l2_ctrl_ranges != NULL) { 516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (i = 0; i < capture->v4l2_ctrl_count; i++) { 517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Return device to initial values: */ 518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* double value = (capture->v4l2_ctrl_ranges[i]->initial_value == 0)?0.0:((float)capture->v4l2_ctrl_ranges[i]->initial_value - capture->v4l2_ctrl_ranges[i]->minimum) / (capture->v4l2_ctrl_ranges[i]->maximum - capture->v4l2_ctrl_ranges[i]->minimum); */ 519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Return device to default values: */ 520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* double value = (capture->v4l2_ctrl_ranges[i]->default_value == 0)?0.0:((float)capture->v4l2_ctrl_ranges[i]->default_value - capture->v4l2_ctrl_ranges[i]->minimum + 1) / (capture->v4l2_ctrl_ranges[i]->maximum - capture->v4l2_ctrl_ranges[i]->minimum); */ 521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* icvSetPropertyCAM_V4L(capture, capture->v4l2_ctrl_ranges[i]->ctrl_id, value); */ 523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler free(capture->v4l2_ctrl_ranges[i]); 524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler free(capture->v4l2_ctrl_ranges); 527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->v4l2_ctrl_count = 0; 528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->v4l2_ctrl_ranges = NULL; 529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void v4l2_add_ctrl_range(CvCaptureCAM_V4L* capture, v4l2_control* ctrl) { 532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_ctrl_range* range = (v4l2_ctrl_range*)malloc(sizeof(v4l2_ctrl_range)); 533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler range->ctrl_id = ctrl->id; 534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler range->initial_value = ctrl->value; 535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler range->current_value = ctrl->value; 536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler range->minimum = capture->queryctrl.minimum; 537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler range->maximum = capture->queryctrl.maximum; 538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler range->default_value = capture->queryctrl.default_value; 539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->v4l2_ctrl_ranges[capture->v4l2_ctrl_count] = range; 540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->v4l2_ctrl_count += 1; 541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->v4l2_ctrl_ranges = (v4l2_ctrl_range**)realloc((v4l2_ctrl_range**)capture->v4l2_ctrl_ranges, (capture->v4l2_ctrl_count + 1) * sizeof(v4l2_ctrl_range*)); 542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int v4l2_get_ctrl_default(CvCaptureCAM_V4L* capture, __u32 id) { 545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int i; 546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (i = 0; i < capture->v4l2_ctrl_count; i++) { 547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (id == capture->v4l2_ctrl_ranges[i]->ctrl_id) { 548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return capture->v4l2_ctrl_ranges[i]->default_value; 549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int v4l2_get_ctrl_min(CvCaptureCAM_V4L* capture, __u32 id) { 555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int i; 556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (i = 0; i < capture->v4l2_ctrl_count; i++) { 557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (id == capture->v4l2_ctrl_ranges[i]->ctrl_id) { 558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return capture->v4l2_ctrl_ranges[i]->minimum; 559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int v4l2_get_ctrl_max(CvCaptureCAM_V4L* capture, __u32 id) { 565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int i; 566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (i = 0; i < capture->v4l2_ctrl_count; i++) { 567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (id == capture->v4l2_ctrl_ranges[i]->ctrl_id) { 568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return capture->v4l2_ctrl_ranges[i]->maximum; 569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void v4l2_scan_controls(CvCaptureCAM_V4L* capture) { 576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler __u32 ctrl_id; 578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_control c; 579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->v4l2_ctrl_ranges != NULL) { 580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_free_ranges(capture); 581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->v4l2_ctrl_ranges = (v4l2_ctrl_range**)malloc(sizeof(v4l2_ctrl_range*)); 583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef V4L2_CTRL_FLAG_NEXT_CTRL 584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Try the extended control API first */ 585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; 586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(0 == v4l2_ioctl (capture->deviceHandle, VIDIOC_QUERYCTRL, &capture->queryctrl)) { 587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler c.id = capture->queryctrl.id; 589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; 590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(capture->queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { 591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(capture->queryctrl.type != V4L2_CTRL_TYPE_INTEGER && 594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.type != V4L2_CTRL_TYPE_BOOLEAN && 595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.type != V4L2_CTRL_TYPE_MENU) { 596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &c) == 0) { 599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_add_ctrl_range(capture, &c); 600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while(0 == v4l2_ioctl (capture->deviceHandle, VIDIOC_QUERYCTRL, &capture->queryctrl)); 603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else 604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Check all the standard controls */ 607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(ctrl_id=V4L2_CID_BASE; ctrl_id<V4L2_CID_LASTP1; ctrl_id++) { 608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.id = ctrl_id; 609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(v4l2_ioctl(capture->deviceHandle, VIDIOC_QUERYCTRL, &capture->queryctrl) == 0) { 610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(capture->queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { 611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(capture->queryctrl.type != V4L2_CTRL_TYPE_INTEGER && 614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.type != V4L2_CTRL_TYPE_BOOLEAN && 615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.type != V4L2_CTRL_TYPE_MENU) { 616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler c.id = ctrl_id; 619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &c) == 0) { 621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_add_ctrl_range(capture, &c); 622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Check any custom controls */ 627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(ctrl_id=V4L2_CID_PRIVATE_BASE; ; ctrl_id++) { 628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.id = ctrl_id; 629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(v4l2_ioctl(capture->deviceHandle, VIDIOC_QUERYCTRL, &capture->queryctrl) == 0) { 630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(capture->queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { 631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(capture->queryctrl.type != V4L2_CTRL_TYPE_INTEGER && 636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.type != V4L2_CTRL_TYPE_BOOLEAN && 637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->queryctrl.type != V4L2_CTRL_TYPE_MENU) { 638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler c.id = ctrl_id; 642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &c) == 0) { 644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_add_ctrl_range(capture, &c); 645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic inline int channels_for_mode(int mode) 654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch(mode) { 656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_GRAY: 657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 1; 658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_YUYV: 659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 2; 660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 3; 662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName) 666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int detect_v4l2 = 0; 668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->deviceName = strdup(deviceName); 670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detect_v4l2 = try_init_v4l2(capture, deviceName); 672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (detect_v4l2 != 1) { 674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* init of the v4l2 device is not OK */ 675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* starting from here, we assume we are in V4L2 mode */ 679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->is_v4l2_device = 1; 680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->v4l2_ctrl_ranges = NULL; 682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->v4l2_ctrl_count = 0; 683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Scan V4L2 controls */ 685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_scan_controls(capture); 686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((capture->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) { 688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Nope. */ 689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L2: device %s is unable to capture video memory.\n",deviceName); 690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* The following code sets the CHANNEL_NUMBER of the video input. Some video sources 695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have sub "Channel Numbers". For a typical V4L TV capture card, this is usually 1. 696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler I myself am using a simple NTSC video input capture card that uses the value of 1. 697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler If you are not in North America or have a different video standard, you WILL have to change 698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the following settings and recompile/reinstall. This set of settings is based on 699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the most commonly encountered input video source types (like my bttv card) */ 700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(capture->inp.index > 0) { 702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->inp); 703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->inp.index = CHANNEL_NUMBER; 704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Set only channel number to CHANNEL_NUMBER */ 705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* V4L2 have a status field from selected video mode */ 706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_ENUMINPUT, &capture->inp)) 707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf (stderr, "VIDEOIO ERROR: V4L2: Aren't able to set channel number\n"); 709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L (capture); 710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* End if */ 713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Find Window info */ 715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->form); 716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) { 719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L2: Could not obtain specifics of capture window.\n\n"); 720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* libv4l will convert from any format to V4L2_PIX_FMT_BGR24, 725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler V4L2_PIX_FMT_RGV24, or V4L2_PIX_FMT_YUV420 */ 726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned int requestedPixelFormat; 727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (capture->mode) { 728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_RGB: 729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler requestedPixelFormat = V4L2_PIX_FMT_RGB24; 730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_GRAY: 732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler requestedPixelFormat = V4L2_PIX_FMT_YUV420; 733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_YUYV: 735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler requestedPixelFormat = V4L2_PIX_FMT_YUYV; 736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler requestedPixelFormat = V4L2_PIX_FMT_BGR24; 739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->form); 742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.pixelformat = requestedPixelFormat; 744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.field = V4L2_FIELD_ANY; 745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.width = capture->width; 746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.height = capture->height; 747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form)) { 749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: libv4l unable to ioctl S_FMT\n"); 750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (requestedPixelFormat != capture->form.fmt.pix.pixelformat) { 754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: libv4l unable convert to requested pixfmt\n"); 755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* icvSetVideoSize(capture, DEFAULT_V4L_WIDTH, DEFAULT_V4L_HEIGHT); */ 759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned int min; 761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Buggy driver paranoia. */ 763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler min = capture->form.fmt.pix.width * 2; 764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->form.fmt.pix.bytesperline < min) 766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.bytesperline = min; 767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler min = capture->form.fmt.pix.bytesperline * capture->form.fmt.pix.height; 769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->form.fmt.pix.sizeimage < min) 771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.sizeimage = min; 772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->req); 774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned int buffer_number = DEFAULT_V4L_BUFFERS; 776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler try_again: 778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->req.count = buffer_number; 780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->req.memory = V4L2_MEMORY_MMAP; 782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_REQBUFS, &capture->req)) 784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (EINVAL == errno) 786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf (stderr, "%s does not support memory mapping\n", deviceName); 788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("VIDIOC_REQBUFS"); 790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* free capture, and returns an error code */ 792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L (capture); 793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->req.count < buffer_number) 797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (buffer_number == 1) 799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf (stderr, "Insufficient buffer memory on %s\n", deviceName); 801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* free capture, and returns an error code */ 803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L (capture); 804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buffer_number--; 807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf (stderr, "Insufficient buffer memory on %s -- decreaseing buffers\n", deviceName); 808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto try_again; 810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (n_buffers = 0; n_buffers < capture->req.count; ++n_buffers) 814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_buffer buf; 816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (buf); 818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf.memory = V4L2_MEMORY_MMAP; 821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf.index = n_buffers; 822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYBUF, &buf)) { 824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("VIDIOC_QUERYBUF"); 825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* free capture, and returns an error code */ 827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L (capture); 828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->buffers[n_buffers].length = buf.length; 832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->buffers[n_buffers].start = 833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_mmap (NULL /* start anywhere */, 834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf.length, 835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PROT_READ | PROT_WRITE /* required */, 836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler MAP_SHARED /* recommended */, 837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->deviceHandle, buf.m.offset); 838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (MAP_FAILED == capture->buffers[n_buffers].start) { 840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("mmap"); 841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* free capture, and returns an error code */ 843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L (capture); 844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef USE_TEMP_BUFFER 848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (n_buffers == 0) { 849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->buffers[MAX_V4L_BUFFERS].start) { 850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler free(capture->buffers[MAX_V4L_BUFFERS].start); 851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->buffers[MAX_V4L_BUFFERS].start = NULL; 852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->buffers[MAX_V4L_BUFFERS].start = malloc(buf.length); 855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->buffers[MAX_V4L_BUFFERS].length = buf.length; 856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler }; 857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Set up Image data */ 861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvInitImageHeader( &capture->frame, 862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvSize( capture->captureWindow.width, 863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->captureWindow.height ), 864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler IPL_DEPTH_8U, channels_for_mode(capture->mode), 865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler IPL_ORIGIN_TL, 4 ); 866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Allocate space for RGBA data */ 867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); 868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 1; 870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}; /* End _capture_V4L2 */ 871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int _capture_V4L (CvCaptureCAM_V4L *capture, char *deviceName) 874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int detect_v4l = 0; 876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detect_v4l = try_init_v4l(capture, deviceName); 878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (detect_v4l == -1) 880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf (stderr, "VIDEOIO ERROR: V4L" 882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ": device %s: Unable to open for READ ONLY\n", deviceName); 883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (detect_v4l <= 0) 888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf (stderr, "VIDEOIO ERROR: V4L" 890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ": device %s: Unable to query number of channels\n", deviceName); 891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((capture->capability.type & VID_TYPE_CAPTURE) == 0) { 897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Nope. */ 898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L: " 899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "device %s is unable to capture video memory.\n",deviceName); 900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* The following code sets the CHANNEL_NUMBER of the video input. Some video sources 908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have sub "Channel Numbers". For a typical V4L TV capture card, this is usually 1. 909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler I myself am using a simple NTSC video input capture card that uses the value of 1. 910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler If you are not in North America or have a different video standard, you WILL have to change 911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the following settings and recompile/reinstall. This set of settings is based on 912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the most commonly encountered input video source types (like my bttv card) */ 913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 914793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(capture->capability.channels>0) { 917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct video_channel selectedChannel; 919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler selectedChannel.channel=CHANNEL_NUMBER; 921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl(capture->deviceHandle, VIDIOCGCHAN , &selectedChannel) != -1) { 922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* set the video mode to ( VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM) */ 923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// selectedChannel.norm = VIDEO_MODE_NTSC; 924793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl(capture->deviceHandle, VIDIOCSCHAN , &selectedChannel) == -1) { 925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Could not set selected channel - Oh well */ 926793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler //printf("\n%d, %s not NTSC capable.\n",selectedChannel.channel, selectedChannel.name); 927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* End if */ 928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* End if */ 929793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* End if */ 930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 934793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(v4l1_ioctl(capture->deviceHandle, VIDIOCGWIN, &capture->captureWindow) == -1) { 936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L: " 937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Could not obtain specifics of capture window.\n\n"); 938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 939793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 944793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(v4l1_ioctl(capture->deviceHandle, VIDIOCGPICT, &capture->imageProperties) < 0) { 946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L: Unable to determine size of incoming image\n"); 947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 949793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int requestedVideoPalette; 952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int depth; 953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (capture->mode) { 954793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_GRAY: 955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler requestedVideoPalette = VIDEO_PALETTE_YUV420; 956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler depth = 8; 957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_YUYV: 959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler requestedVideoPalette = VIDEO_PALETTE_YUYV; 960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler depth = 16; 961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler requestedVideoPalette = VIDEO_PALETTE_RGB24; 964793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler depth = 24; 965793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 966793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 967793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->imageProperties.depth = depth; 968793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->imageProperties.palette = requestedVideoPalette; 969793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl(capture->deviceHandle, VIDIOCSPICT, &capture->imageProperties) < 0) { 970793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: libv4l unable to ioctl VIDIOCSPICT\n\n"); 971793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 972793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 973793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 974793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl(capture->deviceHandle, VIDIOCGPICT, &capture->imageProperties) < 0) { 975793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: libv4l unable to ioctl VIDIOCGPICT\n\n"); 976793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 977793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 978793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 979793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->imageProperties.palette != requestedVideoPalette) { 980793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: libv4l unable convert to requested pixfmt\n\n"); 981793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 982793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 983793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 984793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 985793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 986793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 987793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 988793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 989793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l1_ioctl(capture->deviceHandle, VIDIOCGMBUF, &capture->memoryBuffer); 990793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->memoryMap = (char *)v4l1_mmap(0, 991793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->memoryBuffer.size, 992793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PROT_READ | PROT_WRITE, 993793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler MAP_SHARED, 994793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->deviceHandle, 995793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 0); 996793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->memoryMap == MAP_FAILED) { 997793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L: Mapping Memmory from video source error: %s\n", strerror(errno)); 998793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 999793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1000793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1001793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1002793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Set up video_mmap structure pointing to this memory mapped area so each image may be 1003793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retrieved from an index value */ 1004793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mmaps = (struct video_mmap *) 1005793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (malloc(capture->memoryBuffer.frames * sizeof(struct video_mmap))); 1006793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!capture->mmaps) { 1007793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L: Could not memory map video frames.\n"); 1008793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 1009793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1010793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1011793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1012793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1013793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1014793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Set up Image data */ 1015793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvInitImageHeader( &capture->frame, 1016793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvSize( capture->captureWindow.width, 1017793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->captureWindow.height ), 1018793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler IPL_DEPTH_8U, channels_for_mode(capture->mode), 1019793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler IPL_ORIGIN_TL, 4 ); 1020793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Allocate space for RGBA data */ 1021793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); 1022793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1023793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 1; 1024793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}; /* End _capture_V4L */ 1025793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1026793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index) 1027793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1028793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static int autoindex; 1029793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler autoindex = 0; 1030793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1031793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char deviceName[MAX_DEVICE_DRIVER_NAME]; 1032793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1033793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!numCameras) 1034793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvInitCapture_V4L(); /* Havent called icvInitCapture yet - do it now! */ 1035793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!numCameras) 1036793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return NULL; /* Are there any /dev/video input sources? */ 1037793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1038793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler //search index in indexList 1039793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ( (index>-1) && ! ((1 << index) & indexList) ) 1040793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1041793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L: index %d is not correct!\n",index); 1042793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return NULL; /* Did someone ask for not correct video source number? */ 1043793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1044793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Allocate memory for this humongus CvCaptureCAM_V4L structure that contains ALL 1045793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the handles for V4L processing */ 1046793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CvCaptureCAM_V4L * capture = (CvCaptureCAM_V4L*)cvAlloc(sizeof(CvCaptureCAM_V4L)); 1047793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!capture) { 1048793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L: Could not allocate memory for capture process.\n"); 1049793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return NULL; 1050793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1051793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1052793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef USE_TEMP_BUFFER 1053793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->buffers[MAX_V4L_BUFFERS].start = NULL; 1054793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1055793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1056793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Select camera, or rather, V4L video source */ 1057793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (index<0) { // Asking for the first device available 1058793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (; autoindex<MAX_CAMERAS;autoindex++) 1059793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (indexList & (1<<autoindex)) 1060793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1061793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (autoindex==MAX_CAMERAS) 1062793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return NULL; 1063793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler index=autoindex; 1064793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler autoindex++;// i can recall icvOpenCAM_V4l with index=-1 for next camera 1065793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1066793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Print the CameraNumber at the end of the string with a width of one character */ 1067793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(deviceName, "/dev/video%1d", index); 1068793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1069793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* w/o memset some parts arent initialized - AKA: Fill it with zeros so it is clean */ 1070793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler memset(capture,0,sizeof(CvCaptureCAM_V4L)); 1071793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Present the routines needed for V4L funtionality. They are inserted as part of 1072793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the standard set of cv calls promoting transparency. "Vector Table" insertion. */ 1073793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->FirstCapture = 1; 1074793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1075793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* set the default size */ 1076793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->width = DEFAULT_V4L_WIDTH; 1077793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->height = DEFAULT_V4L_HEIGHT; 1078793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1079793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (_capture_V4L2 (capture, deviceName) == -1) { 1080793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 1081793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->is_v4l2_device = 0; 1082793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (_capture_V4L (capture, deviceName) == -1) { 1083793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 1084793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return NULL; 1085793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1086793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1087793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->is_v4l2_device = 1; 1088793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1089793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1090793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return capture; 1091793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}; /* End icvOpenCAM_V4L */ 1092793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1093793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_CAMV4L2 1094793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1095793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int read_frame_v4l2(CvCaptureCAM_V4L* capture) { 1096793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_buffer buf; 1097793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1098793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (buf); 1099793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf.memory = V4L2_MEMORY_MMAP; 1102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_DQBUF, &buf)) { 1104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (errno) { 1105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case EAGAIN: 1106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case EIO: 1109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Could ignore EIO, see spec. */ 1110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* fall through */ 1112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* display the error and stop processing */ 1115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("VIDIOC_DQBUF"); 1116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 1; 1117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler assert(buf.index < capture->req.count); 1121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef USE_TEMP_BUFFER 1123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler memcpy(capture->buffers[MAX_V4L_BUFFERS].start, 1124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->buffers[buf.index].start, 1125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->buffers[MAX_V4L_BUFFERS].length ); 1126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->bufferIndex = MAX_V4L_BUFFERS; 1127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler //printf("got data in buff %d, len=%d, flags=0x%X, seq=%d, used=%d)\n", 1128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // buf.index, buf.length, buf.flags, buf.sequence, buf.bytesused); 1129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else 1130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->bufferIndex = buf.index; 1131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf)) 1134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("VIDIOC_QBUF"); 1135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler //set timestamp in capture struct to be timestamp of most recent frame 1137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /** where timestamps refer to the instant the field or frame was received by the driver, not the capture time*/ 1138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->timestamp = buf.timestamp; //printf( "timestamp update done \n"); 1139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->sequence = buf.sequence; 1140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 1; 1142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void mainloop_v4l2(CvCaptureCAM_V4L* capture) { 1145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned int count; 1146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler count = 1; 1148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (count-- > 0) { 1150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 1151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fd_set fds; 1152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct timeval tv; 1153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int r; 1154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler FD_ZERO (&fds); 1156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler FD_SET (capture->deviceHandle, &fds); 1157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Timeout. */ 1159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tv.tv_sec = 10; 1160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tv.tv_usec = 0; 1161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler r = select (capture->deviceHandle+1, &fds, NULL, NULL, &tv); 1163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == r) { 1165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (EINTR == errno) 1166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 1167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("select"); 1169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (0 == r) { 1172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf (stderr, "select timeout\n"); 1173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* end the infinite loop */ 1175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (read_frame_v4l2 (capture)) 1179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvGrabFrameCAM_V4L(CvCaptureCAM_V4L* capture) { 1185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->FirstCapture) { 1187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Some general initialization must take place the first time through */ 1188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* This is just a technicality, but all buffers must be filled up before any 1190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler staggered SYNC is applied. SO, filler up. (see V4L HowTo) */ 1191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->is_v4l2_device == 1) 1193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (capture->bufferIndex = 0; 1196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->bufferIndex < ((int)capture->req.count); 1197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ++capture->bufferIndex) 1198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_buffer buf; 1201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (buf); 1203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf.memory = V4L2_MEMORY_MMAP; 1206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf.index = (unsigned long)capture->bufferIndex; 1207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf)) { 1209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("VIDIOC_QBUF"); 1210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* enable the streaming */ 1215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_STREAMON, 1217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &capture->type)) { 1218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* error enabling the stream */ 1219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("VIDIOC_STREAMON"); 1220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else 1223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (capture->bufferIndex = 0; 1226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->bufferIndex < (capture->memoryBuffer.frames-1); 1227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ++capture->bufferIndex) { 1228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mmaps[capture->bufferIndex].frame = capture->bufferIndex; 1230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mmaps[capture->bufferIndex].width = capture->captureWindow.width; 1231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mmaps[capture->bufferIndex].height = capture->captureWindow.height; 1232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mmaps[capture->bufferIndex].format = capture->imageProperties.palette; 1233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl(capture->deviceHandle, VIDIOCMCAPTURE, &capture->mmaps[capture->bufferIndex]) == -1) { 1235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L: Initial Capture Error: Unable to load initial memory buffers.\n"); 1236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* preparation is ok */ 1243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->FirstCapture = 0; 1244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->is_v4l2_device == 1) 1247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mainloop_v4l2(capture); 1250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else 1252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mmaps[capture->bufferIndex].frame = capture->bufferIndex; 1255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mmaps[capture->bufferIndex].width = capture->captureWindow.width; 1256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mmaps[capture->bufferIndex].height = capture->captureWindow.height; 1257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mmaps[capture->bufferIndex].format = capture->imageProperties.palette; 1258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl (capture->deviceHandle, VIDIOCMCAPTURE, 1260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &capture->mmaps[capture->bufferIndex]) == -1) { 1261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* capture is on the way, so just exit */ 1262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 1; 1263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ++capture->bufferIndex; 1266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->bufferIndex == capture->memoryBuffer.frames) { 1267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->bufferIndex = 0; 1268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return(1); 1273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { 1276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->is_v4l2_device == 0) 1278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* [FD] this really belongs here */ 1281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl(capture->deviceHandle, VIDIOCSYNC, &capture->mmaps[capture->bufferIndex].frame) == -1) { 1282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, "VIDEOIO ERROR: V4L: Could not SYNC to video stream. %s\n", strerror(errno)); 1283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Now get what has already been captured as a IplImage return */ 1288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* First, reallocate imageData if the frame size changed */ 1290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->is_v4l2_device == 1) 1292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(((unsigned long)capture->frame.width != capture->form.fmt.pix.width) 1295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler || ((unsigned long)capture->frame.height != capture->form.fmt.pix.height)) { 1296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvFree(&capture->frame.imageData); 1297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvInitImageHeader( &capture->frame, 1298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvSize( capture->form.fmt.pix.width, 1299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.height ), 1300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler IPL_DEPTH_8U, channels_for_mode(capture->mode), 1301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler IPL_ORIGIN_TL, 4 ); 1302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); 1303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else 1306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if((capture->frame.width != capture->mmaps[capture->bufferIndex].width) 1309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler || (capture->frame.height != capture->mmaps[capture->bufferIndex].height)) { 1310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvFree(&capture->frame.imageData); 1311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvInitImageHeader( &capture->frame, 1312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvSize( capture->captureWindow.width, 1313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->captureWindow.height ), 1314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler IPL_DEPTH_8U, channels_for_mode(capture->mode), 1315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler IPL_ORIGIN_TL, 4 ); 1316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); 1317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->is_v4l2_device == 1) 1322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(capture->buffers[capture->bufferIndex].start){ 1325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler memcpy((char *)capture->frame.imageData, 1326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (char *)capture->buffers[capture->bufferIndex].start, 1327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->frame.imageSize); 1328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else 1331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif /* HAVE_CAMV4L2 */ 1332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch(capture->imageProperties.palette) { 1335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case VIDEO_PALETTE_RGB24: 1336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case VIDEO_PALETTE_YUV420: 1337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case VIDEO_PALETTE_YUYV: 1338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler memcpy((char *)capture->frame.imageData, 1339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (char *)(capture->memoryMap + capture->memoryBuffer.offsets[capture->bufferIndex]), 1340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->frame.imageSize); 1341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf( stderr, 1344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "VIDEOIO ERROR: V4L: Cannot convert from palette %d to mode %d\n", 1345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->imageProperties.palette, 1346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mode); 1347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return(&capture->frame); 1353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* TODO: review this adaptation */ 1356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic double icvGetPropertyCAM_V4L (CvCaptureCAM_V4L* capture, 1357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int property_id ) { 1358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char name[32]; 1359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int is_v4l2_device = 0; 1360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* initialize the control structure */ 1361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (property_id) { 1362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_FRAME_WIDTH: 1363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_FRAME_HEIGHT: 1364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->form); 1365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) { 1367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* display an error message, and return an error code */ 1368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("VIDIOC_G_FMT"); 1369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl (capture->deviceHandle, VIDIOCGWIN, &capture->captureWindow) < 0) { 1370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf (stderr, " ERROR: V4L: Unable to determine size of incoming image\n"); 1371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 1372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int retval = (property_id == CV_CAP_PROP_FRAME_WIDTH)?capture->captureWindow.width:capture->captureWindow.height; 1375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return retval / 0xFFFF; 1376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (property_id == CV_CAP_PROP_FRAME_WIDTH)?capture->form.fmt.pix.width:capture->form.fmt.pix.height; 1379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_POS_MSEC: 1381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->FirstCapture) { 1382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler //would be maximally numerically stable to cast to convert as bits, but would also be counterintuitive to decode 1385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 1000 * capture->timestamp.tv_sec + ((double) capture->timestamp.tv_usec) / 1000; 1386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_POS_FRAMES: 1390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return capture->sequence; 1391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_FPS: { 1394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_streamparm sp; 1395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler memset (&sp, 0, sizeof(struct v4l2_streamparm)); 1396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (xioctl (capture->deviceHandle, VIDIOC_G_PARM, &sp) < 0){ 1398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L: Unable to get camera FPS\n"); 1399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (double) -1; 1400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // this is the captureable, not per say what you'll get.. 1403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler double framesPerSec = sp.parm.capture.timeperframe.denominator / (double) sp.parm.capture.timeperframe.numerator ; 1404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return framesPerSec; 1405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_MODE: 1410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return capture->mode; 1411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_BRIGHTNESS: 1413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Brightness"); 1414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_BRIGHTNESS; 1415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_CONTRAST: 1417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Contrast"); 1418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_CONTRAST; 1419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_SATURATION: 1421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Saturation"); 1422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_SATURATION; 1423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_HUE: 1425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Hue"); 1426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_HUE; 1427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_GAIN: 1429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Gain"); 1430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_GAIN; 1431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_EXPOSURE: 1433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Exposure"); 1434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_EXPOSURE; 1435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "<unknown property string>"); 1438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = property_id; 1439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &capture->control) == 0) { 1442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* all went well */ 1443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler is_v4l2_device = 1; 1444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L2: Unable to get property %s(%u) - %s\n", name, capture->control.id, strerror(errno)); 1446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (is_v4l2_device == 1) { 1449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get the min/max values */ 1450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int v4l2_min = v4l2_get_ctrl_min(capture, capture->control.id); 1451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int v4l2_max = v4l2_get_ctrl_max(capture, capture->control.id); 1452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((v4l2_min == -1) && (v4l2_max == -1)) { 1454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L2: Property %s(%u) not supported by device\n", name, property_id); 1455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* all was OK, so convert to 0.0 - 1.0 range, and return the value */ 1459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ((float)capture->control.value - v4l2_min) / (v4l2_max - v4l2_min); 1460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* TODO: review this section */ 1463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int retval = -1; 1464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (property_id) { 1466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_BRIGHTNESS: 1467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval = capture->imageProperties.brightness; 1468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_CONTRAST: 1470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval = capture->imageProperties.contrast; 1471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_SATURATION: 1473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval = capture->imageProperties.colour; 1474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_HUE: 1476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval = capture->imageProperties.hue; 1477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_GAIN: 1479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L: Gain control in V4L is not supported\n"); 1480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_EXPOSURE: 1483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L: Exposure control in V4L is not supported\n"); 1484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (retval == -1) { 1489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* there was a problem */ 1490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* all was OK, so convert to 0.0 - 1.0 range, and return the value */ 1493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return float (retval) / 0xFFFF; 1494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h) { 1498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->is_v4l2_device == 1) 1500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char deviceName[MAX_DEVICE_DRIVER_NAME]; 1502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(deviceName, "%s", capture->deviceName); 1503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 1504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _capture_V4L2(capture, deviceName); 1505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int cropHeight; 1507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int cropWidth; 1508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (capture->mode) { 1509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_GRAY: 1510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cropHeight = h*8; 1511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cropWidth = w*8; 1512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_YUYV: 1514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cropHeight = h*16; 1515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cropWidth = w*16; 1516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cropHeight = h*24; 1519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cropWidth = w*24; 1520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->crop); 1523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->crop.c.left = 0; 1525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->crop.c.top = 0; 1526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->crop.c.height = cropHeight; 1527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->crop.c.width = cropWidth; 1528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* set the crop area, but don't exit if the device don't support croping */ 1530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler xioctl (capture->deviceHandle, VIDIOC_S_CROP, &capture->crop); 1531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->form); 1533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* read the current setting, mainly to retreive the pixelformat information */ 1536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form); 1537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* set the values we want to change */ 1539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.width = w; 1540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.height = h; 1541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.win.chromakey = 0; 1542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.win.field = V4L2_FIELD_ANY; 1543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.win.clips = 0; 1544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.win.clipcount = 0; 1545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->form.fmt.pix.field = V4L2_FIELD_ANY; 1546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* ask the device to change the size 1548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * don't test if the set of the size is ok, because some device 1549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * don't allow changing the size, and we will get the real size 1550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * later */ 1551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler xioctl (capture->deviceHandle, VIDIOC_S_FMT, &capture->form); 1552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* try to set framerate to 30 fps */ 1554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_streamparm setfps; 1556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler memset (&setfps, 0, sizeof(struct v4l2_streamparm)); 1557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler setfps.parm.capture.timeperframe.numerator = 1; 1560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler setfps.parm.capture.timeperframe.denominator = 30; 1561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler xioctl (capture->deviceHandle, VIDIOC_S_PARM, &setfps); 1563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* we need to re-initialize some things, like buffers, because the size has 1566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * changed */ 1567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->FirstCapture = 1; 1568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Get window info again, to get the real value */ 1570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form)) 1571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L/V4L2: Could not obtain specifics of capture window.\n\n"); 1573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 1575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else 1582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture==0) return 0; 1585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (w>capture->capability.maxwidth) { 1586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler w=capture->capability.maxwidth; 1587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (h>capture->capability.maxheight) { 1589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler h=capture->capability.maxheight; 1590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->captureWindow.width=w; 1593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->captureWindow.height=h; 1594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ioctl(capture->deviceHandle, VIDIOCSWIN, &capture->captureWindow) < 0) { 1596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 1597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ioctl(capture->deviceHandle, VIDIOCGWIN, &capture->captureWindow) < 0) { 1601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 1602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->FirstCapture = 1; 1606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvSetControl (CvCaptureCAM_V4L* capture, int property_id, double value) { 1614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_control c; 1615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler __s32 ctrl_value; 1616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char name[32]; 1617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int is_v4l2 = 1; 1618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int v4l2_min = 0; 1619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int v4l2_max = 255; 1620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->v4l2_ctrl_ranges == NULL) { 1621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_scan_controls(capture); 1622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->control); 1625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CLEAR (capture->queryctrl); 1626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get current values */ 1628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (property_id) { 1629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_BRIGHTNESS: 1630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Brightness"); 1631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_BRIGHTNESS; 1632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_CONTRAST: 1634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Contrast"); 1635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_CONTRAST; 1636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_SATURATION: 1638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Saturation"); 1639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_SATURATION; 1640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_HUE: 1642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Hue"); 1643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_HUE; 1644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_GAIN: 1646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Gain"); 1647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_GAIN; 1648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_EXPOSURE: 1650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "Exposure"); 1651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = V4L2_CID_EXPOSURE; 1652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(name, "<unknown property string>"); 1655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->control.id = property_id; 1656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_min = v4l2_get_ctrl_min(capture, capture->control.id); 1659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_max = v4l2_get_ctrl_max(capture, capture->control.id); 1660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((v4l2_min == -1) && (v4l2_max == -1)) { 1662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L: Property %s(%u) not supported by device\n", name, property_id); 1663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(v4l2_ioctl(capture->deviceHandle, VIDIOC_G_CTRL, &capture->control) == 0) { 1667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* all went well */ 1668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L2: Unable to get property %s(%u) - %s\n", name, capture->control.id, strerror(errno)); 1670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l2_max != 0) { 1673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler double val = value; 1674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (value < 0.0) { 1675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler val = 0.0; 1676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else if (value > 1.0) { 1677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler val = 1.0; 1678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ctrl_value = val * (double)(v4l2_max - v4l2_min) + v4l2_min; 1680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ctrl_value = v4l2_get_ctrl_default(capture, capture->control.id) * (double)(v4l2_max - v4l2_min) + v4l2_min; 1682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* try and set value as if it was a v4l2 device */ 1685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler c.id = capture->control.id; 1686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler c.value = ctrl_value; 1687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l2_ioctl(capture->deviceHandle, VIDIOC_S_CTRL, &c) != 0) { 1688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* The driver may clamp the value or return ERANGE, ignored here */ 1689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (errno != ERANGE) { 1690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L2: Failed to set control \"%d\": %s (value %d)\n", c.id, strerror(errno), c.value); 1691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler is_v4l2 = 0; 1692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (is_v4l2 == 0) { /* use v4l1_ioctl */ 1700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO WARNING: Setting property %u through v4l2 failed. Trying with v4l1.\n", c.id); 1701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int v4l_value; 1702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* scale the value to the wanted integer one */ 1703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l_value = (int)(0xFFFF * value); 1704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (property_id) { 1706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_BRIGHTNESS: 1707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->imageProperties.brightness = v4l_value; 1708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_CONTRAST: 1710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->imageProperties.contrast = v4l_value; 1711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_SATURATION: 1713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->imageProperties.colour = v4l_value; 1714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_HUE: 1716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->imageProperties.hue = v4l_value; 1717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_GAIN: 1719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L: Gain control in V4L is not supported\n"); 1720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_EXPOSURE: 1722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L: Exposure control in V4L is not supported\n"); 1723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L: property #%d is not supported\n", property_id); 1726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (v4l1_ioctl(capture->deviceHandle, VIDIOCSPICT, &capture->imageProperties) < 0){ 1730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L: Unable to set video informations\n"); 1731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L(capture); 1732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return -1; 1733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* all was OK */ 1737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvSetPropertyCAM_V4L(CvCaptureCAM_V4L* capture, int property_id, double value){ 1741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static int width = 0, height = 0; 1742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int retval; 1743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* initialization */ 1745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval = 0; 1746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* two subsequent calls setting WIDTH and HEIGHT will change 1748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the video size */ 1749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* the first one will return an error, though. */ 1750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (property_id) { 1752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_FRAME_WIDTH: 1753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler width = cvRound(value); 1754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->width = width; 1755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(width !=0 && height != 0) { 1756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval = icvSetVideoSize( capture, width, height); 1757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler width = height = 0; 1758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_FRAME_HEIGHT: 1761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler height = cvRound(value); 1762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->height = height; 1763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(width !=0 && height != 0) { 1764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval = icvSetVideoSize( capture, width, height); 1765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler width = height = 0; 1766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_MODE: 1769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int mode; 1770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mode = cvRound(value); 1771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->mode != mode) { 1772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (mode) { 1773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_BGR: 1774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_RGB: 1775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_GRAY: 1776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_MODE_YUYV: 1777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->mode = mode; 1778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* recreate the capture buffer for the same output resolution 1779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler but a different pixel format */ 1780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval = icvSetVideoSize(capture, capture->width, capture->height); 1781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L/V4L2: Unsupported mode: %d\n", mode); 1784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval=0; 1785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_CAP_PROP_FPS: 1790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct v4l2_streamparm setfps; 1791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler memset (&setfps, 0, sizeof(struct v4l2_streamparm)); 1792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler setfps.parm.capture.timeperframe.numerator = 1; 1794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler setfps.parm.capture.timeperframe.denominator = value; 1795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (xioctl (capture->deviceHandle, VIDIOC_S_PARM, &setfps) < 0){ 1796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fprintf(stderr, "VIDEOIO ERROR: V4L: Unable to set camera FPS\n"); 1797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval=0; 1798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler retval = icvSetControl(capture, property_id, value); 1802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* return the the status */ 1805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return retval; 1806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ){ 1809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Deallocate space - Hopefully, no leaks */ 1810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture) { 1811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_free_ranges(capture); 1812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->is_v4l2_device == 0) { 1813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->mmaps) { 1814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler free(capture->mmaps); 1815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->memoryMap) { 1817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l1_munmap(capture->memoryMap, capture->memoryBuffer.size); 1818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->deviceHandle != -1) { 1820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l1_close(capture->deviceHandle); 1821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (xioctl(capture->deviceHandle, VIDIOC_STREAMOFF, &capture->type) < 0) { 1825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("Unable to stop the stream."); 1826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (unsigned int n_buffers2 = 0; n_buffers2 < capture->req.count; ++n_buffers2) { 1828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (-1 == v4l2_munmap (capture->buffers[n_buffers2].start, capture->buffers[n_buffers2].length)) { 1829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler perror ("munmap"); 1830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->deviceHandle != -1) { 1834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler v4l2_close(capture->deviceHandle); 1835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->frame.imageData) 1839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvFree(&capture->frame.imageData); 1840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef USE_TEMP_BUFFER 1842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (capture->buffers[MAX_V4L_BUFFERS].start) { 1843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler free(capture->buffers[MAX_V4L_BUFFERS].start); 1844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->buffers[MAX_V4L_BUFFERS].start = NULL; 1845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler free(capture->deviceName); 1849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler capture->deviceName = NULL; 1850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler //v4l2_free_ranges(capture); 1851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler //cvFree((void **)capture); 1852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}; 1854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass CvCaptureCAM_V4L_CPP : CvCapture 1857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpublic: 1859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CvCaptureCAM_V4L_CPP() { captureV4L = 0; } 1860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler virtual ~CvCaptureCAM_V4L_CPP() { close(); } 1861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler virtual bool open( int index ); 1863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler virtual void close(); 1864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler virtual double getProperty(int) const; 1866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler virtual bool setProperty(int, double); 1867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler virtual bool grabFrame(); 1868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler virtual IplImage* retrieveFrame(int); 1869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerprotected: 1870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CvCaptureCAM_V4L* captureV4L; 1872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}; 1873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool CvCaptureCAM_V4L_CPP::open( int index ) 1875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler close(); 1877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler captureV4L = icvCaptureFromCAM_V4L(index); 1878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return captureV4L != 0; 1879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid CvCaptureCAM_V4L_CPP::close() 1882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( captureV4L ) 1884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler icvCloseCAM_V4L( captureV4L ); 1886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvFree( &captureV4L ); 1887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool CvCaptureCAM_V4L_CPP::grabFrame() 1891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return captureV4L ? icvGrabFrameCAM_V4L( captureV4L ) != 0 : false; 1893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1895793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerIplImage* CvCaptureCAM_V4L_CPP::retrieveFrame(int) 1896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return captureV4L ? icvRetrieveFrameCAM_V4L( captureV4L, 0 ) : 0; 1898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerdouble CvCaptureCAM_V4L_CPP::getProperty( int propId ) const 1901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return captureV4L ? icvGetPropertyCAM_V4L( captureV4L, propId ) : 0.0; 1903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool CvCaptureCAM_V4L_CPP::setProperty( int propId, double value ) 1906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return captureV4L ? icvSetPropertyCAM_V4L( captureV4L, propId, value ) != 0 : false; 1908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1910793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCvCapture* cvCreateCameraCapture_V4L( int index ) 1911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CvCaptureCAM_V4L_CPP* capture = new CvCaptureCAM_V4L_CPP; 1913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1914793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( capture->open( index )) 1915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (CvCapture*)capture; 1916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler delete capture; 1918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 1919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1922