fp6-img/aports/temp/libcamera/0011-libcamera-pipeline-simple-Apply-the-lens-position-un.patch
Jorijn van der Graaf 40ccdfeed6
Some checks failed
image / image (push) Has been cancelled
libcamera: backport contrast autofocus for the main camera (r4)
The DW9784 VCM works and libcamera discovers it through the sensor's
ancillary link, but nothing in the software ISP ever moves it. Backport
the out-of-tree autofocus work onto v0.7.2:

- 0007-0009 are Vasiliy Doylov's focus control, contrast autofocus and
  focus-loss detection from the softisp-playground branch;
- 0010 is Pavel Machek's Librem5-tested robustness work (centre-window,
  brightness-normalised sharpness, two-phase sweep, settle skip),
  squashed and adapted;
- 0011-0013 are ours: the lens write no longer sits inside the
  no-frame-start-emitter branch, the lensless-camera paths are guarded,
  and AfMode is advertised with a continuous default so that stock
  applications get autofocus without sending AfTrigger.

Provenance and the adaptations made to each patch are recorded in the
patch commit messages.
2026-08-17 02:02:45 +02:00

74 lines
2.9 KiB
Diff

From 8ee13c9f2a3a8084d2360e78da32ed9793bfe5e9 Mon Sep 17 00:00:00 2001
From: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Date: Mon, 17 Aug 2026 01:58:13 +0200
Subject: [PATCH] libcamera: pipeline: simple: Apply the lens position
unconditionally
The focus control patch applies the lens position inside the branch that
only runs when the pipeline has no frame-start emitter, because that is
where the sensor controls are applied directly. The lens is a different
kind of device: it is a separate subdevice, it is not pushed through
delayedCtrls_, and it has no frame-latched controls, so there is nothing
to synchronise it to. On a platform whose pipeline does register a
frame-start emitter the lens would simply never move.
Hoist the lens write above the early return. The FP6's CAMSS pipeline
registers no frame-start emitter (no subdevice in the graph supports
V4L2_EVENT_FRAME_SYNC), so this makes no difference there, but it is a
prerequisite for the feature working anywhere else.
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
---
src/libcamera/pipeline/simple/simple.cpp | 32 +++++++++++++-----------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 047800b59..0095ea7a5 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -1045,6 +1045,19 @@ void SimpleCameraData::metadataReady(uint32_t frame, const ControlList &metadata
void SimpleCameraData::setSensorControls(const ControlList &sensorControls, const ControlList &lensControls)
{
delayedCtrls_->push(sensorControls);
+
+ /*
+ * The lens is a separate subdevice with no frame-latched controls, so
+ * its position is applied straight away and independently of the
+ * sensor controls below.
+ */
+ CameraLens *focusLens = sensor_->focusLens();
+ if (focusLens && lensControls.contains(V4L2_CID_FOCUS_ABSOLUTE)) {
+ const ControlValue &focusValue =
+ lensControls.get(V4L2_CID_FOCUS_ABSOLUTE);
+ focusLens->setFocusPosition(focusValue.get<int32_t>());
+ }
+
/*
* Directly apply controls now if there is no frameStart signal.
*
@@ -1053,21 +1066,10 @@ void SimpleCameraData::setSensorControls(const ControlList &sensorControls, cons
* but it also bypasses delayedCtrls_, creating AGC regulation issues.
* Both problems should be fixed.
*/
- if (frameStartEmitter_)
- return;
-
- ControlList ctrls(sensorControls);
- sensor_->setControls(&ctrls);
-
- CameraLens *focusLens = sensor_->focusLens();
- if (!focusLens)
- return;
-
- if (!lensControls.contains(V4L2_CID_FOCUS_ABSOLUTE))
- return;
-
- const ControlValue &focusValue = lensControls.get(V4L2_CID_FOCUS_ABSOLUTE);
- focusLens->setFocusPosition(focusValue.get<int32_t>());
+ if (!frameStartEmitter_) {
+ ControlList ctrls(sensorControls);
+ sensor_->setControls(&ctrls);
+ }
}
/* Retrieve all source pads connected to a sink pad through active routes. */