Files
fresnel-fourier/phase7_iter1_verification.md
claude-noether ec9133a5e4 iter1 Phase 7: verification — all 5 criteria GREEN, second codec PASS
Phase 7 verification of iter1 MPEG-2 fix executed against fork tip
229d6d1 (libva-v4l2-request-fourier master = post-Commit-D).
Verbatim raw output captured to phase0_evidence/2026-05-08/
iter1_phase7/. All five Phase 1 criteria green; bonus byte-compare
confirms structural match against Baseline C with one numerical
divergence (vbv_buffer_size, kernel-ignored, non-blocking).

Phase 1 → Phase 7 scoreboard:

  Criterion 1 (vainfo MPEG-2 Simple+Main enum):           PASS
  Criterion 2 (vaCreateConfig SUCCESS for MPEG2Main):     PASS
    Pre-iter1: VA_STATUS_ERROR_UNSUPPORTED_PROFILE (12)
    Post-iter1: VA_STATUS_SUCCESS (verified verbatim libva trace)
  Criterion 3 (ffmpeg-hwaccel-vaapi engages backend):     PASS
    5 frames decoded, exit 0, no Failed-to-create lines,
    no S_EXT_CTRLS EINVAL on the MPEG-2 path
  Criterion 4 (DMA-BUF GL HW=SW byte-identical at +02s):  PASS
    HW frame 1: 6e7873030dbf0403c67f35dd106ebef3c7909a0fd12433b82ad758e7fee9f092
    SW frame 1: 6e7873030dbf0403c67f35dd106ebef3c7909a0fd12433b82ad758e7fee9f092
    HW frame 2: ccc7ce08810d4a96e9ba7a19f4f95bbf6cc861bda9337604b5c668ad52bef7de
    SW frame 2: ccc7ce08810d4a96e9ba7a19f4f95bbf6cc861bda9337604b5c668ad52bef7de
    Frames 1 vs 2 differ in size (real motion).
  Criterion 5 (T4 H.264 reference hashes match):          PASS
    HW + SW frames at +30s into bbb_1080p30_h264.mp4 match
    f623d5f7... and 7d7bc6f2... exactly. No H.264 regression.

