[libcamera-devel] [PATCH v3 14/23] libcamera: camera_sensor: Translate libcamera/V4L2 controls
Jacopo Mondi
jacopo at jmondi.org
Thu Jun 30 15:38:53 CEST 2022
In the process of moving the CameraSensor class control interface
to use libcamera::internal controls modify the
CameraSensor::pushControls() and CameraSensor::getControls() to
use lists of libcamera controls and translate to and from V4L2 controls
to interface with DelayedControls, which will actually take care of
applying controls to the V4L2 subdevice.
Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
src/libcamera/camera_sensor/camera_sensor.cpp | 67 ++++++++++++++++++-
1 file changed, 65 insertions(+), 2 deletions(-)
diff --git a/src/libcamera/camera_sensor/camera_sensor.cpp b/src/libcamera/camera_sensor/camera_sensor.cpp
index cc4cbd4ad509..02810c7c5ad0 100644
--- a/src/libcamera/camera_sensor/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor/camera_sensor.cpp
@@ -1038,19 +1038,82 @@ void CameraSensor::frameStart(uint32_t sequence)
/**
* \brief Push a new set of controls to the CameraSensor
* \param[in] ctrls The list of controls to push to the sensor
+ *
+ * \a ctrls contains a list of libcamera::controls::internal controls
*/
void CameraSensor::pushControls(const ControlList &ctrls)
{
- delayedCtrls_->push(ctrls);
+ ControlList v4l2Ctrls(subdev_->controls());
+
+ /*
+ * DelayedControls applies V4L2 controls for us to the subdevice.
+ * Translate here between libcamera controls and V4L2 controls.
+ *
+ * The currently supported controls are V4L2_CID_VBLANK,
+ * V4L2_CID_EXPOSURE and V4L2_CID_ANALOGUE_GAIN.
+ */
+
+ if (ctrls.contains(controls::internal::AnalogueGain)) {
+ float gain = ctrls.get(controls::internal::AnalogueGain);
+ int32_t gainCode = helper_->gainCode(gain);
+
+ v4l2Ctrls.set(V4L2_CID_ANALOGUE_GAIN, ControlValue(gainCode));
+ }
+
+ if (ctrls.contains(controls::internal::ExposureTime)) {
+ uint32_t exposureTime = ctrls.get(controls::internal::ExposureTime);
+ int32_t exposure = exposureTime / config_.lineDuration;
+
+ v4l2Ctrls.set(V4L2_CID_EXPOSURE, ControlValue(exposure));
+ }
+
+ if (ctrls.contains(controls::internal::FrameDuration)) {
+ uint64_t duration = ctrls.get(controls::internal::FrameDuration);
+ uint32_t frameSize = duration / (1000000.0F / config_.pixelRate);
+ uint32_t lineLength = config_.outputFormat.size.width + config_.hblank;
+ int32_t vblank = frameSize / lineLength - config_.outputFormat.size.height;
+
+ v4l2Ctrls.set(V4L2_CID_VBLANK, vblank);
+ }
+
+ delayedCtrls_->push(v4l2Ctrls);
}
/**
* \brief Get the list of controls applied at frame \a sequence
* \param[in] sequence The frame sequence number
+ *
+ * The returned controls list contains libcamera::controls::internal controls
*/
ControlList CameraSensor::getControls(uint32_t sequence)
{
- return delayedCtrls_->get(sequence);
+ ControlList ctrls(controls::internal::controls);
+ ControlList v4l2Ctrls = delayedCtrls_->get(sequence);
+
+ if (v4l2Ctrls.contains(V4L2_CID_ANALOGUE_GAIN)) {
+ uint32_t gainCode = v4l2Ctrls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>();
+ float gain = static_cast<float>(helper_->gain(gainCode));
+
+ ctrls.set(controls::internal::AnalogueGain, gain);
+ }
+
+ if (v4l2Ctrls.contains(V4L2_CID_EXPOSURE)) {
+ uint32_t exposure = v4l2Ctrls.get(V4L2_CID_EXPOSURE).get<int32_t>();
+ uint32_t exposureTime = exposure * config_.lineDuration;
+
+ ctrls.set(controls::internal::ExposureTime, exposureTime);
+ }
+
+ if (v4l2Ctrls.contains(V4L2_CID_VBLANK)) {
+ uint32_t vblank = v4l2Ctrls.get(V4L2_CID_VBLANK).get<int32_t>();
+ uint32_t frameSize = (config_.outputFormat.size.width + config_.hblank)
+ * (config_.outputFormat.size.height + vblank);
+ uint64_t duration = frameSize / (config_.pixelRate / 1000000.0F);
+
+ ctrls.set(controls::internal::FrameDuration, duration);
+ }
+
+ return ctrls;
}
/**
--
2.36.1
More information about the libcamera-devel
mailing list