diff --git a/phase0_findings_iter2.md b/phase0_findings_iter2.md index e1e69d6..a42e932 100644 --- a/phase0_findings_iter2.md +++ b/phase0_findings_iter2.md @@ -106,3 +106,38 @@ Per the fresnel-iter25 / `feedback_rkvdec_image_fmt_pre_seed` precedent, the bac ## Phase 0 close Substrate captured: 5 existing HEVC controls in the backend, no H.265 parser, VAAPI doesn't expose RPS contents, kernel struct shapes documented, mechanism partially understood (memcmp dereferences invalid memory; precise cause = open Q3). 5 open questions for Phase 1, with Q1 (architecture for RPS sourcing) being the load-bearing decision. + +--- + +## Upstream-consumer survey (added 2026-05-16 post-Phase-0) + +Per `feedback_upstream_alignment_over_speed`, surveyed real upstream V4L2 stateless HEVC consumers for the `EXT_SPS_*_RPS` pattern. Subagent transcript: `~/.../tasks/aa6f3e6382bc0d721.output`. Findings: + +| Consumer | Status | Pattern | +|----------|--------|---------| +| **GStreamer** | **MERGED for GStreamer 1.28** ([!10820](https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10820)) | Walks its own `gst_h265_parser_*`'s `GstH265SPS.short_term_ref_pic_set[]` array — field names match H.265 spec, one-to-one mapping to the V4L2 struct. **Header strategy: runtime-optional control probe, NO `#ifndef` shim.** File: `subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech265dec.c`, function `gst_v4l2_codec_h265_dec_fill_ext_sps_rps` | +| **FFmpeg (Casanova WIP)** | Not yet on ffmpeg-devel (branch `v4l2-request-ext-sps-rps-n8.0.1` at gitlab.collabora.com) | Walks libavcodec's internal `HEVCSPS->st_rps[]` (different field names than spec — `rps_predict`, `delta_idx`, `abs_delta_rps`, etc., requires translation). LT_RPS commented-out (incomplete). Function: `fill_ext_sps_st_rps` in `libavcodec/v4l2_request_hevc.c` | +| cros-codecs | No support yet (would parse via own `cros_codecs::codec::h265::parser::Sps` when added — same shape as GStreamer) | n/a | +| Casanova kernel-test framework | fluster through GStreamer 1.28 + Collabora FFmpeg WIP — no separate reference consumer | n/a | +| Bootlin `libva-v4l2-request` | Dormant since 2019, no 7.0-UAPI work | n/a | + +**Upstream-aligned pattern is unambiguous**: parse the H.265 SPS NAL ourselves, populate the V4L2 controls from our parser's output. Both active upstream consumers (GStreamer merged, FFmpeg WIP) follow this exactly. VAAPI does not and will not expose the RPS array content, so we must parse. + +**GStreamer's mapping is the cleanest reference** — `GstH265ShortTermRefPicSet` field names mirror the H.265 spec, so the V4L2-control assignment is mechanical. FFmpeg's renaming gymnastics are a useful cross-check but should NOT be the primary template. + +**Header strategy decided**: no `#ifndef` shim. Mirror GStreamer's "optional control" probe path — at backend init, `VIDIOC_QUERYCTRL` the two new CIDs; if both present and the active driver-kind is VDPU381/383 HEVC, set them; if absent, log + skip (graceful fallback for older kernels). Constants + struct shapes need to be available at *compile* time, however, so the build pipeline either requires `linux-api-headers` ≥ 7.0 OR ships a minimal internal header with just the two new CIDs + structs (with a comment pointing to the upstream UAPI source). Picking which of those is a tactical Phase 4 detail. + +## Phase 0 update — Q1 (architecture) and Q2 (UAPI shim) resolved + +- **Q1 (architecture for RPS data sourcing)**: **B — implement H.265 SPS parser in backend**, mirroring GStreamer's `gst_v4l2_codec_h265_dec_fill_ext_sps_rps` pattern with one-to-one spec-compliant field names. Per-RPS-set + LT_RPS arrays. +- **Q2 (UAPI shim vs headers bump)**: **runtime-optional control probe** (not a header `#ifndef` shim). Compile-time access to the new CIDs/structs handled via either a headers package bump OR a minimal internal header — Phase 4 picks tactically. +- **Q3 (mechanism reconstruction depth)**: now lower-priority — once the backend populates valid RPS data per the upstream pattern, the OOPS should be gone whatever its precise cause was. If somehow it isn't, then loopback Phase 0 with whatever new evidence the failure surfaces. +- **Q4 (test clip)**: unchanged — BBB iter1 carries. +- **Q5 (Phase 7 anchor)**: unchanged — ampere-fourier iter1 + HEVC C1-C6 added. + +Sub-question remaining for Phase 1 lock: **what's the H.265 SPS parser source?** Three options, all upstream-aligned: +- **(B1) Vendor GStreamer's parser** — copy `subprojects/gst-plugins-bad/codecparsers/gsth265parser.c` (LGPL, compatible with libva backend license). Keeps backend self-contained; reuses thoroughly tested code; carries forward GStreamer's spec-compliant field naming. Mostly a copy + minor adaptation (drop GLib dependency or replace with libc equivalents). +- **(B2) Adapt GStreamer's parser to the backend's idioms** — same data flow but rewritten to match `h264_slice_header.c` style (C plain, no GLib). More work; fewer LOC. +- **(B3) Implement minimal SPS-RPS-only parser fresh from H.265 spec §7.3.7** — narrowest scope (just the bits needed for the two controls), but does not benefit from GStreamer's edge-case handling. + +(B1) is the most upstream-aligned. (B2) is the same data flow with the project's house style. (B3) is the most minimal but reinvents.