forked from unom/punktfunk
`finish` showed `outputs.last()` and retired every other picture an access unit bumped out of the DPB without ever displaying it, and nothing flushed the DPB at end of stream. Measured on .25 against the vendored vectors: 225 of 250 frames for H.264, 204 of 250 for H.265, 45 of 50 for HEVC Main 10. D3D11VA and Vulkan deliver every frame, so this was the rung's alone. All four legs now deliver 250 / 250 / 50 / 250. The same function carried a second defect. `DmabufFrame::keyframe` was stamped with the CURRENT access unit's `is_idr`, not the flag of the picture it was about to display, and on a reordering stream those are different pictures: the IDR is bumped out several units after it decodes and arrived flagged `false` on all three legs' first frame, while a later AU draining the DPB flagged some old trailing picture as a keyframe. That field is `DecodedImage::is_keyframe`, the pump's post-loss re-anchor signal, so a mislabel re-anchors on the wrong frame. Three changes, all inside this rung: * **A deliverable queue**, the same shape as `video_vk_native`'s — extend, ship the front, trim the oldest past the bound, count and rate-limit the drops into `DecodeHealth::dropped`. Its DEPTH is derived differently and the divergence is documented: the Vulkan rung's bound is `HOLD_HEADROOM - PIPELINE_HOLD` = 1 because a queued frame there counts against the pool ON TOP of the DPB's own residency. Here the three claims are disjoint and a bumped picture MOVES from `pending`/slot to `held`, so the queue inherits the claim rather than adding one. The bound is the DPB's depth — the deepest carry-over a bump can leave — and the measured cost is at most one surface (zero on H.264, whose three seven-picture IDR drains are the deepest bursts these vectors have). A bound of 1 would have left 235 of 250 on H.264, most of the defect still in place. * **An end-of-stream flush.** This rung has no EOS signal and cannot have one: the pump feeds access units until the session ends and then drops the decoder. So `flush` has the two honest callers — `Drop`, where nothing can be presented and the job is to release the queue's surfaces and the DPB's before the pool goes, and a caller that KNOWS the stream ended, which today is the conformance harness. One walk, not a production path and an untested teardown path. AV1 needs none: it shows at most one frame per temporal unit and buffers nothing, which its 250/250 says out loud. * **`PictureFacts` recorded when a picture decodes**, and read back when it is displayed. `keyframe` was the defect; `color` and `display` are the same mistake one field along — an in-band HDR switch changes the VUI mid-stream and AV1's render region is per-frame, so a queued frame shown two units later would have been drawn with the newest picture's signalling. Concealment answers `Ok(None)` and deliberately does NOT drain the queue, which is the Vulkan rung's order and is load-bearing: `clears_demotion_streak` is `delivered || !concealed`, so shipping a queued frame on a concealed AU would zero the streak and take away the escape hatch that stops a rung concealing forever from holding a frozen picture. The three delivered-count assertions moved with the fix, and so did the CPU derivation that reproduces them without a GPU — it now simulates the whole delivery model (ledger, queue, one-per-AU hand-off, flush) in the order `decode` does it, and carries the old behaviour beside the new one as a counterfactual: a queue bound of 0 with no flush still reproduces 225/204/45 exactly, and the test fails if it ever stops being SHORT. `settle` was split out as the pure half of `finish` so the claim walk, the display ordering and the picture facts are all assertable with no device; `the_queue_never_needs_a_surface_the_pool_does_not_have` runs the surface-lifetime arithmetic over the real vectors and pins the peak claims (9 of a 16-surface pool on H.264, 8 of 14 on both HEVC vectors), with an unbounded queue as the counterfactual that shows the bound doing its job. Gates run: `cargo fmt --all -- --check`, `cargo clippy -p pf-client-core -p pf-vaadec --all-targets --features sdl3/build-from-source -- -D warnings`, `cargo test -p pf-client-core --lib --features sdl3/build-from-source` (176 pass), the same filtered to `video_vaapi_native -- --include-ignored` (23 pass, 0 ignored) and `cargo test -p pf-vaadec` (48 pass) — all on .25 (Radeon 780M, RDNA3, radeonsi, Mesa 26.0.3, VA-API 1.23); plus `cargo fmt --all -- --check` and `cargo clippy --workspace --all-targets -- -D warnings` in pf-lxcheck2.