Files
libva-multiplanar/phase0_evidence/2026-05-04-firefox/findings.md
T
marfrit f115fa6cbc Phase 0 deliverable #3 (Firefox): headless-rig finding
Firefox 150.0.1 + media.ffmpeg.vaapi.enabled=true + LIBVA_DRIVER_NAME=
v4l2_request, executed under Xvfb on ohm.

Result: inconclusive at the boolean-correctness level. RDD process
dlopens libva.so.2 + libva-drm.so.2 + libva-x11.so.2 for capability
probe then immediately closes them; never reaches vaInitialize, never
opens /dev/dri/renderD128, never reaches v4l2_request_drv_video.so.
Falls back to software H.264 in RDD via FFmpeg-OS-library PDM
(Broadcast support from 'RDD', support=H264 SWDEC).

Root cause: Xvfb provides software framebuffer with no DRI/DRM
render-node integration. Firefox's gfx-environment platform-fitness
check rejects VAAPI before adding it to the RDD PDM order list.
Not a libva-side or driver-side fault — mpv --hwdec=vaapi-copy in
the same headless rig DID engage end-to-end (per
phase0_evidence/2026-05-04/findings.md).

Definitive Firefox verdict requires retesting inside a live Plasma
session — deferred to live-session run (next commit).

Also: Phase 0 deliverable #2 (Step 1 reconciliation into fork
master) was completed and pushed to marfrit/libva-v4l2-request-fourier
between this and the prior Phase 0 commit; status table updated.

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

8.5 KiB

Phase 0 deliverable #3 — Firefox VAAPI engagement test (2026-05-04)

In-session test of stock Firefox 150.0.1 with media.ffmpeg.vaapi.enabled=true + LIBVA_DRIVER_NAME=v4l2_request env. Headless rig (Xvfb under SSH).

Verdict

Inconclusive at the boolean-correctness level under this rig. Firefox loads our libva backend for a capability probe but does not engage it for the actual H.264 decode — falls back to software via FFmpeg in the RDD process. The decision to skip VAAPI happens at Firefox's gfx-environment gating layer, before VAAPI device init is attempted. Likely cause: Xvfb provides software framebuffer with no DRI/DRM render-node integration, which Firefox requires for VAAPI surface allocation. Not a libva-side or driver-side fault.

A definitive Firefox verdict requires retesting inside a real Plasma/X session with live DRM access. That's a Phase 7 verification task once a session is live.

What was actually run

Firefox 150.0.1, profile at /tmp/firefox-vaapi-test/profile/ (preserved as profile_user.js here), with these prefs on top of stock:

  • media.ffmpeg.vaapi.enabled = true
  • media.ffvpx.enabled = false
  • media.hardware-video-decoding.force-enabled = true
  • media.hardware-video-decoding.enabled = true
  • media.av1.enabled = false
  • gfx.x11-egl.force-enabled = true
  • widget.dmabuf.force-enabled = true
  • media.rdd-process.enabled = true
  • media.rdd-ffvpx.enabled = false
  • media.rdd-ffmpeg.enabled = true
  • media.gpu-process-decoder = true
  • logging.PlatformDecoderModule = 5, logging.MediaPDM = 5

Env on top of stock:

  • MOZ_DISABLE_RDD_SANDBOX=1, MOZ_DISABLE_CONTENT_SANDBOX=1, MOZ_DISABLE_GMP_SANDBOX=1, MOZ_DISABLE_SOCKET_PROCESS_SANDBOX=1 (rule out sandbox interference)
  • LIBVA_DRIVER_NAME=v4l2_request + LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video1 + LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media0
  • LIBVA_MESSAGING_LEVEL=2

Run command:

xvfb-run -a -s "-screen 0 1280x720x24" -- \
  strace -ff -ttt -s 256 -o /tmp/firefox-vaapi-test/strace/ff \
    -e trace=ioctl,openat,close,clone,clone3,execve \
    firefox -profile /tmp/firefox-vaapi-test/profile -no-remote -new-instance \
      file:///tmp/firefox-vaapi-test/test.html

Test page autoplays bbb_1080p30_h264.mp4 via <video src="file://..." autoplay muted>. Run ran to 30 s timeout (exit 124).

Evidence — what the strace shows

