[libcamera-devel] [PATCH v5 1/7] libcamera: pipeline: uvcvideo: Refactor control handling

Laurent Pinchart laurent.pinchart at ideasonboard.com
Sat Apr 25 02:45:27 CEST 2020


Move addition and processing of individual controls to separate
functions, to prepare for more complex mappings of control values.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 103 ++++++++++++-------
 1 file changed, 67 insertions(+), 36 deletions(-)

diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index ffbddf27ae2f..92777b9f5fe4 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -42,6 +42,8 @@ public:
 	}
 
 	int init(MediaEntity *entity);
+	void addControl(uint32_t cid, const ControlInfo &v4l2info,
+			ControlInfoMap::Map *ctrls);
 	void bufferReady(FrameBuffer *buffer);
 
 	V4L2VideoDevice *video_;
@@ -76,6 +78,8 @@ public:
 	bool match(DeviceEnumerator *enumerator) override;
 
 private:
+	int processControl(ControlList *controls, unsigned int id,
+			   const ControlValue &value);
 	int processControls(UVCCameraData *data, Request *request);
 
 	UVCCameraData *cameraData(const Camera *camera)
@@ -237,6 +241,37 @@ void PipelineHandlerUVC::stop(Camera *camera)
 	data->video_->releaseBuffers();
 }
 
+int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,
+				       const ControlValue &value)
+{
+	if (value.type() != ControlTypeInteger32)
+		return -EINVAL;
+
+	uint32_t cid;
+
+	if (id == controls::Brightness)
+		cid = V4L2_CID_BRIGHTNESS;
+	else if (id == controls::Contrast)
+		cid = V4L2_CID_CONTRAST;
+	else if (id == controls::Saturation)
+		cid = V4L2_CID_SATURATION;
+	else if (id == controls::ManualExposure)
+		cid = V4L2_CID_EXPOSURE_ABSOLUTE;
+	else if (id == controls::ManualGain)
+		cid = V4L2_CID_GAIN;
+	else
+		return -EINVAL;
+
+	int32_t ivalue = value.get<int32_t>();
+
+	if (cid == V4L2_CID_EXPOSURE_ABSOLUTE)
+		controls->set(V4L2_CID_EXPOSURE_AUTO, static_cast<int32_t>(1));
+
+	controls->set(cid, ivalue);
+
+	return 0;
+}
+
 int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
 {
 	ControlList controls(data->video_->controls());
@@ -245,18 +280,7 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
 		unsigned int id = it.first;
 		ControlValue &value = it.second;
 
-		if (id == controls::Brightness) {
-			controls.set(V4L2_CID_BRIGHTNESS, value);
-		} else if (id == controls::Contrast) {
-			controls.set(V4L2_CID_CONTRAST, value);
-		} else if (id == controls::Saturation) {
-			controls.set(V4L2_CID_SATURATION, value);
-		} else if (id == controls::ManualExposure) {
-			controls.set(V4L2_CID_EXPOSURE_AUTO, static_cast<int32_t>(1));
-			controls.set(V4L2_CID_EXPOSURE_ABSOLUTE, value);
-		} else if (id == controls::ManualGain) {
-			controls.set(V4L2_CID_GAIN, value);
-		}
+		processControl(&controls, id, value);
 	}
 
 	for (const auto &ctrl : controls)
@@ -346,34 +370,13 @@ int UVCCameraData::init(MediaEntity *entity)
 	video_->bufferReady.connect(this, &UVCCameraData::bufferReady);
 
 	/* Initialise the supported controls. */
-	const ControlInfoMap &controls = video_->controls();
 	ControlInfoMap::Map ctrls;
 
-	for (const auto &ctrl : controls) {
+	for (const auto &ctrl : video_->controls()) {
+		uint32_t cid = ctrl.first->id();
 		const ControlInfo &info = ctrl.second;
-		const ControlId *id;
 
-		switch (ctrl.first->id()) {
-		case V4L2_CID_BRIGHTNESS:
-			id = &controls::Brightness;
-			break;
-		case V4L2_CID_CONTRAST:
-			id = &controls::Contrast;
-			break;
-		case V4L2_CID_SATURATION:
-			id = &controls::Saturation;
-			break;
-		case V4L2_CID_EXPOSURE_ABSOLUTE:
-			id = &controls::ManualExposure;
-			break;
-		case V4L2_CID_GAIN:
-			id = &controls::ManualGain;
-			break;
-		default:
-			continue;
-		}
-
-		ctrls.emplace(id, info);
+		addControl(cid, info, &ctrls);
 	}
 
 	controlInfo_ = std::move(ctrls);
@@ -381,6 +384,34 @@ int UVCCameraData::init(MediaEntity *entity)
 	return 0;
 }
 
+void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,
+			       ControlInfoMap::Map *ctrls)
+{
+	const ControlId *id;
+
+	switch (cid) {
+	case V4L2_CID_BRIGHTNESS:
+		id = &controls::Brightness;
+		break;
+	case V4L2_CID_CONTRAST:
+		id = &controls::Contrast;
+		break;
+	case V4L2_CID_SATURATION:
+		id = &controls::Saturation;
+		break;
+	case V4L2_CID_EXPOSURE_ABSOLUTE:
+		id = &controls::ManualExposure;
+		break;
+	case V4L2_CID_GAIN:
+		id = &controls::ManualGain;
+		break;
+	default:
+		return;
+	}
+
+	ctrls->emplace(id, v4l2Info);
+}
+
 void UVCCameraData::bufferReady(FrameBuffer *buffer)
 {
 	Request *request = buffer->request();
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list