firefox-fourier: VAAPI/V4L2-request HW path requires 3 manual prefs on RK3399; ship as defaults #8

Closed
opened 2026-05-15 05:27:15 +00:00 by claude-noether · 0 comments
Contributor

firefox-fourier: VAAPI/V4L2-request HW path not engaged with fresh profile — 3 additional prefs required

Summary

firefox-fourier 150.0.1-16 does not engage the libva-v4l2-request-fourier HW decoder when launched with an empty user profile on RK3399 (fresnel / Pinebook Pro). The shipped pref media.ffmpeg.v4l2-request.enabled=true (patch 0004-prefs-v4l2-request.patch) is necessary but not sufficient. Three additional prefs must be set manually before Firefox negotiates a VAAPI surface; without them it silently falls back to libavcodec software decode.

Environment

  • Host: fresnel (Pinebook Pro / RK3399)
  • Kernel: linux-fresnel-fourier 7.0-14
  • Backend: libva-v4l2-request-fourier iter38b 7ac934e — vainfo lists all 10 profiles in one session, byte-exact bench verified (5/5 codecs)
  • Browser: firefox-fourier 150.0.1-16
  • Compositor: Wayland (autologin SDDM session)

Reproducer

  1. Create an empty profile, set autoplay-on + file-origin-uniqueness off (so the test pages can load local video without click):

    // user.js — minimum to autoplay file:// videos with no other config
    user_pref("media.autoplay.default", 0);
    user_pref("media.autoplay.blocking_policy", 0);
    user_pref("privacy.file_unique_origin", false);
    
  2. Launch firefox-fourier against an H.264 clip, capture MOZ_LOG:

    export XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-0 MOZ_ENABLE_WAYLAND=1
    export LIBVA_DRIVER_NAME=v4l2_request
    export MOZ_LOG="VAAPI:5,PlatformDecoderModule:5,FFmpegVideo:5,Dmabuf:5"
    export MOZ_LOG_FILE=~/ff.log
    firefox-fourier --no-remote --profile /tmp/ff-empty file:///tmp/play.html
    
  3. Inspect ff.log.child-*:

    D/FFmpegVideo FFMPEG: Using preferred software codec h264
    

    No Requesting pixel format VAAPI_VLD, no Got VA-API DMABufSurface, no PRIME import — Gecko bails before the VAAPI PDM.

What unblocks HW (verified working)

Adding these three prefs to user.js and relaunching:

user_pref("widget.dmabuf.force-enabled",                  true);  // most critical
user_pref("media.hardware-video-decoding.force-enabled",  true);
user_pref("media.ffvpx-hw.enabled",                       true);

Result with same H.264 clip, ~10s playback:

D/FFmpegVideo FFMPEG: Requesting pixel format VAAPI_VLD
D/Dmabuf     Got VA-API DMABufSurface FFMPEG ID 0x4000000
D/Dmabuf     ImportPRIMESurfaceDescriptor() ... FOURCC 3231564e  // NV12
D/Dmabuf       plane 0 size 1280 x 720 format 20203852
D/Dmabuf       plane 1 size 640 x 360 format 38385247

LIBVA trace from the parent process shows our backend reached, vaInitialize succeeds, and the RDD child decodes via DMA-BUF PRIME zero-copy import. Sweep across all 5 codecs (with the extra prefs):

Codec VAAPI_VLD req VA-API DMABufSurface / 10 s HW engaged
H.264 1 89 yes
HEVC 1 89 yes
VP8 1 99 yes
VP9 1 95 yes
MPEG-2 0 0 n/a — Gecko has no video/mp2t support, never reaches PDM

Why I think the fix belongs in the package (not user config)

  • widget.dmabuf.force-enabled is the load-bearing pref on RK3399 / panfrost. Upstream Firefox auto-enables DMA-BUF on Mesa/iris and AMD/radv via GBM probe, but on the panfrost EGL stack the probe doesn't fire. Without the force, Gecko refuses to ask libavcodec for a VAAPI surface — the whole patch 3/4 routing never gets a chance to run.
  • media.hardware-video-decoding.force-enabled lets Gecko pick HW even when its (Intel-tuned) cost heuristics say SW is faster. On RK3399 the heuristic is wrong (SW wins on memcpy throughput but loses on power and on real-playback FPS).
  • media.ffvpx-hw.enabled is needed for FFvpx PDM's HW-capable variants to be selected for VP8/VP9.
  • Whole point of firefox-fourier per the package description is "V4L2 stateless HW video decode unlocked for mainline Linux Rockchip" — shipping the necessary pref set is consistent with that intent.

