[libcamera-devel,v3,2/5] libcamera: uvcvideo: Update exposure/gain ctrls set with new units

Message ID 20200403145305.10288-3-naush@raspberrypi.com
State Superseded
Headers show
Series
  • Patchset for libcamera controls
Related show

Commit Message

Naushir Patuck April 3, 2020, 2:53 p.m. UTC
The ExposureTime control now uses units of 1 micro-second, and UVC
uses units of 100 micro-seconds. Correctly map the values before
setting V4L2_CID_EXPOSURE_ABSOLUTE on the V4L2 device.

The AnalogueGain control now uses floats to allow fractional gain
values. Since UVC has no explicit gain units, map the default gain value
to 1.0 and linearly map to the requested value.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
---
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

Comments

Laurent Pinchart April 23, 2020, 5:36 p.m. UTC | #1
Hi Naush,

Thank you for the patch.

On Fri, Apr 03, 2020 at 03:53:02PM +0100, Naushir Patuck wrote:
> The ExposureTime control now uses units of 1 micro-second, and UVC
> uses units of 100 micro-seconds. Correctly map the values before
> setting V4L2_CID_EXPOSURE_ABSOLUTE on the V4L2 device.
> 
> The AnalogueGain control now uses floats to allow fractional gain
> values. Since UVC has no explicit gain units, map the default gain value
> to 1.0 and linearly map to the requested value.
> 
> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> index d7df95e4..9d589f69 100644
> --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
> @@ -253,9 +253,22 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
>  			controls.set(V4L2_CID_SATURATION, value);
>  		} else if (id == controls::ExposureTime) {
>  			controls.set(V4L2_CID_EXPOSURE_AUTO, static_cast<int32_t>(1));
> -			controls.set(V4L2_CID_EXPOSURE_ABSOLUTE, value);
> +			/*
> +			 * controls::ExposureTime is in units of 1 us, and UVC
> +			 * expects V4L2_CID_EXPOSURE_ABSOLUTE in units of 100 us.
> +			 */
> +			controls.set(V4L2_CID_EXPOSURE_ABSOLUTE,
> +				     value.get<int32_t>() / 100);
>  		} else if (id == controls::AnalogueGain) {
> -			controls.set(V4L2_CID_GAIN, value);
> +			/*
> +			 * controls::AnalogueGain is specified as an absolute
> +			 * multiplier for all RGB samples. Map this multiplier
> +			 * in a linear way such that 1.0 -> default gain
> +			 * of the V4L2_CID_GAIN control on the uvcvideo device.
> +			 */
> +			const ControlInfo &gainInfo = controls.infoMap()->at(V4L2_CID_GAIN);
> +			int32_t gain = value.get<float>() * gainInfo.def().get<int32_t>();
> +			controls.set(V4L2_CID_GAIN, gain);
>  		}
>  	}
>

Patch

diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index d7df95e4..9d589f69 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -253,9 +253,22 @@  int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
 			controls.set(V4L2_CID_SATURATION, value);
 		} else if (id == controls::ExposureTime) {
 			controls.set(V4L2_CID_EXPOSURE_AUTO, static_cast<int32_t>(1));
-			controls.set(V4L2_CID_EXPOSURE_ABSOLUTE, value);
+			/*
+			 * controls::ExposureTime is in units of 1 us, and UVC
+			 * expects V4L2_CID_EXPOSURE_ABSOLUTE in units of 100 us.
+			 */
+			controls.set(V4L2_CID_EXPOSURE_ABSOLUTE,
+				     value.get<int32_t>() / 100);
 		} else if (id == controls::AnalogueGain) {
-			controls.set(V4L2_CID_GAIN, value);
+			/*
+			 * controls::AnalogueGain is specified as an absolute
+			 * multiplier for all RGB samples. Map this multiplier
+			 * in a linear way such that 1.0 -> default gain
+			 * of the V4L2_CID_GAIN control on the uvcvideo device.
+			 */
+			const ControlInfo &gainInfo = controls.infoMap()->at(V4L2_CID_GAIN);
+			int32_t gain = value.get<float>() * gainInfo.def().get<int32_t>();
+			controls.set(V4L2_CID_GAIN, gain);
 		}
 	}