# Iteration 5b — Phase 6 v2 (implementation, option β)

Commits A + B + C landed on fork master 2026-05-12 after the Phase 5 v2 review cleared the β plan with two CRIT amendments. Build + install on fresnel pending — fresnel offline at time of commit push.

## Commits

| SHA | Files | LOC | Summary |
|---|---|---|---|
| `1c548b1` (A) | `src/codec.h` (new) · `src/codec.c` (new) · `src/meson.build` | +102 / -2 | NEW codec.h/codec.c — `pixelformat_for_profile()` helper. Identical to reverted iter5b commit A. Registered in meson.build sources + headers. |
| `cc077a0` (B) | `src/config.c` | +11 | Wire `object_config->pixelformat = pixelformat_for_profile(profile)` at CreateConfig. Populates the previously-dead field at config.h:46. |
| `7055b14` (C) | `src/surface.c` · `src/surface.h` · `src/context.c` · `src/request.h` | +238 / -280 | β refactor + CRIT-1 + CRIT-2 + IMP-1 + IMP-2 all in one. Strips ~200 LOC from surface.c::CreateSurfaces2; absorbs OUTPUT-side lifecycle into context.c::RequestCreateContext; adds request_pool_destroy to DestroyContext; deletes `last_output_{width,height}` fields + `surface_reset_format_cache` function. |

Fork tip post-iter5b-β: `7055b14`.

## Phase 5 v2 amendments incorporated

| ID | Amendment | Where landed |
|---|---|---|
| CRIT-1 | Remove `video_format == NULL` early-return at context.c:65-66 | Commit C — restructured CreateContext entry; CAPTURE probe now runs first (within CreateContext), then `output_type`/`capture_type` derived from `video_format->v4l2_mplane`. |
| CRIT-2 | Add `request_pool_destroy(&driver_data->output_pool)` to DestroyContext before REQBUFS(0) | Commit C — inserted with explanatory comment citing the v2 review. |
| IMP-1 | Probe CAPTURE first to derive `output_type`, not the hardcoded `v4l2_type_video_output(true)` | Commit C — IMP-1 ordering applied directly. |
| IMP-2 | Delete dead `surface_reset_format_cache` function + caller + last_output_* fields | Commit C — deleted from surface.c (function definition + comment block), surface.h (declaration), context.c (call in DestroyContext), request.h (fields). |
| IMP-3 | Document error-recovery state in commit comment | Commit C body explains the error-path state. |

All 5 Phase 5 v2 amendments in commit C; no follow-up edits needed.

## File-level changes

| File | Action | Notes |
|---|---|---|
| `src/codec.h` | NEW (commit A) | Helper declaration. |
| `src/codec.c` | NEW (commit A) | Helper definition; switch covers all 5 codec profiles. |
| `src/meson.build` | UPDATE (commit A) | Add `codec.c`/`codec.h` to sources/headers. |
| `src/config.c` | UPDATE (commit B) | Add `#include "codec.h"`; wire `config_object->pixelformat`. |
| `src/surface.c` | STRIP (commit C) | CreateSurfaces2 reduced from ~250 LOC to ~50 LOC. Delete `surface_reset_format_cache` function. Delete OUTPUT-side block + CAPTURE probe + cap_pool_init + per-surface destination_* fill (all moved to context.c). |
| `src/surface.h` | UPDATE (commit C) | Remove `surface_reset_format_cache` declaration. |
| `src/context.c` | EXPAND (commit C) | CreateContext now owns the entire OUTPUT-side lifecycle. DestroyContext adds `request_pool_destroy` (CRIT-2 fix) and drops the `surface_reset_format_cache` call. |
| `src/request.h` | UPDATE (commit C) | Delete `last_output_width`/`last_output_height` fields; replace block with explanatory comment. |

Net delta: +238/-280 LOC across 5 files + 2 new = effectively unchanged total size, but code is now in the architecturally correct place.

## Build + install status

- **Fork tip pushed** to `git.reauktion.de/marfrit/libva-v4l2-request-fourier` master at `7055b14`.
- **Fresnel build/install**: pending. Fresnel offline (`ssh: No route to host`) at push time. When fresnel returns:

```bash
ssh fresnel 'cd ~/src/libva-v4l2-request-fourier && \
  git pull --ff-only origin master && \
  ninja -C build && \
  sudo install -m 644 build/src/v4l2_request_drv_video.so \
       /usr/lib/dri/v4l2_request_drv_video.so && \
  sha256sum /usr/lib/dri/v4l2_request_drv_video.so'
```

Predicted new SHA256: TBD. Will differ from iter4-tip `6e90b7a9b2c33480…` and from rejected iter5b-α' `d7722da742bfcb86…`.

## Phase 7 readiness

The Phase 4 v2 plan's C8 verification matrix is ready to run once the new backend is installed. Re-run `/tmp/iter5b_p7/sweep.sh` (preserved from earlier verification — needs device-path remapping per current boot).

Expected post-β hash matrix (same as Phase 4 v2 C8):

| Codec | Pre-β libva | Expected post-β libva | kdirect (anchor) |
|---|---|---|---|
| H.264 1080p30 | `71ac099b…` keyframe partial | unchanged (Bug 4 deferred) | `1e7a0bc9…` |
| HEVC 720p | `06b2c5a0…` all-zero | **`9340b832…`** | `9340b832…` |
| VP9 720p | `06b2c5a0…` | **`4f1565e8…`** | `4f1565e8…` |
| MPEG-2 720p | `19eefbf4…` worked | `19eefbf4…` (unchanged) | `19eefbf4…` |
| VP8 720p | `06b2c5a0…` | **`136ce5cb…`** | `136ce5cb…` |

PASS criteria: 3 codecs unblocked (HEVC + VP9 + VP8 `libva == kdirect == sw`) + MPEG-2 unchanged + H.264 unchanged.

Phase 7 robustness check (specifically for the α' failure mode): run the sweep TWICE back-to-back in the same shell (or one ffmpeg-vaapi session followed by another with a different codec) to confirm the lifecycle is robust across context cycles. The α' failure mode was multi-CreateSurfaces2 mid-stream; β should handle it because each session is a self-contained CreateContext setup-and-teardown cycle.

## Risk register at Phase 6 close

| Risk | Status |
|---|---|
| Build fails on fresnel | Unknown until fresnel returns. Code review + grep verified all symbols, includes, and types resolve. |
| HEVC SIGSEGV (α' failure mode) | **Mitigated** — β has no in-CreateSurfaces2 destructive teardown branch. |
| CRIT-1 (NULL guard) | **Fixed** in commit C. |
| CRIT-2 (missing request_pool_destroy) | **Fixed** in commit C. |
| mpv probe-then-real | Expected to work — DestroyContext between cycles. |
| ohm backwards compat | Expected to work — MPEG-2 path gets explicit MPEG2_SLICE (which hantro previously substituted anyway). |

## Substrate state at Phase 6 close

- Fork tip `7055b14` on noether + gitea.
- Backend on fresnel: **still iter4-tip SHA `6e90b7a9b2c33480…`** (revert state) until fresnel returns + pull + build + install runs.
- Kernel: `linux-fresnel-fourier 7.0-1` (unchanged, no kernel work in iter5b).
- Test fixtures: unchanged.
- Phase 7 sweep: ready to execute once new backend is installed.
