summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKieran Bingham <kieran.bingham@ideasonboard.com>2020-07-13 12:56:11 +0100
committerKieran Bingham <kieran.bingham@ideasonboard.com>2021-09-09 14:00:30 +0100
commitd2e5a2480b87d5980c4409885d6a7e85a6efed59 (patch)
treee051c8bed2b505ff284a1f2156d2a38f1fdda10e
parent8cfa5edaa97dba0ca271faad3314e44079aa9a3a (diff)
libcamera: pipeline: vivid: Handle controls
When constructing the camera, we parse the available controls on the video capture device, and map supported controls to libcamera controls, and initialise the defaults. The controls are handled during queueRequestDevice for each request and applied to the device through the capture node. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
-rw-r--r--src/libcamera/pipeline/vivid/vivid.cpp80
1 files changed, 79 insertions, 1 deletions
diff --git a/src/libcamera/pipeline/vivid/vivid.cpp b/src/libcamera/pipeline/vivid/vivid.cpp
index bb6a2e10..a07f3012 100644
--- a/src/libcamera/pipeline/vivid/vivid.cpp
+++ b/src/libcamera/pipeline/vivid/vivid.cpp
@@ -5,9 +5,13 @@
* vivid.cpp - Pipeline handler for the vivid capture device
*/
+#include <math.h>
+
#include <libcamera/base/log.h>
#include <libcamera/camera.h>
+#include <libcamera/control_ids.h>
+#include <libcamera/controls.h>
#include <libcamera/formats.h>
#include "libcamera/internal/camera.h"
@@ -252,6 +256,46 @@ void PipelineHandlerVivid::stop(Camera *camera)
data->video_->releaseBuffers();
}
+int PipelineHandlerVivid::processControls(VividCameraData *data, Request *request)
+{
+ ControlList controls(data->video_->controls());
+
+ for (auto it : request->controls()) {
+ unsigned int id = it.first;
+ unsigned int offset;
+ uint32_t cid;
+
+ if (id == controls::Brightness) {
+ cid = V4L2_CID_BRIGHTNESS;
+ offset = 128;
+ } else if (id == controls::Contrast) {
+ cid = V4L2_CID_CONTRAST;
+ offset = 0;
+ } else if (id == controls::Saturation) {
+ cid = V4L2_CID_SATURATION;
+ offset = 0;
+ } else {
+ continue;
+ }
+
+ int32_t value = lroundf(it.second.get<float>() * 128 + offset);
+ controls.set(cid, std::clamp(value, 0, 255));
+ }
+
+ for (const auto &ctrl : controls)
+ LOG(VIVID, Debug)
+ << "Setting control " << utils::hex(ctrl.first)
+ << " to " << ctrl.second.toString();
+
+ int ret = data->video_->setControls(&controls);
+ if (ret) {
+ LOG(VIVID, Error) << "Failed to set controls: " << ret;
+ return ret < 0 ? ret : -EINVAL;
+ }
+
+ return ret;
+}
+
int PipelineHandlerVivid::queueRequestDevice(Camera *camera, Request *request)
{
VividCameraData *data = cameraData(camera);
@@ -263,7 +307,11 @@ int PipelineHandlerVivid::queueRequestDevice(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;
@@ -302,6 +350,36 @@ int VividCameraData::init()
video_->bufferReady.connect(this, &VividCameraData::bufferReady);
+ /* Initialise the supported controls. */
+ const ControlInfoMap &controls = video_->controls();
+ ControlInfoMap::Map ctrls;
+
+ for (const auto &ctrl : controls) {
+ const ControlId *id;
+ ControlInfo info;
+
+ switch (ctrl.first->id()) {
+ case V4L2_CID_BRIGHTNESS:
+ id = &controls::Brightness;
+ info = ControlInfo{ { -1.0f }, { 1.0f }, { 0.0f } };
+ break;
+ case V4L2_CID_CONTRAST:
+ id = &controls::Contrast;
+ info = ControlInfo{ { 0.0f }, { 2.0f }, { 1.0f } };
+ break;
+ case V4L2_CID_SATURATION:
+ id = &controls::Saturation;
+ info = ControlInfo{ { 0.0f }, { 2.0f }, { 1.0f } };
+ break;
+ default:
+ continue;
+ }
+
+ ctrls.emplace(id, info);
+ }
+
+ controlInfo_ = ControlInfoMap(std::move(ctrls), controls::controls);
+
return 0;
}