[libcamera-devel] [PATCH v4 2/5] libcamera: controls: Updates to gain and exposure controls
Naushir Patuck
naush at raspberrypi.com
Fri Apr 24 12:46:57 CEST 2020
Rename:
ManualExposure -> ExposureTime
ManualGain -> AnalogueGain
Use micro-seconds units for ExposureTime. This is changed from milli-
seconds. The latter would not allow very low exposure times.
AnalogueGain switch to use a float to allow fractional gain adjustments.
Update the uvcvideo pipeline handler to use the new exposure and gain
units. For ExposureTime, UVC uses units of 100 micro-seconds, so map
the values before setting V4L2_CID_EXPOSURE_ABSOLUTE. For AnalogueGain,
UVC has no explicit gain units, so map the default gain value to 1.0
and linearly scale to the requested value.
Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
src/libcamera/control_ids.yaml | 22 +++++++-----
src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 37 ++++++++++++++++----
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml
index bcbab195..d8bdb382 100644
--- a/src/libcamera/control_ids.yaml
+++ b/src/libcamera/control_ids.yaml
@@ -12,7 +12,7 @@ controls:
description: |
Enable or disable the AE.
- \sa ManualExposure
+ \sa ExposureTime AnalogueGain
- AeLocked:
type: bool
@@ -30,8 +30,6 @@ controls:
description: |
Enable or disable the AWB.
- \sa ManualGain
-
- Brightness:
type: int32_t
description: Specify a fixed brightness parameter
@@ -44,12 +42,20 @@ controls:
type: int32_t
description: Specify a fixed saturation parameter
- - ManualExposure:
+ - ExposureTime:
type: int32_t
- description: Specify a fixed exposure time in milli-seconds
+ description: |
+ Exposure time (shutter speed) for the frame applied in the sensor
+ device. This value is specified in micro-seconds.
- - ManualGain:
- type: int32_t
- description: Specify a fixed gain parameter
+ \sa AnalogueGain AeEnable
+
+ - AnalogueGain:
+ type: float
+ description: |
+ Analogue gain value applied in the sensor device.
+ The value of the control specifies the gain multiplier applied to all
+ colour channels. This value cannot be lower than 1.0.
+ \sa ExposureTime AeEnable
...
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index ffbddf27..b518ad16 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -7,6 +7,7 @@
#include <algorithm>
#include <iomanip>
+#include <math.h>
#include <sys/sysmacros.h>
#include <tuple>
@@ -251,11 +252,24 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
controls.set(V4L2_CID_CONTRAST, value);
} else if (id == controls::Saturation) {
controls.set(V4L2_CID_SATURATION, value);
- } else if (id == controls::ManualExposure) {
+ } else if (id == controls::ExposureTime) {
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);
+ /*
+ * controls::ExposureTime is in units of 1 us, and UVC
+ * expects V4L2_CID_EXPOSURE_ABSOLUTE in units of 100 us.
+ */
+ controls.set(V4L2_CID_EXPOSURE_ABSOLUTE,
+ value.get<int32_t>() / 100);
+ } else if (id == controls::AnalogueGain) {
+ /*
+ * controls::AnalogueGain is specified as an absolute
+ * multiplier for all RGB samples. Map this multiplier
+ * in a linear way such that 1.0 -> default gain
+ * of the V4L2_CID_GAIN control on the uvcvideo device.
+ */
+ const ControlInfo &gainInfo = controls.infoMap()->at(V4L2_CID_GAIN);
+ int32_t gain = lroundf(value.get<float>() * gainInfo.def().get<int32_t>());
+ controls.set(V4L2_CID_GAIN, gain);
}
}
@@ -350,7 +364,7 @@ int UVCCameraData::init(MediaEntity *entity)
ControlInfoMap::Map ctrls;
for (const auto &ctrl : controls) {
- const ControlInfo &info = ctrl.second;
+ ControlInfo info = ctrl.second;
const ControlId *id;
switch (ctrl.first->id()) {
@@ -364,10 +378,19 @@ int UVCCameraData::init(MediaEntity *entity)
id = &controls::Saturation;
break;
case V4L2_CID_EXPOSURE_ABSOLUTE:
- id = &controls::ManualExposure;
+ id = &controls::ExposureTime;
break;
case V4L2_CID_GAIN:
- id = &controls::ManualGain;
+ id = &controls::AnalogueGain;
+ /*
+ * AnalogueGain is a float control, convert the type of
+ * the range.
+ */
+ info = ControlInfo{
+ { static_cast<float>(info.min().get<int32_t>()) },
+ { static_cast<float>(info.max().get<int32_t>()) },
+ { static_cast<float>(info.def().get<int32_t>()) }
+ };
break;
default:
continue;
--
2.17.1
More information about the libcamera-devel
mailing list