ffmpeg-v4l2-request-git: rebase onto Kwiboo v4l2request-2024-v2-rkvdec branch for H.264 High10 / HEVC Main10 userspace support #21

Closed
opened 2026-05-17 16:48:30 +00:00 by claude-noether · 1 comment
Contributor

Summary

Current arch/ffmpeg-v4l2-request-git/PKGBUILD pins _commit='b57fbbe50c9b2656fad86a1a7eeabfd2b2a50935' on https://github.com/Kwiboo/FFmpeg branch v4l2-request-n8.1 (FFmpeg 8.1 tip, 2026-04-24). That branch does not include the userspace plumbing for H.264 High10 (Hi10P) or HEVC Main10 V4L2 stateless decode through the rkvdec path.

Evidence

Empirical cross-test 2026-05-17 on fresnel (RK3399) + ampere (RK3588):

  • ffmpeg -hwaccel v4l2request -hwaccel_output_format drm_prime -i bbb_hi10p.mp4 ... returns Task finished with error code: -22 (Invalid argument), writes 0 bytes.
  • Same fixture decoded via -c copy SW reference produces real content (222 unique luma values).
  • Kernel side IS ready: linux-fresnel-fourier 7.0-14 (mmind v7.0 baseline) has Karlman v6+ patches in rkvdec — rkvdec_h264_decoded_fmts[] includes NV15/NV20, ctrl cfg.max=HIGH_422_INTRA, bit_depth path live.
  • Our libva backend (marfrit/libva-v4l2-request-fourier) has full Hi10P/Main10 wiring (iter39 series, commit 662f887 + Phase 7 fixes) — verified by S_FMT(CAPTURE, NV15) succeeding with sizeimage=2188800. But our backend ALSO fails (returns all-zero CAPTURE) because ffmpeg-vaapi doesn't expose 10-bit surface attributes correctly without ffmpeg-side patches.

