From 681ffd9a215c5be006999a57b890ee446b4bd801 Mon Sep 17 00:00:00 2001 From: Patrick Welche Date: Mon, 17 Sep 2012 12:03:35 +0200 Subject: [PATCH] NetBSD video(4) support, patch 2 of 3 * Decouple Video4Linux2 support from Video4Linux as existence of v4l2 on a system does not imply support for v4l. * Don't use V4L's struct video_window in V4L2 code. * Removed __USE_GNU as comment says: /* support for MJPEG is only available with libjpeg and gcc, because it's use libjepg and fmemopen() so replace with test for fmemopen() if found necessary. --- modules/highgui/src/cap.cpp | 5 +- modules/highgui/src/cap_v4l.cpp | 181 +++++++++++++++++++++----------- 2 files changed, 123 insertions(+), 63 deletions(-) diff --git a/modules/highgui/src/cap.cpp b/modules/highgui/src/cap.cpp index 821478f1b3..13475f2633 100644 --- a/modules/highgui/src/cap.cpp +++ b/modules/highgui/src/cap.cpp @@ -172,7 +172,8 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index) defined(HAVE_TYZX) || \ defined(HAVE_VFW) || \ defined(HAVE_LIBV4L) || \ - (defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2)) || \ + defined(HAVE_CAMV4L) || \ + defined(HAVE_CAMV4L2) || \ defined(HAVE_VIDEOIO) || \ defined(HAVE_GSTREAMER) || \ defined(HAVE_DC1394_2) || \ @@ -217,7 +218,7 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index) return capture; #endif -#if defined HAVE_LIBV4L || (defined (HAVE_CAMV4L) && defined (HAVE_CAMV4L2)) || defined HAVE_VIDEOIO +#if defined HAVE_LIBV4L || defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO capture = cvCreateCameraCapture_V4L (index); if (capture) return capture; diff --git a/modules/highgui/src/cap_v4l.cpp b/modules/highgui/src/cap_v4l.cpp index 33e0f386aa..a0d51e8d89 100644 --- a/modules/highgui/src/cap_v4l.cpp +++ b/modules/highgui/src/cap_v4l.cpp @@ -202,7 +202,7 @@ make & enjoy! #include "precomp.hpp" -#if !defined WIN32 && ((defined HAVE_CAMV4L && defined HAVE_CAMV4L2) || defined HAVE_VIDEOIO) +#if !defined WIN32 && (defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO) #define CLEAR(x) memset (&(x), 0, sizeof (x)) @@ -214,16 +214,18 @@ make & enjoy! #include #include +#ifdef HAVE_CAMVAL #include +#endif #include #include -#include /* for videodev2.h */ #include #include #include #ifdef HAVE_CAMV4L2 +#include /* for videodev2.h */ #include #endif @@ -293,11 +295,13 @@ typedef struct CvCaptureCAM_V4L int deviceHandle; int bufferIndex; int FirstCapture; +#ifdef HAVE_CAMV4L struct video_capability capability; struct video_window captureWindow; struct video_picture imageProperties; struct video_mbuf memoryBuffer; struct video_mmap *mmaps; +#endif /* HAVE_CAMV4L */ char *memoryMap; IplImage frame; @@ -350,9 +354,6 @@ static int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h); static int numCameras = 0; static int indexList = 0; -#ifdef HAVE_CAMV4L2 - -// IOCTL handling for V4L2 static int xioctl( int fd, int request, void *arg) { @@ -366,8 +367,6 @@ static int xioctl( int fd, int request, void *arg) } -#endif /* HAVE_CAMV4L2 */ - /* Simple test program: Find number of Video Sources available. Start from 0 and go to MAX_CAMERAS while checking for the device with that name. If it fails on the first attempt of /dev/video0, then check if /dev/video is valid. @@ -398,6 +397,8 @@ static void icvInitCapture_V4L() { }; /* End icvInitCapture_V4L */ +#ifdef HAVE_CAMV4L + static int try_palette(int fd, struct video_picture *cam_pic, @@ -415,6 +416,8 @@ try_palette(int fd, return 0; } +#endif /* HAVE_CAMV4L */ + #ifdef HAVE_CAMV4L2 static int try_palette_v4l2(CvCaptureCAM_V4L* capture, unsigned long colorspace) @@ -439,6 +442,8 @@ static int try_palette_v4l2(CvCaptureCAM_V4L* capture, unsigned long colorspace) #endif /* HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName) { @@ -454,7 +459,6 @@ static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName) /* No matter what the name - it still must be opened! */ capture->deviceHandle = open(deviceName, O_RDWR); - if (capture->deviceHandle == 0) { detect = -1; @@ -468,7 +472,6 @@ static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName) if (ioctl(capture->deviceHandle, VIDIOCGCAP, &capture->capability) < 0) { detect = 0; - icvCloseCAM_V4L(capture); } else @@ -481,54 +484,64 @@ static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName) } +#endif /* HAVE_CAMV4L */ + #ifdef HAVE_CAMV4L2 static int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName) { - - // if detect = -1 then unable to open device - // if detect = 0 then detected nothing - // if detect = 1 then V4L2 device - int detect = 0; - - // Test device for V4L2 compability + // Return value: + // -1 then unable to open device + // 0 then detected nothing + // 1 then V4L2 device + + int deviceIndex; /* Open and test V4L2 device */ capture->deviceHandle = open (deviceName, O_RDWR /* required */ | O_NONBLOCK, 0); - - - - if (capture->deviceHandle == 0) + if (-1 == capture->deviceHandle) { - detect = -1; - +#ifndef NDEBUG + fprintf(stderr, "(DEBUG) try_init_v4l2 open \"%s\": %s\n", deviceName, strerror(errno)); +#endif icvCloseCAM_V4L(capture); + return -1; } - if (detect == 0) + CLEAR (capture->cap); + if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYCAP, &capture->cap)) { - CLEAR (capture->cap); - if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYCAP, &capture->cap)) - { - detect = 0; +#ifndef NDEBUG + fprintf(stderr, "(DEBUG) try_init_v4l2 VIDIOC_QUERYCAP \"%s\": %s\n", deviceName, strerror(errno)); +#endif + icvCloseCAM_V4L(capture); + return 0; + } - icvCloseCAM_V4L(capture); - } - else - { - CLEAR (capture->capability); - capture->capability.type = capture->cap.capabilities; + /* Query channels number */ + if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_INPUT, &deviceIndex)) + { +#ifndef NDEBUG + fprintf(stderr, "(DEBUG) try_init_v4l2 VIDIOC_G_INPUT \"%s\": %s\n", deviceName, strerror(errno)); +#endif + icvCloseCAM_V4L(capture); + return 0; + } - /* Query channels number */ - if (-1 != xioctl (capture->deviceHandle, VIDIOC_G_INPUT, &capture->capability.channels)) - { - detect = 1; - } - } + /* Query information about current input */ + CLEAR (capture->inp); + capture->inp.index = deviceIndex; + if (-1 == xioctl (capture->deviceHandle, VIDIOC_ENUMINPUT, &capture->inp)) + { +#ifndef NDEBUG + fprintf(stderr, "(DEBUG) try_init_v4l2 VIDIOC_ENUMINPUT \"%s\": %s\n", deviceName, strerror(errno)); +#endif + icvCloseCAM_V4L(capture); + return 0; } - return detect; + return 1; } @@ -551,17 +564,12 @@ static int autosetup_capture_mode_v4l2(CvCaptureCAM_V4L* capture) else #ifdef HAVE_JPEG -#ifdef __USE_GNU - /* support for MJPEG is only available with libjpeg and gcc, - because it's use libjepg and fmemopen() - */ if (try_palette_v4l2(capture, V4L2_PIX_FMT_MJPEG) == 0 || try_palette_v4l2(capture, V4L2_PIX_FMT_JPEG) == 0) { capture->palette = PALETTE_MJPEG; } else -#endif #endif if (try_palette_v4l2(capture, V4L2_PIX_FMT_YUYV) == 0) @@ -598,6 +606,8 @@ static int autosetup_capture_mode_v4l2(CvCaptureCAM_V4L* capture) #endif /* HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + static int autosetup_capture_mode_v4l(CvCaptureCAM_V4L* capture) { @@ -631,6 +641,8 @@ static int autosetup_capture_mode_v4l(CvCaptureCAM_V4L* capture) } +#endif /* HAVE_CAMV4L */ + #ifdef HAVE_CAMV4L2 static void v4l2_scan_controls_enumerate_menu(CvCaptureCAM_V4L* capture) @@ -981,8 +993,8 @@ static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName) /* Set up Image data */ cvInitImageHeader( &capture->frame, - cvSize( capture->captureWindow.width, - capture->captureWindow.height ), + cvSize( capture->form.fmt.pix.width, + capture->form.fmt.pix.height ), IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 ); /* Allocate space for RGBA data */ capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); @@ -992,6 +1004,8 @@ static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName) #endif /* HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L + static int _capture_V4L (CvCaptureCAM_V4L *capture, char *deviceName) { int detect_v4l = 0; @@ -1110,6 +1124,8 @@ static int _capture_V4L (CvCaptureCAM_V4L *capture, char *deviceName) return 1; }; /* End _capture_V4L */ +#endif /* HAVE_CAMV4L */ + static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index) { static int autoindex; @@ -1159,10 +1175,12 @@ static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index) icvCloseCAM_V4L(capture); V4L2_SUPPORT = 0; #endif /* HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L if (_capture_V4L (capture, deviceName) == -1) { icvCloseCAM_V4L(capture); return NULL; } +#endif /* HAVE_CAMV4L */ #ifdef HAVE_CAMV4L2 } else { V4L2_SUPPORT = 1; @@ -1271,7 +1289,9 @@ static int icvGrabFrameCAM_V4L(CvCaptureCAM_V4L* capture) { #ifdef HAVE_CAMV4L2 +#ifdef HAVE_CAMV4L if (V4L2_SUPPORT == 1) +#endif { for (capture->bufferIndex = 0; @@ -1301,8 +1321,12 @@ static int icvGrabFrameCAM_V4L(CvCaptureCAM_V4L* capture) { perror ("VIDIOC_STREAMON"); return 0; } - } else + } #endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L { for (capture->bufferIndex = 0; @@ -1321,6 +1345,7 @@ static int icvGrabFrameCAM_V4L(CvCaptureCAM_V4L* capture) { } } +#endif /* HAVE_CAMV4L */ #if defined(V4L_ABORT_BADJPEG) && defined(HAVE_CAMV4L2) if (V4L2_SUPPORT == 1) @@ -1342,8 +1367,12 @@ static int icvGrabFrameCAM_V4L(CvCaptureCAM_V4L* capture) { mainloop_v4l2(capture); - } else + } #endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L { capture->mmaps[capture->bufferIndex].frame = capture->bufferIndex; @@ -1363,6 +1392,7 @@ static int icvGrabFrameCAM_V4L(CvCaptureCAM_V4L* capture) { } } +#endif /* HAVE_CAMV4L */ return(1); } @@ -2080,6 +2110,7 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { #ifdef HAVE_CAMV4L2 if (V4L2_SUPPORT == 0) #endif /* HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L { /* [FD] this really belongs here */ @@ -2088,6 +2119,7 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { } } +#endif /* HAVE_CAMV4L */ /* Now get what has already been captured as a IplImage return */ @@ -2108,8 +2140,12 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize); } - } else + } #endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L { if((capture->frame.width != capture->mmaps[capture->bufferIndex].width) @@ -2123,6 +2159,7 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { } } +#endif /* HAVE_CAMV4L */ #ifdef HAVE_CAMV4L2 @@ -2150,10 +2187,6 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { (unsigned char*)capture->frame.imageData); break; #ifdef HAVE_JPEG -#ifdef __USE_GNU - /* support for MJPEG is only available with libjpeg and gcc, - because it's use libjepg and fmemopen() - */ case PALETTE_MJPEG: if (!mjpeg_to_rgb24(capture->form.fmt.pix.width, capture->form.fmt.pix.height, @@ -2163,7 +2196,6 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { (unsigned char*)capture->frame.imageData)) return 0; break; -#endif #endif case PALETTE_YUYV: @@ -2206,8 +2238,12 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { (unsigned char*)capture->frame.imageData); break; } - } else + } #endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L { switch(capture->imageProperties.palette) { @@ -2243,6 +2279,7 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { } } +#endif /* HAVE_CAMV4L */ return(&capture->frame); } @@ -2252,7 +2289,9 @@ static double icvGetPropertyCAM_V4L (CvCaptureCAM_V4L* capture, #ifdef HAVE_CAMV4L2 +#ifdef HAVE_CAMV4L if (V4L2_SUPPORT == 1) +#endif { /* default value for min and max */ @@ -2363,8 +2402,12 @@ static double icvGetPropertyCAM_V4L (CvCaptureCAM_V4L* capture, /* all was OK, so convert to 0.0 - 1.0 range, and return the value */ return ((float)capture->control.value - v4l2_min + 1) / (v4l2_max - v4l2_min); - } else + } #endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L { int retval = -1; @@ -2422,6 +2465,7 @@ static double icvGetPropertyCAM_V4L (CvCaptureCAM_V4L* capture, return float (retval) / 0xFFFF; } +#endif /* HAVE_CAMV4L */ }; @@ -2494,8 +2538,12 @@ static int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h) { return 0; - } else + } #endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L { if (capture==0) return 0; @@ -2522,6 +2570,7 @@ static int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h) { capture->FirstCapture = 1; } +#endif /* HAVE_CAMV4L */ return 0; @@ -2653,8 +2702,12 @@ static int icvSetControl (CvCaptureCAM_V4L* capture, perror ("VIDIOC_S_CTRL"); return -1; } - } else + } #endif /* HAVE_CAMV4L2 */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L { int v4l_value; @@ -2699,6 +2752,7 @@ static int icvSetControl (CvCaptureCAM_V4L* capture, return -1; } } +#endif /* HAVE_CAMV4L */ /* all was OK */ return 0; @@ -2759,6 +2813,7 @@ static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ){ #ifdef HAVE_CAMV4L2 if (V4L2_SUPPORT == 0) #endif /* HAVE_CAMV4L2 */ +#ifdef HAVE_CAMV4L { if (capture->mmaps) @@ -2767,10 +2822,14 @@ static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ){ munmap(capture->memoryMap, capture->memoryBuffer.size); } +#endif /* HAVE_CAMV4L */ +#if defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2) + else +#endif /* HAVE_CAMV4L && HAVE_CAMV4L2 */ #ifdef HAVE_CAMV4L2 - else { + { capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (ioctl(capture->deviceHandle, VIDIOC_STREAMOFF, &capture->type) < 0) { + if (-1 == ioctl(capture->deviceHandle, VIDIOC_STREAMOFF, &capture->type)) { perror ("Unable to stop the stream."); }