libcamera: sensor: ov2740: Add sensor delays to CameraSensorProperties
diff mbox series

Message ID 20261026061628.87001-1-georg.martius@web.de
State New
Headers show
Series
  • libcamera: sensor: ov2740: Add sensor delays to CameraSensorProperties
Related show

Commit Message

Georg Martius Oct. 26, 2026, 6:16 a.m. UTC
The sensor delays for the OV2740 are missing from the
CameraSensorProperties table, so the defaults (exposure 2, gain 1) are
used. On the OV2740 the analogue gain is however latched together with
the exposure time.

This was measured on a ThinkPad X1 Yoga Gen 8 (IPU6, simple pipeline
with software ISP) by streaming raw frames and writing exposure and
gain in a single VIDIOC_S_EXT_CTRLS call, toggling between pairs with
the same exposure * gain product (exposure halved, gain doubled). The
per-frame mean stays flat across all toggles, while a gain-only toggle
shows a clean step, so both controls take effect on the same frame.

With the default gain delay of 1, DelayedControls reports the gain of
the wrong frame to the software ISP AGC. Its per-update steps then form
two interleaved chains, and after a large brightness change (e.g. a
hand in front of the lens) each chain only sees frames produced by the
other chain's gain. The AGC then locks into a permanent oscillation
between the minimum and maximum analogue gain until the stream is
restarted. With a gain delay of 2 the AGC converges again after such
disturbances.

Set the exposure and gain delays to 2. The vblank and hblank delays
have not been characterised; use 2 as for other OmniVision sensors.

Signed-off-by: Georg Martius <georg.martius@web.de>
---
Tested on a Lenovo ThinkPad X1 Yoga Gen 8 (Raptor Lake IPU6, ov2740,
simple pipeline + GPU soft ISP), Ubuntu 26.04, libcamera 0.7.0 with this
change applied.

Without the patch, covering and uncovering the lens a few times makes the
AGC log (IPASoftExposure:DEBUG) alternate between two sequences, e.g.

  exposureMSV 3.87 again 1        exposureMSV 1.12 again 15.4922
  exposureMSV 3.87 again 1        exposureMSV 1.12 again 15.4922

and the image pumps between dark and bright with a period of 8 frames
until the stream is restarted. With the patch, the AGC settles within a
few seconds after the same disturbance and stays there.

The latency measurement bypasses libcamera: raw SGRBG10 capture on the
ISYS video node, with exposure/gain pairs (800, 2x) <-> (400, 4x) written
in one VIDIOC_S_EXT_CTRLS while streaming. No transient frame at any
toggle; gain-only toggles (2x <-> 4x) show a clean step.

The debugging, the latency measurement and this patch were done with
the help of an AI assistant (Claude, Anthropic); I have reviewed and
tested the change myself.

 src/libcamera/sensor/camera_sensor_properties.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/src/libcamera/sensor/camera_sensor_properties.cpp b/src/libcamera/sensor/camera_sensor_properties.cpp
index 20cfd0bc..8d0f6f5f 100644
--- a/src/libcamera/sensor/camera_sensor_properties.cpp
+++ b/src/libcamera/sensor/camera_sensor_properties.cpp
@@ -424,7 +424,12 @@  const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen
 				{ controls::draft::TestPatternModeOff, 0 },
 				{ controls::draft::TestPatternModeColorBars, 1},
 			},
-			.sensorDelays = { },
+			.sensorDelays = {
+				.exposureDelay = 2,
+				.gainDelay = 2,
+				.vblankDelay = 2,
+				.hblankDelay = 2
+			},
 		} },
 		{ "ov4689", {
 			.unitCellSize = { 2000, 2000 },