After iter11 close, both Bug 4 (H.264 partial fill) and Bug 5 (HEVC all-zero) share the same architectural pattern: libva control payloads can be made byte-equivalent to kdirect for fields rkvdec consumes, yet libva produces wrong output while kdirect succeeds. Remaining unexamined surface = OUTPUT bitstream bytes (source_data that the kernel reads). iter12 candidate α-16: extend γ infra to dump source_data pre-QBUF, compare with kdirect. If bytes match → both bugs are outside libva (kernel/HW state). If bytes differ → narrow to bitstream-write divergence site. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.5 KiB
Iteration 12 — Phase 0 (substrate / motivation / inventory) → Phase 1 lock
Opens 2026-05-14 after iter11 PARTIAL close. Combined Bug 4 + Bug 5 wire-byte search exhausted; both bugs share an architectural pattern (libva controls byte-equivalent to kdirect for fields rkvdec consumes, yet libva produces wrong output and kdirect produces correct output). The remaining unexamined surface is the OUTPUT bitstream bytes.
Locked research question (iter12, 2026-05-14)
"For BBB H.264 frame 1 and BBB HEVC frame 1: do the bytes in libva's OUTPUT V4L2 buffer (source_data[0..slices_size]) byte-match the bytes in kdirect's OUTPUT V4L2 buffer for the same input frame? If yes, the cause is in non-ioctl state (kernel-state, hardware-state); if no, the cause is in the libva bitstream-write path."
Pass/fail (boolean)
- PASS (full): libva H.264 == kdirect H.264 hash AND libva HEVC == kdirect HEVC hash, byte-identical on 3-frame sweep. Indicates the iter12 instrumentation surfaced and fixed a real bitstream-write bug.
- PASS (PARTIAL/diagnostic): iter12's γ-output instrumentation produces a byte-by-byte diff log. If libva's source_data differs from kdirect's: localize the divergence to a specific position, narrow to the bitstream-write site, fix.
- PASS (architectural): libva's OUTPUT bytes byte-match kdirect's. Then Bug 4 + Bug 5 are NOT in libva at all — they're in non-ioctl state outside our control. Document, defer.
Substrate state at iter12 open
| Property | Value |
|---|---|
| Kernel | linux-fresnel-fourier 7.0-1 |
| Fork tip | 8e2c04f (iter11 close) |
| Backend SHA | 521c1474c51154373e2d27f99d715a5af73a5fd9f72a83d947f8b552f2755d1f |
| Diagnostic surface | γ (CAPTURE dump) + IMP-1 (memset gate) preserved env-gated |
| α-13/α-14 in shipping state | Yes — wire hygiene improvements, zero regression |
Phase 4 mechanism (predicted)
Extend the existing γ infrastructure:
-
α-16 OUTPUT dump: in
picture.c::RequestEndPicture, aftercodec_set_controlsbuilds the source_data, before OUTPUT QBUF, dump source_data[0..slices_size] to a per-frame file gated byLIBVA_V4L2_DUMP_OUTPUT=1. ~20 LOC. -
Reference: for kdirect, modify ffmpeg-v4l2request's
ff_v4l2_request_append_output(and the OUTPUT QBUF site) to dump the same content. OR — simpler — extract the input file's NAL-unit bytes viaffmpeg -bsf:v ... -c:v copyand compare against libva's dump (kdirect should also produce these same bytes, modulo start-code prefixing). -
Compare: hash both dumps. If they match → Bug 4 + 5 are outside libva's control. If they diverge → narrow to first divergence offset, identify which code path produces the diff.
Quick test path: skip kdirect instrumentation. Just dump libva's source_data and inspect for sanity (start code present, NAL header looks right, frame bytes intact). If libva's bytes look correct AND kdirect's bytes (from a known-working sweep) ARE the same, then bug is elsewhere.
Scope locks
In scope:
src/picture.c::RequestEndPicture— add env-gated OUTPUT byte dump.- Phase 7c-style byte-level comparison with a captured reference.
Out of scope (until iter12 Phase 7 demands them):
- Modifying ffmpeg-v4l2request to instrument kdirect (heavyweight; defer if unnecessary).
- Per-codec changes (HEVC fixes already shipped α-13/α-14).
- Kernel patches.
Phase 5 review concerns to invite
- Per
feedback_wire_vs_behavior.md: Phase 7 must verify against the actual YUV hash, not just byte-equivalence at one layer. - Per
feedback_grep_callsites_before_no_change.md: confirm the OUTPUT byte-write path is fully in libva's codec_store_buffer / EndPicture, no other call sites. - Per
feedback_per_driver_kludge_gating.md: any per-codec gating in α-16 if found.
Predicted iter12 cadence
- Phase 0: this doc.
- Phase 4: small plan ~10 min.
- Phase 5: brief review ~15 min.
- Phase 6: implement α-16 + ~15 min.
- Phase 7: capture dump on fresnel, compare. ~20 min.
- Phase 8: close. ~10 min.
Total: ~1.5 hours.
What iter12 outcomes mean
- OUTPUT bytes match → both bugs are non-libva. iter12 closes with a definitive narrowing: "all Phase-investigatable surfaces in libva backend are byte-clean; Bug 4 + 5 lie outside ioctl boundary." Likely requires kernel-side or hardware-side investigation, which would route via kernel-agent.
- OUTPUT bytes differ at offset X → narrow to where libva writes that byte differently from kdirect; fix in
codec_store_bufferor upstream.
Either outcome is high-information value for the campaign's bug closure path.