[v3,3/4] libcamera: pipeline: uvcvideo: Retrieve current exposure mode on start
diff mbox series

Message ID 20250314174248.1015718-4-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • libcamera: pipeline: uvcvideo: Fix `ExposureTimeMode` control
Related show

Commit Message

Barnabás Pőcze March 14, 2025, 5:42 p.m. UTC
If `ExposureTimeMode` is supported, then retrieve the current value
of `V4L2_CID_EXPOSURE_AUTO` in `PipelineHandlerUVC::start()`, and
convert it to the appropriate `ExposureTimeModeEnum` value. If it
is not supported or the conversion fails, then fall back to assuming
that `ExposureTimeModeManual` is in effect.

This is necessary to be able to properly handle the `ExposureTime`
control as its value is required to be ignored if `ExposureTimeMode`
is not manual.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
---
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 4ff79c291..7d882ebe1 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -62,6 +62,15 @@  public:
 	std::optional<v4l2_exposure_auto_type> autoExposureMode_;
 	std::optional<v4l2_exposure_auto_type> manualExposureMode_;
 
+	struct State {
+		std::optional<controls::ExposureTimeModeEnum> exp;
+
+		void reset()
+		{
+			exp.reset();
+		}
+	} state_;
+
 private:
 	bool generateId();
 
@@ -303,6 +312,16 @@  int PipelineHandlerUVC::start(Camera *camera, [[maybe_unused]] const ControlList
 		return ret;
 	}
 
+	if (data->autoExposureMode_ || data->manualExposureMode_) {
+		const auto &ctrls = data->video_->getControls({ V4L2_CID_EXPOSURE_AUTO });
+		const auto &value = ctrls.get(V4L2_CID_EXPOSURE_AUTO);
+		if (!value.isNone())
+			data->state_.exp = v4l2ToExposureMode(value.get<int32_t>());
+	}
+
+	if (!data->state_.exp)
+		data->state_.exp = controls::ExposureTimeModeManual;
+
 	return 0;
 }
 
@@ -311,6 +330,7 @@  void PipelineHandlerUVC::stopDevice(Camera *camera)
 	UVCCameraData *data = cameraData(camera);
 	data->video_->streamOff();
 	data->video_->releaseBuffers();
+	data->state_.reset();
 }
 
 int PipelineHandlerUVC::processControl(const UVCCameraData *data, ControlList *controls,