iter1 Phase 4: plan — contract clauses, diff scope, Phase 7 harness
Phase 4 plan for the iter1 MPEG-2 fix, structured per the feedback_dev_process.md Phase 6 contract-before-code worked example (0012-h264-omit-scaling-matrix-frame-based.patch shape): contract clauses with citations first, then code changes mapping 1:1 to clauses. Phase 1 criterion #3 re-locked per Phase 3 → Phase 1 loopback: Original: "mpv --hwdec=vaapi-copy ... engages backend" Adjusted: "ffmpeg -hwaccel vaapi ... engages backend" Phase 3 Baseline A established mpv silently filters MPEG-2 out before libva is loaded; the original wording was unfalsifiable. ffmpeg-direct exercises the path. mpv-driven testing → separate follow-up task. Other 4 criteria unchanged (vainfo regression, vaCreateConfig SUCCESS, DMA-BUF GL pixel verify HW=SW at +02s, T4 H.264 regression). Six contract clauses cited from authoritative sources: Clause 1 — Three split controls in one batched VIDIOC_S_EXT_CTRLS Authority: linux/v4l2-controls.h:1988-2105 Reference impl: FFmpeg libavcodec/v4l2_request_mpeg2.c:130-155 Empirical anchor: Phase 3 Baseline C verbatim payload Clause 2 — v4l2_ctrl_mpeg2_sequence layout (12 bytes) Authority: linux/v4l2-controls.h:2009-2017 Field-by-field VAAPI source mapping table Note: progressive_frame is used as proxy for progressive_sequence (VAAPI doesn't expose the latter; same bit for BBB). Clause 3 — v4l2_ctrl_mpeg2_picture layout (32 bytes) Authority: linux/v4l2-controls.h:2056-2065 reserved[5] MUST be zeroed (kernel doc 2052) 8 picture flags decoded; field-by-field VAAPI mapping Clause 4 — v4l2_ctrl_mpeg2_quantisation layout (256 bytes) Authority: linux/v4l2-controls.h:2089-2096 Matrices in zigzag scanning order; no permutation in libva backend (kernel hantro_mpeg2_dec_copy_qtable handles zigzag-to-raster) Decision: when iqmatrix_set is false, populate from MPEG-2 spec defaults (ISO/IEC 13818-2 Table 7-3) to avoid kernel rejecting a batch missing the QUANTISATION control. Clause 5 — Per-frame submission via v4l2_set_controls Authority: existing src/h264.c:986 pattern surface_object->request_fd binds controls to per-surface request Clause 6 — config.c MPEG-2 case must break; Authority: C semantics; H.264 case shape at config.c:62-63 Empirical anchor: Phase 3 Baseline B confirmed scratch-fix shape. Diff scope: src/config.c — 3 lines added (break for MPEG-2 cases) + drop stale #include <mpeg2-ctrls.h> src/mpeg2.c — full rewrite of mpeg2_set_controls against new split API; ~120 lines replaced; switches from 2× v4l2_set_control(single) to 1× batched v4l2_set_controls(3-control array) include/mpeg2-ctrls.h — DELETE (staging-era, masks kernel UAPI) src/picture.c, src/context.c, meson.build — no changes (verified Phase 2 + Phase 3) Phase 6 implementation order (3 logical commits): Commit A: config.c break — substrate fix in isolation Commit B: mpeg2.c rewrite + drop mpeg2-ctrls.h includes Commit C: delete include/mpeg2-ctrls.h Phase 7 verification harness (full Bash incantations included in plan body): Criterion 1: vainfo MPEG-2 enumeration regression check Criterion 2: vaCreateConfig SUCCESS via libva trace Criterion 3: ffmpeg -hwaccel vaapi exit 0, no Failed-to-create Criterion 4: mpv --hwdec=vaapi --vo=image at +02s seek; HW=SW byte-identical hashes for 2 distinct frames (fallback to ffmpeg hwdownload if mpv-vaapi also filters MPEG-2; criterion holds, harness adapts) Criterion 5: T4 H.264 hashes still f623d5f7... and 7d7bc6f2... Bonus: byte-compare post-fix S_EXT_CTRLS payload vs Baseline C Pre-identified Phase 7 → Phase 4 loopback triggers: 1. S_EXT_CTRLS EINVAL post-fix → check pic.reserved[5] memset, struct sizes, flag value collisions 2. Pixel hash mismatch → check f_code packing, field/frame interpretation, ref timestamps, IQ matrix order 3. mpv-vaapi filters MPEG-2 out (same as -copy) → fall-forward to ffmpeg hwdownload pixel verify (criterion holds, harness adapts; do not redefine criterion) 4. H.264 regression → re-locate the offending change in Bug 1 5. Header deletion breaks unaudited consumer → git grep audit Out of scope (LOCKED): HEVC/VP9/VP8 (later iterations); vaDerive Image cache-stale fix; chromium-fourier 149 install; perf metrics; long-duration stress; other MPEG-2 containers; mpv-hwdec follow-up; context.c H.264 device-init EINVAL (auxiliary, intentional); profile/chroma/progressive_sequence refinement; upstream engagement. Phase 5 entry: artifacts handover (no summary, raw bundle) per feedback_dev_process.md — phase0_findings_iter1.md, phase2_iter1_situation.md, phase3_iter1_baseline.md, phase4_iter1_plan.md, plus phase0_evidence/2026-05-07/iter1_phase3/. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,555 @@
|
||||
# Iteration 1 — Phase 4 (plan)
|
||||
|
||||
Implementation plan for iter1 MPEG-2 boolean correctness on fresnel. Inputs:
|
||||
|
||||
- [`phase0_findings_iter1.md`](phase0_findings_iter1.md) — Phase 1 lock (5 boolean criteria; #3 adjusted by Phase 3 loopback below).
|
||||
- [`phase2_iter1_situation.md`](phase2_iter1_situation.md) — three bugs identified, all in libva backend.
|
||||
- [`phase3_iter1_baseline.md`](phase3_iter1_baseline.md) — bugs confirmed empirically; Baseline C verbatim contract anchor; one criterion adjustment.
|
||||
|
||||
Per `feedback_dev_process.md` Phase 6 contract-before-code: this plan opens with the contract clauses (kernel doc + driver + sibling implementation citations), then specifies code changes that map 1:1 to those clauses. No reverse-engineering from observed Baseline B behavior, no mimicking of FFmpeg without spec-rooting.
|
||||
|
||||
## Phase 1 criterion #3 — re-lock with adjusted wording
|
||||
|
||||
Per Phase 3 → Phase 1 loopback per `feedback_dev_process.md`:
|
||||
|
||||
**Original (Phase 1 lock 2026-05-07)**:
|
||||
|
||||
> 3. End-to-end decode engages the backend. `mpv --hwdec=vaapi-copy --frames=2 --vo=null --no-audio … bbb_720p10s_mpeg2.ts` engages our backend, exits 0 with no `Failed to create decode configuration` lines.
|
||||
|
||||
**Adjusted (Phase 4 lock 2026-05-08)**:
|
||||
|
||||
> 3. End-to-end decode engages the backend. `ffmpeg -hwaccel vaapi -i bbb_720p10s_mpeg2.ts -frames:v 2 -f null -` (with `LIBVA_DRIVER_NAME=v4l2_request`, `LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video5`, `LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media2`) shows the `[VAAPI] libva: Trying to open /usr/lib/dri/v4l2_request_drv_video.so` chain in stderr, the libva trace shows `vaCreateConfig ret = VA_STATUS_SUCCESS`, no `Failed to create decode configuration` lines, no `EINVAL` from `VIDIOC_S_EXT_CTRLS`, and ffmpeg exits 0 cleanly.
|
||||
|
||||
Reason: Phase 3 Baseline A established that mpv-vaapi-copy never engages libva for MPEG-2 (mpv's hwdec policy filters MPEG-2 out before libva is loaded). The original criterion #3 was unfalsifiable through the original incantation. ffmpeg-direct does engage the path and reaches the failure mode that iter1 fixes — so it's the right anchor for Phase 7 verification.
|
||||
|
||||
mpv-driven MPEG-2 testing becomes a separate, smaller follow-up task (mpv `--hwdec-codecs` filter override or upstream mpv investigation), out of iter1 scope.
|
||||
|
||||
The other four criteria hold unchanged:
|
||||
|
||||
1. `vainfo` enumerates VAProfileMPEG2Simple + VAProfileMPEG2Main (regression check).
|
||||
2. `vaCreateConfig(VAProfileMPEG2Main, VLD)` returns `VA_STATUS_SUCCESS`.
|
||||
4. DMA-BUF GL import HW frames byte-identical to SW reference for 2 distinct frames at `+02s` seek.
|
||||
5. T4 H.264 reference hashes (`f623d5f7…`, `7d7bc6f2…`) at `+30s` continue to match.
|
||||
|
||||
## Contract clauses (cite-before-code)
|
||||
|
||||
### Clause 1 — Three split controls submitted in one batched VIDIOC_S_EXT_CTRLS
|
||||
|
||||
**Authority**: Linux mainline `include/uapi/linux/v4l2-controls.h:1988-2105` defines three separate stateless controls for MPEG-2:
|
||||
|
||||
```c
|
||||
#define V4L2_CID_STATELESS_MPEG2_SEQUENCE (V4L2_CID_CODEC_STATELESS_BASE+220) /* 0xa409dc */
|
||||
#define V4L2_CID_STATELESS_MPEG2_PICTURE (V4L2_CID_CODEC_STATELESS_BASE+221) /* 0xa409dd */
|
||||
#define V4L2_CID_STATELESS_MPEG2_QUANTISATION (V4L2_CID_CODEC_STATELESS_BASE+222) /* 0xa409de */
|
||||
```
|
||||
|
||||
**Reference implementation**: FFmpeg `libavcodec/v4l2_request_mpeg2.c:130-155` builds a 3-element `v4l2_ext_control` array and submits via a single `ff_v4l2_request_decode_frame()` call (which calls `VIDIOC_S_EXT_CTRLS` once with the whole batch).
|
||||
|
||||
**Empirical anchor**: Phase 3 Baseline C strace verbatim (from `phase3_iter1_baseline.md`) shows `ffmpeg -hwaccel v4l2request` submits exactly `count=3, ctrl_class=0xf010000` per frame.
|
||||
|
||||
**Implication for iter1**: `mpeg2_set_controls` builds a 3-entry `struct v4l2_ext_control` array and submits via the existing `v4l2_set_controls(driver_data->video_fd, surface_object->request_fd, controls, 3)` API (same call shape as `src/h264.c:986`). One VIDIOC_S_EXT_CTRLS per frame, not three.
|
||||
|
||||
### Clause 2 — `v4l2_ctrl_mpeg2_sequence` field layout (12 bytes)
|
||||
|
||||
**Authority**: `linux/v4l2-controls.h:2009-2017`:
|
||||
|
||||
```c
|
||||
struct v4l2_ctrl_mpeg2_sequence {
|
||||
__u16 horizontal_size; /* offset 0 */
|
||||
__u16 vertical_size; /* offset 2 */
|
||||
__u32 vbv_buffer_size; /* offset 4 */
|
||||
__u16 profile_and_level_indication;/* offset 8 */
|
||||
__u8 chroma_format; /* offset 10 */
|
||||
__u8 flags; /* offset 11 — V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE only */
|
||||
};
|
||||
```
|
||||
|
||||
Total 12 bytes. The `flags` field has exactly one defined bit:
|
||||
|
||||
```c
|
||||
#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE 0x01 /* v4l2-controls.h:1985 */
|
||||
```
|
||||
|
||||
**VAAPI source mapping** (no permutation, direct):
|
||||
|
||||
| Sequence field | Source: `VAPictureParameterBufferMPEG2 *picture` |
|
||||
|---|---|
|
||||
| `horizontal_size` | `picture->horizontal_size` |
|
||||
| `vertical_size` | `picture->vertical_size` |
|
||||
| `vbv_buffer_size` | `surface_object->source_size` (the OUTPUT buffer's size — matches FFmpeg's `controls->pic.output->size` per `v4l2_request_mpeg2.c:51`) |
|
||||
| `profile_and_level_indication` | 0 (current `mpeg2.c:70` already hardcodes; VAAPI doesn't expose profile/level on the picture buffer) |
|
||||
| `chroma_format` | 1 (4:2:0; current `mpeg2.c:72` hardcodes; iter1 keeps this since fixture is 4:2:0 and campaign codec scope locked at 8-bit 4:2:0) |
|
||||
| `flags` | `picture->picture_coding_extension.bits.progressive_frame ? V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE : 0` |
|
||||
|
||||
**Note on `progressive_frame` vs `progressive_sequence`**: VAAPI's `VAPictureParameterBufferMPEG2` does not expose the bitstream's `progressive_sequence` flag from the sequence-extension header — only `progressive_frame` from the picture-coding extension. They're the same bit for typical MPEG-2 streams (BBB is progressive throughout). iter1 uses `progressive_frame` as the proxy. This is documented in the patch as a known approximation (good enough for binding-cell correctness; refinement is post-iter1).
|
||||
|
||||
### Clause 3 — `v4l2_ctrl_mpeg2_picture` field layout (32 bytes)
|
||||
|
||||
**Authority**: `linux/v4l2-controls.h:2056-2065`:
|
||||
|
||||
```c
|
||||
struct v4l2_ctrl_mpeg2_picture {
|
||||
__u64 backward_ref_ts; /* offset 0 */
|
||||
__u64 forward_ref_ts; /* offset 8 */
|
||||
__u32 flags; /* offset 16 */
|
||||
__u8 f_code[2][2]; /* offset 20 — packed [4 bytes] */
|
||||
__u8 picture_coding_type; /* offset 24 */
|
||||
__u8 picture_structure; /* offset 25 */
|
||||
__u8 intra_dc_precision; /* offset 26 */
|
||||
__u8 reserved[5]; /* offset 27 — must be zero per kernel doc */
|
||||
};
|
||||
```
|
||||
|
||||
Total 32 bytes. **Reserved bytes must be zeroed** (`v4l2-controls.h:2052: "@reserved: padding field. Should be zeroed by applications."`). Fix shape: `memset(&picture, 0, sizeof picture)` before populating; populating only listed fields leaves reserved zero.
|
||||
|
||||
`flags` defined bits (`v4l2-controls.h:2026-2033`):
|
||||
|
||||
```c
|
||||
#define V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST 0x0001
|
||||
#define V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT 0x0002
|
||||
#define V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV 0x0004
|
||||
#define V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE 0x0008
|
||||
#define V4L2_MPEG2_PIC_FLAG_INTRA_VLC 0x0010
|
||||
#define V4L2_MPEG2_PIC_FLAG_ALT_SCAN 0x0020
|
||||
#define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST 0x0040
|
||||
#define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE 0x0080
|
||||
```
|
||||
|
||||
`picture_coding_type` enum (`v4l2-controls.h:1990-1993`):
|
||||
|
||||
```c
|
||||
#define V4L2_MPEG2_PIC_CODING_TYPE_I 1
|
||||
#define V4L2_MPEG2_PIC_CODING_TYPE_P 2
|
||||
#define V4L2_MPEG2_PIC_CODING_TYPE_B 3
|
||||
#define V4L2_MPEG2_PIC_CODING_TYPE_D 4
|
||||
```
|
||||
|
||||
`picture_structure` enum (`v4l2-controls.h:1995-1997`):
|
||||
|
||||
```c
|
||||
#define V4L2_MPEG2_PIC_TOP_FIELD 0x1
|
||||
#define V4L2_MPEG2_PIC_BOTTOM_FIELD 0x2
|
||||
#define V4L2_MPEG2_PIC_FRAME 0x3
|
||||
```
|
||||
|
||||
**VAAPI source mapping**:
|
||||
|
||||
| Picture field | Source: `VAPictureParameterBufferMPEG2 *picture`, etc. | Notes |
|
||||
|---|---|---|
|
||||
| `backward_ref_ts` | `v4l2_timeval_to_ns(&backward_reference_surface->timestamp)` if `picture->backward_reference_picture != VA_INVALID_ID`, else `0` | Existing `mpeg2.c:112-118` logic preserved; just routes to picture struct instead of slice_params |
|
||||
| `forward_ref_ts` | `v4l2_timeval_to_ns(&forward_reference_surface->timestamp)` if `picture->forward_reference_picture != VA_INVALID_ID`, else `0` | Same |
|
||||
| `flags` (bitwise OR of:) | | |
|
||||
| `_TOP_FIELD_FIRST` | `picture->picture_coding_extension.bits.top_field_first` |
|
||||
| `_FRAME_PRED_DCT` | `picture->picture_coding_extension.bits.frame_pred_frame_dct` |
|
||||
| `_CONCEALMENT_MV` | `picture->picture_coding_extension.bits.concealment_motion_vectors` |
|
||||
| `_Q_SCALE_TYPE` | `picture->picture_coding_extension.bits.q_scale_type` |
|
||||
| `_INTRA_VLC` | `picture->picture_coding_extension.bits.intra_vlc_format` |
|
||||
| `_ALT_SCAN` | `picture->picture_coding_extension.bits.alternate_scan` |
|
||||
| `_REPEAT_FIRST` | `picture->picture_coding_extension.bits.repeat_first_field` |
|
||||
| `_PROGRESSIVE` | `picture->picture_coding_extension.bits.progressive_frame` |
|
||||
| `f_code[0][0]` | `(picture->f_code >> 12) & 0x0f` | Existing `mpeg2.c:75` logic preserved |
|
||||
| `f_code[0][1]` | `(picture->f_code >> 8) & 0x0f` |
|
||||
| `f_code[1][0]` | `(picture->f_code >> 4) & 0x0f` |
|
||||
| `f_code[1][1]` | `(picture->f_code >> 0) & 0x0f` |
|
||||
| `picture_coding_type` | `picture->picture_coding_type` (VAAPI uses I=1, P=2, B=3, D=4 — same as new V4L2 macros) |
|
||||
| `picture_structure` | `picture->picture_coding_extension.bits.picture_structure` (VAAPI uses TOP=1, BOTTOM=2, FRAME=3 — same as new V4L2 macros) |
|
||||
| `intra_dc_precision` | `picture->picture_coding_extension.bits.intra_dc_precision` |
|
||||
| `reserved[5]` | zero (via `memset`) |
|
||||
|
||||
**No semantic change in source extraction** — same VAAPI field reads as the current `mpeg2.c:74-100`. Only the destination struct layout changes (field reorder + booleans collapsed into `flags`).
|
||||
|
||||
### Clause 4 — `v4l2_ctrl_mpeg2_quantisation` field layout (256 bytes)
|
||||
|
||||
**Authority**: `linux/v4l2-controls.h:2089-2096`:
|
||||
|
||||
```c
|
||||
struct v4l2_ctrl_mpeg2_quantisation {
|
||||
__u8 intra_quantiser_matrix[64]; /* offset 0 */
|
||||
__u8 non_intra_quantiser_matrix[64]; /* offset 64 */
|
||||
__u8 chroma_intra_quantiser_matrix[64]; /* offset 128 */
|
||||
__u8 chroma_non_intra_quantiser_matrix[64]; /* offset 192 */
|
||||
};
|
||||
```
|
||||
|
||||
Total 256 bytes. Matrices in **zigzag scanning order** per kernel doc (`v4l2-controls.h:2076`: "in zigzag scanning order").
|
||||
|
||||
**Quantisation submission semantics** — what to do when VAAPI doesn't supply an IQ matrix:
|
||||
|
||||
The current `mpeg2.c:126-151` only sends `V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION` when `iqmatrix_set` is true (the consumer sent a `VAIQMatrixBufferType` for this surface). With the **new** API the question is: does the kernel allow omission of `STATELESS_MPEG2_QUANTISATION` from the batch when the bitstream uses default matrices?
|
||||
|
||||
Reading kernel `drivers/media/platform/verisilicon/hantro_mpeg2.c:hantro_mpeg2_dec_copy_qtable` (line 12-26 in the mainline reference): the function takes `const struct v4l2_ctrl_mpeg2_quantisation *ctrl` and applies zigzag-to-raster permutation while copying the four matrices into the hardware qtable. The driver's `hantro_g1_mpeg2_dec.c::config_decoding_engine` (the engine entry that uses qtable) calls this unconditionally. **The kernel always reads all four matrices**; it doesn't have a "no quantisation control set" code path that synthesizes defaults.
|
||||
|
||||
So either:
|
||||
- (a) the libva backend always sends `QUANTISATION` in the batch, populating from `iqmatrix` if `iqmatrix_set`, or filling with the MPEG-2 default matrices otherwise; or
|
||||
- (b) the kernel rejects (EINVAL) the batch if `QUANTISATION` is absent.
|
||||
|
||||
FFmpeg's reference `v4l2_request_mpeg2.c:110-116` always populates and submits `QUANTISATION` from the codec's internal matrix state (which has the bitstream-provided or spec-default matrices, depending on whether the bitstream supplied custom ones). So FFmpeg takes path (a).
|
||||
|
||||
**Phase 4 decision**: iter1 takes path (a). When `iqmatrix_set` is false, populate the 4 matrices with the canonical MPEG-2 default values from the spec:
|
||||
|
||||
- `intra_quantiser_matrix` = `{8, 16, 16, 19, 16, 19, 22, 22, 22, 22, 22, 22, 26, 24, 26, 27, 27, 27, 26, 26, 26, 26, 27, 27, 27, 29, 29, 29, 34, 34, 34, 29, 29, 29, 34, 37, 38, 37, 35, 35, 38, 41, 41, 38, 38, 41, 41, 45, 45, 45, 49, 49, 56, 56, 64, 69, 83, ...}` (ISO/IEC 13818-2 Table 7-3 default intra matrix in zigzag scan order — same as Baseline C's verbatim payload first row).
|
||||
- `non_intra_quantiser_matrix` = all 16's (ISO/IEC 13818-2 default non-intra matrix, flat 16).
|
||||
- `chroma_intra_quantiser_matrix` = same as `intra_quantiser_matrix` (spec default for 4:2:0).
|
||||
- `chroma_non_intra_quantiser_matrix` = all 16's (spec default for 4:2:0).
|
||||
|
||||
VAAPI's `VAIQMatrixBufferMPEG2` matrices are also in zigzag scanning order (per VAAPI spec, `va_dec_mpeg2.h`). Direct memcpy works; no permutation in the libva backend.
|
||||
|
||||
**Empirical anchor**: Baseline C's QUANTISATION first row (`8, 16, 16, 19, 16, 19, 22, 22, ...`) matches the spec default, indicating the BBB-720p10s_mpeg2.ts fixture uses default matrices (no custom matrices in the sequence-extension). For iter1 verification: when `iqmatrix_set` is false on this fixture, the synthesized defaults must produce a payload byte-identical to Baseline C's QUANTISATION 256 bytes.
|
||||
|
||||
### Clause 5 — Per-frame submission shape
|
||||
|
||||
**Authority**: existing `src/h264.c:986` shows the established pattern in this fork:
|
||||
|
||||
```c
|
||||
rc = v4l2_set_controls(driver_data->video_fd, surface->request_fd,
|
||||
controls, num_controls);
|
||||
```
|
||||
|
||||
`v4l2_set_controls` (defined `src/v4l2.c:475-489`) wraps `VIDIOC_S_EXT_CTRLS` with `request_fd` set to the per-surface request_fd (binds the controls to the request, not to the device-wide state).
|
||||
|
||||
**Implication for iter1**: `mpeg2_set_controls` builds the 3-entry array, calls `v4l2_set_controls` once. Replaces the current two-call pattern (`v4l2_set_control(SLICE_PARAMS)` + conditional `v4l2_set_control(QUANTIZATION)`).
|
||||
|
||||
### Clause 6 — `RequestCreateConfig` MPEG-2 case must `break;`, not fall through
|
||||
|
||||
**Authority**: C language semantics. `src/config.c:55-69` switch falls through from `case VAProfileMPEG2Simple/Main:` (lines 64-65) to `default:` (line 67) which returns the error. H.264 cases at `src/config.c:57-62` have an explicit `break;` at line 63. The H.264 `// FIXME` comment at line 62 indicates profile-specific validation logic was anticipated but never landed; treating MPEG-2 the same way (no validation, just accept the profile) is the smallest patch and matches H.264's current behavior.
|
||||
|
||||
**Empirical anchor**: Phase 3 Baseline B verified the patch shape in scratch — adding `break;` for MPEG-2 cases lets `vaCreateConfig` return `VA_STATUS_SUCCESS` and the V4L2 setup proceeds normally up to the next failure point (`VIDIOC_S_EXT_CTRLS` with old CIDs).
|
||||
|
||||
## Diff scope
|
||||
|
||||
### File 1: `src/config.c` — add `break;` for MPEG-2 cases
|
||||
|
||||
3 lines added, no other changes:
|
||||
|
||||
```diff
|
||||
@@ -63,6 +63,9 @@ VAStatus RequestCreateConfig(VADriverContextP context, VAProfile profile,
|
||||
break;
|
||||
case VAProfileMPEG2Simple:
|
||||
case VAProfileMPEG2Main:
|
||||
+ // MPEG-2 enabled iter1; same shape as H.264 — no profile-
|
||||
+ // specific config validation in the libva backend (validation
|
||||
+ // happens at vaCreateContext / control submission time).
|
||||
+ break;
|
||||
case VAProfileHEVCMain:
|
||||
default:
|
||||
return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
```
|
||||
|
||||
Also drop the now-stale `#include <mpeg2-ctrls.h>` line (line 37) — no `V4L2_CID_MPEG_VIDEO_MPEG2_*` symbols are referenced in `config.c` after this edit; the kernel UAPI for MPEG-2 control IDs comes from `<linux/v4l2-controls.h>` (pulled transitively via `<linux/videodev2.h>`).
|
||||
|
||||
### File 2: `src/mpeg2.c` — full rewrite of `mpeg2_set_controls`
|
||||
|
||||
Per Clause 1–5. New shape (commented to map 1:1 to clause numbers):
|
||||
|
||||
```c
|
||||
int mpeg2_set_controls(struct request_data *driver_data,
|
||||
struct object_context *context_object,
|
||||
struct object_surface *surface_object)
|
||||
{
|
||||
VAPictureParameterBufferMPEG2 *picture =
|
||||
&surface_object->params.mpeg2.picture;
|
||||
VAIQMatrixBufferMPEG2 *iqmatrix =
|
||||
&surface_object->params.mpeg2.iqmatrix;
|
||||
bool iqmatrix_set = surface_object->params.mpeg2.iqmatrix_set;
|
||||
|
||||
/* Clause 2: v4l2_ctrl_mpeg2_sequence (12 bytes) */
|
||||
struct v4l2_ctrl_mpeg2_sequence sequence;
|
||||
/* Clause 3: v4l2_ctrl_mpeg2_picture (32 bytes; reserved[5] must be zero) */
|
||||
struct v4l2_ctrl_mpeg2_picture pic;
|
||||
/* Clause 4: v4l2_ctrl_mpeg2_quantisation (256 bytes) */
|
||||
struct v4l2_ctrl_mpeg2_quantisation quant;
|
||||
|
||||
struct object_surface *forward_reference_surface;
|
||||
struct object_surface *backward_reference_surface;
|
||||
int rc;
|
||||
|
||||
memset(&sequence, 0, sizeof sequence);
|
||||
memset(&pic, 0, sizeof pic); /* zeros pic.reserved[5] per Clause 3 */
|
||||
memset(&quant, 0, sizeof quant);
|
||||
|
||||
/* --- Clause 2: SEQUENCE --- */
|
||||
sequence.horizontal_size = picture->horizontal_size;
|
||||
sequence.vertical_size = picture->vertical_size;
|
||||
sequence.vbv_buffer_size = surface_object->source_size;
|
||||
sequence.profile_and_level_indication = 0; /* not exposed by VAAPI picture buffer */
|
||||
sequence.chroma_format = 1; /* 4:2:0 — campaign codec scope */
|
||||
if (picture->picture_coding_extension.bits.progressive_frame)
|
||||
sequence.flags |= V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE;
|
||||
|
||||
/* --- Clause 3: PICTURE --- */
|
||||
forward_reference_surface =
|
||||
SURFACE(driver_data, picture->forward_reference_picture);
|
||||
if (forward_reference_surface != NULL)
|
||||
pic.forward_ref_ts =
|
||||
v4l2_timeval_to_ns(&forward_reference_surface->timestamp);
|
||||
|
||||
backward_reference_surface =
|
||||
SURFACE(driver_data, picture->backward_reference_picture);
|
||||
if (backward_reference_surface != NULL)
|
||||
pic.backward_ref_ts =
|
||||
v4l2_timeval_to_ns(&backward_reference_surface->timestamp);
|
||||
|
||||
if (picture->picture_coding_extension.bits.top_field_first)
|
||||
pic.flags |= V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST;
|
||||
if (picture->picture_coding_extension.bits.frame_pred_frame_dct)
|
||||
pic.flags |= V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT;
|
||||
if (picture->picture_coding_extension.bits.concealment_motion_vectors)
|
||||
pic.flags |= V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV;
|
||||
if (picture->picture_coding_extension.bits.q_scale_type)
|
||||
pic.flags |= V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE;
|
||||
if (picture->picture_coding_extension.bits.intra_vlc_format)
|
||||
pic.flags |= V4L2_MPEG2_PIC_FLAG_INTRA_VLC;
|
||||
if (picture->picture_coding_extension.bits.alternate_scan)
|
||||
pic.flags |= V4L2_MPEG2_PIC_FLAG_ALT_SCAN;
|
||||
if (picture->picture_coding_extension.bits.repeat_first_field)
|
||||
pic.flags |= V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST;
|
||||
if (picture->picture_coding_extension.bits.progressive_frame)
|
||||
pic.flags |= V4L2_MPEG2_PIC_FLAG_PROGRESSIVE;
|
||||
|
||||
pic.f_code[0][0] = (picture->f_code >> 12) & 0x0f;
|
||||
pic.f_code[0][1] = (picture->f_code >> 8) & 0x0f;
|
||||
pic.f_code[1][0] = (picture->f_code >> 4) & 0x0f;
|
||||
pic.f_code[1][1] = (picture->f_code >> 0) & 0x0f;
|
||||
pic.picture_coding_type = picture->picture_coding_type;
|
||||
pic.picture_structure = picture->picture_coding_extension.bits.picture_structure;
|
||||
pic.intra_dc_precision = picture->picture_coding_extension.bits.intra_dc_precision;
|
||||
/* pic.reserved[5] zero via memset */
|
||||
|
||||
/* --- Clause 4: QUANTISATION --- */
|
||||
if (iqmatrix_set) {
|
||||
memcpy(quant.intra_quantiser_matrix,
|
||||
iqmatrix->intra_quantiser_matrix, 64);
|
||||
memcpy(quant.non_intra_quantiser_matrix,
|
||||
iqmatrix->non_intra_quantiser_matrix, 64);
|
||||
memcpy(quant.chroma_intra_quantiser_matrix,
|
||||
iqmatrix->chroma_intra_quantiser_matrix, 64);
|
||||
memcpy(quant.chroma_non_intra_quantiser_matrix,
|
||||
iqmatrix->chroma_non_intra_quantiser_matrix, 64);
|
||||
} else {
|
||||
/* MPEG-2 spec defaults: ISO/IEC 13818-2 Table 7-3 default
|
||||
* intra; flat 16 for non-intra. Matrices are in zigzag
|
||||
* scanning order per kernel doc (v4l2-controls.h:2076). */
|
||||
static const __u8 default_intra[64] = {
|
||||
8, 16, 16, 19, 16, 19, 22, 22, 22, 22, 22, 22,
|
||||
26, 24, 26, 27, 27, 27, 26, 26, 26, 26, 27, 27,
|
||||
27, 29, 29, 29, 34, 34, 34, 29, 29, 29, 34, 37,
|
||||
38, 37, 35, 35, 38, 41, 41, 38, 38, 41, 41, 45,
|
||||
45, 45, 49, 49, 56, 56, 64, 69, 83 /* zigzag, ... */
|
||||
};
|
||||
/* non_intra/chroma_non_intra: all 16's (memset to 16) */
|
||||
memcpy(quant.intra_quantiser_matrix, default_intra, 64);
|
||||
memcpy(quant.chroma_intra_quantiser_matrix, default_intra, 64);
|
||||
memset(quant.non_intra_quantiser_matrix, 16, 64);
|
||||
memset(quant.chroma_non_intra_quantiser_matrix, 16, 64);
|
||||
}
|
||||
|
||||
/* --- Clause 1+5: batched submission --- */
|
||||
struct v4l2_ext_control ctrls[3] = {
|
||||
{ .id = V4L2_CID_STATELESS_MPEG2_SEQUENCE,
|
||||
.ptr = &sequence, .size = sizeof sequence },
|
||||
{ .id = V4L2_CID_STATELESS_MPEG2_PICTURE,
|
||||
.ptr = &pic, .size = sizeof pic },
|
||||
{ .id = V4L2_CID_STATELESS_MPEG2_QUANTISATION,
|
||||
.ptr = &quant, .size = sizeof quant },
|
||||
};
|
||||
|
||||
rc = v4l2_set_controls(driver_data->video_fd,
|
||||
surface_object->request_fd,
|
||||
ctrls, 3);
|
||||
if (rc < 0)
|
||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Drop `#include <mpeg2-ctrls.h>` from `mpeg2.c:38`. Add `#include <linux/v4l2-controls.h>` if not transitively included via `<linux/videodev2.h>` — verify at compile time.
|
||||
|
||||
`default_intra[64]` table needs the full 64 entries spelled out — abbreviated above with `...`; the actual Phase 6 patch will list all 64 verbatim from ISO/IEC 13818-2 Table 7-3. The first 57 values shown above are correct; remaining 7 from the spec to be transcribed verbatim during Phase 6.
|
||||
|
||||
### File 3: `include/mpeg2-ctrls.h` — delete
|
||||
|
||||
The file's preamble explicitly warns:
|
||||
|
||||
> It turns out that these structs are not stable yet and will undergo more changes. So keep them private until they are stable and ready to become part of the official public API.
|
||||
|
||||
The structs DID stabilize and DID become public — at different CIDs and with different layouts. The local header now actively masks the kernel's modern definitions.
|
||||
|
||||
Delete the file entirely. Audit `git grep "mpeg2-ctrls.h"` for any remaining includes (Phase 2 found two: `src/config.c:37` and `src/mpeg2.c:38`, both removed in File 1 + File 2 above; verify no other references exist).
|
||||
|
||||
### File 4: `src/picture.c` — no changes
|
||||
|
||||
Phase 2 verified: `codec_store_buffer` handles `VAPictureParameterBufferType` and `VAIQMatrixBufferType` for MPEG-2 correctly (lines 87-92, 140-146). `codec_set_controls` dispatches to `mpeg2_set_controls` (lines 186-191). The unconditional `params.h264.matrix_set = false` reset at line 287 is benign for MPEG-2 (union aliasing puts it in mpeg2-struct space, RenderPicture overwrites that byte before mpeg2_set_controls reads anything).
|
||||
|
||||
### File 5: `src/context.c` — no changes
|
||||
|
||||
Phase 2 + Phase 3 verified: the unconditional H.264 device-init at lines 142-155 is intentional best-effort — `(void)v4l2_set_controls(...)` discards the return value. The EINVAL on hantro is silently swallowed, doesn't propagate. Auxiliary noise in the trace, not blocking MPEG-2.
|
||||
|
||||
### Files 6+: meson, headers, includes — verify only
|
||||
|
||||
- `meson.build`, `src/meson.build` — no changes. `mpeg2.c` is already in the sources list; no new files.
|
||||
- `<linux/v4l2-controls.h>` symbol checks — verify that `V4L2_CID_STATELESS_MPEG2_{SEQUENCE,PICTURE,QUANTISATION}`, `struct v4l2_ctrl_mpeg2_{sequence,picture,quantisation}`, and the flag macros (`V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE`, `V4L2_MPEG2_PIC_FLAG_*`, `V4L2_MPEG2_PIC_CODING_TYPE_*`, `V4L2_MPEG2_PIC_*_FIELD`/`FRAME`) are all available via `<linux/videodev2.h>` on the build host. Phase 0 build already showed `linux-api-headers` is present and the H.264 + HEVC + MPEG-2 stateless symbols are all defined; this is a sanity-check, not a likely failure.
|
||||
|
||||
## Implementation order (Phase 6)
|
||||
|
||||
Phase 6 lands in three logical commits, each independently testable:
|
||||
|
||||
1. **Commit A — config.c break**: 1-file diff, 3 lines added. Verifies the substrate fix in isolation. Phase 7 partial verification: criteria #1, #2 should pass (vainfo enumeration unchanged, vaCreateConfig succeeds). Criterion #3-#5 still fail/regress until subsequent commits land.
|
||||
|
||||
2. **Commit B — mpeg2.c rewrite + drop mpeg2-ctrls.h include from config.c and mpeg2.c**: the bulk of the work. Verifies the new control submission. Phase 7 partial verification: criteria #1, #2, #3 should pass (vaCreateConfig + S_EXT_CTRLS both succeed); criterion #4 (DMA-BUF GL pixel verify) should pass for the bbb fixture; criterion #5 (H.264 regression) holds.
|
||||
|
||||
3. **Commit C — delete `include/mpeg2-ctrls.h`**: pure cleanup. No behavior change (after Commit B, no remaining symbols are referenced). Phase 7 verification re-run, all 5 criteria still green.
|
||||
|
||||
If Commit A or B causes Phase 7 regression that doesn't loop back cleanly to Phase 4, treat the regression as a finding (don't paper over it).
|
||||
|
||||
## Phase 7 verification harness
|
||||
|
||||
Each verification uses fresnel directly. All 5 criteria run in one pass; raw output captured to `phase0_evidence/2026-05-08/iter1_phase7/`.
|
||||
|
||||
```bash
|
||||
# Re-build + install
|
||||
ssh fresnel '
|
||||
cd ~/src/libva-v4l2-request-fourier
|
||||
git pull --ff-only
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
'
|
||||
|
||||
# Criterion 1: vainfo regression (must list MPEG-2 Simple + Main on hantro)
|
||||
ssh fresnel '
|
||||
LIBVA_DRIVER_NAME=v4l2_request \
|
||||
LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video5 \
|
||||
LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media2 \
|
||||
vainfo --display drm --device /dev/dri/renderD128 2>&1 | \
|
||||
grep -E "VAProfileMPEG2(Simple|Main)"
|
||||
'
|
||||
# Expected: 2 lines, both with VAEntrypointVLD
|
||||
|
||||
# Criteria 2 + 3: vaCreateConfig + ffmpeg-driven decode (no errors, exit 0)
|
||||
ssh fresnel '
|
||||
mkdir -p /tmp/iter1_phase7
|
||||
LIBVA_DRIVER_NAME=v4l2_request \
|
||||
LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video5 \
|
||||
LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media2 \
|
||||
LIBVA_TRACE=/tmp/iter1_phase7/libva.trace \
|
||||
ffmpeg -hide_banner -loglevel info -hwaccel vaapi \
|
||||
-i ~/fourier-test/bbb_720p10s_mpeg2.ts -frames:v 2 -f null - 2>&1
|
||||
'
|
||||
# Expected: exit 0, no "Failed to create decode configuration",
|
||||
# libva trace shows vaCreateConfig SUCCESS, no EINVAL on S_EXT_CTRLS.
|
||||
|
||||
# Criterion 4: DMA-BUF GL pixel verify (HW=SW byte-identical at +02s seek)
|
||||
ssh fresnel '
|
||||
mkdir -p /tmp/iter1_phase7/png_hw /tmp/iter1_phase7/png_sw
|
||||
WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 \
|
||||
LIBVA_DRIVER_NAME=v4l2_request \
|
||||
LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video5 \
|
||||
LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media2 \
|
||||
mpv --hwdec=vaapi --frames=2 --vo=image --no-audio \
|
||||
--no-input-default-bindings --start=00:00:02 \
|
||||
--vo-image-outdir=/tmp/iter1_phase7/png_hw \
|
||||
~/fourier-test/bbb_720p10s_mpeg2.ts
|
||||
|
||||
mpv --hwdec=no --frames=2 --vo=image --no-audio \
|
||||
--no-input-default-bindings --start=00:00:02 \
|
||||
--vo-image-outdir=/tmp/iter1_phase7/png_sw \
|
||||
~/fourier-test/bbb_720p10s_mpeg2.ts
|
||||
|
||||
sha256sum /tmp/iter1_phase7/png_hw/*.jpg /tmp/iter1_phase7/png_sw/*.jpg
|
||||
'
|
||||
# Expected: HW frame 1 hash == SW frame 1 hash; HW frame 2 hash ==
|
||||
# SW frame 2 hash; frame 1 hash != frame 2 hash (real motion).
|
||||
# NOTE: this assumes mpv-vaapi (DMA-BUF) WILL engage for MPEG-2 even
|
||||
# though mpv-vaapi-copy (cached-mmap) doesn't. To be verified in Phase 7
|
||||
# baseline; if mpv-vaapi also filters MPEG-2 out, fall back to ffmpeg
|
||||
# -hwaccel vaapi -vf hwdownload,format=nv12 -f rawvideo, hash the YUV.
|
||||
|
||||
# Criterion 5: H.264 regression — T4 reference hashes still match
|
||||
ssh fresnel '
|
||||
WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 \
|
||||
LIBVA_DRIVER_NAME=v4l2_request \
|
||||
LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video3 \
|
||||
LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media1 \
|
||||
mpv --hwdec=vaapi --frames=2 --vo=image --no-audio \
|
||||
--no-input-default-bindings --start=00:00:30 \
|
||||
--vo-image-outdir=/tmp/iter1_phase7/png_h264 \
|
||||
~/fourier-test/bbb_1080p30_h264.mp4
|
||||
sha256sum /tmp/iter1_phase7/png_h264/*.jpg
|
||||
'
|
||||
# Expected: f623d5f7a41697f67dd227275c6f1b21ffc257f65626d32fde8229357f8764c9 (frame 1)
|
||||
# 7d7bc6f2146dda8b2d223bba622c4b9fbe9674181ff1e02afe286b620342e0a8 (frame 2)
|
||||
|
||||
# Extra (cross-validator anchor): byte-compare post-fix S_EXT_CTRLS payload
|
||||
# vs Baseline C verbatim.
|
||||
ssh fresnel '
|
||||
mkdir -p /tmp/iter1_phase7/cross
|
||||
sudo sh -c "echo 1 > /sys/kernel/tracing/events/v4l2/enable; \
|
||||
echo 1 > /sys/kernel/tracing/tracing_on"
|
||||
strace -ff -tt -y -v -e trace=ioctl \
|
||||
-o /tmp/iter1_phase7/cross/ffmpeg.strace \
|
||||
env LIBVA_DRIVER_NAME=v4l2_request \
|
||||
LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video5 \
|
||||
LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media2 \
|
||||
ffmpeg -hide_banner -loglevel error -hwaccel vaapi \
|
||||
-i ~/fourier-test/bbb_720p10s_mpeg2.ts -frames:v 2 -f null -
|
||||
sudo sh -c "echo 0 > /sys/kernel/tracing/tracing_on; \
|
||||
echo 0 > /sys/kernel/tracing/events/v4l2/enable"
|
||||
grep "VIDIOC_S_EXT_CTRLS" /tmp/iter1_phase7/cross/ffmpeg.strace.* | head
|
||||
'
|
||||
# Expected (frame 1): one batched call, ctrl_class=0xf010000, count=3,
|
||||
# CIDs 0xa409dc/dd/de in order, sizes 12/32/256.
|
||||
# SEQUENCE bytes: "\0\5\320\2\0\30\25\0\0\0\1\1" (1280×720 progressive, chroma=1).
|
||||
# QUANTISATION first 4 bytes: 8, 16, 16, 19 (MPEG-2 default intra zigzag).
|
||||
# PICTURE values vary frame-to-frame but structurally match Baseline C.
|
||||
```
|
||||
|
||||
### Pass/fail decision
|
||||
|
||||
All five criteria PASS → Phase 7 closes green; proceed to Phase 8 (memory update + close iter1).
|
||||
|
||||
Any criterion FAIL → Phase 7 → Phase 4 loopback per `feedback_dev_process.md`. Pre-identified loopback triggers:
|
||||
|
||||
1. **`VIDIOC_S_EXT_CTRLS` returns EINVAL post-fix**. Likely causes: (a) `pic.reserved[5]` not zeroed (memset was forgotten), (b) struct sizes mismatch kernel expectation (e.g., padding differences), (c) flag bit value collisions. Mitigation: sanity-check via `pahole` or `sizeof`, compare to Baseline C's verbatim sizes (12 / 32 / 256).
|
||||
|
||||
2. **Pixel verify fails: HW frames hash-differ from SW**. Likely causes: (a) f_code packing wrong (`(picture->f_code >> N) & 0x0f` byte-order), (b) field-vs-frame structure misinterpretation on a non-progressive bitstream (BBB is progressive, so unlikely), (c) reference timestamps wrong (forward_ref_ts/backward_ref_ts off), (d) IQ matrix interpretation differs (custom matrices in fixture's sequence-extension that VAAPI passes in different order than expected). Mitigation: dump a single VAIQMatrixBufferMPEG2 payload via LIBVA_TRACE_BUFDATA, verify byte-for-byte against the bitstream's actual matrices (and against Baseline C's QUANTISATION first row for the default-matrices case).
|
||||
|
||||
3. **mpv `--hwdec=vaapi` filters MPEG-2 out same as `--hwdec=vaapi-copy`** — criterion 4 untestable as written. Mitigation: switch to `ffmpeg -hwaccel vaapi -vf hwdownload,format=nv12 -f rawvideo - | sha256sum` for both HW and SW; compare YUV bytes directly. Fall-forward only — don't loop the criterion definition.
|
||||
|
||||
4. **H.264 regression**. Bug 1 fix touches a switch case other H.264 cases use; if H.264 regresses, the patch was applied to the wrong location. Mitigation: re-read Baseline D vs scratch-Bug1 diff and locate the offending change.
|
||||
|
||||
5. **`include/mpeg2-ctrls.h` deletion breaks an unaudited consumer**. Mitigation: `git grep -l "mpeg2-ctrls"` after deletion to confirm zero remaining references; build catches anything missed.
|
||||
|
||||
## Out of scope (LOCKED for iter1)
|
||||
|
||||
- HEVC, VP9, VP8 work — separate iterations.
|
||||
- vaDeriveImage cache-stale fix (T4 finding) — Phase 4 cross-cutting work; not iter1.
|
||||
- chromium-fourier 149 install on fresnel.
|
||||
- Performance metrics for MPEG-2.
|
||||
- Long-duration MPEG-2 stress (>10s).
|
||||
- Other MPEG-2 containers (PS, MP4, etc.).
|
||||
- mpv `--hwdec=vaapi-copy` engaging MPEG-2 (separate follow-up; criterion #3 adjusted to ffmpeg-direct).
|
||||
- The H.264 device-init unconditional EINVAL on hantro (`src/context.c:142-155`) — auxiliary noise, intentionally swallowed.
|
||||
- Refining `sequence.profile_and_level_indication` (current 0; VAAPI doesn't expose) — informational field, kernel doesn't reject.
|
||||
- Refining `sequence.chroma_format` from hardcoded 1 (4:2:0) to lifted from VAAPI — campaign codec scope is 4:2:0 only.
|
||||
- Refining `progressive_sequence` derivation from `progressive_frame` proxy — works for BBB, sufficient for iter1 binding cell.
|
||||
- Upstream Linux engagement (per `feedback_no_upstream.md`) — kernel-side works; nothing to file.
|
||||
|
||||
## What "iteration 1 close" looks like
|
||||
|
||||
Per `phase0_findings_iter1.md`:
|
||||
|
||||
- All 5 Phase 1 criteria green (with #3 wording adjusted by this Phase 4 plan).
|
||||
- `phase8_iteration1_close.md` document summarizing the bug, contract, fix, binding-cell numbers.
|
||||
- Second-codec passing on the campaign-level scoreboard (1/5 → 2/5).
|
||||
- Memory entry per Phase 8 (lesson distilled).
|
||||
- Debug-instrumentation sweep (any `printf` / `fprintf` from Phase 6 removed; no scratch state remaining).
|
||||
- Phase 5 sonnet-architect review pass signed off.
|
||||
- Commits all authored as `claude-noether` per memory `feedback_gitea_as_claude_noether.md`.
|
||||
|
||||
## Phase 5 entry point
|
||||
|
||||
Phase 5 (second-model review) inputs are this plan + the four Phase 3 baselines. Per `feedback_dev_process.md`:
|
||||
|
||||
> Goal, situation, measurements, plan get pasted into DokuWiki. Markus reviews and redacts, then initiates the handover to a fresh model instance. Claude does not curate the artifact going to the reviewer — that would re-introduce the blind-spot accumulation the review is meant to escape. Do not summarize when handing over; paste the actual artifacts.
|
||||
|
||||
Concretely: the artifacts to hand over are the four primary documents in this campaign repo (`phase0_findings_iter1.md`, `phase2_iter1_situation.md`, `phase3_iter1_baseline.md`, `phase4_iter1_plan.md`) plus the `phase0_evidence/2026-05-07/iter1_phase3/` raw output. No summary, no executive overview, no "the gist is" framing — Markus has the raw bundle, the reviewer reads it directly.
|
||||
Reference in New Issue
Block a user