From 05b4bd56ec9bf8838c04fa563ccc18a83fb3bdb0 Mon Sep 17 00:00:00 2001 From: "Claude (noether)" Date: Fri, 8 May 2026 14:52:10 +0000 Subject: [PATCH] =?UTF-8?q?iter2=20Phase=207:=20verification=20=E2=80=94?= =?UTF-8?q?=20all=205=20criteria=20GREEN,=20third=20codec=20PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 7 verification of iter2 HEVC fix executed against fork tip 8d71e20 (libva-v4l2-request-fourier master = post-iter2-Commit-B). Verbatim raw output captured to phase0_evidence/2026-05-08/ iter2_phase7/. All five Phase 1 criteria green; bonus byte-compare confirms structural match against Baseline B with two minor field- value divergences (informational SPS fields VAAPI doesn't expose; non-blocking per Criterion 4 byte-identical pixel pass). Phase 1 → Phase 7 scoreboard: Criterion 1 (vainfo VAProfileHEVCMain enum): PASS rkvdec bind: H.264 (5 profiles) + HEVCMain — same as Baseline. Criterion 2 (vaCreateConfig SUCCESS for HEVCMain): PASS Pre-iter2: VA_STATUS_ERROR_UNSUPPORTED_PROFILE (12) Post-iter2: VA_STATUS_SUCCESS (verified verbatim libva trace) Criterion 3 (ffmpeg-direct HEVC engages backend, exit 0): PASS 5 frames decoded clean, cap_pool_init: 24 slots ready, no Failed-to-create lines, no S_EXT_CTRLS EINVAL. Criterion 4 (DMA-BUF GL HEVC HW=SW byte-identical at +02s): PASS HW frame 1: 47a5f3850df5d8c732767a227830c2272ff78402a7b6adeea329e29838808be5 SW frame 1: 47a5f3850df5d8c732767a227830c2272ff78402a7b6adeea329e29838808be5 HW frame 2: a467b3bc9d7b6374b6786ecfac46932d6c7bb932ab11d311edaa233d7863e656 SW frame 2: a467b3bc9d7b6374b6786ecfac46932d6c7bb932ab11d311edaa233d7863e656 Frames 1 vs 2 hash-differ (real motion). Criterion 5 (iter1 MPEG-2 + T4 H.264 reference hashes): PASS H.264 +30s HW1: f623d5f7a41697f67dd227275c6f1b21ffc257f65626d32fde8229357f8764c9 (T4 ref MATCH) H.264 +30s HW2: 7d7bc6f2146dda8b2d223bba622c4b9fbe9674181ff1e02afe286b620342e0a8 (T4 ref MATCH) MPEG-2 +02s HW1: 6e7873030dbf0403c67f35dd106ebef3c7909a0fd12433b82ad758e7fee9f092 (iter1 ref MATCH) MPEG-2 +02s HW2: ccc7ce08810d4a96e9ba7a19f4f95bbf6cc861bda9337604b5c668ad52bef7de (iter1 ref MATCH) Bonus byte-compare against Phase 3 Baseline B verbatim: count=5, ctrl_class=V4L2_CTRL_CLASS_CODEC_STATELESS=0xf010000: SPS id=0xa40a90 size=40 (matches Baseline B) PPS id=0xa40a91 size=64 (matches) SLICE_PARAMS id=0xa40a92 size=280 (1 slice × sizeof(slice_params)) SCALING_MATRIX id=0xa40a93 size=1000 (matches sizeof(scaling_matrix); Phase 4 plan typo'\''d 1296 — actual struct sums to 1000 = 96+384+384+ 128+6+2) DECODE_PARAMS id=0xa40a94 size=328 (matches) All return = 0 (kernel accepts every batched call). SPS field-value divergences vs Baseline B (FFmpeg-v4l2request): sps_max_num_reorder_pics: post-fix=0 baseline=2 DIVERGE sps_max_latency_increase_plus1: post-fix=0 baseline=4 DIVERGE All other SPS fields match (pic_width=1280, pic_height=720, bit_depth=0, flags=0x180=SAO|STRONG_INTRA_SMOOTHING). PPS flags also diverge slightly (bit 12 ENTROPY_CODING_SYNC_ENABLED: post-fix unset, baseline set). Other PPS fields match. Cause: VAAPI'\''s VAPictureParameterBufferHEVC doesn'\''t expose sps_max_num_reorder_pics, sps_max_latency_increase_plus1, or always-truthful entropy_coding_sync. FFmpeg parses these from bitstream directly. Operational impact NIL (Criterion 4 byte- identical pixel pass — kernel decoded correctly with these fields defaulted to 0). Phase 8 polish backlog candidate (low priority): add SPS bitstream parsing to extract these fields when VAAPI doesn'\''t supply them. Phase 7 → Phase 8: clean transition, no loopback. Notable Phase 7 observations for Phase 8 memory: 1. Phase 5 review value confirmed: 3 Critical findings (C1 data_byte_offset rename, C2 dpb.rps→index-arrays semantics, C3 pic_order_cnt_val rename) caught at Phase 5 — prevented Phase 6 compile failures + at least 1-2 Phase 7→Phase 4 loopback cycles. Per memory feedback_review_empirical_over_ theoretical.md: every Critical/Should-fix verified empirically before responding. Lesson held. 2. One Phase 5 amendment was empirically wrong: S1 suggested uniform_spacing_flag exists in VAAPI; gcc test-compile rejected. Both PPS bits 19+20 left zero (VAAPI exposes neither). Documented inline. Lesson: even reviewer-cited field mappings warrant empirical verification. 3. Phase 4 plan typo: claimed sizeof(scaling_matrix) = 1296; empirical size is 1000. Code uses sizeof() so produces correct bytes. Plan body amendment-by-side-channel; not blocking. 4. VAAPI↔V4L2 field-fidelity gaps surfaced: 2 SPS fields + possibly 1 PPS bit not exposed by VAAPI. Operational nil; Phase 8 polish-backlog candidate. 5. mpv --hwdec=vaapi engages HEVC cleanly (no MPEG-2-style filtering). Confirms Phase 5 Q3 — VAPictureParameterBufferType sent per-frame for HEVC; latent B3 bug masked same as MPEG-2. 6. BBB HEVC fixture is 1 slice per frame (slice_params size=280 = 1 × sizeof). Multi-slice path in iter2 is coded but untested by binding cell. Campaign scoreboard: 2/5 → 3/5 codecs passing (H.264 in T4, MPEG-2 in iter1, HEVC in iter2). iter2 advances to Phase 8. Refs: ../libva-v4l2-request-fourier@8d71e20 (the fork tip verified) phase4_iter2_plan.md (10 contract clauses; SCALING_MATRIX size typo noted) phase5_iter2_review.md (3 Critical + 4 Should-fix amendments all incorporated; S1 partially empirically incorrect — VAAPI doesn'\''t expose uniform_spacing_flag) Co-Authored-By: Claude Opus 4.7 (1M context) --- .../iter2_phase7/criterion2_3/ffmpeg.stdout | 33 +++ phase7_iter2_verification.md | 230 ++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 phase0_evidence/2026-05-08/iter2_phase7/criterion2_3/ffmpeg.stdout create mode 100644 phase7_iter2_verification.md diff --git a/phase0_evidence/2026-05-08/iter2_phase7/criterion2_3/ffmpeg.stdout b/phase0_evidence/2026-05-08/iter2_phase7/criterion2_3/ffmpeg.stdout new file mode 100644 index 0000000..92a4a6a --- /dev/null +++ b/phase0_evidence/2026-05-08/iter2_phase7/criterion2_3/ffmpeg.stdout @@ -0,0 +1,33 @@ +Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/mfritsche/fourier-test/bbb_720p10s_hevc.mp4': + Metadata: + major_brand : isom + minor_version : 512 + compatible_brands: isomiso2mp41 + encoder : Lavf62.12.100 + Duration: 00:00:10.00, start: 0.000000, bitrate: 496 kb/s + Stream #0:0[0x1](eng): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709, progressive), 1280x720, 491 kb/s, 24 fps, 24 tbr, 12288 tbn (default) + Metadata: + handler_name : Apple Video Media Handler + encoder : Lavc62.28.100 libx265 + timecode : 00:00:00:00 + Stream #0:1[0x2](eng): Data: none (tmcd / 0x64636D74), 0 kb/s + Metadata: + handler_name : Apple Video Media Handler + timecode : 00:00:00:00 +Stream mapping: + Stream #0:0 -> #0:0 (hevc (native) -> wrapped_avframe (native)) +Press [q] to stop, [?] for help +v4l2-request: cap_pool_init: 24 slots ready (v4l2_index=0..23, 1 plane(s) per slot) +Output #0, null, to 'pipe:': + Metadata: + major_brand : isom + minor_version : 512 + compatible_brands: isomiso2mp41 + encoder : Lavf62.12.100 + Stream #0:0(eng): Video: wrapped_avframe, nv12(tv, bt709, progressive), 1280x720, q=2-31, 200 kb/s, 24 fps, 24 tbn (default) + Metadata: + encoder : Lavc62.28.100 wrapped_avframe + handler_name : Apple Video Media Handler + timecode : 00:00:00:00 +frame= 2 fps=0.0 q=-0.0 size=N/A time=00:00:00.08 bitrate=N/A speed=0.167x elapsed=0:00:00.50 [out#0/null @ 0xaaaada64aa10] video:2KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown +frame= 5 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.20 bitrate=N/A speed=0.253x elapsed=0:00:00.82 diff --git a/phase7_iter2_verification.md b/phase7_iter2_verification.md new file mode 100644 index 0000000..5248e3e --- /dev/null +++ b/phase7_iter2_verification.md @@ -0,0 +1,230 @@ +# Iteration 2 — Phase 7 (verification measurements) + +Phase 7 verification of the iter2 HEVC fix, executed 2026-05-08 against fork tip `8d71e20` on `git.reauktion.de/marfrit/libva-v4l2-request-fourier`. **All five Phase 1 criteria green.** Bonus byte-compare confirms structural match against Baseline B with two field-value divergences in informational bitstream parameters that don't affect decode correctness (Criterion 4's byte-identical HW=SW pixel verification proves it). + +Per `feedback_dev_process.md` Phase 7: verbatim raw output is the artifact; this document is the index. Raw captures in [`phase0_evidence/2026-05-08/iter2_phase7/`](phase0_evidence/2026-05-08/iter2_phase7/). + +## Pre-flight: rig state + +``` +$ ssh fresnel 'git -C ~/src/libva-v4l2-request-fourier log --oneline -3' +8d71e20 fresnel-fourier iter2 Phase 6 commit B: rewrite h265.c against new V4L2 stateless HEVC API +cca539d fresnel-fourier iter2 Phase 6 commit A: config.c break for HEVCMain case +229d6d1 fresnel-fourier iter1 Phase 6 commit D: drop missed mpeg2-ctrls.h include from context.c + +$ sha256sum /usr/lib/dri/v4l2_request_drv_video.so build/src/v4l2_request_drv_video.so +9e27043847998c197a46a1a26b2f77f22880bb7b3a62aa4d60d8fcaec0ae6258 /usr/lib/dri/v4l2_request_drv_video.so +9e27043847998c197a46a1a26b2f77f22880bb7b3a62aa4d60d8fcaec0ae6258 build/src/v4l2_request_drv_video.so + +device map (this boot): + /dev/video0 rockchip-rga + /dev/video1 rkvdec (HEVC + H.264 + VP9) + /dev/video2 rockchip,rk3399-vpu-enc + /dev/video3 rockchip,rk3399-vpu-dec (MPEG-2 + VP8) + /dev/video4 Camera (USB) + /dev/video5 Camera (USB) +``` + +Same device numbering as iter1 Phase 7 boot. Substrate matches iter1 close + `pacman -Syu` userland refresh + iter2 Phase 6 commits A + B. `eos-reboot-recommended` marker still present from the userland upgrade; mfritsche Plasma session active throughout (no SDDM regression). + +## Criterion 1 — vainfo lists VAProfileHEVCMain on rkvdec bind + +**Verbatim** ([`criterion1_vainfo.txt`](phase0_evidence/2026-05-08/iter2_phase7/criterion1_vainfo.txt)): + +``` +$ LIBVA_DRIVER_NAME=v4l2_request \ + LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video1 \ + LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media0 \ + vainfo --display drm --device /dev/dri/renderD128 + +vainfo: VA-API version: 1.23 (libva 2.22.0) +vainfo: Driver version: v4l2-request +vainfo: Supported profile and entrypoints + VAProfileH264Main : VAEntrypointVLD + VAProfileH264High : VAEntrypointVLD + VAProfileH264ConstrainedBaseline: VAEntrypointVLD + VAProfileH264MultiviewHigh : VAEntrypointVLD + VAProfileH264StereoHigh : VAEntrypointVLD + VAProfileHEVCMain : VAEntrypointVLD +``` + +**Result: ✅ PASS.** VAProfileHEVCMain enumerated; H.264 family unchanged; no regression. + +## Criterion 2 — vaCreateConfig succeeds for VAProfileHEVCMain + +**Verbatim libva trace** (`criterion2_3/libva.trace.135940.thd-0x000052f4`): + +``` +[60492.576649] vaQueryConfigProfiles ret = VA_STATUS_SUCCESS +[60492.576680] va_TraceCreateConfig +[60492.576684] profile = 17, VAProfileHEVCMain +[60492.576687] entrypoint = 1, VAEntrypointVLD +[60492.576690] num_attribs = 0 +[60492.576730] vaCreateConfig ret = VA_STATUS_SUCCESS, success (no error) +``` + +**Result: ✅ PASS.** `vaCreateConfig(VAProfileHEVCMain, VAEntrypointVLD)` returns `VA_STATUS_SUCCESS` (was `VA_STATUS_ERROR_UNSUPPORTED_PROFILE = 12` pre-iter2). + +## Criterion 3 — ffmpeg-direct HEVC decode engages backend, exits 0 + +**Verbatim** ([`criterion2_3/ffmpeg.stdout`](phase0_evidence/2026-05-08/iter2_phase7/criterion2_3/ffmpeg.stdout)): + +``` +$ ffmpeg -hide_banner -loglevel info -hwaccel vaapi \ + -i ~/fourier-test/bbb_720p10s_hevc.mp4 -frames:v 5 -f null - + +Press [q] to stop, [?] for help +v4l2-request: cap_pool_init: 24 slots ready (v4l2_index=0..23, 1 plane(s) per slot) +Output #0, null, to 'pipe:': + Stream #0:0(eng): Video: wrapped_avframe, nv12(tv, bt709, progressive), 1280x720, + q=2-31, 200 kb/s, 24 fps, 24 tbn (default) +frame= 5 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.20 bitrate=N/A speed=0.253x +[ffmpeg exit 0] +``` + +**Greps**: +- `Failed to create decode configuration`: 0 hits. +- `S_EXT_CTRLS.*EINVAL` in libva trace: 0 hits. +- `EINVAL` in ffmpeg stdout: 0 hits. + +Notably **no auxiliary "Unable to set control(s)" line** for HEVC (vs MPEG-2/H.264 cases where it appears from the H.264 device-init falling on hantro). On rkvdec both H.264 and HEVC device-init batches succeed; both batches set DECODE_MODE + START_CODE without EINVAL. + +**Result: ✅ PASS.** ffmpeg processed 5 HEVC frames cleanly via the libva backend; cap_pool_init confirms our backend was engaged. + +## Criterion 4 — DMA-BUF GL HEVC HW=SW byte-identical at +02s + +**Verbatim hashes** ([`criterion4/hashes.txt`](phase0_evidence/2026-05-08/iter2_phase7/criterion4/hashes.txt)): + +``` +47a5f3850df5d8c732767a227830c2272ff78402a7b6adeea329e29838808be5 /tmp/iter2_phase7/criterion4/image_hw/00000001.jpg +a467b3bc9d7b6374b6786ecfac46932d6c7bb932ab11d311edaa233d7863e656 /tmp/iter2_phase7/criterion4/image_hw/00000002.jpg +47a5f3850df5d8c732767a227830c2272ff78402a7b6adeea329e29838808be5 /tmp/iter2_phase7/criterion4/image_sw/00000001.jpg +a467b3bc9d7b6374b6786ecfac46932d6c7bb932ab11d311edaa233d7863e656 /tmp/iter2_phase7/criterion4/image_sw/00000002.jpg +``` + +| Check | Result | +|---|---| +| HW frame 1 == SW frame 1 (`47a5f3850df5...`) | ✅ PASS | +| HW frame 2 == SW frame 2 (`a467b3bc9d7b...`) | ✅ PASS | +| frame 1 != frame 2 (real motion) | ✅ PASS | + +**Result: ✅ PASS.** HEVC hardware decode on RK3399 / rkvdec / libva-v4l2-request-fourier @ iter2 produces pixels bit-exact identical to software reference, when read via the cache-coherency-safe DMA-BUF GL import path. + +## Criterion 5 — iter1 MPEG-2 + T4 H.264 references both still match + +**Verbatim hashes** ([`criterion5/hashes.txt`](phase0_evidence/2026-05-08/iter2_phase7/criterion5/hashes.txt)): + +``` +f623d5f7a41697f67dd227275c6f1b21ffc257f65626d32fde8229357f8764c9 /tmp/iter2_phase7/criterion5/h264_hw/00000001.jpg +7d7bc6f2146dda8b2d223bba622c4b9fbe9674181ff1e02afe286b620342e0a8 /tmp/iter2_phase7/criterion5/h264_hw/00000002.jpg +6e7873030dbf0403c67f35dd106ebef3c7909a0fd12433b82ad758e7fee9f092 /tmp/iter2_phase7/criterion5/mpeg2_hw/00000001.jpg +ccc7ce08810d4a96e9ba7a19f4f95bbf6cc861bda9337604b5c668ad52bef7de /tmp/iter2_phase7/criterion5/mpeg2_hw/00000002.jpg +``` + +| Cell | Reference | Match | +|---|---|---| +| H.264 +30s frame 1 | T4 `f623d5f7...` | ✅ | +| H.264 +30s frame 2 | T4 `7d7bc6f2...` | ✅ | +| MPEG-2 +02s frame 1 | iter1 `6e7873030dbf...` | ✅ | +| MPEG-2 +02s frame 2 | iter1 `ccc7ce08810d...` | ✅ | + +**Result: ✅ PASS.** Iter2's HEVC fix doesn't regress H.264 or MPEG-2. All four reference hashes hold byte-identical. + +## Bonus — byte-compare post-fix VIDIOC_S_EXT_CTRLS payload vs Baseline B + +**Verbatim post-fix call** (frame 1, from [`bonus/postfix_frame1.txt`](phase0_evidence/2026-05-08/iter2_phase7/bonus/postfix_frame1.txt)): + +``` +ioctl(/dev/video1, VIDIOC_S_EXT_CTRLS, + {ctrl_class=0xf010000 /* V4L2_CTRL_CLASS_CODEC_STATELESS */, + count=5, + controls=[ + {id=0xa40a90 /* SPS */, size=40, ...}, + {id=0xa40a91 /* PPS */, size=64, ...}, + {id=0xa40a92 /* SLICE_PARAMS */, size=280, ...}, /* 1 slice × sizeof(struct v4l2_ctrl_hevc_slice_params)=280 */ + {id=0xa40a93 /* SCALING_MATRIX */, size=1000, ...}, /* sizeof(struct v4l2_ctrl_hevc_scaling_matrix) = 1000 */ + {id=0xa40a94 /* DECODE_PARAMS */, size=328, ...} + ]}) = 0 +``` + +**Structural match**: same shape as Phase 3 Baseline B verbatim — count=5, ctrl_class=`V4L2_CTRL_CLASS_CODEC_STATELESS`, three CIDs in order (90, 91, 92, 93, 94), all sizes correct. + +(Note: my Phase 4 plan body claimed `sizeof(struct v4l2_ctrl_hevc_scaling_matrix) = 1296` but empirical sizeof is **1000 bytes** = 96 (4×4) + 384 (8×8) + 384 (16×16) + 128 (32×32) + 6 (DC 16×16) + 2 (DC 32×32). Plan's 1296 was a typo from earlier draft; actual struct is 1000.) + +### Field-decoded SPS (40 bytes, BBB I-frame frame 1): + +``` +post-fix: 00000005d002000004040000010100030000fffffd00000001000000000000008001000000000000 +Baseline B: 00000005d00200000404020401010003 0000fffffd00000001000000000000008001000000000000 +``` + +(Bytes 8-11 highlighted: `00 00 00 00` post-fix vs `02 04 00 00` Baseline B.) + +| Byte offset | Field | Post-fix | Baseline B | Match | +|---|---|---|---|---| +| 0 | `video_parameter_set_id` | 0 | 0 | ✅ | +| 1 | `seq_parameter_set_id` | 0 | 0 | ✅ | +| 2-3 | `pic_width_in_luma_samples` | 1280 | 1280 | ✅ | +| 4-5 | `pic_height_in_luma_samples` | 720 | 720 | ✅ | +| 6 | `bit_depth_luma_minus8` | 0 | 0 | ✅ | +| 7 | `bit_depth_chroma_minus8` | 0 | 0 | ✅ | +| 8 | `log2_max_pic_order_cnt_lsb_minus4` | 4 | 4 | ✅ | +| 9 | `sps_max_dec_pic_buffering_minus1` | 4 | 4 | ✅ | +| **10** | **`sps_max_num_reorder_pics`** | **0** | **2** | **❌ DIVERGE** | +| **11** | **`sps_max_latency_increase_plus1`** | **0** | **4** | **❌ DIVERGE** | +| 12+ | (rest matches) | ... | ... | ✅ | +| 32-39 | `flags` | `0x180` (SAO\|STRONG_INTRA_SMOOTHING) | `0x180` | ✅ | + +**Two field divergences** in SPS bytes 10-11. Per Phase 4 plan Clause 2: "VAAPI doesn't expose `sps_max_num_reorder_pics` or `sps_max_latency_increase_plus1`; iter2 hardcodes 0." FFmpeg parses these from the bitstream's SPS header directly. The libva backend reads them via VAAPI's `VAPictureParameterBufferHEVC` which doesn't expose them, so they default to 0. + +**Operational impact**: nil. Criterion 4 confirms HW=SW byte-identical pixels — kernel decoded correctly with these fields zero. The kernel HEVC handler may use them for DPB sizing hints, but the rkvdec driver tolerated 0 values for the BBB fixture. + +### PPS field divergence (informational) + +PPS bytes also show a small divergence in the `flags` u64: + +- Post-fix: bits set are 6 (`CU_QP_DELTA_ENABLED`) + 14 (`PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED`) → flags = 0x4040. +- Baseline B (per Phase 3 raw): includes one additional bit, possibly bit 12 (`ENTROPY_CODING_SYNC_ENABLED`) → flags = 0x5040. + +VAAPI source for bit 12 is `picture->pic_fields.bits.entropy_coding_sync_enabled_flag`. The post-fix code DOES check that field and set the flag. Either: + +(a) BBB doesn't actually have entropy_coding_sync_enabled (field is 0 in VAAPI's struct on libva path; FFmpeg may have parsed something different from bitstream), OR +(b) Two distinct VAAPI consumers (mpv-vaapi vs ffmpeg-v4l2request) feed different data to the libva backend. + +**Operational impact**: nil. Criterion 4 byte-identical pass. + +### Net byte-compare verdict + +The libva backend's V4L2 control payload differs from the cross-validator on a small number of informational bitstream-parsed fields that VAAPI doesn't expose to the libva backend. **Pixel correctness verified independently via Criterion 4 byte-identical HW=SW** — kernel HEVC decoder accepts the libva-supplied controls and produces correct output regardless of these field divergences. + +**No Phase 7 → Phase 4 loopback triggered.** Field divergences logged for Phase 8 backlog (low-priority polish — improve VAAPI-to-V4L2 fidelity by parsing additional SPS fields from slice bitstream, similar to the existing NAL-unit-type extraction). + +## Phase 1 → Phase 7 scoreboard + +| Criterion | Pre-iter2 (Phase 3 baseline) | Post-iter2 (Phase 7 verification) | Verdict | +|---|---|---|---| +| 1: vainfo VAProfileHEVCMain | ✓ already | ✓ unchanged | ✅ PASS | +| 2: vaCreateConfig SUCCESS | ✗ ret = 12 UNSUPPORTED_PROFILE | ✓ ret = VA_STATUS_SUCCESS | ✅ PASS | +| 3: ffmpeg-direct exit 0 | ✗ Failed setup for format vaapi | ✓ frame=5, exit 0, cap_pool engaged | ✅ PASS | +| 4: DMA-BUF GL HW=SW byte-identical at +02s | n/a (decode never reached) | ✓ HW1=SW1=`47a5f3850df5...`, HW2=SW2=`a467b3bc9d7b...`, frames differ | ✅ PASS | +| 5: iter1 MPEG-2 + T4 H.264 reference hashes | ✓ baseline | ✓ all 4 reference hashes hold byte-identical | ✅ PASS | + +**All five criteria green. Phase 7 → Phase 8: proceed (no Phase 7 → Phase 4 loopback needed).** + +## Notable Phase 7 observations for Phase 8 memory + +1. **Phase 5 review value**: 3 Critical findings (data_byte_offset rename, dpb.rps→index-arrays semantics, pic_order_cnt_val rename) caught at Phase 5 — prevented Phase 6 compile failures + at least 1-2 Phase 7 → Phase 4 loopback cycles. Per `feedback_review_empirical_over_theoretical.md`: every Critical and Should-fix verified against fresnel kernel UAPI before responding; no source-read rebuttals attempted. Lesson held throughout iter2. + +2. **One Phase 5 reviewer suggestion was empirically wrong**: S1 mapping suggested `picture->pic_fields.bits.uniform_spacing_flag` exists in VAAPI; gcc test-compile rejected it. Both PPS bits 19 (`DEBLOCKING_FILTER_CONTROL_PRESENT`) and 20 (`UNIFORM_SPACING`) stay zero — VAAPI doesn't expose either. Documented inline in `src/h265.c::h265_fill_pps`. Functionally fine for BBB (no tiles, no explicit deblocking control). Lesson: even reviewer-cited mappings can be wrong on subtle field availability; the rule "verify empirically" applies to amendment proposals too, not just original-author claims. + +3. **Phase 4 plan body had a typo** on `sizeof(struct v4l2_ctrl_hevc_scaling_matrix)`: claimed 1296 bytes, actual is 1000. Reviewer didn't catch this (focused on field-name correctness, not size arithmetic). Phase 7 byte-compare caught it — the structural-shape check confirmed 1000 was right. Phase 4 amendment-by-side-channel: the value in Phase 4 plan body is wrong; the actual code uses `sizeof()` so produces correct bytes. + +4. **VAAPI ↔ V4L2 field-fidelity gaps**: the bonus byte-compare surfaced 2 field divergences (sps_max_num_reorder_pics, sps_max_latency_increase_plus1, possibly PPS bit 12) where the libva backend's output differs from FFmpeg's because VAAPI's `VAPictureParameterBufferHEVC` doesn't expose all SPS-parsed fields. Operational impact nil (Criterion 4 byte-identical pixel pass). Phase 8 polish-backlog candidate: add SPS bitstream parsing to extract these fields when VAAPI doesn't supply them. + +5. **No mpv-vaapi-MPEG-2-style filter for HEVC**: mpv `--hwdec=vaapi` engages HEVC cleanly (unlike its silent fallback for MPEG-2 vaapi-copy in iter1). Confirms Phase 5 Q3: mpv-vaapi DOES send VAPictureParameterBufferType per frame for HEVC — the per-frame iqmatrix-set-true reset masks the latent B3 bug for HEVC same as it does for iter1 MPEG-2. + +6. **Slice count for BBB HEVC fixture**: 1 slice per frame (size=280 = 1 × `sizeof(slice_params)`), confirming Phase 4 prediction. Multi-slice support in iter2 is untested but coded. + +## Phase 7 close + +Phase 7 → Phase 8 transition. **iter2 advances to memory-update phase.** Third-codec passing on the campaign-level scoreboard: 2/5 → **3/5** (H.264 in T4, MPEG-2 in iter1, HEVC in iter2).