Process PID Behavior
Parent 143578 dconf warnings only, no media path
RDD 143696 Opens /usr/lib/libva.so.2 + libva-drm.so.2 + libva-x11.so.2, immediately closes them all (~9 ms apart, no fd retained). Capability probe pattern: dlopendlsymdlclose.
Content 143725 No libva opens; talks to RDD via IPC for decode
Utility 143764 Second probe of libva.so.2 + libva-drm.so.2 + libva-x11.so.2; gets ENETDOWN first try (sandbox path mangling), retries with `O_NOCTTY
(forkserver) 143775 143775 Re-probes the same libva chain; same close-immediately pattern
Anywhere Zero opens of /dev/dri/renderD128 (the DRM render node libva-v4l2-request would use); only /dev/dri directory enumeration to enumerate render nodes
Anywhere 3 V4L2 ioctls total — and the three /dev/video[012] opens at 1777888991.21x are Firefox's webrtc/camera enumeration probe, not libva-driven (timestamps precede the libva opens by ~115 ms)
Anywhere v4l2_request_drv_video.so never opened — libva-v4l2-request was never reached

So the libva backend is reachable from Firefox's process tree and not blocked by sandbox; Firefox just doesn't drive it.

Evidence — what the MOZ_LOG shows

From firefox.log.child-2.moz_log (RDD process, 276 KB):

[RDD 143696: Main Thread]: D/PlatformDecoderModule PDMInitializer, Init PDMs in RDD process
[RDD 143696: Main Thread]: D/PlatformDecoderModule FFMPEG: version: 0x200, macro: 62, micro: 100/101, isFFMpeg: yes
[RDD 143696: Main Thread]: D/PlatformDecoderModule FFVPX: Link result: Success
[RDD 143696: Main Thread]: D/PlatformDecoderModule PDMInitializer, RDD PDM order:
[RDD 143696: Main Thread]: D/PlatformDecoderModule PDMInitializer, 0: FFmpeg(FFVPX)
[RDD 143696: Main Thread]: D/PlatformDecoderModule PDMInitializer, 1: FFmpeg(OS library)
[RDD 143696: Main Thread]: D/PlatformDecoderModule PDMInitializer, 2: Agnostic

PDM order in RDD is FFVPX → FFmpeg(OS library) → Agnostic. No VAAPI PDM in the order list — Firefox's PDM enumerator concluded VAAPI isn't usable on this rig before adding it to the list.

From firefox.log.moz_log (parent, 210 B):

[Parent 143578: Main Thread]: D/PlatformDecoderModule Broadcast support from 'RDD', support=H264 SWDEC

The SWDEC suffix is decisive: parent confirms RDD reports H.264 capability at the software-decode tier, not VAAPI / hardware tier.

Steady-state during playback: many [RDD 143696: MediaPDecoder #4]: V/PlatformDecoderModule ProcessDecode: mDuration=41666µs ; mTime=... lines — RDD is decoding 24 fps content via FFmpeg (mDuration=41666µs = 1/24 sec), software path.

Why this happens

Firefox's VAAPI gating in modern code (since ~115) requires a working EGL+DMABUF environment that can allocate VAAPI surfaces and import them as DMA-BUFs for compositing. The check happens during PDM enumeration in the RDD process, before any VAAPI device init. Under Xvfb:

  • Xvfb is a software X server with no /dev/dri integration (its rendering goes to a software framebuffer, not the GPU).
  • gfx.x11-egl.force-enabled = true lets Firefox try EGL on Xvfb, but the EGL context can't get a GBM device.
  • DMABUF allocation requires a render node with GBM support, which Xvfb doesn't expose.

So Firefox's PDM enumerator skips VAAPI and the OS-library FFmpeg PDM falls through to software H.264. The probe of libva.so.2 we see is Firefox checking that libva is installed (so it knows to add VAAPI as a candidate for environments that support it), but the platform-fitness check then disqualifies the candidate.

The probe is not the engagement. The engagement is what we'd see if we got a /dev/dri/renderD128 open + vaCreateContext ioctls + __vaDriverInit_1_23 symbol call into our v4l2_request_drv_video.so + the V4L2-stateless contract trace on /dev/video1 + /dev/media0. None of that happened.

Predecessor-claim retest

Claim Result
Firefox 150 + media.ffmpeg.vaapi.enabled=true + LIBVA env vars engages our backend (Mozilla bug 1965646 documents this is "supposed to work" on RK3566/RK3588) Not engaged under Xvfb headless rig. Capability probe only; SW fallback.
LIBVA_DRIVER_NAME=v4l2_request is sufficient for Firefox to choose our backend Sufficient at the libva-driver-selection layer (libva.so loaded the right driver), but Firefox doesn't reach that layer because gfx-env check fails first.
MOZ_DISABLE_RDD_SANDBOX=1 clears sandbox-related blockers RDD sandbox not the blocker — even with sandbox disabled, VAAPI isn't engaged. The ENETDOWN-then-retry pattern in some processes is unrelated noise.

Implication for Phase 1 lock

Firefox-as-test-consumer: ✓ libva backend reachable, ✗ engagement not demonstrable in this rig, ⚠ definitive answer requires real Plasma session.

Two options for closing this Phase 0 deliverable:

  1. Accept rig limitation, defer Firefox engagement test to Phase 7 verification. Phase 1 binding cells include Firefox as a target consumer; Phase 6 implementation (if any beyond Step 1) goes ahead; Phase 7 retests Firefox in real Plasma session at the end. Risk: if there's a Firefox-specific engagement bug, we discover it late.
  2. Run the test inside a live Plasma session (drive sddm-greeter through to a user session, or wake the user session via SSH loginctl unlock-session/etc.). Removes the Xvfb confound. Ohm currently has SDDM greeter on tty1 + no live user session, so this requires either physical interaction or a session-start orchestration script.

mpv --hwdec=vaapi-copy in the same headless rig DID engage the libva backend end-to-end (per phase0_evidence/2026-05-04/findings.md), so the issue isn't "headless can't VAAPI" — it's specifically Firefox's gfx-env requirements being stricter than mpv's.

Artifacts

  • profile_user.js — Firefox profile prefs
  • test.html — autoplay test page
  • firefox.log.{moz_log,child-1.moz_log,child-2.moz_log} — MOZ_LOG output
  • firefox_stderr — stderr (mostly dconf-CRITICAL noise from missing XDG_RUNTIME_DIR perms)
  • strace_parent_143578, strace_rdd_143696, strace_content_143725, strace_utility_143764 — per-process strace