Suggested fix

Extend patches/0004-prefs-v4l2-request.patch (or add 0006-prefs-rockchip-defaults.patch) to flip the three prefs to true by default. They are currently RelaxedAtomicBool static prefs in modules/libpref/init/StaticPrefList.yaml:

  • widget.dmabuf.force-enabledvalue: falsevalue: true
  • media.hardware-video-decoding.force-enabled — same
  • media.ffvpx-hw.enabled — same

Alternative: ship them via /usr/lib/firefox-fourier/defaults/pref/ (lower-precedence default that user.js can still override).

Risk / blast radius

  • These prefs only affect the Linux/GTK build (already gated by MOZ_WIDGET_GTK in StaticPrefList.yaml).
  • widget.dmabuf.force-enabled=true on a host with no DMA-BUF support cleanly falls back (Gecko's DMABuf probe logs the failure and disables itself for that session — observed in earlier sweep before MOZ_ENABLE_WAYLAND was set).
  • No effect on Windows / macOS builds of upstream Firefox.

Logs / artefacts on fresnel

  • ~/measurements/firefox-test/profile/user.js — repro profile (extra prefs added)
  • ~/measurements/firefox-test/logs/ff_{h264,hevc,vp8,vp9,mpeg2}.log.child-* — MOZ_LOG per codec
  • ~/measurements/firefox-test/logs/sweep.log — per-codec engagement summary
  • ~/measurements/firefox-test/libva_trace/h264.trace.* — parent-process LIBVA trace
  • ~/measurements/firefox-test/pages/play_*.html — minimal autoplay HTML per codec
  • Sibling iter38b campaign close: marfrit/fresnel-fourier @ e66c5c0

Filed during fresnel-fourier post-iter38 measurement sweep (2026-05-15).

# firefox-fourier: VAAPI/V4L2-request HW path not engaged with fresh profile — 3 additional prefs required ## Summary `firefox-fourier 150.0.1-16` does not engage the libva-v4l2-request-fourier HW decoder when launched with an empty user profile on RK3399 (fresnel / Pinebook Pro). The shipped pref `media.ffmpeg.v4l2-request.enabled=true` (patch `0004-prefs-v4l2-request.patch`) is necessary but **not sufficient**. Three additional prefs must be set manually before Firefox negotiates a VAAPI surface; without them it silently falls back to libavcodec software decode. ## Environment - Host: fresnel (Pinebook Pro / RK3399) - Kernel: `linux-fresnel-fourier 7.0-14` - Backend: `libva-v4l2-request-fourier` iter38b `7ac934e` — vainfo lists all 10 profiles in one session, byte-exact bench verified (5/5 codecs) - Browser: `firefox-fourier 150.0.1-16` - Compositor: Wayland (autologin SDDM session) ## Reproducer 1. Create an empty profile, set autoplay-on + file-origin-uniqueness off (so the test pages can load local video without click): ```js // user.js — minimum to autoplay file:// videos with no other config user_pref("media.autoplay.default", 0); user_pref("media.autoplay.blocking_policy", 0); user_pref("privacy.file_unique_origin", false); ``` 2. Launch firefox-fourier against an H.264 clip, capture MOZ_LOG: ```sh export XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-0 MOZ_ENABLE_WAYLAND=1 export LIBVA_DRIVER_NAME=v4l2_request export MOZ_LOG="VAAPI:5,PlatformDecoderModule:5,FFmpegVideo:5,Dmabuf:5" export MOZ_LOG_FILE=~/ff.log firefox-fourier --no-remote --profile /tmp/ff-empty file:///tmp/play.html ``` 3. Inspect `ff.log.child-*`: ``` D/FFmpegVideo FFMPEG: Using preferred software codec h264 ``` No `Requesting pixel format VAAPI_VLD`, no `Got VA-API DMABufSurface`, no PRIME import — Gecko bails before the VAAPI PDM. ## What unblocks HW (verified working) Adding these three prefs to `user.js` and relaunching: ```js user_pref("widget.dmabuf.force-enabled", true); // most critical user_pref("media.hardware-video-decoding.force-enabled", true); user_pref("media.ffvpx-hw.enabled", true); ``` Result with same H.264 clip, ~10s playback: ``` D/FFmpegVideo FFMPEG: Requesting pixel format VAAPI_VLD D/Dmabuf Got VA-API DMABufSurface FFMPEG ID 0x4000000 D/Dmabuf ImportPRIMESurfaceDescriptor() ... FOURCC 3231564e // NV12 D/Dmabuf plane 0 size 1280 x 720 format 20203852 D/Dmabuf plane 1 size 640 x 360 format 38385247 ``` LIBVA trace from the parent process shows our backend reached, `vaInitialize` succeeds, and the RDD child decodes via DMA-BUF PRIME zero-copy import. Sweep across all 5 codecs (with the extra prefs): | Codec | VAAPI_VLD req | VA-API DMABufSurface / 10 s | HW engaged | |--------|---------------|------------------------------|------------| | H.264 | 1 | 89 | yes | | HEVC | 1 | 89 | yes | | VP8 | 1 | 99 | yes | | VP9 | 1 | 95 | yes | | MPEG-2 | 0 | 0 | n/a — Gecko has no `video/mp2t` support, never reaches PDM | ## Why I think the fix belongs in the package (not user config) - `widget.dmabuf.force-enabled` is the load-bearing pref on RK3399 / panfrost. Upstream Firefox auto-enables DMA-BUF on Mesa/iris and AMD/radv via GBM probe, but on the panfrost EGL stack the probe doesn't fire. Without the force, Gecko refuses to ask libavcodec for a VAAPI surface — the whole patch 3/4 routing never gets a chance to run. - `media.hardware-video-decoding.force-enabled` lets Gecko pick HW even when its (Intel-tuned) cost heuristics say SW is faster. On RK3399 the heuristic is wrong (SW wins on memcpy throughput but loses on power and on real-playback FPS). - `media.ffvpx-hw.enabled` is needed for FFvpx PDM's HW-capable variants to be selected for VP8/VP9. - Whole point of `firefox-fourier` per the package description is "V4L2 stateless HW video decode unlocked for mainline Linux Rockchip" — shipping the necessary pref set is consistent with that intent. ## Suggested fix Extend `patches/0004-prefs-v4l2-request.patch` (or add `0006-prefs-rockchip-defaults.patch`) to flip the three prefs to `true` by default. They are currently `RelaxedAtomicBool` static prefs in `modules/libpref/init/StaticPrefList.yaml`: - `widget.dmabuf.force-enabled` — `value: false` → `value: true` - `media.hardware-video-decoding.force-enabled` — same - `media.ffvpx-hw.enabled` — same Alternative: ship them via `/usr/lib/firefox-fourier/defaults/pref/` (lower-precedence default that user.js can still override). ## Risk / blast radius - These prefs only affect the Linux/GTK build (already gated by `MOZ_WIDGET_GTK` in StaticPrefList.yaml). - `widget.dmabuf.force-enabled=true` on a host with no DMA-BUF support cleanly falls back (Gecko's DMABuf probe logs the failure and disables itself for that session — observed in earlier sweep before MOZ_ENABLE_WAYLAND was set). - No effect on Windows / macOS builds of upstream Firefox. ## Logs / artefacts on fresnel - `~/measurements/firefox-test/profile/user.js` — repro profile (extra prefs added) - `~/measurements/firefox-test/logs/ff_{h264,hevc,vp8,vp9,mpeg2}.log.child-*` — MOZ_LOG per codec - `~/measurements/firefox-test/logs/sweep.log` — per-codec engagement summary - `~/measurements/firefox-test/libva_trace/h264.trace.*` — parent-process LIBVA trace - `~/measurements/firefox-test/pages/play_*.html` — minimal autoplay HTML per codec - Sibling iter38b campaign close: `marfrit/fresnel-fourier` @ `e66c5c0` Filed during fresnel-fourier post-iter38 measurement sweep (2026-05-15).
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#8