Files
fresnel-fourier/phase0_findings.md
T
claude-noether 60e62da666 phase 0 corrections: hantro RK3399 has no H.264; substrate is iter8 master
Two empirical corrections to the morning-of-2026-05-07 phase 0 lock,
based on V4L2 inventory + iter8 fork build smoke captured this evening
on fresnel (kernel 6.19.9-99-eos-arm).

Correction 1 — hantro-vpu-dec on RK3399 does not advertise H.264.

phase0_findings.md morning lock claimed both rkvdec (/dev/video3)
and hantro-vpu-dec (/dev/video5) advertise H.264. Empirical
v4l2-ctl --list-formats-out shows hantro-vpu-dec exposes only
MG2S (MPEG-2) and VP8F (VP8) — no S264. Likely carryover from
RK3568 (ohm) hantro, which does support H.264; the RK3399 hantro
kernel variant in drivers/media/platform/verisilicon/ registers
a different codec list. Fix:

  - README.md hardware-target table: drop "+ H.264" from Decoder
    block 2.
  - README.md decode-side surface-area paragraph: note hantro is
    MPEG-2 + VP8 only and that there is exactly one bind for H.264
    (rkvdec).
  - phase0_findings.md mechanism table: drop H.264 from /dev/video5
    row; correct DT compatible to rockchip,rk3399-vpu (the actual
    parent device compatible — sysfs reports rockchip,rk3399-vpu,
    not rockchip,rk3399-vpu-dec which is just the v4l2 card type
    string).
  - phase0_findings.md "H.264 lands on both blocks" sentence:
    inverted to "H.264 lands only on rkvdec".
  - phase0_findings.md Open Question #2 (two-block H.264 routing):
    marked RESOLVED 2026-05-07 evening (null). Single bind, no
    routing decision, one test cell per codec.

Empirical evidence: phase0_evidence/2026-05-07/v4l2_inventory_findings.md
(distilled from v4l2_inventory.txt — the latter is gitignored as
raw data, regenerable via the v4l2-ctl invocation documented in
the findings file).

Correction 2 — substrate is iter8 master (65969da), not iter5-end.

phase0_findings.md morning lock framed the substrate as "iter5-end
fork." That was true on 2026-05-05 (iter5 close); between then and
the 2026-05-07 fresnel-fourier scaffold libva-multiplanar continued
through iter6 (per-OUTPUT-slot REINIT request_fd binding), iter7
(slot-leak fix, cap_pool harness, msync verify harness, OUTPUT-pool
teardown), and iter8 (perf binding cell harness, RK3566/3568 doc
fix). Building from master tip 65969da inherits all the iter6-iter8
hardening at zero cost. Fix:

  - phase0_findings.md substrate paragraph: strikethrough the
    "iter5-end" framing, add corrected paragraph naming master
    tip 65969da and listing what iter6/7/8 added.
  - phase0_findings.md top-of-doc: add an "Empirical corrections
    2026-05-07 evening" callout linking to the evidence files,
    so a reader spotting the locked-vs-corrected mismatch knows
    where the empirical update came from.

Empirical evidence: phase0_evidence/2026-05-07/iter8_build_smoke.md
(clean build, vainfo profile enumeration, HEVC anomaly write-up).

What's preserved on purpose:

The strikethrough rendering in phase0_findings.md keeps the original
locked text visible alongside the correction — campaign convention
treats locks as historical record, not editable state. A reader
landing on the file from a deep link sees both the morning's
intent and the evening's empirical update. Git history has the
clean diff if anyone wants the original without strikethrough.

What's not changed:

The codec scope in the locked research question stays correct in
count — five codecs (H.264 + HEVC + VP9 + MPEG-2 + VP8). The
routing table changes (H.264 → rkvdec only; MPEG-2 → hantro only;
no shared block) but the boolean-correctness pass/fail criterion
per codec is unaffected. Phase 1 lock can proceed on the corrected
map without re-opening scope.

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

