app+docs: 参考帧窗口参数化(baselineFrames, 默认4)——实测延长到8会把开快门帧收进参考导致不稳定;结论:需快门感知的参考收集

This commit is contained in:
ZXCLI
2026-10-06 04:47:36 +08:00
parent 1d6c5e3e55
commit 3510bdc774
4 changed files with 43 additions and 12 deletions
@@ -20,6 +20,16 @@ class RenderPipeline(
private val ffcPeriod: Int = 1800,
private val ffcDrift: Int = 250,
private val warmFrames: Int = 20,
/**
* Number of *settled* shutter frames averaged into the FFC reference.
*
* The official core feeds every frame of the shutter window into
* `CAccumulator` (`CFunctions::PushBaselineRaw`), so its reference is much
* cleaner than a short 4-frame average — which is why the official image
* shows less residual FPN (fewer stripes) at the same frame-to-frame noise.
* Default 4 keeps the byte-exact C reference behaviour (tests).
*/
private val baselineFrames: Int = 4,
private val cdfPivot75: Boolean = true,
private val force75: Boolean = true,
/** FFC command callback: param 0 = FFC(0), 1 = FFC(1). */
@@ -224,8 +234,9 @@ class RenderPipeline(
for (i in 0 until npix) refAcc[i] += frame[i]
}
refCnt++
if (refCnt >= 4) {
for (i in 0 until npix) ref[i] = refAcc[i] shr 2
if (refCnt >= baselineFrames.coerceIn(1, 64)) {
val n = refCnt
for (i in 0 until npix) ref[i] = refAcc[i] / n
refCnt = 0
hasRef = true
}
@@ -609,15 +620,16 @@ class RenderPipeline(
if (idx == 1) rebuildTables(shutterAtFfc)
return 1
}
if (idx <= 9) {
if (idx == 9) onFfc?.invoke(1)
val refEnd = 5 + baselineFrames.coerceIn(1, 64)
if (idx <= refEnd) {
if (idx == refEnd) onFfc?.invoke(1)
if (idx == 6) {
refCnt = 0
hasRef = false
}
return 2 // ref collection window
}
if (idx <= 13) return 1
if (idx <= refEnd + 4) return 1
// normal frame: FFC condition
var drift = shutterIn - shutterAtFfc
if (drift < 0) drift = -drift
@@ -324,6 +324,11 @@ class IrSession(context: Context) {
// off the two distributions coincide (median 50 vs 61, mean 80 vs 82).
// See docs/android_app/rendering_diff_phone_20261006.md §8.
cdfPivot75 = false,
// baselineFrames stays at the verified 4: extending the window to 8 made
// the output *unstable* (frame-to-frame gray noise 3.95 -> 8.8), i.e. the
// device re-opens the shutter earlier than our schedule assumes, so the
// extra frames poison the reference. A shutter-aware reference
// collection is the follow-up (docs/android_app/rendering_diff_phone_20261006.md §9.4).
onFfc = { param ->
sendCmd(
MagProtocol.cmd8(MagProtocol.CMD_SET_SHUTTER_STATE, param),