kernel + daemon: revert PRs #7 + #8 (parking design incompatible with V4L2 stateless 1:1 expectation) #10

Merged
marfrit merged 2 commits from noether/revert-parking-pr7-pr8 into main 2026-05-21 13:39:09 +00:00
Owner

Why

Field test of #7 + #8 on higgs (Pi CM5) via mpv --hwdec=vaapi-copy bbb_720p_h264.mp4 reproduces issue #9: mpv shows a black window and exits with

v4l2-request: Unable to dequeue buffer: Resource temporarily unavailable
[ffmpeg/video] h264: Failed to end picture decode issue: 1 (operation failed).
Attempting next decoding method after failure of h264-vaapi-copy.

Daemon journal confirms each REQ_DECODE is processed successfully — pixels are produced — but they arrive on a DIFFERENT cookie's CAPTURE buffer than the one mpv just submitted on. Specifically:

Cookie src_pts in OK frame's src_pts
1 1000 1000 ✓
2 2000 (none) ← libavcodec EAGAIN; dst[2] parked
3 3000 3000 ✓
4 4000 2000 ← cookie 2's frame finally emerges, lands in dst[2]
5 5000 4000
... ... (steady-state lag of 1 cookie)

Root cause

The V4L2 stateless decoder protocol contract is 1:1: every OUTPUT (bitstream) buffer submitted must produce exactly one CAPTURE (pixels) completion, with the kernel/decoder responsible for filling the matching CAPTURE buffer immediately. The userspace V4L2 client (libva-v4l2-request-fourier) is responsible for display-order reordering using H.264 POC values after it dequeues the CAPTURE buffers. Real HW stateless decoders (cedrus / rkvdec / hantro) decode a slice into a designated DPB CAPTURE buffer and complete it immediately, regardless of display order.

PR #7's design parked CAPTURE buffers for cookies whose pixels libavcodec hadn't yet released for display-order output. That violated the 1:1 contract: cookie M's CAPTURE buffer wouldn't complete until N requests later, leaving libva / mpv DQBUF returning EAGAIN. Firefox tolerated the resulting stale-pixel mess (which produced the visible "2 1 4 3 6 5" frame pairing the user originally reported); mpv does not — its hwaccel propagates the DQBUF EAGAIN as a hard decode failure and gives up.

PR #8 fixed the kernel panic that #7's parking model caused, but did not address the architectural mismatch.

What stays

This revert leaves only PR #4 (DECODE_MODE + START_CODE menu controls) on top of f0d4186. PR #4 is independent — it just retires the cosmetic Unable to set control(s) error_idx=2/2 warning — and stays. Last fully-working pin is now 714d781 (this revert's tip), behaviour-equivalent to f0d4186 plus PR #4.

What's next

The proper fix is option 3 in the issue #9 thread: re-architect the daemon for concurrent in-flight requests + move H.264 display-order reorder back into libva-v4l2-request-fourier where the V4L2 stateless API expects it. Multi-day effort, separate issue. Userspace daemon as it stands cannot honor 1:1 without that work, so the visible "2 1 4 3" pairing in Firefox YouTube playback returns — accepted regression in exchange for unblocking mpv and other strict V4L2 stateless clients.

Verified

  • Diff vs f0d4186 is exactly the PR #4 changes (kernel/daedalus_v4l2_main.c: H.264 menu ctrls registration + handler init +2 capacity bump). No other deltas.
  • Builds clean cross-compiled on higgs against 6.18.29+rpt-rpi-2712.
  • Field test pending — needs marfrit-packages bump to 714d781 (lock-step kernel + daemon, both revert to f0d4186-content; PROTO_VERSION drops 1 → 0 wire-compatibly when both halves install together).
## Why Field test of #7 + #8 on higgs (Pi CM5) via `mpv --hwdec=vaapi-copy bbb_720p_h264.mp4` reproduces issue #9: mpv shows a black window and exits with ``` v4l2-request: Unable to dequeue buffer: Resource temporarily unavailable [ffmpeg/video] h264: Failed to end picture decode issue: 1 (operation failed). Attempting next decoding method after failure of h264-vaapi-copy. ``` Daemon journal confirms each REQ_DECODE is processed successfully — pixels are produced — but they arrive on a DIFFERENT cookie's CAPTURE buffer than the one mpv just submitted on. Specifically: | Cookie | src_pts in | OK frame's src_pts | |---|---|---| | 1 | 1000 | 1000 ✓ | | 2 | 2000 | (none) ← libavcodec EAGAIN; dst[2] parked | | 3 | 3000 | 3000 ✓ | | 4 | 4000 | 2000 ← cookie 2's frame finally emerges, lands in dst[2] | | 5 | 5000 | 4000 | | ... | ... | (steady-state lag of 1 cookie) | ## Root cause **The V4L2 stateless decoder protocol contract is 1:1**: every OUTPUT (bitstream) buffer submitted must produce exactly one CAPTURE (pixels) completion, with the kernel/decoder responsible for filling the matching CAPTURE buffer immediately. The userspace V4L2 client (libva-v4l2-request-fourier) is responsible for *display-order reordering* using H.264 POC values *after* it dequeues the CAPTURE buffers. Real HW stateless decoders (cedrus / rkvdec / hantro) decode a slice into a designated DPB CAPTURE buffer and complete it immediately, regardless of display order. PR #7's design parked CAPTURE buffers for cookies whose pixels libavcodec hadn't yet released for display-order output. That violated the 1:1 contract: cookie M's CAPTURE buffer wouldn't complete until N requests later, leaving libva / mpv DQBUF returning EAGAIN. Firefox tolerated the resulting stale-pixel mess (which produced the visible "2 1 4 3 6 5" frame pairing the user originally reported); mpv does not — its hwaccel propagates the DQBUF EAGAIN as a hard decode failure and gives up. PR #8 fixed the kernel panic that #7's parking model caused, but did not address the architectural mismatch. ## What stays This revert leaves only PR #4 (DECODE_MODE + START_CODE menu controls) on top of `f0d4186`. PR #4 is independent — it just retires the cosmetic `Unable to set control(s) error_idx=2/2` warning — and stays. Last fully-working pin is now `714d781` (this revert's tip), behaviour-equivalent to `f0d4186` plus PR #4. ## What's next The proper fix is option 3 in the issue #9 thread: re-architect the daemon for concurrent in-flight requests + move H.264 display-order reorder back into `libva-v4l2-request-fourier` where the V4L2 stateless API expects it. Multi-day effort, separate issue. Userspace daemon as it stands cannot honor 1:1 without that work, so the visible "2 1 4 3" pairing in Firefox YouTube playback returns — accepted regression in exchange for unblocking mpv and other strict V4L2 stateless clients. ## Verified - Diff vs `f0d4186` is exactly the PR #4 changes (kernel/daedalus_v4l2_main.c: H.264 menu ctrls registration + handler init `+2` capacity bump). No other deltas. - Builds clean cross-compiled on higgs against `6.18.29+rpt-rpi-2712`. - Field test pending — needs marfrit-packages bump to `714d781` (lock-step kernel + daemon, both revert to f0d4186-content; PROTO_VERSION drops 1 → 0 wire-compatibly when both halves install together).
marfrit added 2 commits 2026-05-21 12:42:03 +00:00
marfrit merged commit 5d8b4369e5 into main 2026-05-21 13:39:09 +00:00
marfrit deleted branch noether/revert-parking-pr7-pr8 2026-05-21 13:39:09 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: reauktion/daedalus-v4l2#10