Files
fresnel-fourier/phase8_iteration9_close.md
marfrit 5e2a228cfd iter9 Phase 8 close: α-7 inert as predicted; wire-byte search exhausted
α-7 (monotonic timestamp counter) changed wire bytes but H.264 output
unchanged (71ac099b...). Confirms Phase 5 CRIT-1 prediction: VP9/MPEG-2
PASS via libva with the same v4l2_timeval_to_ns(&ref->timestamp)
pattern; therefore timestamp magnitude was never load-bearing.

5-codec regression sweep: all 4 non-H.264 anchors hold. Zero regression.

Cumulative state after iter8+iter9:
- 6 hypotheses eliminated (libva-readback, slot-binding, stale-residue,
  constraint_set_flags, POC sentinel, reference_ts magnitude)
- libva-vs-kdirect H.264 wire-byte diff is now empirically zero
- α-2 + α-7 shipped as wire-payload hygiene cleanups (zero behavior
  change but cleaner semantics)

iter10 candidate ranking:
1. α-8 OUTPUT bitstream byte dump (compare in-memory slice bytes)
2. α-9 untraced control diff (device-wide controls beyond DECODE_MODE
   + START_CODE)
3. Kernel-side investigation (rkvdec source dive for 16x32 partial-
   decode signature)
4. Pivot to Bug 5 (HEVC) or Bug 6 (VP8)

Two more iterations of diminishing returns suggest either deeper
empirical work (OUTPUT-byte dump or kernel investigation) or pivot
to a different bug.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:57:26 +00:00