Recipe (per Kwiboo's gist)

Kwiboo published the exact branch combo for Hi10P support at https://gist.github.com/Kwiboo/f4ac15576b2c72887ae2bc5d58b5c865:

Kernel: https://github.com/Kwiboo/linux-rockchip — branch linuxtv-rkvdec-high-10-v6
FFmpeg: https://github.com/Kwiboo/FFmpeg     — branch v4l2request-2024-v2-rkvdec

Validated to 65/69 JVT-AVC_V1 conformance tests passing on ROCK Pi 4 (RK3399).

Suggested changes

Option A — switch to the rkvdec branch:

_commit='<tip-of-v4l2request-2024-v2-rkvdec>'
url='https://github.com/Kwiboo/FFmpeg'
source=(... 'git+${url}#branch=v4l2request-2024-v2-rkvdec')

Tradeoff: that branch is on FFmpeg 4.x-era (older); loses BROADCOM_SAND128 / AFBC_16X16 / latest decoder features that n8.1 has.

Option B — cherry-pick the Hi10P userspace commits from v4l2request-2024-v2-rkvdec onto our v4l2-request-n8.1 pin. Need to identify the relevant subset (NV15 stride handling, image_fmt-aware decoder selection, 10-bit surface attribute reporting). Requires the upstream rebase work.

Option C — wait for Kwiboo to merge Hi10P into the n-line branches. Track upstream activity.

Recommend Option B for the campaign — keeps the newer ffmpeg + adds the Hi10P plumbing. Cross-referenced issue: marfrit/libva-v4l2-request-fourier#4 ("Hi10P + Main10 enumeration: Option B applied iter39").

Closing the loop

When this is done:

  • ffmpeg -hwaccel v4l2request -hwaccel_output_format drm_prime -i bbb_hi10p.mp4 -vf hwdownload,format=p010le -frames:v 5 -f rawvideo /tmp/k.yuv produces non-zero, real-content output on fresnel.
  • Re-enable Hi10P/Main10 enumeration in marfrit/libva-v4l2-request-fourier::RequestQueryConfigProfiles (uncomment two profiles[index++] lines, bump H264 guard from -5 to -6).
  • Phase 7 test rig (fresnel-fourier/phase7_iter39_test_rig.sh) PASSes.

References

## Summary Current `arch/ffmpeg-v4l2-request-git/PKGBUILD` pins `_commit='b57fbbe50c9b2656fad86a1a7eeabfd2b2a50935'` on `https://github.com/Kwiboo/FFmpeg` branch `v4l2-request-n8.1` (FFmpeg 8.1 tip, 2026-04-24). That branch does **not** include the userspace plumbing for H.264 High10 (Hi10P) or HEVC Main10 V4L2 stateless decode through the rkvdec path. ## Evidence Empirical cross-test 2026-05-17 on fresnel (RK3399) + ampere (RK3588): - `ffmpeg -hwaccel v4l2request -hwaccel_output_format drm_prime -i bbb_hi10p.mp4 ...` returns `Task finished with error code: -22 (Invalid argument)`, writes 0 bytes. - Same fixture decoded via `-c copy` SW reference produces real content (222 unique luma values). - Kernel side IS ready: `linux-fresnel-fourier 7.0-14` (mmind v7.0 baseline) has Karlman v6+ patches in rkvdec — `rkvdec_h264_decoded_fmts[]` includes NV15/NV20, ctrl `cfg.max=HIGH_422_INTRA`, bit_depth path live. - Our libva backend (`marfrit/libva-v4l2-request-fourier`) has full Hi10P/Main10 wiring (iter39 series, commit `662f887` + Phase 7 fixes) — verified by S_FMT(CAPTURE, NV15) succeeding with `sizeimage=2188800`. But our backend ALSO fails (returns all-zero CAPTURE) because ffmpeg-vaapi doesn't expose 10-bit surface attributes correctly without ffmpeg-side patches. ## Recipe (per Kwiboo's gist) Kwiboo published the exact branch combo for Hi10P support at https://gist.github.com/Kwiboo/f4ac15576b2c72887ae2bc5d58b5c865: ``` Kernel: https://github.com/Kwiboo/linux-rockchip — branch linuxtv-rkvdec-high-10-v6 FFmpeg: https://github.com/Kwiboo/FFmpeg — branch v4l2request-2024-v2-rkvdec ``` Validated to 65/69 JVT-AVC_V1 conformance tests passing on ROCK Pi 4 (RK3399). ## Suggested changes Option A — switch to the rkvdec branch: ``` _commit='<tip-of-v4l2request-2024-v2-rkvdec>' url='https://github.com/Kwiboo/FFmpeg' source=(... 'git+${url}#branch=v4l2request-2024-v2-rkvdec') ``` Tradeoff: that branch is on FFmpeg 4.x-era (older); loses BROADCOM_SAND128 / AFBC_16X16 / latest decoder features that n8.1 has. Option B — cherry-pick the Hi10P userspace commits from `v4l2request-2024-v2-rkvdec` onto our `v4l2-request-n8.1` pin. Need to identify the relevant subset (NV15 stride handling, image_fmt-aware decoder selection, 10-bit surface attribute reporting). Requires the upstream rebase work. Option C — wait for Kwiboo to merge Hi10P into the n-line branches. Track upstream activity. Recommend **Option B** for the campaign — keeps the newer ffmpeg + adds the Hi10P plumbing. Cross-referenced issue: `marfrit/libva-v4l2-request-fourier#4` ("Hi10P + Main10 enumeration: Option B applied iter39"). ## Closing the loop When this is done: - `ffmpeg -hwaccel v4l2request -hwaccel_output_format drm_prime -i bbb_hi10p.mp4 -vf hwdownload,format=p010le -frames:v 5 -f rawvideo /tmp/k.yuv` produces non-zero, real-content output on fresnel. - Re-enable Hi10P/Main10 enumeration in `marfrit/libva-v4l2-request-fourier::RequestQueryConfigProfiles` (uncomment two `profiles[index++]` lines, bump H264 guard from `-5` to `-6`). - Phase 7 test rig (`fresnel-fourier/phase7_iter39_test_rig.sh`) PASSes. ## References - Kwiboo gist: https://gist.github.com/Kwiboo/f4ac15576b2c72887ae2bc5d58b5c865 - LWN summary of Karlman series: https://lwn.net/Articles/950434/ - Cross-issue: `marfrit/libva-v4l2-request-fourier#4` - Empirical evidence: `marfrit/fresnel-fourier:phase7_iter39_close.md` @ `a4855f7`
Author
Contributor

Fix landed via PR #260002-nv15-to-p010-unpack.patch on top of n8.1 (b57fbbe50c), bumping pkgrel 4 → 5.

TL;DR — the issue's premise was inverted

n8.1 already has more Hi10P / Main10 plumbing than v4l2request-2024-v2-rkvdec:

Capability n8.1 status
bit_depth propagation from H.264 SPS → frame_params present (v4l2_request_h264.c:511)
ff_v4l2_request_frame_params(pixelformat, bit_depth) signature present (vs. v2/v3-rkvdec's older (avctx, hw_frames_ctx))
bit-depth-aware capture format selection (NV15 over NV12 for 10-bit) present (hwcontext_v4l2request.c:253–300)
V4L2_PIX_FMT_NV15AV_PIX_FMT_YUV420P10 sw_format present
h264 slice context dec_ref_pic_marking_bit_size / pic_order_cnt_bit_size present (h264dec.h:325,334)
BROADCOM_SAND128 modifier (Pi 5) present (b57fbbe50c, Dec 2025)

The v2/v3-rkvdec branches are the older FFmpeg 7.1.1-era lineage; switching would have been a regression.

What actually broke

Reproduced on fresnel with -loglevel debug:

[AVHWFramesContext @ ...] Using V4L2 media driver rkvdec (7.0.0) for S264
[AVHWFramesContext @ ...] Using CAPTURE buffer format NV15 (1280x720)
[h264 @ ...] Reinit context to 1280x720, pix_fmt: drm_prime
... 2 frames decoded; 0 decode errors ...
[hwdownload @ ...] Invalid output format p010le for hwframe download.
[vf#0:0 @ ...] Task finished with error code: -22 (Invalid argument)

Kernel decode runs cleanly. The -22 EINVAL is from filter-graph init — v4l2request_transfer_get_formats (hwcontext_v4l2request.c:1076) deliberately blanks the format list for YUV420P10 sw_format. The author intended consumers to call av_hwframe_map + chain a swscale unpack, but hwdownload doesn't do that chaining. So NV15 surfaces decode fine but never reach userspace through the filter graph.

Verification

Test (fresnel, RK3399, linux-fresnel-fourier 7.0-14, pkgrel=5) Result
Issue's exact smoke test (-vf hwdownload,format=p010le, 5 frames) exit 0, 13,824,000 bytes (correct P010 size)
20-frame mid-fixture decode, HW vs SW reference bit-exact match sha=7d9b66d48d8f17b2281da1881c663ecc31722bb218aba1ae23bf28d07aa66b08
8-bit H.264 baseline (NV12 path) bit-exact HW==SW, no regression
Pre-patch (pkgrel=4) reproducer on ampere (RK3588) confirmed identical -22 EINVAL — cross-device, not RK3399-specific

The bit-exact 20-frame Hi10P result also overturns feedback_rk3399_h264_hi10p_advertised_not_functional: RK3399 rkvdec Hi10P is functional. The apparent "all-zero output" in the prior phase 7 close was the 5-frame fadein title card being correctly decoded as uniform black.

Closing-the-loop checklist (from issue body)

  • ffmpeg -hwaccel v4l2request -hwaccel_output_format drm_prime -i bbb_hi10p.mp4 -vf hwdownload,format=p010le ... produces non-zero, real-content output on fresnel
  • Re-enable Hi10P/Main10 in marfrit/libva-v4l2-request-fourier::RequestQueryConfigProfiles — separate ticket; libva backend has its own NV15 unpack already (src/nv15.c) but Hi10P/Main10 were dropped from the profile list in iter39 Option B based on the (now-overturned) "advertised not functional" finding. That needs its own re-verification pass on fresnel + ampere.
  • phase7_iter39_test_rig.sh PASS — separate run; requires the libva re-enable above first.

Closing once PR #26 merges.

Fix landed via PR #26 — `0002-nv15-to-p010-unpack.patch` on top of n8.1 (`b57fbbe50c`), bumping pkgrel 4 → 5. ## TL;DR — the issue's premise was inverted n8.1 already has more Hi10P / Main10 plumbing than `v4l2request-2024-v2-rkvdec`: | Capability | n8.1 status | |---|---| | `bit_depth` propagation from H.264 SPS → frame_params | present (`v4l2_request_h264.c:511`) | | `ff_v4l2_request_frame_params(pixelformat, bit_depth)` signature | present (vs. v2/v3-rkvdec's older `(avctx, hw_frames_ctx)`) | | bit-depth-aware capture format selection (NV15 over NV12 for 10-bit) | present (`hwcontext_v4l2request.c:253–300`) | | `V4L2_PIX_FMT_NV15` → `AV_PIX_FMT_YUV420P10` sw_format | present | | h264 slice context `dec_ref_pic_marking_bit_size` / `pic_order_cnt_bit_size` | present (`h264dec.h:325,334`) | | `BROADCOM_SAND128` modifier (Pi 5) | present (`b57fbbe50c`, Dec 2025) | The v2/v3-rkvdec branches are the **older** FFmpeg 7.1.1-era lineage; switching would have been a regression. ## What actually broke Reproduced on fresnel with `-loglevel debug`: ``` [AVHWFramesContext @ ...] Using V4L2 media driver rkvdec (7.0.0) for S264 [AVHWFramesContext @ ...] Using CAPTURE buffer format NV15 (1280x720) [h264 @ ...] Reinit context to 1280x720, pix_fmt: drm_prime ... 2 frames decoded; 0 decode errors ... [hwdownload @ ...] Invalid output format p010le for hwframe download. [vf#0:0 @ ...] Task finished with error code: -22 (Invalid argument) ``` Kernel decode runs cleanly. The `-22 EINVAL` is from filter-graph init — `v4l2request_transfer_get_formats` (`hwcontext_v4l2request.c:1076`) deliberately blanks the format list for `YUV420P10` sw_format. The author intended consumers to call `av_hwframe_map` + chain a swscale unpack, but `hwdownload` doesn't do that chaining. So NV15 surfaces decode fine but never reach userspace through the filter graph. ## Verification | Test (fresnel, RK3399, `linux-fresnel-fourier 7.0-14`, pkgrel=5) | Result | |---|---| | Issue's exact smoke test (`-vf hwdownload,format=p010le`, 5 frames) | exit 0, 13,824,000 bytes (correct P010 size) | | 20-frame mid-fixture decode, HW vs SW reference | **bit-exact match** `sha=7d9b66d48d8f17b2281da1881c663ecc31722bb218aba1ae23bf28d07aa66b08` | | 8-bit H.264 baseline (NV12 path) | bit-exact HW==SW, no regression | | Pre-patch (`pkgrel=4`) reproducer on ampere (RK3588) | confirmed identical -22 EINVAL — cross-device, not RK3399-specific | The bit-exact 20-frame Hi10P result **also overturns** `feedback_rk3399_h264_hi10p_advertised_not_functional`: RK3399 rkvdec Hi10P **is functional**. The apparent "all-zero output" in the prior phase 7 close was the 5-frame fadein title card being correctly decoded as uniform black. ## Closing-the-loop checklist (from issue body) - ✅ `ffmpeg -hwaccel v4l2request -hwaccel_output_format drm_prime -i bbb_hi10p.mp4 -vf hwdownload,format=p010le ...` produces non-zero, real-content output on fresnel - ⏳ Re-enable Hi10P/Main10 in `marfrit/libva-v4l2-request-fourier::RequestQueryConfigProfiles` — separate ticket; libva backend has its own NV15 unpack already (`src/nv15.c`) but Hi10P/Main10 were dropped from the profile list in iter39 Option B based on the (now-overturned) "advertised not functional" finding. That needs its own re-verification pass on fresnel + ampere. - ⏳ `phase7_iter39_test_rig.sh` PASS — separate run; requires the libva re-enable above first. Closing once PR #26 merges.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marfrit/marfrit-packages#21