libcamera: af: re-baseline the scene reference after a sweep (r5)
Some checks failed
image / image (push) Has been cancelled
Some checks failed
image / image (push) Has been cancelled
Hardware finding from the first r4 run on the phone: the focus-loss detector compared the settled scene against the maximum sharpness recorded during the sweep, which was measured under a different AGC state. On the FP6 that maximum read 4848088 and the same position two stats frames later read 1995445, so the detector fired immediately and the lens swept forever. Patch 0014 takes the reference after the lens settles and requires four consecutive out-of-band frames. Verified on the phone: r4 re-swept without end, r5 completes one sweep and stays put.
This commit is contained in:
parent
40ccdfeed6
commit
236015ef36
2 changed files with 117 additions and 1 deletions
|
|
@ -0,0 +1,114 @@
|
|||
From b99ba09cd463cbfbb6530a82c9e2702bfd0bb29a Mon Sep 17 00:00:00 2001
|
||||
From: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
|
||||
Date: Mon, 17 Aug 2026 02:18:32 +0200
|
||||
Subject: [PATCH] libcamera: software_isp: af: Re-baseline the scene reference
|
||||
after a sweep
|
||||
|
||||
Measured on the FP6 with the DW9784: a sweep converged on 38% with a
|
||||
recorded maximum sharpness of 4848088, and two stats frames later the
|
||||
metric at that same position read 1995445 - a 59% drop with the lens
|
||||
parked and the scene unchanged. The sweep maximum was measured under
|
||||
whatever exposure and gain the AGC happened to be using several hundred
|
||||
milliseconds earlier, so comparing the settled scene against it fires
|
||||
the focus-loss detector immediately and the lens sweeps forever.
|
||||
|
||||
Take the reference from the first measurement after the lens has
|
||||
settled, and require the scene to look different for four consecutive
|
||||
stats frames before re-focusing, so that a single AGC excursion does not
|
||||
count as the scene changing.
|
||||
|
||||
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
|
||||
---
|
||||
src/ipa/simple/algorithms/af.cpp | 37 ++++++++++++++++++++++++++------
|
||||
src/ipa/simple/ipa_context.h | 4 ++++
|
||||
2 files changed, 35 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/ipa/simple/algorithms/af.cpp b/src/ipa/simple/algorithms/af.cpp
|
||||
index 00148ce1b..6c9510389 100644
|
||||
--- a/src/ipa/simple/algorithms/af.cpp
|
||||
+++ b/src/ipa/simple/algorithms/af.cpp
|
||||
@@ -34,6 +34,8 @@ constexpr double kFineStepMin = 1.0;
|
||||
constexpr uint32_t kSettleSkipLong = 3;
|
||||
/* Relative sharpness change that makes a settled scene worth re-focusing. */
|
||||
constexpr double kFocusLossThreshold = 0.3;
|
||||
+/* Consecutive stats frames that change must persist for before re-focusing. */
|
||||
+constexpr uint32_t kFocusLossFrames = 4;
|
||||
/*
|
||||
* Focus continuously by default: applications that know nothing about AF never
|
||||
* send an AfMode or an AfTrigger, and they are the ones this exists for.
|
||||
@@ -140,6 +142,8 @@ void Af::restart(IPAContext &context)
|
||||
focus.stop = 100;
|
||||
focus.step = kCoarseStep;
|
||||
focus.skip = kSettleSkipLong;
|
||||
+ focus.settled = false;
|
||||
+ focus.lossCount = 0;
|
||||
context.activeState.knobs.focus_pos = 0;
|
||||
context.activeState.knobs.focus_sweep = true;
|
||||
LOG(IPASoftAutoFocus, Info) << "Starting focus sweep";
|
||||
@@ -165,13 +169,34 @@ void Af::step(IPAContext &context, double &focus_pos, uint64_t sharp, bool &swee
|
||||
if (context.activeState.knobs.af_mode != controls::AfModeContinuous)
|
||||
return;
|
||||
|
||||
- if (utils::abs_diff(sharp, focus.sharpness_max) >
|
||||
+ /*
|
||||
+ * Take the reference the scene is compared against here, at
|
||||
+ * the settled position, rather than reusing the maximum found
|
||||
+ * during the sweep: that maximum was measured under whatever
|
||||
+ * exposure and gain the AGC happened to be using at the time.
|
||||
+ */
|
||||
+ if (!focus.settled) {
|
||||
+ focus.sharpness_max = sharp;
|
||||
+ focus.lossCount = 0;
|
||||
+ focus.settled = true;
|
||||
+ LOG(IPASoftAutoFocus, Debug)
|
||||
+ << "Settled sharpness reference " << sharp;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (utils::abs_diff(sharp, focus.sharpness_max) <=
|
||||
focus.sharpness_max * kFocusLossThreshold) {
|
||||
- LOG(IPASoftAutoFocus, Info)
|
||||
- << "Focus lost: " << sharp << " vs "
|
||||
- << focus.sharpness_max;
|
||||
- restart(context);
|
||||
+ focus.lossCount = 0;
|
||||
+ return;
|
||||
}
|
||||
+
|
||||
+ if (++focus.lossCount < kFocusLossFrames)
|
||||
+ return;
|
||||
+
|
||||
+ LOG(IPASoftAutoFocus, Info)
|
||||
+ << "Focus lost: " << sharp << " vs "
|
||||
+ << focus.sharpness_max;
|
||||
+ restart(context);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -204,10 +229,10 @@ void Af::step(IPAContext &context, double &focus_pos, uint64_t sharp, bool &swee
|
||||
|
||||
sweep = false;
|
||||
focus_pos = focus.focus_max_pos;
|
||||
+ focus.settled = false;
|
||||
LOG(IPASoftAutoFocus, Info)
|
||||
<< "Sweep end. Best focus: " << focus.focus_max_pos
|
||||
<< " after " << steps_ << " frames";
|
||||
- /* sharpness_max is kept to detect the scene changing later on. */
|
||||
}
|
||||
|
||||
void Af::process(IPAContext &context,
|
||||
diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h
|
||||
index 4c594cd29..36a28256b 100644
|
||||
--- a/src/ipa/simple/ipa_context.h
|
||||
+++ b/src/ipa/simple/ipa_context.h
|
||||
@@ -41,6 +41,10 @@ struct IPASessionConfiguration {
|
||||
double start, stop, step;
|
||||
/* Stats frames to ignore while the lens settles */
|
||||
uint32_t skip;
|
||||
+ /* Set once the post-sweep sharpness reference has been taken */
|
||||
+ bool settled;
|
||||
+ /* Consecutive stats frames the scene has looked different */
|
||||
+ uint32_t lossCount;
|
||||
} focus;
|
||||
};
|
||||
|
||||
|
|
@ -3,7 +3,7 @@ maintainer="Robert Mader <robert.mader@collabora.com>"
|
|||
pkgname=libcamera
|
||||
_pkgver=0.7.2
|
||||
pkgver=9999$_pkgver
|
||||
pkgrel=4
|
||||
pkgrel=5
|
||||
pkgdesc="Linux camera framework"
|
||||
url="https://libcamera.org/"
|
||||
arch="all"
|
||||
|
|
@ -70,6 +70,7 @@ source="https://gitlab.freedesktop.org/camera/libcamera/-/archive/v$_pkgver/libc
|
|||
0011-libcamera-pipeline-simple-Apply-the-lens-position-un.patch
|
||||
0012-libcamera-software_isp-af-Harden-the-lens-control-ha.patch
|
||||
0013-libcamera-software_isp-af-Add-AfMode-and-focus-witho.patch
|
||||
0014-libcamera-software_isp-af-Re-baseline-the-scene-refe.patch
|
||||
qcam.desktop
|
||||
$_tuning_files
|
||||
"
|
||||
|
|
@ -196,6 +197,7 @@ c8ddc64ab943d9b215f4c997f2629e4403744c0ddb5de88cd42d384506a27c0762191eddd4d13559
|
|||
3965405be757917030c89db5da60aa226d0f0591e213d055d8312dbddee0c3d81fbcaa5928d6de4d3cb636572a27261d8686d87ae39b9634d70b33cf8388dc73 0011-libcamera-pipeline-simple-Apply-the-lens-position-un.patch
|
||||
8734e27966bd1bc5a4b0324a3d8a3ee4ab371f6d1536500b2bb44d49bde874c3fd6f244312332226c352e4716ba12fb72bf51e64b9e97cf6fa646aa6dfef3277 0012-libcamera-software_isp-af-Harden-the-lens-control-ha.patch
|
||||
dce81c2863ff6b9374115325f4af14ac5d396a6e2aee12f87d55a47d1d0bda860ae2af5a9d6885b126e20a12b7f3f40e49a2b9d738f94c04177bff6149da64e1 0013-libcamera-software_isp-af-Add-AfMode-and-focus-witho.patch
|
||||
18ed6a03fbe3bcd750fac280831d1e62f2a2e35f76880535f2dc16ff196308512535e077ab0d8a923ad241090713edb53d1777e0dd6e5dcc10de495db1277052 0014-libcamera-software_isp-af-Re-baseline-the-scene-refe.patch
|
||||
22167a4eceb6d1b40b0b7c45fdf116c71684f5340de7f767535cb8e160ad9d2ae0f00cb3d461f73a344520a48a4641cf46226841d78bee06bfbfd2a91337f754 qcam.desktop
|
||||
2ee566653b17d565d2c0de67cbe6ebad25df5aac6051cad78e6bae52016fa2ca0247e964d735ac776b3e0bd447ead9c4fcb26cd7629228cdba3ceb91b46f378f hi846.yaml
|
||||
55dab9dcb9b1982143b9d63e4e51138c5bffd7c8f4a8e4e122750b3ad9d475446956bc297d9f564819ade4be75a575d06633a064e14f8ba3ef77986783c5f067 imx355.yaml
|
||||
|
|
|
|||
Loading…
Reference in a new issue