claude-noether b9625af278 iter1 Phase 3: baseline measurements — Phase 2 confirmed empirically
Four Phase 3 baselines captured on fresnel post-reboot 2026-05-08
00:39 CEST. SDDM watchpoint condition stayed green (greeter passed
cleanly on the new boot). All four baselines confirm Phase 2's
situation analysis empirically; one Phase 1 criterion needs minor
adjustment (Phase 3 → Phase 1 loopback per feedback_dev_process.md).

Baseline A — pre-patch failure mode (master tip 65969da):

  ffmpeg -hwaccel vaapi -i bbb_720p10s_mpeg2.ts ... under strace +
  LIBVA_TRACE captures the chain:

  vaInitialize ret = SUCCESS
  vaQueryConfigProfiles ret = SUCCESS
  vaCreateConfig(profile=VAProfileMPEG2Main, entrypoint=VLD)
    ret = VA_STATUS_ERROR_UNSUPPORTED_PROFILE

  No V4L2 ioctls beyond ENUM_FMT probes from RequestQueryConfigProfiles.
  Confirms Phase 2 Bug 1 (config.c:55-69 fall-through to default).

Baseline B — post Bug 1 scratch patch (the missing break added):

  vaCreateConfig now returns SUCCESS. V4L2 setup proceeds:
  CREATE_BUFS, QUERYBUF (40), REQBUFS, STREAMON, S_FMT, etc.
  Then VIDIOC_S_EXT_CTRLS fails:

    ioctl(/dev/video5, VIDIOC_S_EXT_CTRLS,
          {ctrl_class=0xf010000,
           count=1,
           controls=[
             {id=V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
              size=56, ...}
           ]})
        = -1 EINVAL

  CID 0x9909fa (V4L2_CID_MPEG_BASE+250) doesn't exist on this kernel —
  mainline removed it in favor of the split V4L2_CID_STATELESS_MPEG2_*
  CIDs. Size 56 = sizeof(combined v4l2_ctrl_mpeg2_slice_params) from
  the fork's local include/mpeg2-ctrls.h. Confirms Phase 2 Bug 2.

  Auxiliary EINVAL: src/context.c:142-155 unconditionally sets H.264
  device-wide controls (H264_DECODE_MODE, H264_START_CODE) on every
  CreateContext, regardless of profile. EINVALs on hantro-vpu-dec
  (no H.264 controls there). Intentional best-effort behavior —
  return value is cast to (void) and discarded. Auxiliary, not iter1
  scope.

Baseline C — cross-validator verbatim contract anchor:

  ffmpeg -hwaccel v4l2request strace shows ONE batched call per frame:

    ioctl(/dev/video5, VIDIOC_S_EXT_CTRLS,
          {ctrl_class=0xf010000,    // V4L2_CTRL_CLASS_CODEC_STATELESS
           count=3,
           controls=[
             {id=0xa409dc, size=12,  ...},   // SEQUENCE
             {id=0xa409dd, size=32,  ...},   // PICTURE
             {id=0xa409de, size=256, ...}    // QUANTISATION
           ]}) = 0

  Field-by-field decode of frame 1 (I-picture):
    SEQUENCE: 1280×720, vbv=0x151800, profile_level=0,
              chroma_format=1, flags=PROGRESSIVE
    PICTURE: back/fwd_ref_ts=0/0, flags=0x82
             (FRAME_PRED_DCT|PROGRESSIVE), f_code=0xF×4 (I-frame
             default), P_C_T=1 (I), structure=3 (FRAME),
             intra_dc_precision=0
    QUANTISATION: starts [8, 16, 16, 19, 16, 19, 22, 22, ...] —
                  canonical MPEG-2 default intra matrix in zigzag
                  scanning order.

  Frame 2 (P-picture) shows real f_code values {{1,1},{15,15}}
  and forward_ref_ts pointing to frame 1's timestamp. Confirms
  Phase 2's claim that matrices arrive in zigzag order;
  no permutation needed in the libva backend (kernel's
  hantro_mpeg2_dec_copy_qtable handles zigzag-to-raster).

  This is the iter1 contract anchor: every Phase 4 implementation
  diff must produce a structurally indistinguishable
  VIDIOC_S_EXT_CTRLS call.