174 lines
19 KiB
Markdown
Raw 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.
# Phase 0 — fresnel-fourier
This campaign's substrate, locked research question, and pre-Phase-1 inventory work for the fresnel/RK3399 leg of the libva-v4l2-request-fourier rollout. Peer to libva-multiplanar (ohm/RK3568); see [`README.md`](README.md) for topology.
**Empirical corrections 2026-05-07 evening.** This document was locked 2026-05-07 morning before the V4L2 surface was empirically enumerated and before iter6iter8 work in libva-multiplanar was reflected in fresnel-fourier's substrate framing. Two facts have been corrected inline: (1) hantro-vpu-dec on RK3399 does **not** advertise H.264 — only MPEG-2 + VP8 (so Open Question #2 is null); (2) substrate is libva-v4l2-request-fourier `master` tip `65969da` (iter8 Phase 4), not "iter5-end". See [`phase0_evidence/2026-05-07/v4l2_inventory_findings.md`](phase0_evidence/2026-05-07/v4l2_inventory_findings.md) and [`phase0_evidence/2026-05-07/iter8_build_smoke.md`](phase0_evidence/2026-05-07/iter8_build_smoke.md) for the empirical evidence.
## Campaign-contained data discipline (governing rule)
Per [`feedback_dev_process.md`](../../.claude/projects/-home-mfritsche-src/memory/feedback_dev_process.md) Phase 0 + [`feedback_replicate_baseline_first.md`](../../.claude/projects/-home-mfritsche-src-kwin-overlay-subsurface/memory/feedback_replicate_baseline_first.md):
This campaign acquires its own measurement data on fresnel in-session. libva-multiplanar's ohm-side findings (iter1..iter5 close documents, the patch-0011 cache-coherency lesson, the FFmpeg/GStreamer source-read references, the H.264 control-submission corrections) are documented for **state** carry-over — bug catalog, contract analysis, source pointers, build recipe shapes — but every claim that depends on hardware behaviour ("hantro accepts X", "the parser rejects Y", "DPB needs Z") is **reference history** until re-verified on RK3399's `rkvdec` and `rk3399-vpu-dec` blocks. Different silicon, possibly different firmware, definitely different driver path: don't assume.
## Research question (LOCKED 2026-05-07)
> **"Make libva-v4l2-request-fourier accepted by VA-API consumers on fresnel (Rockchip RK3399), providing access to all decode-capable codecs the SoC ships — H.264 + HEVC + VP9 via the rkvdec block, MPEG-2 + VP8 via the hantro-vpu-dec block — end-to-end. Performance metrics are explicitly deferred to a follow-up iteration."**
Pass/fail is **boolean correctness** per codec, not throughput:
- For each of {H.264, HEVC, VP9, MPEG-2, VP8}: does the consumer dlopen `v4l2_request_drv_video.so`, complete the VA-API surface lifecycle without falling back to SW, route to the correct V4L2 device node (rkvdec vs hantro-vpu-dec), and produce a CAPTURE buffer with **non-zero, non-sentinel, semantically-correct decoded pixels** (cache-coherency-safe verification, per the libva-multiplanar iter1 0011-sentinel lesson)?
If yes for a codec → that codec passes for the iteration. Frame-rate / CPU% / drops measurement is a separate iteration whose binding cells will be locked separately.
## Mechanism the question targets
fresnel exposes **two** V4L2 stateless decode interfaces (verified 2026-05-07 via `v4l2-ctl --info` + `--list-formats`):
| Node | Driver | DT compatible | Codecs (kernel CIDs) | Capture format |
|---|---|---|---|---|
| `/dev/video3` | `rkvdec` | `rockchip,rk3399-vdec` | H.264 (`V4L2_PIX_FMT_H264_SLICE`), HEVC (`V4L2_PIX_FMT_HEVC_SLICE`), VP9 (`V4L2_PIX_FMT_VP9_FRAME`) | NV12 |
| `/dev/video5` | `hantro-vpu` | `rockchip,rk3399-vpu` | MPEG-2 (`V4L2_PIX_FMT_MPEG2_SLICE`), VP8 (`V4L2_PIX_FMT_VP8_FRAME`) | NV12 |
Both are `V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE` + `V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`, both speak the request-API for control submission, both produce NV12 output. **H.264 lands only on rkvdec** — RK3399's hantro-vpu-dec does not advertise H.264 (corrected 2026-05-07 evening; the original lock cited H.264 on hantro, which was incorrect on running kernel 6.19.9-99-eos-arm). There is no two-block routing decision for H.264 on this SoC.
VA-API consumers (mpv, Firefox, chromium-fourier, vainfo) speak libva. The bridge they expect is `libva-v4l2-request-fourier`. As of libva-multiplanar iter5-close (2026-05-05), the fork is hardened against ohm's hantro-vpu (`rk3568-vpu`) — the test consumers run end-to-end on H.264 with all known iter1..iter4 bugs fixed. Whether that hardening transfers to:
1. fresnel's hantro-vpu-dec (`rk3399-vpu-dec`) — same driver family, possibly different SoC quirks
2. fresnel's rkvdec — a *different* driver entirely; new code paths in the libva backend may be needed
3. HEVC + VP9 + MPEG-2 + VP8 — codecs the fork has never decoded on real hardware to date
are open empirical questions that this campaign answers.
External pointers (carried from libva-multiplanar/phase0_findings.md):
- Mozilla bug 1833354 / 1965646 — Firefox HW decode on RK35xx via libva-v4l2-request.
- Bootlin upstream `bootlin/libva-v4l2-request` — dormant since 2021, sunxi-cedrus single-plane only.
- Linux kernel `drivers/staging/media/rkvdec/` — the rkvdec driver source. H.264 + HEVC + VP9 control-submission contract reference for fresnel.
- Linux kernel `drivers/media/platform/verisilicon/hantro_*` — the hantro-vpu driver source. RK3399-vpu-dec MPEG-2/H.264/VP8 control protocol reference.
- Christian Hewitt patch series ([LKML 2025/12/26/206](https://lkml.org/lkml/2025/12/26/206)) — RK3566 rkvdec2/vdpu346 (NOT applicable here; fresnel's rkvdec is mainline and works).
## Predecessor close-out summary (state carry-over, not data)
### From `~/src/libva-multiplanar/` — iter1..iter5 closed on ohm
The full chain of bugs found and fixed on ohm/RK3568 hantro is the substrate. Read in order:
- `phase8_iteration1_close.md` — iter1: contract trace lands; surface-export DMA-BUF lifecycle race; multi-resolution session corruption; Mesa WSI 64-pitch alignment; **patch-0011 sentinel cache-coherency bug** (the readback was lying — kernel was writing zeros).
- `phase8_iteration2_close.md` — iter2: Fix 1 (resolution-change format-cache invalidation), Fix 2 (DRM_FORMAT_MOD_INVALID conditional for non-64 pitch), Fix 3 (decoupled `cap_pool` with LRU recycling).
- `phase8_iteration3_close.md` — iter3: Firefox RDD sandbox fix (broker policy + seccomp + `select() → poll()` driver migration); frame-11 EINVAL reproduced deterministically.
- `phase8_iteration4_close.md` — iter4: frame-11 EINVAL fixed (DPB `fields=FRAME_REF`, fresh request_fd per frame, B-slice L1 reflist `.fields` copy-paste). mpv 2130 BeginPictures over 90s with 0 EINVAL.
- `phase8_iteration5_close.md` — iter5: ~339 lines of debug instrumentation removed; firefox-fourier 150.0.1-1.1 rebuilt non-PGO (21× smaller libxul, 2.7× faster decode); `LAST_OUTPUT_*` moved per-driver-data; mpv `--vo=gpu` 0 segfaults. **iter6+ caveat: cap_pool resolution-change race latent under untested consumer probe patterns** (Phase 5 sonnet C4).
~~The iter5-end fork is the substrate fresnel-fourier starts from.~~ **Corrected 2026-05-07 evening:** the substrate is `master` tip `65969da` (iter8 Phase 4) — libva-multiplanar continued past iter5 into iter6 (per-OUTPUT-slot REINIT request_fd binding), iter7 (slot-leak fix, cap_pool harness, msync verify, OUTPUT-pool teardown), and iter8 (perf binding cell harness) between the 2026-05-05 iter5 close and the 2026-05-07 fresnel-fourier scaffold. Building from master inherits all that hardening at zero cost. Codepaths not exercised on ohm — the rkvdec driver path entirely; HEVC + VP9 + MPEG-2 + VP8 control submission — are unknown territory and the most likely Phase 6 work.
### From the libva-v4l2-request-fourier fork itself
Carry-over **state** (re-verify before treating as current):
- 12 commits ahead of bootlin `a3c2476` plus 5 iterations of patches, all on `master`. Build harness: `meson setup` + `ninja`. Install: `/usr/lib/dri/v4l2_request_drv_video.so`. Activation: `LIBVA_DRIVER_NAME=v4l2_request` + `LIBVA_V4L2_REQUEST_VIDEO_PATH=...` + `LIBVA_V4L2_REQUEST_MEDIA_PATH=...`.
- Build artefact size on ohm: ~265 KB `.so` (small — no distcc).
### From the SDDM-greeter recovery plan (`~/.claude/plans/dynamic-forging-piglet.md`)
fresnel currently cannot graphical-login — `/usr/bin/sddm-greeter-qt6` crash-loops with a `qFatal()` call from `libqxcb-glx-integration.so` after `QOpenGLContext::create` returned failure. Coredump bt confirmed; `qt6-base-fourier` is exonerated (downgrade to stock didn't fix it; bt path is GLX, our patches gate on ES 3+). The plan lists three step-1 invocations to capture the qFatal message, an iterative downgrade test against the recent `pacman -Syyuu` (mesa, qt6-base, qt6-declarative, libdrm-pinebookpro candidates), and two workaround options (Wayland greeter via SDDM `Compositor`, or TTY autologin with `exec startplasma-wayland`).
This recovery is fresnel-fourier Phase 0 task 1 (LOCKED 2026-05-07). Without graphical login there's no Plasma session to host VAAPI consumers under; headless Xvfb is documented (libva-multiplanar phase0) to give the wrong answer for Firefox.
## Current fresnel state (verified 2026-05-07 over SSH)
- Kernel: `linux-eos-arm 6.19.9-99` (custom OC kernel, ALARM/EndeavourOS-ARM). `CONFIG_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_DYNAMIC_FTRACE=y, CONFIG_TRACING=y` confirmed via `zcat /proc/config.gz`. `/sys/kernel/tracing/` populated.
- V4L2 decode nodes: `/dev/video3` (rkvdec), `/dev/video5` (hantro-vpu-dec) — listed above.
- Encoder: `/dev/video4` (hantro-vpu-enc, JPEG only).
- RGA: `/dev/video0` (rockchip-rga, scaling/format-conversion accelerator — out of scope but worth knowing about).
- USB cameras: `/dev/video{1,2}` — irrelevant.
- Graphical session: **DOWN** — sddm-greeter-qt6 crash-loop. Phase 0 task 1.
## In-scope (LOCKED 2026-05-07)
- libva-v4l2-request-fourier **backend only**.
- Hardware target: **fresnel RK3399**, both decode nodes (rkvdec + hantro-vpu-dec).
- Codecs: **H.264 + HEVC + VP9 + MPEG-2 + VP8** — everything fresnel can hardware-decode. Each codec is a separate boolean cell.
- Test consumers (LOCKED 2026-05-07):
- `vainfo` — smoke test, enumerates profiles + entrypoints per codec.
- `mpv --hwdec=vaapi` (and `--hwdec=vaapi-copy` for the headless intermediate runs) — most directly testable end-to-end consumer for HW decode validation.
- Firefox via `media.ffmpeg.vaapi.enabled=true` + LIBVA env — Mozilla bug 1965646 anchor.
- chromium-fourier 149 — regression check inherited from libva-multiplanar.
- Brave 1.89 — *deferred* (chromeos-pipeline gating is upstream of libva, same as libva-multiplanar's reasoning).
- Phase 1 success criterion: per-codec **boolean correctness** including cache-coherency-safe pixel-content verification (NOT the patch-0011 mmap pattern — that lesson is non-negotiable per libva-multiplanar iter1 close).
- **Phase 0 task 1: recover fresnel SDDM** (per `dynamic-forging-piglet.md`). Bookkept inside this campaign.
## Out-of-scope (LOCKED 2026-05-07)
- Front-end libva.
- Other hardware (ohm in libva-multiplanar; ampere/boltzmann RK3588 are a separate not-yet-named campaign).
- AV1 (no decoder block on RK3399 supports it).
- Userspace bitstream parsing (kernel V4L2-stateless does this).
- Performance metrics (CPU%, fps, drops_60s, panfrost freq, GPU residency). **Explicitly deferred.** Do not lock Phase 1 binding cells around performance.
- KWin / panfrost / Mali-T860 work — orthogonal until proven otherwise. A `kwin-fourier-fresnel` campaign would be a separate decision.
- `cros-codecs` Rust replacement (per `user_stance_rust.md`).
- Bootlin / Collabora upstreaming — default-deferred (per `feedback_no_upstream.md`). Same discipline as libva-multiplanar.
- `/dev/video0` rockchip-rga acceleration — not on the libva path.
## Open questions before Phase 1 lock
1. **SDDM recovery root cause** — is the `qFatal` from a Mesa 26.0.5 panfrost regression on Mali-T860 (Midgard), Qt 6.11.0 xcb-glx-integration internals, or qt6-declarative? Phase 0 task 1 must determine this before Phase 1 locks, because it affects rig stability for measurement.
2. ~~**Two-block H.264 routing**~~**RESOLVED 2026-05-07 evening (null).** Empirical V4L2 enumeration showed hantro-vpu-dec on RK3399 does not advertise H.264. Only rkvdec accepts H.264 on this SoC. Single bind, no routing decision, single test cell per codec.
3. **HEVC control-submission contract on rkvdec** — the fork has had HEVC stripped per the libva-multiplanar build-cleanly stack. Re-introducing it for rkvdec is a code addition, not a regression-test. Phase 2 source-read of rkvdec H.265 path + FFmpeg's `v4l2_request_hevc.c` is gating.
4. **VP9 control-submission contract on rkvdec** — never been in the fork. Same Phase 2 source-read need: kernel `rkvdec_vp9.c` + FFmpeg `v4l2_request_vp9.c`. Plus VAAPI-VP9 consumer testing — does mpv exercise it? does Firefox?
5. **MPEG-2 control-submission contract on hantro-vpu-dec** — was iter1 backlog in libva-multiplanar, dropped at iter6 close because A55 CPU handles it fine. On RK3399 the A53 cluster is weaker; HW MPEG-2 decode might be more useful. Phase 2 source-read: kernel `hantro_mpeg2.c` + FFmpeg `v4l2_request_mpeg2.c`.
6. **VP8 control-submission contract on hantro-vpu-dec** — same shape: source-read kernel + FFmpeg. VP8 consumer matrix is thin; mostly Firefox / WebRTC paths.
7. **rkvdec node device path env var** — backend likely uses `LIBVA_V4L2_REQUEST_VIDEO_PATH` for one node. Two nodes may need a richer config: explicit per-codec routing or a probe loop. Phase 4 design decision.
8. **firefox-fourier suitability for fresnel** — the iter3 RDD sandbox patch is Mali-G52-rig-tested. Does it apply on Mali-T860 / panfrost on RK3399 unchanged, or are sandbox-side surprises lurking? Phase 0 inventory item: confirm the iter5 firefox-fourier package installs and runs on fresnel.
9. **Test corpus per codec**`bbb_1080p30_h264.mp4` (carryover). HEVC, VP9, MPEG-2, VP8 test clips need sourcing or generating. Doppler / `/moviedata/fourier-test/` may already have some.
10. **Brave 1.89 / chromium-fourier 149 binaries on aarch64 for fresnel** — both already exist for ohm. Same aarch64 architecture; should run on fresnel without rebuild. Verify.
## What Phase 0 will deliver
Independent of detail, Phase 0 produces:
1. **fresnel SDDM recovered** — either root-caused + downgraded to a working version, or workaround-A (Wayland greeter) installed. Findings logged in this directory under `phase0_recovery_<date>.md`. Loop back to phase 0 (not phase 1) if a root cause has campaign-relevant implications (e.g., a Mesa 26.0.5 panfrost regression that also affects video display paths).
2. **fresnel V4L2 inventory written**`v4l2-ctl` enumeration of every codec controls + supported formats per node, captured to `phase0_evidence/<date>/v4l2_inventory.txt`. Already partially done in this document; expand to include `--list-ctrls-menus`, `--all` per node, and supported `OUTPUT_MPLANE` codec formats.
3. **iter5-end fork built on fresnel and installed**`meson setup && ninja` directly on fresnel (no distcc per libva-multiplanar precedent). Install to `/usr/lib/dri/v4l2_request_drv_video.so`. Run vainfo, capture profile enumeration. This is the smoke test before any iteration even starts — does the existing fork even *load* on RK3399?
4. **H.264 baseline trace**`mpv --hwdec=vaapi-copy --frames=2` against `bbb_1080p30_h264.mp4` on fresnel, ftrace-instrumented, **with cache-coherency-safe pixel verification** per the libva-multiplanar iter1 patch-0011 lesson. Compare control-submission ioctl sequence against ohm's iter5 trace. Identify divergences.
5. **Per-codec test fixture inventory** — what test clips exist for HEVC / VP9 / MPEG-2 / VP8, what we need to source or generate, and where they'll live.
6. **Phase 0 baseline anchor** — for the boolean-success criterion per codec, the anchor is again a contract trace, not a metric distribution. Capture the V4L2 request-API ioctl sequence on a known-working consumer per codec on fresnel — chromium-fourier 149 binary is the cross-validator (does it engage rkvdec for HEVC? VP9? for the codecs it natively uses) — for 1 frame's decode each, in-session, before any fork modifications.
Phase 0 is **not** the place to start coding HEVC/VP9 support in the fork. That work, if it lands, is Phase 4 onwards of an iteration whose Phase 1 has already locked the codec scope.
## Source-read references (carried + extended for fresnel)
For Phase 2 source-read and Phase 6 implementation:
**Carried from libva-multiplanar (H.264 path):**
- **FFmpeg** — `libavcodec/v4l2_request.c`, `v4l2_request_buffer.c`, `v4l2_request_h264.c`. Active downstream: `code.ffmpeg.org/Kwiboo/FFmpeg.git` branch `v4l2-request-n8.1`.
- **GStreamer v4l2codecs** — `gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.c` + `gstv4l2codecsh264dec.c`.
- **Chromium** — `media/gpu/v4l2/v4l2_video_decoder_backend_stateless.{h,cc}` + `v4l2_queue.cc`.
**Added for fresnel (HEVC/VP9/MPEG-2/VP8):**
- **FFmpeg `v4l2_request_hevc.c`** — HEVC slice-mode control submission.
- **FFmpeg `v4l2_request_vp9.c`** — VP9 frame control submission.
- **FFmpeg `v4l2_request_mpeg2.c`** — MPEG-2 slice control submission.
- **FFmpeg `v4l2_request_vp8.c`** — VP8 frame control submission.
- **GStreamer** — `gstv4l2codecsh265dec.c`, `gstv4l2codecsvp9dec.c`, `gstv4l2codecsmpeg2dec.c`, `gstv4l2codecsvp8dec.c`.
- **Linux kernel** — `drivers/staging/media/rkvdec/{rkvdec_h264.c, rkvdec_hevc.c, rkvdec_vp9.c}` for the rkvdec block; `drivers/media/platform/verisilicon/hantro_h264.c, hantro_mpeg2.c, hantro_vp8.c` for the hantro block.
## Test fixtures
- **H.264**: `bbb_1080p30_h264.mp4` (carry-over from `fourier_attribution` / libva-multiplanar). Pull via hertz `lxc file pull` from `data:/moviedata/fourier-test/` or copy from ohm's `/home/mfritsche/fourier-test/`.
- **HEVC, VP9, MPEG-2, VP8**: TBD per Phase 0 deliverable #5. Likely Big Buck Bunny in those codecs from the same operator-internal `/moviedata/` if available; otherwise generate via `ffmpeg -i bbb_1080p30_h264.mp4 -c:v <codec> -y bbb_1080p30_<codec>.<ext>`.
## Build + install on fresnel
- `meson setup build && ninja -C build` directly on fresnel. Same default as libva-multiplanar: small library, no distcc.
- Install path: `/usr/lib/dri/v4l2_request_drv_video.so`.
- Activation: `LIBVA_DRIVER_NAME=v4l2_request` + (per-node env vars; exact layout depends on Phase 4 device-routing decision).
- Once a working state is reached: package as `marfrit/libva-v4l2-request-fourier-fresnel` next to existing fourier packages — out of Phase 1 scope, post-Phase-7.
## Cross-link to libva-multiplanar
This campaign is a **peer**, not a child. libva-multiplanar Phase 8 closes happen iteration-by-iteration on ohm independently of fresnel-fourier progress. Cross-references:
- libva-multiplanar/README.md:87 names fresnel + RK3588 as "future iterations after ohm path is solid" — that promise is now formally taken up here.
- Code-side work in the shared fork (`../libva-multiplanar/libva-v4l2-request-fourier/`) lands either as `#ifdef`/runtime-detected paths on `master` (preferred when behavior is RK3399-specific but doesn't break ohm) or on a feature branch (when scope diverges sharply). Phase 2 source-read of each iteration decides.
- libva-multiplanar's iter1 **patch-0011 cache-coherency lesson** is non-negotiable for fresnel-fourier: pixel-content verification must use cache-flushed reads (e.g. mpv `--vo=image-sequence`, or DMA-BUF GL import via mpv `--vo=gpu`, or a small C reproducer with `msync(MS_SYNC|MS_INVALIDATE)`), never the cached mmap readback pattern.