libcamera: pipeline: uvcvideo: Retrieve v4l2 device control information
diff mbox series

Message ID 01020191ec7e0ad5-37e0d829-4553-4d41-8063-37af6c08c380-000000@eu-west-1.amazonses.com
State New
Headers show
Series
  • libcamera: pipeline: uvcvideo: Retrieve v4l2 device control information
Related show

Commit Message

Cláudio Paulo Sept. 13, 2024, 5:46 p.m. UTC
Populate frame metadata by using V4L2Device::getControls() to get
the values for all supported controls on each frame.

Signed-off-by: Cláudio Paulo <claudio.paulo@makewise.pt>
---
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 58 ++++++++++++++++++--
 1 file changed, 54 insertions(+), 4 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 6b32fa18..98a41557 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -333,8 +333,8 @@  int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,
 
 	case V4L2_CID_EXPOSURE_AUTO: {
 		int32_t ivalue = value.get<bool>()
-			       ? V4L2_EXPOSURE_APERTURE_PRIORITY
-			       : V4L2_EXPOSURE_MANUAL;
+					 ? V4L2_EXPOSURE_APERTURE_PRIORITY
+					 : V4L2_EXPOSURE_MANUAL;
 		controls->set(V4L2_CID_EXPOSURE_AUTO, ivalue);
 		break;
 	}
@@ -750,10 +750,60 @@  void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,
 void UVCCameraData::bufferReady(FrameBuffer *buffer)
 {
 	Request *request = buffer->request();
+	ControlList *metadata = &request->metadata();
 
 	/* \todo Use the UVC metadata to calculate a more precise timestamp */
-	request->metadata().set(controls::SensorTimestamp,
-				buffer->metadata().timestamp);
+	metadata->set(controls::SensorTimestamp, buffer->metadata().timestamp);
+
+	/* Retrieve control as reported by the device. */
+	std::vector<uint32_t> ids;
+	for (const auto &ctrl : video_->controls()) {
+		uint32_t cid = ctrl.first->id();
+		switch (cid) {
+		case V4L2_CID_BRIGHTNESS:
+		case V4L2_CID_CONTRAST:
+		case V4L2_CID_SATURATION:
+		case V4L2_CID_EXPOSURE_AUTO:
+		case V4L2_CID_EXPOSURE_ABSOLUTE:
+		case V4L2_CID_GAIN:
+		case V4L2_CID_FOCUS_ABSOLUTE:
+		case V4L2_CID_FOCUS_AUTO:
+			ids.push_back(cid);
+			break;
+		default:
+			continue;
+		}
+	}
+
+	ControlList deviceControls = video_->getControls(ids);
+	for (const auto &item : deviceControls) {
+		switch (item.first) {
+		case V4L2_CID_BRIGHTNESS:
+			metadata->set(controls::Brightness, item.second.get<float>());
+			break;
+		case V4L2_CID_CONTRAST:
+			metadata->set(controls::Contrast, item.second.get<float>());
+			break;
+		case V4L2_CID_SATURATION:
+			metadata->set(controls::Saturation, item.second.get<float>());
+			break;
+		case V4L2_CID_EXPOSURE_AUTO:
+			metadata->set(controls::AeEnable, item.second.get<bool>());
+			break;
+		case V4L2_CID_EXPOSURE_ABSOLUTE:
+			metadata->set(controls::ExposureTime, item.second.get<int>());
+			break;
+		case V4L2_CID_GAIN:
+			metadata->set(controls::AnalogueGain, item.second.get<float>());
+			break;
+		case V4L2_CID_FOCUS_ABSOLUTE:
+			metadata->set(controls::LensPosition, item.second.get<float>());
+			break;
+		case V4L2_CID_FOCUS_AUTO:
+			metadata->set(controls::AfMode, item.second.get<int>());
+			break;
+		}
+	}
 
 	pipe()->completeBuffer(request, buffer);
 	pipe()->completeRequest(request);