113 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Iteration 9 — Phase 8 (close)
Closes 2026-05-13. iter9 = Bug 4 — α-7 timestamp scheme test → confirmed inert. PARTIAL close. Wire-byte search space now exhausted.
## Summary
| Metric | Value |
|---|---|
| Iteration target | Bug 4 — α-7 monotonic timestamp counter |
| Fork tip start (iter8 close) | `0226684` |
| Fork tip end (iter9 close) | `e0be4e6` (1 fork commit: timestamp counter scheme) |
| LOC delta | +23 / -1 across src/context.h, src/context.c, src/picture.c |
| Phase 1 criteria | 5/6 PASS (C1 PARTIAL — H.264 hash unchanged) |
| Reviews | 1 (Phase 5 CRIT-1 correctly predicted α-7 inert) |
| Cumulative hypothesis eliminations | 6 (iter8's 5 + α-7 timestamp) |
## Results
| Codec | Anchor | iter9 α-7 | Verdict |
|---|---|---|---|
| H.264 | `1e7a0bc9…` (kdirect target) | `71ac099b…` (unchanged broken) | **FAIL** (Bug 4 unfixed) |
| VP9 | `4f1565e8…` | `4f1565e8…` | PASS unchanged |
| MPEG-2 | `19eefbf4…` | `19eefbf4…` | PASS unchanged |
| HEVC | `06b2c5a0…` | `06b2c5a0…` | unchanged (Bug 5 deferred) |
| VP8 | `bcc57ed5…` | `bcc57ed5…` | unchanged (Bug 6 deferred) |
α-7 changed the wire-level timestamp values (libva now sends small µs counter values matching kdirect's pattern) but H.264 output remains identical to pre-α-7 broken state. **Timestamp magnitude is not load-bearing.**
Phase 5 reviewer's CRIT-1 was correct: VP9 (vp9.c:624) and MPEG-2 (mpeg2.c:150,156) use the same `v4l2_timeval_to_ns(&ref->timestamp)` pattern as H.264 and both decode correctly with gettimeofday-derived giant ns. If timestamp magnitude were load-bearing, those would also fail.
## Wire-byte search space — now exhausted
After iter8 + iter9, all observable libva-vs-kdirect wire diffs in H.264 control submission have been tested:
| Field | libva | kdirect | Tested | Verdict |
|---|---|---|---|---|
| SPS constraint_set_flags | 0x00 | 0x02 | α-1 review | inert (rkvdec source) |
| SPS all other bytes | identical | identical | Phase 3 + Phase 0 iter9 | match |
| PPS all bytes | identical | identical | Phase 0 iter9 | match |
| SCALING_MATRIX | flat 16/16 | flat 16/16 | Phase 3 | match |
| DPB[].POC (after α-2) | sentinel-encoded | sentinel-encoded | α-2 implemented | match wire, no behavior change |
| DPB[].flags | 0x03 VALID|ACTIVE | 0x03 | Phase 0 iter9 | match |
| DPB[].pic_num/frame_num/fields | match | match | Phase 0 iter9 | match |
| DPB[].reference_ts magnitude | small µs | small µs (post-α-7) | α-7 implemented | match wire, no behavior change |
| DECODE_PARAMS post-DPB (bytes 512-559) | identical | identical | Phase 0 iter9 deep-strace | match |
| OUTPUT QBUF bytesused | slices_size | slices_size | Same v4l2_queue_buffer logic | match (untested empirically) |
| Slice data bytes in OUTPUT buffer | start_code + raw NAL | start_code + raw NAL | Same backend logic | match (untested empirically) |
The only NOT-yet-empirically-verified surface is:
- **Actual byte content of the OUTPUT buffer**. Both backends construct slice data the same way (start_code prefix + NAL data), but no byte-for-byte dump of the in-memory OUTPUT buffer has been done.
- **OUTPUT QBUF m.planes[0].bytesused**. The strace abbreviated this; both backends *should* be setting it from their slice-count tracking variable. Worth confirming via VIDIOC_QBUF dump.
## Iter9 hypothesis ranking, final state
| Hypothesis | Status after iter8+iter9 |
|---|---|
| libva-readback bug | ❌ Eliminated (γ dump) |
| Slot-binding wrong | ❌ Eliminated (γ dump) |
| Stale residue | ❌ Eliminated (IMP-1 memset) |
| SPS constraint_set_flags | ❌ Eliminated (Phase 5b CRIT-1, rkvdec source) |
| POC sentinel | ❌ Eliminated (α-2 wire change, no behavior) |
| reference_ts magnitude | ❌ Eliminated (α-7 wire change, no behavior; VP9/MPEG-2 use same pattern and PASS) |
**Bug 4 search space exhaustion on the libva wire-byte side.**
## Lessons from iter9
### Lesson 1: Reviewer's empirical CRIT-1 caught α-7 before build
Phase 5 CRIT-1 correctly identified that VP9/MPEG-2 use the same timestamp path and PASS — making α-7 a low-probability fix. The empirical test (α-7 build + verify) confirmed the prediction. Saved no time vs the prediction itself, but added an empirical confirmation to the elimination.
### Lesson 2: Two consecutive α-attempts (α-2 POC, α-7 timestamp) changed wire bytes without changing behavior
Reinforcement of `feedback_wire_vs_behavior.md`: wire-equivalence is necessary but not sufficient. The pattern of "change wire to match kdirect, observe no decoder output change" is now repeated twice in this iteration. Suggests Bug 4 is in something NOT carried by the libva→kernel ioctl payload — likely either the OUTPUT bitstream bytes themselves, or some kernel-internal state that depends on neither.
### Lesson 3: Wire-byte hypothesis space has finite size
After 6 eliminations across iter8+iter9, the libva-vs-kdirect H.264 ioctl-payload-byte diff is empirically zero (modulo `constraint_set_flags` which is inert). Any iter10+ Bug 4 fix must either:
- (a) Find a diff in OUTPUT bitstream bytes (in-memory dump comparison).
- (b) Find a diff in some untraced control (device-init controls, REQBUFS counts, S_FMT details).
- (c) Pivot to kernel-side investigation (rkvdec source dive for the 16×32 partial-decode signature).
## iter9 → iter10 handoff
Substrate at close:
- Fork tip `e0be4e6` on noether + fresnel + gitea.
- Backend SHA `a17e3c39671d4f430a7c6f2be04ec128545aa44737a5f4df2b4558b158019a43` on fresnel.
- Kernel `linux-fresnel-fourier 7.0-1` unchanged.
- All diagnostic instrumentation (γ + IMP-1 memset gate) preserved.
- α-2 POC strip removal + α-7 timestamp counter both shipped as hygiene improvements (zero behavior change but cleaner wire-payload semantics).
iter10 candidate ranking:
1. **α-8 OUTPUT bitstream byte dump** — add γ-style dump of `source_data` immediately before OUTPUT QBUF. Compare against kdirect's bytes (kdirect can also be instrumented via LD_PRELOAD or ffmpeg patch). ~30 LOC + analysis time.
2. **α-9 untraced control diff** — VIDIOC_S_EXT_CTRLS with device-wide ctrl_class (not request-attached) controls. Currently only DECODE_MODE + START_CODE + HEVC versions are set at init. Check what kdirect's S_EXT_CTRLS does that we don't.
3. **kernel-side** — read rkvdec assemble_hw_pps + run_hw fully. Look for a code path that produces a 16×32-byte partial write with luma-neutral default values.
4. **Pivot to a different bug** — Bug 5 (HEVC) or Bug 6 (VP8 partial). Bug 4's diminishing-returns curve suggests it may be better to defer until kernel knowledge ramps up.
Campaign scoreboard (unchanged):
```
H.264 | rkvdec | PARTIAL | Bug 4 narrowed via 6 eliminations
HEVC | rkvdec | DEGRADED | Bug 5 deferred
VP9 | rkvdec | PASS direct | iter5b-β
MPEG-2 | hantro | PASS (env) | iter1
VP8 | hantro | PARTIAL (env) | Bug 6 deferred
```
iter8 + iter9 net contribution: significant Bug 4 narrowing (6 hypotheses eliminated, wire-byte search exhausted), plus diagnostic instrumentation infrastructure (γ + memset gate) for any future libva-side investigation. Zero codec fixes shipped.
## Phase 8 commit
iter9 PARTIAL close. Fork at `e0be4e6`. Backend SHA `a17e3c39…`. 5/6 criteria PASS. iter10 needs a fundamentally different approach to make progress on Bug 4 — OUTPUT bitstream byte comparison OR kernel-side investigation OR pivot to a different bug.