[libcamera-devel,RFC,v2,8/9,PoC] UVCPipelineHandler: Set Controls

Message ID 20190621161401.28337-9-kieran.bingham@ideasonboard.com
State Superseded
Headers show
Series
  • Libcamera Controls
Related show

Commit Message

Kieran Bingham June 21, 2019, 4:14 p.m. UTC
Provide an initial sketch of setting controls on the UVC Video Device
making use of the V4L2Control API and interacting with Libcamera
controls.

This is not intended to be a full implementation, simply an initial
demonstration of setting real-world controls from requests.

Not-signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/libcamera/pipeline/uvcvideo.cpp | 43 ++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

Patch

diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 2e22523d7cb1..14a2089ea654 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -8,6 +8,7 @@ 
 #include <algorithm>
 
 #include <libcamera/camera.h>
+#include <libcamera/controls.h>
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
 
@@ -16,6 +17,7 @@ 
 #include "media_device.h"
 #include "pipeline_handler.h"
 #include "utils.h"
+#include "v4l2_controls.h"
 #include "v4l2_videodevice.h"
 
 namespace libcamera {
@@ -71,6 +73,8 @@  public:
 	bool match(DeviceEnumerator *enumerator) override;
 
 private:
+	int processControls(UVCCameraData *data, Request *request);
+
 	UVCCameraData *cameraData(const Camera *camera)
 	{
 		return static_cast<UVCCameraData *>(
@@ -216,6 +220,39 @@  void PipelineHandlerUVC::stop(Camera *camera)
 	PipelineHandler::stop(camera);
 }
 
+int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
+{
+	V4L2Controls controls;
+
+	for (auto it : request->controls()) {
+		const ControlInfo &ci = it.first;
+		Value &value = it.second;
+
+		switch (ci.id()) {
+		case ManualBrightness:
+			LOG(UVC, Debug) << "Setting Brightness to : " << value;
+			controls.add(V4L2_CID_BRIGHTNESS, value.getInt());
+			break;
+		case ManualExposure:
+			LOG(UVC, Debug) << "Setting Exposure to : " << value;
+			controls.add(V4L2_CID_EXPOSURE_AUTO, 1);
+			controls.add(V4L2_CID_EXPOSURE_ABSOLUTE, value.getInt());
+			break;
+		case ManualGain:
+		default:
+			LOG(UVC, Debug) << "Unsupported control: "
+					<< ci.name() << " : " << value;
+			break;
+		}
+	}
+
+	int ret = data->video_->setControls(&controls);
+	if (ret)
+		LOG(UVC, Error) << "Failed to set controls";
+
+	return ret;
+}
+
 int PipelineHandlerUVC::queueRequest(Camera *camera, Request *request)
 {
 	UVCCameraData *data = cameraData(camera);
@@ -227,7 +264,11 @@  int PipelineHandlerUVC::queueRequest(Camera *camera, Request *request)
 		return -ENOENT;
 	}
 
-	int ret = data->video_->queueBuffer(buffer);
+	int ret = processControls(data, request);
+	if (ret < 0)
+		return ret;
+
+	ret = data->video_->queueBuffer(buffer);
 	if (ret < 0)
 		return ret;