Baseline D — H.264 regression check (Phase 1 criterion #5):

  T4 reference hashes match exactly with scratch Bug 1 fix installed:
    HW frame 1: f623d5f7a41697f67dd227275c6f1b21ffc257f65626d32fde8229357f8764c9
    SW frame 1: f623d5f7a41697f67dd227275c6f1b21ffc257f65626d32fde8229357f8764c9
    HW frame 2: 7d7bc6f2146dda8b2d223bba622c4b9fbe9674181ff1e02afe286b620342e0a8
    SW frame 2: 7d7bc6f2146dda8b2d223bba622c4b9fbe9674181ff1e02afe286b620342e0a8

  Bug 1 fix in isolation does not regress H.264.

Phase 1 criterion #3 needs adjustment (Phase 3 → Phase 1 loopback):

  Original wording: "mpv --hwdec=vaapi-copy ... engages the backend"
  Reality: mpv-vaapi-copy never loads libva for MPEG-2. mpv's hwdec
  policy filters MPEG-2 out before libva is touched. Zero V4L2
  ioctls, zero libva trace, silent SW fallback. Independent of
  Bug 1 fix state.

  Adjusted criterion #3 (proposed; locks alongside Phase 4 plan):
    "ffmpeg -hwaccel vaapi -i bbb_720p10s_mpeg2.ts -frames:v 2
     -f null - shows vaCreateConfig SUCCESS, no Failed to create
     decode configuration lines, no EINVAL from VIDIOC_S_EXT_CTRLS,
     exits 0 cleanly."

  mpv-driven testing moves to a follow-up task (mpv hwdec-codecs
  filter override), separate from iter1.

Other 4 Phase 1 criteria (vainfo regression, vaCreateConfig SUCCESS,
DMA-BUF GL pixel verify HW=SW, T4 H.264 regression) hold as locked.

Scratch state cleanup: scratch patch reverted, master backend
reinstalled, MPEG-2 fails again with vaCreateConfig=12 — back to
Baseline A state, no leak.

Phase 4 plan inputs:

  - Diff scope: src/config.c (1 break), src/mpeg2.c (rewrite to
    new API), include/mpeg2-ctrls.h (delete or empty). picture.c
    + context.c unchanged.
  - Contract anchor: cite verbatim from
    linux/v4l2-controls.h:1985-2105, FFmpeg
    libavcodec/v4l2_request_mpeg2.c:130-155, kernel
    drivers/media/platform/verisilicon/hantro_mpeg2.c, AND this
    document's Baseline C verbatim payload.
  - Phase 7 verification: re-run all 5 Phase 1 criteria
    (with #3 adjusted), byte-by-byte compare post-fix
    VIDIOC_S_EXT_CTRLS payload against Baseline C.

Evidence files:

  Tracked (text):
    phase3_iter1_baseline.md (writeup with verbatim raw output)
    phase0_evidence/2026-05-07/iter1_phase3/baseline_A_ffmpeg/ffmpeg.stdout
    phase0_evidence/2026-05-07/iter1_phase3/baseline_B_postbug1/ffmpeg.stdout
    phase0_evidence/2026-05-07/iter1_phase3/baseline_C_xvalidator/ffmpeg.stdout

  Gitignored (regenerable from re-run incantations in the writeup):
    *.strace.*  *.txt (ftrace) libva.trace.* (added the latter pattern)

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

fresnel-fourier

TL;DR

Peer campaign to libva-multiplanar, targeting fresnel (Pinebook Pro / Rockchip RK3399) instead of ohm (PineTab2 / RK3566). Same deliverable shape — make libva-v4l2-request-fourier work end-to-end, for production VA-API consumers — but on a different SoC with a different (and broader) V4L2 decoder surface.

The libva backend fork itself (libva-v4l2-request-fourier) is shared: it lives at ../libva-multiplanar/libva-v4l2-request-fourier/. This campaign does not nest a second copy. Code-side work that turns out to be RK3399-specific lands either as #ifdef/runtime-detected paths inside that fork's master or, if scope diverges sharply, on a feature branch — Phase 2 source-read of each iteration decides.

Origin

libva-multiplanar reached iter5-close on 2026-05-05 with the ohm path solid: hantro (rk3568-vpu DT compatible) decodes H.264 to NV12 dmabufs end-to-end, three iterations of bugs fixed, mpv --hwdec=vaapi smooth, firefox-fourier RDD-sandboxed Firefox engages the backend without MOZ_DISABLE_RDD_SANDBOX=1, chromium-fourier 149 confirmed as the regression-check consumer.

That campaign's README explicitly names fresnel (RK3399) and ampere/boltzmann (RK3588) as "future iterations after ohm path is solid" (libva-multiplanar/README.md:87). fresnel-fourier is the formal peer campaign for the RK3399 leg of that promise.

Topology choice (LOCKED 2026-05-07): peer campaign, not child of libva-multiplanar. Each runs its own 8(+1) phase loop. Cross-link only — fresnel-fourier results do not gate libva-multiplanar's Phase 8 close (which already happened iteration-by-iteration on ohm).

Hardware target

fresnel — Pinebook Pro laptop. See reference_fresnel_kernel_constraints.md for the custom-OC-kernel discipline (don't let pacman -Syu clobber the OC DTB) and project_fresnel.md for fleet placement.

Property Value
SoC Rockchip RK3399 (2× Cortex-A72 + 4× Cortex-A53)
GPU Mali-T860 MP4 (Midgard, panfrost)
Decoder block 1 rkvdec (/dev/video3) — H.264 + HEVC + VP9
Decoder block 2 hantro-vpu-dec (rk3399-vpu-dec, /dev/video5) — MPEG-2 + VP8 (RK3399 hantro does not advertise H.264; corrected 2026-05-07 from empirical V4L2 enumeration — see phase0_evidence/2026-05-07/v4l2_inventory_findings.md)
Encoder block hantro-vpu-enc (/dev/video4) — JPEG only
OS EndeavourOS-ARM (Arch derivative; same pacman + marfrit-packages mechanism as ohm)
Kernel linux-eos-arm 6.19.9-99CONFIG_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_DYNAMIC_FTRACE=y, CONFIG_TRACING=y verified 2026-05-07. No rebuild needed for trace work.

The decode-side surface area is genuinely broader than ohm. ohm has hantro (H.264 + MPEG-2 + VP8) and an rkvdec block whose mainline rkvdec2/vdpu346 driver isn't merged. fresnel has hantro (MPEG-2 + VP8 only — empirical, see correction note in the table above) plus a fully-driven mainline rkvdec covering H.264 + HEVC + VP9. So this campaign exercises codecs (HEVC, VP9) the libva-v4l2-request-fourier fork has never run on real hardware to date, and there is exactly one decoder bind for H.264 (rkvdec) — no two-block routing decision.

GPU side: panfrost on Mali-T860 (Midgard) is a different generation than ohm's Mali-G52 (Bifrost). KWin / Mesa / panfrost stack regressions or wins on T860 are not assumed to track G52 — the kwin-fourier verdict from fourier_attribution doesn't transfer for free.

Scope (LOCKED 2026-05-07 in phase0_findings.md)

In scope:

  • libva-v4l2-request-fourier backend exercised on fresnel V4L2 decode nodes (rkvdec + hantro-vpu-dec).
  • Codecs: everything decode-capable — H.264 + HEVC + VP9 (via rkvdec) + MPEG-2 + VP8 (via hantro-vpu-dec). This is the explicit broadening from libva-multiplanar's H.264-first locked scope.
  • Test consumers: vainfo, mpv --hwdec=vaapi, Firefox via media.ffmpeg.vaapi.enabled, chromium-fourier 149 (regression check).
  • Phase 1 success criterion (matching libva-multiplanar): boolean correctness — "libva accepted + providing access to hardware decoder for each codec." Performance metrics deferred.
  • Phase 0 task 1: recover fresnel from the SDDM greeter crash-loop (per ~/.claude/plans/dynamic-forging-piglet.md). Recovery is bookkept as substrate work inside this campaign, not as a separate prereq.

Out of scope:

  • Front-end libva (API library). Backend only.
  • Other hardware (ohm + ampere/boltzmann are libva-multiplanar's iterations).
  • AV1 (no decoder block on RK3399 supports it).
  • Performance metrics — fresnel CPU/GPU benchmarking is a separate iteration after correctness lands.
  • cros-codecs Rust replacement (per user_stance_rust.md).
  • Bootlin / Collabora upstreaming default-deferred (per feedback_no_upstream.md). Same discipline as libva-multiplanar.
  • KWin / panfrost / Mali-T860 work — orthogonal until proven otherwise; a parallel kwin-fourier-fresnel campaign would be a separate decision.

Process

8(+1) phase loop per feedback_dev_process.md. Phase 0 substrate is in phase0_findings.md. Phase 5 review uses the sonnet-architect subagent pattern (Plan with model: sonnet).

In-session-acquired data discipline per feedback_replicate_baseline_first.md: libva-multiplanar's ohm-side measurements are reference history, not threshold sources for fresnel-fourier cells.

Predecessor work this campaign builds on

  • ../libva-multiplanar/ — five closed iterations on ohm. Read in order:
    • README.md — current state, codec scope, file map.
    • phase8_iteration5_close.md — most recent close. The iter5-end backend is the substrate fresnel-fourier starts from.
    • phase0_findings.md (and phase0_findings_iter[2-5].md) — locked-scope precedent for codec breadth and consumer matrix on ohm; useful frame-of-reference when locking fresnel-side scope.
    • phase8_iteration1_close.md — iter1 surface-export DMA-BUF lifecycle race + multi-resolution cache + 64-pitch alignment bugs. Likely re-surface candidates on RK3399.
  • ../libva-multiplanar/libva-v4l2-request-fourier/ — the fork itself. 12 commits ahead of bootlin tip plus iter1..iter5 work. git log for the actual landing record.
  • ~/.claude/plans/dynamic-forging-piglet.md — fresnel SDDM greeter crash diagnosis + recovery plan. Phase 0 task 1 picks up from here.
  • ~/src/fourier_attribution/ — ohm-only attribution matrix. The chromium-fourier WHEAT-but-fragile verdict and Cell E (vanilla Chromium 149 control) item are ohm-side context, not fresnel data.

External reference (carry-over from libva-multiplanar):

  • Mozilla bug 1833354 / 1965646 (Firefox HW decode on RK35xx via libva-v4l2-request).
  • Bootlin upstream bootlin/libva-v4l2-request — dormant since 2021.
  • Linux kernel drivers/staging/media/rkvdec/ — RK3399 rkvdec H.264/HEVC/VP9 control protocol reference.
  • Linux kernel drivers/media/platform/verisilicon/hantro_* — RK3399-vpu-dec MPEG-2/H.264/VP8 control protocol reference.

Repository layout

~/src/fresnel-fourier/                     <- this campaign (its own git repo)
├── README.md                              <- this file
├── phase0_findings.md                     <- locked research question + Phase 0 work list
├── (worklist.md, phase[2-8]*.md as phases land)
└── (the libva fork is NOT here — see ../libva-multiplanar/libva-v4l2-request-fourier/)

The campaign repo and the fork repo stay separate. fresnel-fourier commits its findings here; code changes to the backend land on the fork's master (or a branch named per the iteration if scope diverges from libva-multiplanar's ohm-side master).

Operator-facing repo URL: git.reauktion.de/marfrit/fresnel-fourier — created empty during scaffolding, no push until first iteration finds something worth publishing.

Non-upstreaming default

Inherited from libva-multiplanar / feedback_no_upstream.md. Patches must be aligned to upstream in syntax and semantics; PR/MR/bug-report only on explicit operator instruction.

Build infrastructure

distcc/cross-build path is the existing fleet: aarch64crosscompiler LXD on data, tesla LXD on hertz, dcc1 on dcw3. See reference_distcc_kernel_builds.md for invocation. Per the locked Phase 0 answer for libva-multiplanar (item 9), no distcc for libva builds — libva is small and links fast, hand-build on fresnel directly. Same default applies here unless a specific reason emerges.

For chromium-fourier 149 / firefox-fourier rebuilds against fresnel-side findings, the boltzmann LXD container path from libva-multiplanar iter3 is reusable.

S
Description
libva-v4l2-request-fourier peer campaign for fresnel (Pinebook Pro / RK3399).
Readme 48 MiB
Languages
Shell 100%