Bonus byte-compare against Phase 3 Baseline C verbatim:

  count=3, ctrl_class=V4L2_CTRL_CLASS_CODEC_STATELESS=0xf010000:
    SEQUENCE     id=0xa409dc size=12   (matches)
    PICTURE      id=0xa409dd size=32   (matches structurally)
    QUANTISATION id=0xa409de size=256  (intra matrix bytes
                                        IDENTICAL to Baseline C
                                        verbatim 64 bytes;
                                        non_intra all 16's)
    All return = 0 (kernel accepts every batched call).

  One numerical divergence: sequence.vbv_buffer_size
    post-fix:    0x100000 = 1 048 576 (= SOURCE_SIZE_MAX)
    Baseline C:  0x151800 = 1 376 256 (= negotiated sizeimage)
    Kernel ignores per v4l2-controls.h:2003 (informational).
    Decode is bit-exact correct regardless. Phase 5 reviewer S2
    was numerically prescient; my Phase 5 response (rejected with
    "slot->size = sizeimage") was wrong empirically; operational
    impact nil. Tracked as low-priority post-iter1 polish.

Phase 7 → Phase 8: clean transition, no loopback to Phase 4.

Notable observations for Phase 8 memory update:

  1. V4L2 /dev/videoN numbering shuffles across reboots on RK3399.
     Phase 0/3 had rkvdec=video3+media1, hantro=video5+media2; this
     boot has rkvdec=video1+media0, hantro=video3+media1. Phase 1
     binding cells using fixed paths fragile across reboots. Phase
     4 cross-cutting fix candidate: backend probes /dev/media* for
     driver=hantro-vpu/rkvdec rather than env-var stability.

  2. iter1 patch-0011 cache-stale bug class also affects MPEG-2
     (verified empirically; same as H.264 in T4). vaDeriveImage
     readback returns all-zero NV12 via ffmpeg-vaapi+hwdownload.
     Workaround: DMA-BUF GL import (mpv --vo=image) is cache-
     coherency-safe. Phase 4 cross-cutting fix candidate: add
     VIDIOC_EXPBUF + DMA_BUF_IOCTL_SYNC support to libva backend
     image-export path.

  3. src/context.c:142-155 H.264 device-init logs noisy EINVAL on
     hantro every CreateContext (return value cast to (void) but
     v4l2.c:484 still calls request_log). Cosmetic suppression
     candidate; low priority.

  4. Phase 6 commit D (fix-forward for missed mpeg2-ctrls.h
     include in context.c) — Phase 2 grep audit was incomplete.
     Phase 8 lesson: when deleting a header, completeness check
     is git rm + clean rebuild, not grep alone.

Campaign scoreboard: 1/5 → 2/5 codecs passing
(H.264 in T4, MPEG-2 in iter1). Iter1 advances to Phase 8.

Refs:
  ../libva-v4l2-request-fourier@229d6d1 (the fork tip verified)
  phase4_iter1_plan.md (criteria as locked, including Phase 5
                        amendments to criterion 3 + criterion 4)
  phase5_iter1_review.md (S2 partial-correct; S3, Q4, Q5
                          confirmed empirically)

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

233 lines
16 KiB
Markdown
Raw Permalink 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.
# Iteration 1 — Phase 7 (verification measurements)
Phase 7 verification of the iter1 MPEG-2 fix, executed 2026-05-08 against fork tip `229d6d1` on `git.reauktion.de/marfrit/libva-v4l2-request-fourier`. All five Phase 1 criteria green. Bonus byte-compare against Baseline C confirms structural match with one numerical divergence in an informational field (vbv_buffer_size; kernel ignores; decode is bit-exact correct regardless).
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/iter1_phase7/`](phase0_evidence/2026-05-08/iter1_phase7/).
## Pre-flight: rig state
```
$ ssh fresnel 'cd ~/src/libva-v4l2-request-fourier; git status -sb; git log --oneline -1'
## master...origin/master [ahead 4]
229d6d1 fresnel-fourier iter1 Phase 6 commit D: drop missed mpeg2-ctrls.h include from context.c
```
(The `[ahead 4]` is a stale local-tracking artifact: I pushed via the explicit HTTPS+token URL, not via `origin`. gitea has all four commits — verified by the push output `65969da..3aab187` then `3aab187..229d6d1`.)
```
$ sha256sum /usr/lib/dri/v4l2_request_drv_video.so build/src/v4l2_request_drv_video.so
5fb7212ce9c0408401030971f90c0609aec867ede24e320086ff845bd1a2476a /usr/lib/dri/v4l2_request_drv_video.so
5fb7212ce9c0408401030971f90c0609aec867ede24e320086ff845bd1a2476a build/src/v4l2_request_drv_video.so
```
Same hash both sides — install matches build.
**Device numbering this boot** (changed across reboot from Phase 0/3):
| Driver | This boot | Phase 0/3 boot |
|---|---|---|
| rkvdec | `/dev/video1` + `/dev/media0` | `/dev/video3` + `/dev/media1` |
| hantro-vpu-dec | `/dev/video3` + `/dev/media1` | `/dev/video5` + `/dev/media2` |
V4L2 device-number assignment depends on driver-init order, which can shuffle boot-to-boot. Phase 1 binding cells using fixed device paths are fragile; flagged for Phase 8 (memory + iter2+ scope: backend should probe `/dev/media*` for `driver=hantro-vpu` / `rkvdec` rather than rely on env-var device-number stability).
## Criterion 1 — vainfo enumeration regression check
**Goal**: vainfo continues to list `VAProfileMPEG2Simple` + `VAProfileMPEG2Main` on the hantro env binding (proves enumerator wasn't broken by iter1 patches).
**Verbatim output** ([`criterion1_vainfo.txt`](phase0_evidence/2026-05-08/iter1_phase7/criterion1_vainfo.txt)):
```
$ LIBVA_DRIVER_NAME=v4l2_request \
LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video3 \
LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media1 \
vainfo --display drm --device /dev/dri/renderD128
Trying display: drm
vainfo: VA-API version: 1.23 (libva 2.22.0)
vainfo: Driver version: v4l2-request
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointVLD
```
**Result: ✅ PASS.** Both profiles present with VAEntrypointVLD.
## Criterion 2 — vaCreateConfig succeeds
**Goal**: `vaCreateConfig(VAProfileMPEG2Main, VAEntrypointVLD)` returns `VA_STATUS_SUCCESS`. (Pre-iter1 returned `12 = VA_STATUS_ERROR_UNSUPPORTED_PROFILE` per Phase 3 Baseline A.)
**Verbatim libva trace** (extract from `criterion2_3/libva.trace.083913.thd-0x000017e9`):
```
[41265.157833][ctx none]=========vaQueryConfigProfiles ret = VA_STATUS_SUCCESS, success (no error)
[41265.157884][ctx none]==========va_TraceCreateConfig
[41265.157888][ctx none] profile = 1, VAProfileMPEG2Main
[41265.157891][ctx none] entrypoint = 1, VAEntrypointVLD
[41265.157894][ctx none] num_attribs = 0
[41265.157946][ctx none]=========vaCreateConfig ret = VA_STATUS_SUCCESS, success (no error)
```
**Result: ✅ PASS.** `vaCreateConfig` returned `VA_STATUS_SUCCESS` for `VAProfileMPEG2Main` (was failing with code 12 in Phase 3 Baseline A).
## Criterion 3 — End-to-end decode engages backend (adjusted Phase 1 wording)
**Goal** (Phase 4-amended, Phase 5-confirmed): `ffmpeg -hwaccel vaapi -i bbb_720p10s_mpeg2.ts -frames:v N -f null -` shows the libva chain in stderr, no `Failed to create decode configuration`, no `EINVAL` from `VIDIOC_S_EXT_CTRLS`, exits 0.
**Verbatim ffmpeg log** ([`criterion2_3/ffmpeg.stdout`](phase0_evidence/2026-05-08/iter1_phase7/criterion2_3/ffmpeg.stdout)):
```
Input #0, mpegts, from '/home/mfritsche/fourier-test/bbb_720p10s_mpeg2.ts':
Stream #0:0[0x100]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv, bt709, progressive), 1280x720
Stream mapping:
Stream #0:0 -> #0:0 (mpeg2video (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)
v4l2-request: Unable to set control(s): Invalid argument
Output #0, null, to 'pipe:':
Stream #0:0: Video: wrapped_avframe, nv12(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9]
frame= 5 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.20 bitrate=N/A speed=1.46x elapsed=0:00:00.14
[ffmpeg exit 0]
```
**Greps**:
- `Failed to create decode configuration`: 0 hits.
- `S_EXT_CTRLS.*EINVAL` (in libva trace): 0 hits.
**Result: ✅ PASS.** ffmpeg processed 5 frames cleanly, exit 0. The `v4l2-request: Unable to set control(s): Invalid argument` line is the documented auxiliary noise from `src/context.c:142-155` (H.264 device-init unconditionally on every CreateContext, return value cast to `(void)` and discarded). It does NOT come from the MPEG-2 path; my MPEG-2 batched `S_EXT_CTRLS count=3` calls all return 0 (verified verbatim in the bonus byte-compare below).
## Criterion 4 — DMA-BUF GL pixel verify (HW=SW byte-identical at +02s)
**Goal** (Phase 5-amended): `mpv --hwdec=vaapi --vo=image` (DMA-BUF GL import path) at `--start=00:00:02` produces 2 distinct frames whose hashes are byte-identical to a software-decoded reference for the same fixture.
(Phase 5 Q4 amendment specified `ffmpeg+hwdownload` as primary, but Phase 6 empirically showed that path returns all-zero NV12 because of the iter1 patch-0011 cache-stale class on RK3399. Per the pre-identified fall-forward in Phase 4 plan, mpv-vaapi-vo=image is the cache-coherency-safe verifier — confirmed in T4 for H.264, now confirmed for MPEG-2.)
**Verbatim hash output** ([`criterion4/hashes.txt`](phase0_evidence/2026-05-08/iter1_phase7/criterion4/hashes.txt)):
```
6e7873030dbf0403c67f35dd106ebef3c7909a0fd12433b82ad758e7fee9f092 /tmp/iter1_phase7/criterion4/png_hw/00000001.jpg
ccc7ce08810d4a96e9ba7a19f4f95bbf6cc861bda9337604b5c668ad52bef7de /tmp/iter1_phase7/criterion4/png_hw/00000002.jpg
6e7873030dbf0403c67f35dd106ebef3c7909a0fd12433b82ad758e7fee9f092 /tmp/iter1_phase7/criterion4/png_sw/00000001.jpg
ccc7ce08810d4a96e9ba7a19f4f95bbf6cc861bda9337604b5c668ad52bef7de /tmp/iter1_phase7/criterion4/png_sw/00000002.jpg
```
| Check | Result |
|---|---|
| HW frame 1 == SW frame 1 (`6e7873030dbf...`) | ✅ PASS |
| HW frame 2 == SW frame 2 (`ccc7ce08810d...`) | ✅ PASS |
| frame 1 != frame 2 (real motion) | ✅ PASS |
**Result: ✅ PASS.** MPEG-2 hardware decode on RK3399 / hantro-vpu-dec / libva-v4l2-request-fourier produces pixels bit-exact identical to software reference, when read via the cache-coherency-safe DMA-BUF GL import path.
JPEG file sizes: 160522 + 178975 bytes — different sizes confirm content variation (real bunny motion at +02s seek into the fixture, not solid color).
## Criterion 5 — H.264 regression check (T4 reference hashes)
**Goal**: Re-run T4's reference incantation against `bbb_1080p30_h264.mp4` at `+30s` seek. HW + SW hashes must match the T4 reference values exactly:
- `f623d5f7a41697f67dd227275c6f1b21ffc257f65626d32fde8229357f8764c9` (frame 1)
- `7d7bc6f2146dda8b2d223bba622c4b9fbe9674181ff1e02afe286b620342e0a8` (frame 2)
(Note: this boot routes rkvdec at `/dev/video1` + `/dev/media0`, not `/dev/video3` + `/dev/media1` like Phase 0/T4. Path adjusted accordingly.)
**Verbatim hash output** ([`criterion5/hashes.txt`](phase0_evidence/2026-05-08/iter1_phase7/criterion5/hashes.txt)):
```
f623d5f7a41697f67dd227275c6f1b21ffc257f65626d32fde8229357f8764c9 /tmp/iter1_phase7/criterion5/png_hw/00000001.jpg
7d7bc6f2146dda8b2d223bba622c4b9fbe9674181ff1e02afe286b620342e0a8 /tmp/iter1_phase7/criterion5/png_hw/00000002.jpg
f623d5f7a41697f67dd227275c6f1b21ffc257f65626d32fde8229357f8764c9 /tmp/iter1_phase7/criterion5/png_sw/00000001.jpg
7d7bc6f2146dda8b2d223bba622c4b9fbe9674181ff1e02afe286b620342e0a8 /tmp/iter1_phase7/criterion5/png_sw/00000002.jpg
```
| Check | Result |
|---|---|
| HW frame 1 == T4 reference (`f623d5f7...`) | ✅ PASS |
| HW frame 2 == T4 reference (`7d7bc6f2...`) | ✅ PASS |
| SW frame 1 == T4 reference | ✅ PASS |
| SW frame 2 == T4 reference | ✅ PASS |
**Result: ✅ PASS.** Iter1's MPEG-2 fix doesn't regress H.264. Both HW and SW H.264 paths produce bit-identical pixels to T4 reference.
## Bonus — byte-compare post-fix VIDIOC_S_EXT_CTRLS payload vs Baseline C
**Goal**: Confirm the post-fix V4L2 traffic from our libva backend is structurally indistinguishable from the cross-validator's (ffmpeg-v4l2request) reference per Phase 4 plan: `count=3, ctrl_class=0xf010000`, three CIDs in order, sizes 12 / 32 / 256, with field values matching what VAAPI's `VAPictureParameterBufferMPEG2` and `VAIQMatrixBufferMPEG2` carry for the same fixture.
**Verbatim post-fix call** (frame 1, from `bonus/postfix_frame1.txt`):
```
ioctl(5</dev/video3>, VIDIOC_S_EXT_CTRLS,
{ctrl_class=0xf010000 /* V4L2_CTRL_CLASS_CODEC_STATELESS */,
count=3,
controls=[
{id=0xa409dc /* SEQUENCE */, size=12, string="\0\5\320\2\0\0\20\0\0\0\1\1"},
{id=0xa409dd /* PICTURE */, size=32, string="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\202\0\0\0\17\17\17\17\1\3\0\0\0\0\0\0"},
{id=0xa409de /* QUANTISATION */, size=256, string="\10\20\20\23\20\23\26\26\26\26\26\26..."}
]}) = 0
```
**Decoded SEQUENCE field values** (post-fix vs Baseline C):
| Field | Post-fix | Baseline C | Match |
|---|---|---|---|
| `horizontal_size` | 1280 | 1280 | ✅ |
| `vertical_size` | 720 | 720 | ✅ |
| `vbv_buffer_size` | 0x100000 (1 048 576) | 0x151800 (1 376 256) | ❌ differ |
| `profile_and_level_indication` | 0 | 0 | ✅ |
| `chroma_format` | 1 (4:2:0) | 1 (4:2:0) | ✅ |
| `flags` | 0x01 (PROGRESSIVE) | 0x01 (PROGRESSIVE) | ✅ |
**Decoded QUANTISATION** (post-fix):
- `intra[0:8] = [8, 16, 16, 19, 16, 19, 22, 22]`
- `intra[60:64] = [58, 69, 69, 83]`
- `non_intra` all 16's: `True`
- `intra_matrix == Baseline C verbatim 64 bytes`: **`True`**
**Decoded PICTURE** (post-fix, frame 1 = I-frame):
- size 12 + 32 + 256 = 300 bytes total payload, matches Baseline C's per-frame 12+32+256 = 300 byte layout exactly.
- I-frame structural fields: `forward_ref_ts = backward_ref_ts = 0`, `flags = 0x82 (FRAME_PRED_DCT | PROGRESSIVE)`, `f_code = 0xF×4`, `picture_coding_type = 1 (I)`, `picture_structure = 3 (FRAME)` — all match Baseline C frame 1 verbatim.
### vbv_buffer_size divergence (informational, non-blocking)
The single field divergence is `sequence.vbv_buffer_size`: our backend sends 0x100000 (1 MB = `SOURCE_SIZE_MAX`), Baseline C's ffmpeg-v4l2request sends 0x151800 (1.31 MB = bbb fixture's negotiated `sizeimage`).
This **partially confirms Phase 5 reviewer's S2 finding** (which I marked "rejected" in the Phase 5 review response on the assumption that `slot->size = sizeimage = 1382400`). Empirically the libva backend's `surface_object->source_size` resolves to 1 MB, not 1382400 — meaning either:
(a) The backend's `S_FMT(OUTPUT_MPLANE)` set `sizeimage = SOURCE_SIZE_MAX` (1 MB) and the kernel's `QUERYBUF` returned that value back through `slot->size` in `request_pool.c:71` rather than re-negotiating to the fixture's actual 1.31 MB.
(b) Some other code path in the iter6/7/8 OUTPUT-pool changes made `slot->size` resolve to a constant.
Source-read deferred (would require reading `request_pool.c` + `v4l2_create_buffers` paths in detail; this Phase 7 already passes pixel-correct on the boolean criterion, so this is non-blocking informational data).
**Kernel ignores `vbv_buffer_size`** per the kernel doc (`v4l2-controls.h:2003`: "vbv_buffer_size: combination of elements vbv_buffer_size_value and vbv_buffer_size_extension" — informational, no validation logic in `hantro_mpeg2.c`). Decode is bit-exact correct (criterion 4 confirms). Net: reviewer's S2 was numerically prescient; my Phase 5 response was wrong about the slot->size = sizeimage equivalence; the operational impact is nil. Worth correcting in `phase5_iter1_review.md` for the historical record.
**Phase 8 backlog item** (low priority): track down why `surface_object->source_size = 1 MB` not 1.31 MB. Either fix the libva backend's S_FMT to negotiate, or accept the 1 MB hardcoded value as fine since kernel ignores it. Almost certainly post-iter1 polish.
## Phase 1 → Phase 7 scoreboard
| Criterion | Pre-iter1 (Phase 3 baseline) | Post-iter1 (Phase 7 verification) | Verdict |
|---|---|---|---|
| 1: vainfo enumerates MPEG-2 Simple+Main | ✓ already (config.c:126-127 unconditional) | ✓ unchanged | ✅ PASS |
| 2: vaCreateConfig succeeds | ✗ ret = 12 UNSUPPORTED_PROFILE | ✓ ret = VA_STATUS_SUCCESS | ✅ PASS |
| 3: ffmpeg engages backend, exit 0 | ✗ Failed to create decode configuration | ✓ frame=5, exit 0, no errors | ✅ PASS |
| 4: DMA-BUF GL HW=SW byte-identical at +02s | n/a (couldn't reach decode) | ✓ HW frame 1 = SW frame 1, HW frame 2 = SW frame 2, frame 1 ≠ frame 2 | ✅ PASS |
| 5: T4 H.264 reference hashes still match | ✓ baseline | ✓ HW + SW match `f623d5f7...` and `7d7bc6f2...` exactly | ✅ 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. **V4L2 device-numbering shuffles across reboots** on RK3399. Hardcoded env-var paths are fragile. iter2+ Phase 4 cross-cutting fix candidate: backend probes `/dev/media*` for `driver=hantro-vpu` / `rkvdec` rather than relying on env-var stability.
2. **iter1 patch-0011 cache-stale bug class also affects MPEG-2** (not just H.264 from T4). The libva backend's `vaDeriveImage` path returns all-zero NV12 on RK3399 when ffmpeg-vaapi+hwdownload is the readback path. **Workaround**: pixel verification must use DMA-BUF GL import (mpv `--vo=image`), not `vaDeriveImage` / cached mmap. **Phase 4 cross-cutting fix candidate**: add `VIDIOC_EXPBUF` + `DMA_BUF_IOCTL_SYNC` support to the libva backend's image-export path. Tracked separately from per-codec iterations.
3. **`src/context.c:142-155` H.264 device-init produces a noisy EINVAL on hantro** every CreateContext. Documented as auxiliary in Phase 3; intentional best-effort behavior. The `request_log("Unable to set control(s): %s\n", strerror(errno))` from `src/v4l2.c:484` fires unconditionally even though the caller cast the return to `(void)`. Cosmetic fix candidate (suppress the log when called with intent to silently fail), low priority.
4. **vbv_buffer_size discrepancy** (1 MB vs negotiated 1.31 MB) — informational divergence, kernel ignores. Post-iter1 polish item.
5. **The Phase 6 → Phase 4 fix-forward (Commit D)** was caused by an incomplete Phase 2 grep audit (`#include <mpeg2-ctrls.h>` was in three files; Phase 2 found two). **Phase 8 lesson**: when deleting a header, the authoritative completeness check is `git rm` followed by clean rebuild — not grep alone. Surfaced in Commit D message; lock into memory at iter1 close.
6. **Phase 5 reviewer's S2 was right after all** about the vbv_buffer_size numerical mismatch. My Phase 5 response that "slot->size = sizeimage = 1382400, exactly matches Baseline C" was wrong — empirically slot->size = 1 MB. Worth correcting in `phase5_iter1_review.md` for the historical record (operational impact: nil; kernel ignores the field).
## Phase 7 close
Phase 7 → Phase 8 transition. iter1 advances to memory-update phase. Second-codec passing on the campaign-level scoreboard: 1/5 → **2/5** (H.264 + MPEG-2).