Empirical follow-up to #9. After packaging 150.0.1-4 and installing on
fresnel, MOZ_LOG showed the failure pattern was still present:
D/FFmpegVideo FFMPEG: Using preferred software codec h264
No VAAPI_VLD engagement, no dmabuf surface locking — Gecko bailed
before reaching the patched VAAPI path. Same symptom as issue #8
pre-fix, despite the prefs file being on disk at the expected path.
Root cause: /usr/lib/firefox-fourier/browser/defaults/preferences/ is
NOT a vendor-prefs scan location in Firefox 150. Mozilla's canonical
scan dir is /usr/lib/<app>/defaults/preferences/ — without the
'browser/' prefix.
Verified by hand-copying the same file to /usr/lib/firefox-fourier/
defaults/preferences/ and re-running the H.264 playback test:
D/FFmpegVideo FFMPEG: Requesting pixel format VAAPI_VLD
D/Dmabuf VideoFrameSurface: VAAPI locking dmabuf surface UID 26267
FFMPEG ID 0x4000000 mAVHWFrameContext ...
D/Dmabuf VideoFrameSurface: VAAPI locking dmabuf surface UID 26268
FFMPEG ID 0x4000001 ...
(15+ surface locks)
End-to-end zero-copy DMABUF path engaged, hantro/rkvdec dekodes the
H.264 stream via libva-v4l2-request-fourier iter38b.
pkgrel 4 -> 5. No other PKGBUILD changes.
Follow-up to #10. The subdir layout I assumed worked turned out to not
work — per 'man PKGBUILD':
The filename in the array must NOT include any path components like ./
makepkg's source-staging only honors basenames; the patches/ subdir
references staged the files but the basename-lookup at apply time
failed with the same 'not found in build directory' error that #9 hit.
I copied the chromium-fourier convention thinking it was proven, but
chromium-fourier has no CI either and likely has the same latent
breakage (separate issue, not in this PR's scope).
The actually-working pattern is the mpv-fourier one: patches at the
top level next to the PKGBUILD. mpv-fourier iter2 just built green
on CI (#92) with that layout.
This commit:
- Moves all 8 patches (5 fourier + 3 arch upstream) from patches/
to arch/firefox-fourier/ via git mv (preserves blame).
- Removes the now-empty patches/ subdir.
- Strips 'patches/' prefix from source array entries.
- Strips '/patches' from prepare() patch -i paths.
No semantic change to the patch content or apply order.
pkgrel 3 -> 4.
The PKGBUILD has been structurally broken since at least the 150.0.1
import: source array referenced patches at top level ('0001-...patch')
but the actual files live in patches/ — makepkg searched for them in
the package root and failed before doing any work. The arch-0002/3/4
upstream toolchain patches (clang 22, glibc 2.43, Rust 1.95) weren't
shipped in the repo at all.
Caught when boltzmann tried to build 150.0.1-2 (PR #9 follow-up); fails
at the source-staging phase with:
==> ERROR: arch-0002-Bug-2033279-Make-enable-rust-simd-work-with-Rust-1.9.patch
was not found in the build directory and is not a URL.
Why nobody noticed: firefox-fourier has no Gitea Actions job (too heavy
for the runner pool). The shipped 150.0.1-1 .pkg.tar.zst was produced
by hand-staging files; the PKGBUILD itself never reproduced from a
clean checkout.
This commit:
- Moves all source-array patch references under patches/ to match the
on-disk layout (same convention as chromium-fourier).
- Updates prepare() paths accordingly.
- Adds arch-0002/3/4 patches fetched verbatim from
https://gitlab.archlinux.org/archlinux/packaging/packages/firefox
(raw/main/{0002,0003,0004}-...patch). Renamed with arch- prefix in
the repo to avoid namespace collision with the local 0001..0005.
- Adds the previously-omitted 0005-rdd-sandbox-v4l2-media-ctl.patch
to the source array + prepare(); this is the patch that broadens
the RDD sandbox so /dev/media* and /dev/video* ioctls reach the
decoder child (README §1 enumerates it as load-bearing for the HW
path). It was present in patches/ but not wired up.
Dry-run verified all 8 patches apply cleanly against firefox-150.0.1
source (some hunks offset by ≤3 lines, no conflicts).
pkgrel 2 -> 3.
Three prefs that gate the patched VAAPI / V4L2-request code path are
'false' upstream and need to be 'true' for the libva-v4l2-request
backend to actually engage on RK3399 / panfrost EGL:
widget.dmabuf.force-enabled
media.hardware-video-decoding.force-enabled
media.ffvpx-hw.enabled
Without them, Gecko's DMA-BUF probe silently fails (panfrost EGL
doesn't trip the right detection), the (Intel-tuned) HW-vs-SW cost
heuristic picks SW, and the FFvpx PDM never selects its HW-capable
variant for VP8/VP9. Net result: fresh profiles SW-decode despite the
0001..0004 unlock patches being applied.
Shipped as a vendor-default file at:
/usr/lib/firefox-fourier/browser/defaults/preferences/rockchip-fourier-defaults.js
Lower precedence than user.js / about:config — power users debugging
HW decode can still flip them off without touching the package.
pkgrel 1 -> 2.
Closes: #8
Extends Mozilla's RDD sandbox to permit /dev/media* (driver-matched),
the MEDIA_IOC_* ioctl family ('|'), and the sysfs paths libudev would
need to enumerate the media controller (read-only AddTree on
/sys/class, /sys/bus, /sys/dev/char, /sys/devices/platform plus
/run/udev, /etc/udev/udev.conf, /proc/self, /dev/dma_heap).
Necessary but not sufficient on its own: Mozilla's OpenAtTrap
rejects fd-relative openat used by systemd's chase() inside libudev.
The companion ffmpeg-v4l2-request-git patch adds a brute-force
fallback that opens /dev/media[0..15] directly with absolute paths,
which composes with this broker policy.
Validated on RK3399 / Pinebook Pro / mainline rkvdec: with both
patches in place, default RDD sandbox runs HW decode at ~5% CPU on
1080p30 H.264 (vs ~64% software fallback before). Closes the
parity gap with MOZ_DISABLE_RDD_SANDBOX=1 baseline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Earlier todays edit on patch 3 (commit e0af915) replaced the
hw_configs-only sanity check with the dual-mechanism (named codec
first, hw_configs fallback) probe. The patch text body was correct
but the unified-diff hunk header at the .cpp portion still claimed
the original +105-line content while the new content was 130 lines —
so patch -p1 failed with malformed-patch errors.
This commit regenerates the .cpp portion canonically via diff -u
from the boltzmann working tree (which has the corrected logic
applied). The .h portion is unchanged. Patch description body
updated to match the new dual-mechanism behavior.
Empirical evidence the new logic is correct lives in the boltzmann
build; this commit just makes the patch file replay correctly from
scratch.
Diagnostic on fresnel (RK3399 / Mali-T860 / mainline) showed
InitV4L2RequestDecoder running at runtime but failing the
hw_configs sanity check:
FFMPEG: Initialising V4L2 stateless (request API) FFmpeg decoder
FFMPEG: codec h264 has no DRM hwaccel —
libavcodec built without --enable-v4l2-request?
FFMPEG: Initialising V4L2-DRM FFmpeg decoder ← falls through to stateful
FFMPEG: V4L2 codec h264_v4l2m2m : V4L2 mem2mem H.264 decoder wrapper
FFMPEG: Couldn't initialise V4L2 decoder ← stateful also fails
…despite the system libavcodec.so being built with
--enable-v4l2-request and exposing h264_v4l2request, vp8_v4l2request,
etc. as named AVCodec entries.
Root cause: libavcodec exposes v4l2_request through one of two
mechanisms depending on the build:
(a) Named AVCodec entry (legacy, distro-portable): looked up via
avcodec_find_decoder_by_name("h264_v4l2request"). ALARM,
Debian, most distros use this.
(b) hw_configs entry on the generic codec (modern, upstream): the
generic codec's AVCodecHWConfig array advertises
AV_HWDEVICE_TYPE_DRM. Setting hw_device_ctx binds the hwaccel.
Patch 3 originally only probed (b). On builds that ship (a) — the
common case — the check failed even though v4l2_request was fully
functional.
Fix: probe (a) first via the codec-name lookup table, fall back to
(b) walking hw_configs. Both shapes work; the decoder is opened with
whichever AVCodec the probe selected. The DRM hwdevice ctx
attachment is unchanged (both mechanisms need it for surface
allocation).
Patch description and the in-code comment block updated to document
the dual mechanism. Behaviour on stateful-only boards (Pi4 / vendor
MPP) preserved: neither named codec nor hw_configs DRM is registered,
the function bails out, the existing InitV4L2Decoder runs as before.