[libcamera-devel,v3,2/8] libcamera: pipeline: uvcvideo: Support the new AE controls
diff mbox series

Message ID 20211221043610.2512334-3-paul.elder@ideasonboard.com
State New
Delegated to: Paul Elder
Headers show
Series
  • The Great AE Changes
Related show

Commit Message

Paul Elder Dec. 21, 2021, 4:36 a.m. UTC
Add support for the new AE controls in the uvcvideo pipeline handler.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=42
Bug: https://bugs.libcamera.org/show_bug.cgi?id=43
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>

---
Changes in v3:
- fix the construction of the ControlInfo of enum values
- fix auto gain in processControl
- improve auto exposure in processControl

Changes in v2:
- fix the rebase error where some uvc stuff was in rasberrypi
---
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 43 +++++++++++++++++---
 1 file changed, 38 insertions(+), 5 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 40654a0b..ee17add8 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -268,8 +268,10 @@  int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,
 		cid = V4L2_CID_CONTRAST;
 	else if (id == controls::Saturation)
 		cid = V4L2_CID_SATURATION;
-	else if (id == controls::AeEnable)
+	else if (id == controls::ExposureTimeMode)
 		cid = V4L2_CID_EXPOSURE_AUTO;
+	else if (id == controls::AnalogueGainMode)
+		cid = V4L2_CID_AUTOGAIN;
 	else if (id == controls::ExposureTime)
 		cid = V4L2_CID_EXPOSURE_ABSOLUTE;
 	else if (id == controls::AnalogueGain)
@@ -302,13 +304,44 @@  int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,
 	}
 
 	case V4L2_CID_EXPOSURE_AUTO: {
-		int32_t ivalue = value.get<bool>()
-			       ? V4L2_EXPOSURE_APERTURE_PRIORITY
+		bool autoGainSet = controls->contains(V4L2_CID_AUTOGAIN);
+
+		int32_t ivalue;
+		if (autoGainSet) {
+			bool autoGain = controls->get(V4L2_CID_AUTOGAIN).get<bool>();
+			ivalue = value.get<int32_t>() == controls::ExposureTimeModeAuto
+			       ? (autoGain
+				  /* Both exposure time and gain are auto */
+				  ? V4L2_EXPOSURE_AUTO
+				  /* Exposure time is auto but gain is manual */
+				  : V4L2_EXPOSURE_APERTURE_PRIORITY)
+			       : (autoGain
+				 /* Exposure time is manual but gain is auto */
+				 ? V4L2_EXPOSURE_SHUTTER_PRIORITY
+				 /* Both exposure time and gain are manual */
+				 : V4L2_EXPOSURE_MANUAL);
+		} else {
+			/*
+			 * auto gain is not set, so simply set the auto exposure
+			 * mode from what's set in the libcamera control.
+			 *
+			 * \todo Figure out how to properly handle priority
+			 * when auto exposure is set before auto gain
+			 */
+			ivalue = value.get<int32_t>() == controls::ExposureTimeModeAuto
+			       ? V4L2_EXPOSURE_AUTO
 			       : V4L2_EXPOSURE_MANUAL;
+		}
+
 		controls->set(V4L2_CID_EXPOSURE_AUTO, ivalue);
+
 		break;
 	}
 
+	case V4L2_CID_AUTOGAIN:
+		controls->set(V4L2_CID_AUTOGAIN, value.get<bool>());
+		break;
+
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		controls->set(cid, value.get<int32_t>() / 100);
 		break;
@@ -559,7 +592,7 @@  void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,
 		id = &controls::Saturation;
 		break;
 	case V4L2_CID_EXPOSURE_AUTO:
-		id = &controls::AeEnable;
+		id = &controls::ExposureTimeMode;
 		break;
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		id = &controls::ExposureTime;
@@ -610,7 +643,7 @@  void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,
 		break;
 
 	case V4L2_CID_EXPOSURE_AUTO:
-		info = ControlInfo{ false, true, true };
+		info = ControlInfo(controls::ExposureTimeModeValues);
 		break;
 
 	case V4L2_CID_EXPOSURE_ABSOLUTE: