From 411c6dc06a11ea8b242d2bb62a6c907ab5d13ddd Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Mon, 20 Jul 2026 20:49:37 +0200 Subject: [PATCH] =?UTF-8?q?fix(encode):=20forward=20set=5Fpipelined=20thro?= =?UTF-8?q?ugh=20TrackedEncoder=20=E2=80=94=20the=20LN3=20escalation=20no-?= =?UTF-8?q?oped=20through=20the=20wrapper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every session encoder is boxed in TrackedEncoder (open_video), and the wrapper never forwarded Encoder::set_pipelined — so the host loop's contention escalation (ae673158) hit the trait default, which returns false ("backend can't pipeline, stop asking"), and the pipelined-retrieve stage could never engage adaptively. Only the explicit PUNKTFUNK_NVENC_ASYNC=1 open-time path worked. The exact defaulted-method trap the wrapper's own comment documents for set_wire_chunking. Co-Authored-By: Claude Fable 5 --- crates/pf-encode/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/pf-encode/src/lib.rs b/crates/pf-encode/src/lib.rs index c8d093ef..273bd071 100644 --- a/crates/pf-encode/src/lib.rs +++ b/crates/pf-encode/src/lib.rs @@ -203,6 +203,12 @@ impl Encoder for TrackedEncoder { fn invalidate_ref_frames(&mut self, first_frame: i64, last_frame: i64) -> bool { self.inner.invalidate_ref_frames(first_frame, last_frame) } + // Forwarded for the same reason as `set_wire_chunking` below — the unforwarded default + // (`false` = "backend can't pipeline, stop asking") silently killed the §7 LN3 contention + // escalation for every session, since the host loop only ever holds the wrapped box. + fn set_pipelined(&mut self, on: bool) -> bool { + self.inner.set_pipelined(on) + } // The classic TrackedEncoder trap: a defaulted trait method that isn't forwarded // silently no-ops through the wrapper (bit the direct-NVENC work, then THIS — the // §4.4 chunking probe run hit the default while the plan said Some(1408)).