From b9b40a73bab744e9605773b0983ea3a3bc7644d6 Mon Sep 17 00:00:00 2001 From: "Anton V. Shokurov" Date: Wed, 28 Oct 2015 07:37:51 -0400 Subject: [PATCH] Exposure and autofocus properties fixed/added. Exposure can now be manually controlled (implemented only in libv4l). Will work only with a kernel version >= 4.5. Autofocus can be enabled/disabled. --- modules/videoio/src/cap_libv4l.cpp | 74 +++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/modules/videoio/src/cap_libv4l.cpp b/modules/videoio/src/cap_libv4l.cpp index 46fac95..e6b80ba 100644 --- a/modules/videoio/src/cap_libv4l.cpp +++ b/modules/videoio/src/cap_libv4l.cpp @@ -1352,6 +1352,29 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) { return(&capture->frame); } +static int zeroPropertyQuietly(CvCaptureCAM_V4L* capture, int property_id, int value) +{ + struct v4l2_control c; + int v4l2_min; + int v4l2_max; + //we need to make sure that the autocontrol is switch off, if available. + capture->control.id = property_id; + v4l2_min = v4l2_get_ctrl_min(capture, capture->control.id); + v4l2_max = v4l2_get_ctrl_max(capture, capture->control.id); + if ( !((v4l2_min == -1) && (v4l2_max == -1)) ) { + //autocontrol capability is supported, switch it off. + c.id = capture->control.id; + c.value = value; + if( v4l2_ioctl(capture->deviceHandle, VIDIOC_S_CTRL, &c) != 0 ){ + if (errno != ERANGE) { + fprintf(stderr, "VIDEOIO ERROR: V4L2: Failed to set autocontrol \"%d\": %s (value %d)\n", c.id, strerror(errno), c.value); + return -1; + } + } + }//lack of support should not be considerred an error. + return 0; +} + /* TODO: review this adaptation */ static double icvGetPropertyCAM_V4L (CvCaptureCAM_V4L* capture, int property_id ) { @@ -1431,32 +1454,15 @@ static double icvGetPropertyCAM_V4L (CvCaptureCAM_V4L* capture, break; case CV_CAP_PROP_EXPOSURE: sprintf(name, "Exposure"); - capture->control.id = V4L2_CID_EXPOSURE; + capture->control.id = V4L2_CID_EXPOSURE_ABSOLUTE; break; - case CV_CAP_PROP_FOCUS: { - struct v4l2_control c; - int v4l2_min; - int v4l2_max; - //we need to make sure that the autofocus is switch off, if available. - capture->control.id = V4L2_CID_FOCUS_AUTO; - v4l2_min = v4l2_get_ctrl_min(capture, capture->control.id); - v4l2_max = v4l2_get_ctrl_max(capture, capture->control.id); - if ( !((v4l2_min == -1) && (v4l2_max == -1)) ) { - //autofocus capability is supported, switch it off. - c.id = capture->control.id; - c.value = 0;//off - if( v4l2_ioctl(capture->deviceHandle, VIDIOC_S_CTRL, &c) != 0 ){ - if (errno != ERANGE) { - fprintf(stderr, "VIDEOIO ERROR: V4L2: Failed to set control \"%d\"(FOCUS_AUTO): %s (value %d)\n", c.id, strerror(errno), c.value); - return -1; - } - } - }//lack of support should not be considerred an error. - + case CV_CAP_PROP_FOCUS: sprintf(name, "Focus"); capture->control.id = V4L2_CID_FOCUS_ABSOLUTE; break; - } + case CV_CAP_PROP_AUTOFOCUS: + sprintf(name, "Autofocus"); + capture->control.id = V4L2_CID_FOCUS_AUTO; default: sprintf(name, ""); capture->control.id = property_id; @@ -1671,30 +1677,22 @@ static int icvSetControl (CvCaptureCAM_V4L* capture, int property_id, double val capture->control.id = V4L2_CID_GAIN; break; case CV_CAP_PROP_EXPOSURE: + //we need to make sure that the autoexposure is switch off, if available. + zeroPropertyQuietly(capture, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL); + //now get the manual exposure value sprintf(name, "Exposure"); - capture->control.id = V4L2_CID_EXPOSURE; + capture->control.id = V4L2_CID_EXPOSURE_ABSOLUTE; break; case CV_CAP_PROP_FOCUS: //we need to make sure that the autofocus is switch off, if available. - capture->control.id = V4L2_CID_FOCUS_AUTO; - v4l2_min = v4l2_get_ctrl_min(capture, capture->control.id); - v4l2_max = v4l2_get_ctrl_max(capture, capture->control.id); - if ( !((v4l2_min == -1) && (v4l2_max == -1)) ) { - //autofocus capability is supported, switch it off. - c.id = capture->control.id; - c.value = 0;//off - if( v4l2_ioctl(capture->deviceHandle, VIDIOC_S_CTRL, &c) != 0 ){ - if (errno != ERANGE) { - fprintf(stderr, "VIDEOIO ERROR: V4L2: Failed to set control \"%d\"(FOCUS_AUTO): %s (value %d)\n", c.id, strerror(errno), c.value); - return -1; - } - } - }//lack of support should not be considerred an error. - + zeroPropertyQuietly(capture, V4L2_CID_FOCUS_AUTO, 0 /*off*/); //now set the manual focus sprintf(name, "Focus"); capture->control.id = V4L2_CID_FOCUS_ABSOLUTE; break; + case CV_CAP_PROP_AUTOFOCUS: + sprintf(name, "Autofocus"); + capture->control.id = V4L2_CID_FOCUS_AUTO; default: sprintf(name, ""); capture->control.id = property_id; -- 2.7.4