chromium-fourier r2 + firefox-fourier 150.0.1 + KWIN_PIVOT.md
build and publish packages / distcc-avahi-aarch64 (push) Successful in 46s
build and publish packages / lmcp-any (push) Successful in 9s
build and publish packages / lmcp-debian (push) Successful in 4s
build and publish packages / claude-his-any (push) Successful in 7s
build and publish packages / ffmpeg-v4l2-request-aarch64 (push) Successful in 12m8s
build and publish packages / claude-his-debian (push) Successful in 5s
build and publish packages / distcc-avahi-aarch64 (push) Successful in 46s
build and publish packages / lmcp-any (push) Successful in 9s
build and publish packages / lmcp-debian (push) Successful in 4s
build and publish packages / claude-his-any (push) Successful in 7s
build and publish packages / ffmpeg-v4l2-request-aarch64 (push) Successful in 12m8s
build and publish packages / claude-his-debian (push) Successful in 5s
chromium-fourier: - patch 3/3 nv12-external-oes-on-modifier-external-only.patch — adds NativePixmapEGLBinding::ModifierRequiresExternalOES helper, extends OzoneImageGLTexturesHolder::GetBinding to honor EGL external_only flag for NV12 dmabufs on panfrost / panthor. Validated on ohm (RK3566 hantro mainline 6.19.10): bbb_1080p30_h264.mp4 plays at 34.7 % combined CPU vs ~131 % pre-patch baseline (~3.8x). - PKGBUILD pkgrel 1->2, source array + sha256sums + prepare() hook for patch 4, patch numbering 1/2,2/2 -> 1/3,2/3,3/3. - NEXT.md appended with 2026-04-28 section: patch 4 design, validation log, KWin GL_ALPHA bug pinpoint (preexisting since 2026-03-06, affects every wayland video client; unrelated to chromium-fourier), device-renumbering note (/dev/video1 = encoder post-reboot). - KWIN_PIVOT.md: 4-phase plan to identify and patch KWin's glTexImage2D(internalFormat=GL_ALPHA) site, ohm-only test plan, scope discipline. - patches/ now tracked (compiler-rt-adjust-paths, enable-v4l2, wayland-allow-direct-egl-gles2, nv12-external-oes); the dead-end chromeos-pipeline-bypass.patch removed. firefox-fourier: - 4 patches (gfxinfo v4l2 stateless fourccs, libwrapper hwdevice ctx, ffmpegvideo v4l2-request route, prefs v4l2-request default). - PKGBUILD bumped to firefox 150.0.1, Arch toolchain glue patches layered in, mozconfig with --without-wasm-sandboxed-libraries for ALARM, package() launcher fix (rm -f symlink before cat > to avoid ENOENT through the dangling /usr/local symlink mach install drops). - 150.0.1-1-aarch64.pkg.tar.zst built on boltzmann (95 MB), pending fresnel power-on for V4L2 stateless validation on RK3399.
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
# Maintainer: Markus Fritsche <mfritsche@reauktion.de>
|
||||
#
|
||||
# Firefox with V4L2 stateless (request API) hardware video decode
|
||||
# unlocked for mainline-Linux Rockchip (RK3399 rkvdec, RK3566/RK3588
|
||||
# hantro multiplanar, RK3588 rkvdec2). Sibling to chromium-fourier;
|
||||
# same niche. No vendor MPP, no Mali blob, no panfork, no 5.10 BSP.
|
||||
#
|
||||
# Patch series adds 4 thin shims around upstream firefox (~+169 lines,
|
||||
# zero deletions). Architecture: stateless decode rides libavcodec's
|
||||
# v4l2_request hwaccel (AV_HWDEVICE_TYPE_DRM); no separate Mozilla V4L2
|
||||
# decoder gets written. See ../../arch/firefox-fourier/PLAN.md for
|
||||
# the full diagnosis. Mozilla bug 1969297.
|
||||
|
||||
pkgname=firefox-fourier
|
||||
pkgver=150.0.1
|
||||
pkgrel=1
|
||||
pkgdesc='Firefox with V4L2 stateless HW video decode unlocked for mainline Linux Rockchip'
|
||||
arch=('aarch64' 'x86_64')
|
||||
url='https://www.mozilla.org/firefox'
|
||||
license=('MPL-2.0')
|
||||
depends=(
|
||||
alsa-lib
|
||||
at-spi2-core
|
||||
cairo
|
||||
dbus
|
||||
ffmpeg
|
||||
fontconfig
|
||||
freetype2
|
||||
gcc-libs
|
||||
gdk-pixbuf2
|
||||
glib2
|
||||
glibc
|
||||
gtk3
|
||||
hicolor-icon-theme
|
||||
libdrm
|
||||
libpulse
|
||||
libva
|
||||
libxcb
|
||||
libxkbcommon
|
||||
mesa
|
||||
nspr
|
||||
nss
|
||||
pango
|
||||
pciutils
|
||||
ttf-liberation
|
||||
v4l-utils
|
||||
)
|
||||
makedepends=(
|
||||
cbindgen
|
||||
clang
|
||||
imagemagick
|
||||
inetutils
|
||||
lld
|
||||
llvm
|
||||
mesa
|
||||
nasm
|
||||
nodejs
|
||||
python
|
||||
rust
|
||||
unzip
|
||||
wasi-compiler-rt
|
||||
wasi-libc
|
||||
yasm
|
||||
zip
|
||||
)
|
||||
optdepends=(
|
||||
'hunspell-en_us: spell checking, American English'
|
||||
'libnotify: send notifications when downloads complete'
|
||||
'pulseaudio: audio support'
|
||||
)
|
||||
provides=(firefox)
|
||||
conflicts=(firefox)
|
||||
options=('!emptydirs' '!strip')
|
||||
source=(
|
||||
"https://archive.mozilla.org/pub/firefox/releases/${pkgver}/source/firefox-${pkgver}.source.tar.xz"
|
||||
'mozconfig'
|
||||
# Arch's official firefox patches — toolchain glue for clang 22 +
|
||||
# glibc 2.43 + Rust 1.95+. Picked up verbatim because we hit the same
|
||||
# walls. arch-0001 (install-under-remoting) skipped — our launcher
|
||||
# ships under /usr/bin/firefox-fourier with our own wrapper.
|
||||
# https://gitlab.archlinux.org/archlinux/packaging/packages/firefox
|
||||
'arch-0002-Bug-2033279-Make-enable-rust-simd-work-with-Rust-1.9.patch'
|
||||
'arch-0003-Patch-glsl-optimizer-to-build-with-glibc-2.43.patch'
|
||||
'arch-0004-Bug-2023597-Use-wasm32-wasip1-target-for-clang-22.1-.patch'
|
||||
# firefox-fourier patches — V4L2 stateless decode unlock.
|
||||
'0001-gfxinfo-v4l2-stateless-fourccs.patch'
|
||||
'0002-libwrapper-hwdevice-ctx-create.patch'
|
||||
'0003-ffmpegvideo-v4l2-request-route.patch'
|
||||
'0004-prefs-v4l2-request.patch'
|
||||
)
|
||||
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/firefox-${pkgver}"
|
||||
|
||||
# Toolchain glue (Arch upstream) — apply BEFORE the fourier patches.
|
||||
patch -Np1 -i "${srcdir}/arch-0002-Bug-2033279-Make-enable-rust-simd-work-with-Rust-1.9.patch"
|
||||
patch -Np1 -i "${srcdir}/arch-0003-Patch-glsl-optimizer-to-build-with-glibc-2.43.patch"
|
||||
patch -Np1 -i "${srcdir}/arch-0004-Bug-2023597-Use-wasm32-wasip1-target-for-clang-22.1-.patch"
|
||||
|
||||
# Fourier patches — order matters; see ../PLAN.md for rationale.
|
||||
patch -Np1 -i "${srcdir}/0001-gfxinfo-v4l2-stateless-fourccs.patch"
|
||||
patch -Np1 -i "${srcdir}/0002-libwrapper-hwdevice-ctx-create.patch"
|
||||
patch -Np1 -i "${srcdir}/0003-ffmpegvideo-v4l2-request-route.patch"
|
||||
patch -Np1 -i "${srcdir}/0004-prefs-v4l2-request.patch"
|
||||
|
||||
cp "${srcdir}/mozconfig" .mozconfig
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/firefox-${pkgver}"
|
||||
|
||||
# Arch's makepkg.conf injects -fexceptions into CFLAGS/CXXFLAGS by
|
||||
# default for hardening. Mozilla's STL wrappers refuse to compile
|
||||
# with exceptions enabled (#error "STL code can only be used with
|
||||
# -fno-exceptions"). Strip the offender before mach configure picks
|
||||
# up the env. Same trick the upstream Arch firefox PKGBUILD uses.
|
||||
CFLAGS="${CFLAGS//-fexceptions/}"
|
||||
CXXFLAGS="${CXXFLAGS//-fexceptions/}"
|
||||
export CFLAGS CXXFLAGS
|
||||
|
||||
export MOZ_NOSPAM=1
|
||||
export MOZ_API_KEY_UNUSED=1
|
||||
export MOZ_TELEMETRY_REPORTING=
|
||||
export MOZ_REQUIRE_SIGNING=
|
||||
export MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system
|
||||
export PYTHON=/usr/bin/python
|
||||
|
||||
./mach configure
|
||||
./mach build
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/firefox-${pkgver}"
|
||||
|
||||
DESTDIR="${pkgdir}" ./mach install
|
||||
|
||||
# Move mach's default /usr/local/* layout to /usr/* so we conflict
|
||||
# with `firefox` cleanly and `provides=firefox` actually works.
|
||||
# `cp -r` preserves the bin symlink (target lives in /usr/local) —
|
||||
# delete it before staging the launcher so `cat >` doesn't follow a
|
||||
# dangling symlink and ENOENT.
|
||||
if [ -d "${pkgdir}/usr/local" ]; then
|
||||
cp -r "${pkgdir}/usr/local/." "${pkgdir}/usr/"
|
||||
rm -rf "${pkgdir}/usr/local"
|
||||
fi
|
||||
rm -f "${pkgdir}/usr/bin/firefox-fourier"
|
||||
|
||||
# Launcher script. mach's install drops the binary at
|
||||
# /usr/lib/firefox-fourier/firefox-fourier (a small bash launcher) plus
|
||||
# firefox-fourier-bin alongside; we exec the launcher.
|
||||
cat > "${pkgdir}/usr/bin/firefox-fourier" <<'LAUNCHER'
|
||||
#!/bin/bash
|
||||
# firefox-fourier launcher — V4L2 stateless HW decode path defaults.
|
||||
# Patch 4/4 already defaults media.ffmpeg.v4l2-request.enabled=true on
|
||||
# Linux; the env vars below cover the platform-detection bits firefox
|
||||
# still consults at startup.
|
||||
export MOZ_ENABLE_WAYLAND="${MOZ_ENABLE_WAYLAND:-1}"
|
||||
export MOZ_X11_EGL="${MOZ_X11_EGL:-1}"
|
||||
exec /usr/lib/firefox-fourier/firefox-fourier "$@"
|
||||
LAUNCHER
|
||||
chmod 0755 "${pkgdir}/usr/bin/firefox-fourier"
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
# firefox-fourier — V4L2 Stateless Decoder Patch Plan
|
||||
|
||||
Plan to extend Firefox 149's V4L2 hardware decode path to cover Rockchip
|
||||
mainline kernel boards (RK3399 rkvdec, RK3566/RK3588 hantro, RK3588
|
||||
rkvdec2) by routing stateless `S264`/`S265`/`VP9F` fourccs through
|
||||
libavcodec's `v4l2_request` hwaccel, which mainline FFmpeg surfaces via
|
||||
`AV_HWDEVICE_TYPE_DRM` (no dedicated `_V4L2REQUEST` enum exists upstream
|
||||
— confirmed against `libavutil/hwcontext.h`).
|
||||
|
||||
## 1. Files touched (in order)
|
||||
|
||||
| # | Path | Change | Lines |
|
||||
|---|------|--------|-------|
|
||||
| 1 | `widget/gtk/GfxInfo.cpp` | `V4L2ProbeDevice` (~L1030–1110): add `S264`/`S265`/`VP9F` matches alongside existing `H264`/`HEVC`/`VP90`. Set `mIsV4L2Supported = Some(true)` and OR the same `CODEC_HW_DEC_*` bits. Tag a new bool `mV4L2IsStateless` so downstream can branch. | +35 / -2 |
|
||||
| 2 | `dom/media/platforms/ffmpeg/FFmpegLibWrapper.h` | Add wrappers for `av_hwdevice_ctx_create` (currently only `_alloc`/`_init` per L173–174) and `av_hwdevice_find_type_by_name`. Needed because stateless wants the *device-path-aware* `_create` form to bind `/dev/dri/renderD128`. | +4 / 0 |
|
||||
| 3 | `dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp` | `dlsym` the two new pointers; gate behind `LIBAVUTIL_VERSION_MAJOR >= 56`. | +6 / 0 |
|
||||
| 4 | `dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h` | Add `AVBufferRef* mDRMDeviceContext = nullptr;` and `bool mUsingV4L2Request = false;` next to existing `mUsingV4L2`. | +3 / 0 |
|
||||
| 5 | `dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp` | New `CreateV4L2RequestDeviceContext()` modelled on `CreateVAAPIDeviceContext` (current uses `av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI)`). Wire it in alongside the existing V4L2 init branch (the one feeding `ChooseV4L2PixelFormat` at L~258). `FindVideoHardwareAVCodec` call at L708 stays unchanged for stateless — we want the *generic* `h264`/`hevc`/`vp9` decoder + a DRM hw_device_ctx, not a `_v4l2m2m` codec. | +90 / -5 |
|
||||
| 6 | `modules/libpref/init/StaticPrefList.yaml` | New pref `media.ffmpeg.v4l2-request.enabled` mirroring `media.ffmpeg.vaapi.enabled` (default `@IS_LINUX@`). | +6 / 0 |
|
||||
| 7 | `dom/media/ipc/RDDProcessHost.cpp` + sandbox policy file | Whitelist `/dev/media*`, `/dev/dri/renderD*`, `/dev/video*` for the RDD process (already partly done for VAAPI — verify `policy/linux/SandboxBrokerPolicyFactory.cpp`). | +6 / 0 |
|
||||
|
||||
Total: roughly **+150 / -10** across 7 files.
|
||||
|
||||
## 2. Probe extension — `GfxInfo.cpp::V4L2ProbeDevice`
|
||||
|
||||
Existing pattern (~L1075):
|
||||
```cpp
|
||||
if (outFormats.Contains("H264")) { mIsV4L2Supported = Some(true);
|
||||
mV4L2SupportedCodecs |= CODEC_HW_DEC_H264; ... }
|
||||
```
|
||||
|
||||
Add three siblings, each setting an additional `mV4L2IsStateless = true`:
|
||||
```cpp
|
||||
if (outFormats.Contains("S264")) { /* CODEC_HW_DEC_H264 | stateless */ }
|
||||
if (outFormats.Contains("S265")) { /* CODEC_HW_DEC_HEVC | stateless */ }
|
||||
if (outFormats.Contains("VP9F")) { /* CODEC_HW_DEC_VP9 | stateless */ }
|
||||
```
|
||||
|
||||
Decision: do **not** introduce a separate `mIsV4L2StatelessSupported`.
|
||||
Collapse under `mIsV4L2Supported` so the existing feature-gate plumbing
|
||||
(`MediaCodecsSupport`, `gfxFeature::HW_DECODE_VIDEO`) flips identically
|
||||
— only `mV4L2IsStateless` distinguishes the routing in step 3. Stateful
|
||||
+ stateless on the same SoC (rare, but RK3588 has both rkvdec2 + hantro
|
||||
VEPU) gracefully degrades to whichever codec wins enumeration order.
|
||||
|
||||
The capture-format gate (`YV12`/`NV12`) needs widening: stateless
|
||||
decoders frequently expose only `NV12` or `NV15` (10-bit, RK3588 HEVC).
|
||||
Add `NV15` and `NM12` (multiplanar NV12, hantro). Without this the
|
||||
prober rejects an otherwise-good device.
|
||||
|
||||
## 3. Decoder routing — `FFmpegVideoDecoder.cpp`
|
||||
|
||||
Codec selection happens at **L651** (`AV_HWDEVICE_TYPE_VAAPI` →
|
||||
`h264_vaapi`) and **L708** (the V4L2 fallback path → `h264_v4l2m2m` via
|
||||
`FindVideoHardwareAVCodec(mLib, mCodecID)` resolving by suffix). The
|
||||
stateless route diverges from both: the *codec* must remain the generic
|
||||
`h264`/`hevc`/`vp9` decoder (libavcodec auto-binds `v4l2_request` from
|
||||
its `hw_configs` when a DRM hw_device_ctx is attached). Pseudo-patch:
|
||||
|
||||
```cpp
|
||||
if (gfxInfo.mUsingV4L2 && gfxInfo.mV4L2IsStateless) {
|
||||
AVCodec* codec = mLib->avcodec_find_decoder(mCodecID); // generic
|
||||
mCodecContext = mLib->avcodec_alloc_context3(codec);
|
||||
if (!CreateV4L2RequestDeviceContext()) return false;
|
||||
mCodecContext->get_format = ChooseV4L2PixelFormat; // already returns DRM_PRIME
|
||||
mUsingV4L2Request = true;
|
||||
}
|
||||
```
|
||||
|
||||
`CreateV4L2RequestDeviceContext()` body:
|
||||
```cpp
|
||||
const char* drm = "/dev/dri/renderD128";
|
||||
if (mLib->av_hwdevice_ctx_create(&mDRMDeviceContext,
|
||||
AV_HWDEVICE_TYPE_DRM, drm, nullptr, 0) < 0) return false;
|
||||
mCodecContext->hw_device_ctx = mLib->av_buffer_ref(mDRMDeviceContext);
|
||||
```
|
||||
|
||||
`av_hwdevice_ctx_create` — not currently wrapped — is the entry point.
|
||||
The codec's internal hwaccel selector then walks
|
||||
`avcodec_get_hw_config()` and picks the entry whose `device_type ==
|
||||
AV_HWDEVICE_TYPE_DRM` and `pix_fmt == AV_PIX_FMT_DRM_PRIME`, which is
|
||||
the v4l2_request hwaccel registered in `libavcodec/v4l2_request_*.c`.
|
||||
No `av_hwdevice_find_type_by_name("v4l2_request")` needed — stays an
|
||||
internal libavcodec name.
|
||||
|
||||
## 4. Dmabuf / DRM_PRIME reuse
|
||||
|
||||
`ChooseV4L2PixelFormat` at L~258–270 already returns
|
||||
`AV_PIX_FMT_DRM_PRIME` and is the *only* format the v4l2_request
|
||||
hwaccel produces. The downstream consumer (DMABufSurfaceYUV import in
|
||||
`FFmpegVideoFramePool.cpp`) is already DRM_PRIME-aware for the
|
||||
stateful path — same code reads `AVDRMFrameDescriptor` from
|
||||
`frame->data[0]`. **No new output handling required for NV12/YV12.**
|
||||
|
||||
10-bit caveat: RK3588 HEVC outputs `DRM_FORMAT_NV15` / `NV20`
|
||||
(Mali-tile). Existing `WaylandDMABufSurface::CreateYUVSurface`
|
||||
modifier list does not include `DRM_FORMAT_MOD_ARM_AFBC` or NV15
|
||||
fourcc. Either reject 10-bit at probe (capture format gate above) or
|
||||
extend `gfx/layers/DMABUFSurfaceImage.cpp` — out of scope for v1; gate
|
||||
to NV12 only.
|
||||
|
||||
SAND format pollution Turner mentioned in bug 1969297 c#3 is
|
||||
**Pi5-specific**; rkvdec/hantro do not produce SAND. Safe to ignore for
|
||||
the Rockchip target.
|
||||
|
||||
## 5. Configuration
|
||||
|
||||
New pref:
|
||||
```yaml
|
||||
- name: media.ffmpeg.v4l2-request.enabled
|
||||
type: RelaxedAtomicBool
|
||||
value: @IS_LINUX@
|
||||
mirror: always
|
||||
```
|
||||
|
||||
No new env var. No `MOZ_X11_EGL`-style kludge. The existing
|
||||
`MOZ_LOG=PlatformDecoderModule:5` covers diagnostics. Default-on
|
||||
matches `media.ffmpeg.vaapi.enabled` shape; users get fallback to
|
||||
software via existing failure paths if `av_hwdevice_ctx_create` fails
|
||||
(e.g., missing `/dev/media0`).
|
||||
|
||||
## 6. Test plan (fresnel — RK3399, KDE Wayland)
|
||||
|
||||
1. `ls /dev/video* /dev/media*` — confirm `/dev/video0` (rkvdec
|
||||
output) and `/dev/media0` exist.
|
||||
2. `v4l2-ctl -d /dev/video0 --list-formats-out` — expect
|
||||
`S264`/`S265`/`VP9F`.
|
||||
3. Start: `MOZ_LOG="PlatformDecoderModule:5,FFmpegVideo:5"
|
||||
firefox-fourier 2>&1 | tee fx.log`.
|
||||
4. Open `https://test-videos.co.uk/bigbuckbunny/mp4-h264` 1080p clip.
|
||||
5. Success markers in `fx.log`:
|
||||
- `V4L2ProbeDevice: /dev/video0 supports S264 (stateless)`
|
||||
- `Choosing FFmpeg pixel format for V4L2 video decoding.`
|
||||
- `Requesting pixel format DRM PRIME`
|
||||
- `av_hwdevice_ctx_create(DRM, /dev/dri/renderD128) ok`
|
||||
- **No** `Using preferred software codec h264`.
|
||||
6. `cat /sys/kernel/debug/clk/clk_summary | grep vdec` — clock should
|
||||
be active during playback.
|
||||
7. `top` — CPU < 40% on a single A72 core for 1080p H.264 (stock =
|
||||
100% on all 6 cores).
|
||||
|
||||
## 7. Build + ship — `firefox-fourier` PKGBUILD
|
||||
|
||||
Mirror `chromium-fourier` shape exactly (sibling).
|
||||
|
||||
```bash
|
||||
pkgname=firefox-fourier
|
||||
pkgver=149.0
|
||||
arch=('aarch64' 'x86_64')
|
||||
makedepends=(rust clang lld nodejs python cbindgen nasm yasm wasi-libc-bin
|
||||
gtk3 mesa libva ffmpeg) # ffmpeg only for headers via system libs
|
||||
source=(
|
||||
"https://archive.mozilla.org/pub/firefox/releases/${pkgver}/source/firefox-${pkgver}.source.tar.xz"
|
||||
patches/0001-gfxinfo-v4l2-stateless-fourccs.patch
|
||||
patches/0002-libwrapper-hwdevice-ctx-create.patch
|
||||
patches/0003-ffmpegvideo-v4l2-request-route.patch
|
||||
patches/0004-prefs-v4l2-request.patch
|
||||
mozconfig
|
||||
)
|
||||
```
|
||||
|
||||
`prepare()`: `cd firefox-${pkgver}` → apply patches with `patch -Np1`.
|
||||
`build()`: `MOZ_NOSPAM=1 ./mach build`. `package()`: `./mach install
|
||||
DESTDIR=${pkgdir}`. `mozconfig` enables
|
||||
`--enable-default-toolkit=cairo-gtk3-wayland`, `--with-system-ffmpeg`,
|
||||
`ac_add_options --disable-tests`. **No** `--enable-media-gpu-process`
|
||||
— let it default. Tarball is the official Mozilla source release (not
|
||||
gecko-dev).
|
||||
|
||||
Extra makedepends vs. stock firefox PKGBUILD: none — this only
|
||||
modifies existing C++.
|
||||
|
||||
## 8. Risk register (ranked)
|
||||
|
||||
1. **libavcodec ABI mismatch.** ALARM ships ffmpeg 7.x; Firefox dlopens
|
||||
whatever's at `libavcodec.so.61`. If the v4l2_request hwaccel was
|
||||
compiled out (Arch's ffmpeg has it; ALARM rebuild may not),
|
||||
`av_hwdevice_ctx_create(DRM, ...)` succeeds but no codec binds —
|
||||
silent fallback. Mitigation: `ffmpeg -hwaccels` should list `drm`.
|
||||
2. **Renderer-process sandbox** blocks `/dev/dri/renderD128` open.
|
||||
VAAPI already brokered this for RDD process; verify
|
||||
`SandboxBrokerPolicyFactory.cpp` covers `/dev/media*` too — likely
|
||||
doesn't.
|
||||
3. **glxtest probe runs in stripped env.** `v4l2test` (the
|
||||
FireTestProcess child) needs `cap_sys_admin` for
|
||||
`VIDIOC_S_EXT_CTRLS` request API ioctls? No — request API just
|
||||
needs `O_RDWR` on `/dev/media*`. Should be fine.
|
||||
4. **Regression of stateful path.** Adding new fourccs is additive;
|
||||
the routing branch is gated on `mV4L2IsStateless`. Stateful boards
|
||||
(Pi4) untouched.
|
||||
5. **NV15/10-bit on RK3588** — explicitly out-of-scope v1;
|
||||
gate-rejected.
|
||||
6. **rkvdec2 driver maturity.** Linux 6.12 mainline rkvdec2 H.264
|
||||
works; HEVC/VP9 still upstream-pending on some boards. Probe will
|
||||
skip what kernel doesn't expose.
|
||||
7. **DMA-BUF modifier negotiation** with panfrost/panthor on Wayland
|
||||
— already shaken out by chromium-fourier on RK3566; same code
|
||||
path.
|
||||
|
||||
## 9. Upstream path (bug 1969297)
|
||||
|
||||
Split into 4 reviewable commits matching files 1, 2+3, 5, 6 from the
|
||||
table. Add a gtest exercising `V4L2ProbeDevice` against a synthetic
|
||||
v4l2test stdout containing `S264` (no kernel needed). Reach out to
|
||||
skyevg (D252119 author) for review continuity. r? jya for the
|
||||
FFmpegVideoDecoder change. The `av_hwdevice_ctx_create` wrapper
|
||||
addition is a self-contained 6-liner that should land independently.
|
||||
The 10-bit/SAND concerns Turner raised remain valid for Pi5 —
|
||||
explicitly scope this series to **stateless DRM_PRIME NV12 only**,
|
||||
leaving SAND for a follow-up bug.
|
||||
@@ -0,0 +1,36 @@
|
||||
# firefox-fourier mozconfig — minimal, Wayland + system ffmpeg.
|
||||
|
||||
ac_add_options --enable-application=browser
|
||||
ac_add_options --enable-default-toolkit=cairo-gtk3-wayland
|
||||
ac_add_options --enable-release
|
||||
ac_add_options --enable-optimize
|
||||
ac_add_options --enable-rust-simd
|
||||
ac_add_options --enable-linker=lld
|
||||
|
||||
# Arch's 0004 patch updates the wasm32-wasip1 target string but ALARM's
|
||||
# wasi-libc package doesn't expose the headers at the path Mozilla's
|
||||
# probe looks for. Disable the wasm sandbox — hardens font/graphics
|
||||
# parsers only, no impact on V4L2 decode. Revisit when ALARM's
|
||||
# wasi-libc catches up to Arch x86_64's layout.
|
||||
ac_add_options --without-wasm-sandboxed-libraries
|
||||
|
||||
# Firefox dlopens libavcodec.so at runtime regardless of build flags;
|
||||
# the v4l2_request hwaccel routing happens via the system libavcodec
|
||||
# loaded at startup, controlled by media.ffmpeg.enabled (default true).
|
||||
# No configure-time hook needed.
|
||||
|
||||
ac_add_options --disable-tests
|
||||
ac_add_options --disable-debug
|
||||
ac_add_options --disable-debug-symbols
|
||||
ac_add_options --disable-crashreporter
|
||||
ac_add_options --disable-updater
|
||||
ac_add_options --disable-default-browser-agent
|
||||
|
||||
# Mozilla branding requires a separate signed-build-tooling agreement
|
||||
# we don't have; ship with the unbranded "firefox-fourier" identity.
|
||||
ac_add_options --with-app-name=firefox-fourier
|
||||
ac_add_options --with-app-basename=Firefox
|
||||
ac_add_options --with-distribution-id=de.reauktion.fourier
|
||||
|
||||
# Reduce build memory pressure on aarch64 — parallel link is heavy.
|
||||
mk_add_options MOZ_PARALLEL_BUILD=8
|
||||
@@ -0,0 +1,75 @@
|
||||
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Subject: [PATCH 1/4] widget/gtk: recognize V4L2 stateless fourccs in
|
||||
GfxInfo prober (S264 / S265 / VP9F)
|
||||
Date: 2026-04-27
|
||||
|
||||
Background
|
||||
----------
|
||||
Firefox's V4L2 prober in `widget/gtk/GfxInfo.cpp::V4L2ProbeDevice`
|
||||
parses `v4l2test`'s `V4L2_OUTPUT_FMTS` line and matches against the
|
||||
fourccs of stateful V4L2-M2M decoders (`H264`, `VP80`, `VP90`, `HEVC`).
|
||||
That's correct for Pi4 / Mediatek / vendor-MPP stateful decoders but
|
||||
silently skips every mainline-Linux Rockchip board: RK3399 `rkvdec`,
|
||||
RK3566 `hantro` (multiplanar), RK3588 `hantro` and `rkvdec2` all
|
||||
expose stateless fourccs only — `S264`, `S265`, `VP9F`. The probe
|
||||
binary itself enumerates these correctly (verified end-to-end on
|
||||
fresnel / Pinebook Pro / RK3399 with `v4l2test --device /dev/video1`
|
||||
showing `V4L2_OUTPUT_FMTS: S265 S264 VP9F` and
|
||||
`V4L2_SUPPORTED: TRUE`); the gap is purely in this string table.
|
||||
|
||||
This patch adds the three sibling blocks for the stateless fourccs,
|
||||
each identical in shape to the existing stateful blocks except for
|
||||
setting a new `mV4L2IsStateless` member. The follow-up patches in
|
||||
this series (2/4, 3/4, 4/4) consume that member to route through the
|
||||
libavcodec v4l2_request hwaccel (`AV_HWDEVICE_TYPE_DRM`) instead of
|
||||
the v4l2m2m codec wrapper used for stateful boards.
|
||||
|
||||
Bug 1969297.
|
||||
|
||||
diff --git a/widget/gtk/GfxInfo.h b/widget/gtk/GfxInfo.h
|
||||
--- a/widget/gtk/GfxInfo.h
|
||||
+++ b/widget/gtk/GfxInfo.h
|
||||
@@ -127,6 +127,10 @@
|
||||
mozilla::Maybe<bool> mIsVAAPISupported;
|
||||
int mVAAPISupportedCodecs = 0;
|
||||
mozilla::Maybe<bool> mIsV4L2Supported;
|
||||
+ // firefox-fourier: true when probe matched at least one stateless
|
||||
+ // V4L2 fourcc (S264 / S265 / VP9F). Drives libavcodec v4l2_request
|
||||
+ // hwaccel routing in FFmpegVideoDecoder.cpp.
|
||||
+ bool mV4L2IsStateless = false;
|
||||
int mV4L2SupportedCodecs = 0;
|
||||
|
||||
static int sGLXTestPipe;
|
||||
diff --git a/widget/gtk/GfxInfo.cpp b/widget/gtk/GfxInfo.cpp
|
||||
--- a/widget/gtk/GfxInfo.cpp
|
||||
+++ b/widget/gtk/GfxInfo.cpp
|
||||
@@ -852,6 +852,29 @@ void GfxInfo::V4L2ProbeDevice(nsCString& dev) {
|
||||
media::MCSInfo::AddSupport(media::MediaCodecsSupport::HEVCHardwareDecode);
|
||||
mV4L2SupportedCodecs |= CODEC_HW_DEC_HEVC;
|
||||
}
|
||||
+ // firefox-fourier: V4L2 stateless (request API) fourccs. Mainline
|
||||
+ // Rockchip rkvdec / hantro / rkvdec2 expose these instead of the
|
||||
+ // V4L2-M2M-stateful fourccs above. Decoding routes through
|
||||
+ // libavcodec's v4l2_request hwaccel (AV_HWDEVICE_TYPE_DRM) rather
|
||||
+ // than the *_v4l2m2m codec wrappers — see FFmpegVideoDecoder.cpp.
|
||||
+ if (outFormats.Contains("S264")) {
|
||||
+ mIsV4L2Supported = Some(true);
|
||||
+ mV4L2IsStateless = true;
|
||||
+ media::MCSInfo::AddSupport(media::MediaCodecsSupport::H264HardwareDecode);
|
||||
+ mV4L2SupportedCodecs |= CODEC_HW_DEC_H264;
|
||||
+ }
|
||||
+ if (outFormats.Contains("S265")) {
|
||||
+ mIsV4L2Supported = Some(true);
|
||||
+ mV4L2IsStateless = true;
|
||||
+ media::MCSInfo::AddSupport(media::MediaCodecsSupport::HEVCHardwareDecode);
|
||||
+ mV4L2SupportedCodecs |= CODEC_HW_DEC_HEVC;
|
||||
+ }
|
||||
+ if (outFormats.Contains("VP9F")) {
|
||||
+ mIsV4L2Supported = Some(true);
|
||||
+ mV4L2IsStateless = true;
|
||||
+ media::MCSInfo::AddSupport(media::MediaCodecsSupport::VP9HardwareDecode);
|
||||
+ mV4L2SupportedCodecs |= CODEC_HW_DEC_VP9;
|
||||
+ }
|
||||
}
|
||||
|
||||
const nsTArray<RefPtr<GfxDriverInfo>>& GfxInfo::GetGfxDriverInfo() {
|
||||
@@ -0,0 +1,52 @@
|
||||
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Subject: [PATCH 2/4] dom/media/platforms/ffmpeg: wrap
|
||||
av_hwdevice_ctx_create
|
||||
Date: 2026-04-27
|
||||
|
||||
Background
|
||||
----------
|
||||
`FFmpegLibWrapper` already wraps `av_hwdevice_ctx_alloc` (no device
|
||||
path) and `av_hwdevice_ctx_init`, used by the VAAPI codepath which
|
||||
discovers the DRM device implicitly. The v4l2_request hwaccel needs
|
||||
the *path-aware* constructor `av_hwdevice_ctx_create`, which lets the
|
||||
caller pass `"/dev/dri/renderD128"` (or similar) directly when
|
||||
creating an `AV_HWDEVICE_TYPE_DRM` context. libavcodec then binds the
|
||||
v4l2_request hwaccel internally based on the codec's `hw_configs`.
|
||||
|
||||
This patch adds the function pointer + the `AV_FUNC_OPTION_SILENT`
|
||||
registration. Same versioning as the other `av_hwdevice_ctx_*`
|
||||
wrappers (libavutil 58–62). No callers yet — patch 3/4
|
||||
(FFmpegVideoDecoder routing) consumes it.
|
||||
|
||||
Bug 1969297.
|
||||
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
|
||||
@@ -177,6 +177,11 @@
|
||||
// libavutil >= 58
|
||||
AVBufferRef* (*av_hwdevice_ctx_alloc)(int);
|
||||
int (*av_hwdevice_ctx_init)(AVBufferRef* ref);
|
||||
+ // firefox-fourier: device-path-aware constructor needed to bind a
|
||||
+ // DRM hwdevice (AV_HWDEVICE_TYPE_DRM) to /dev/dri/renderD* for the
|
||||
+ // libavcodec v4l2_request hwaccel.
|
||||
+ int (*av_hwdevice_ctx_create)(AVBufferRef** device_ctx, int type,
|
||||
+ const char* device, void* opts, int flags);
|
||||
AVBufferRef* (*av_hwframe_ctx_alloc)(AVBufferRef* device_ctx);
|
||||
int (*av_hwframe_ctx_init)(AVBufferRef* ref);
|
||||
AVBufferRef* (*av_buffer_ref)(AVBufferRef* buf);
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
|
||||
@@ -293,6 +293,11 @@ FFmpegLibWrapper::LinkResult FFmpegLibWrapper::Link() {
|
||||
AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
|
||||
AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 |
|
||||
AV_FUNC_AVUTIL_62)
|
||||
+ // firefox-fourier: see comment in FFmpegLibWrapper.h
|
||||
+ AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_create,
|
||||
+ AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
|
||||
+ AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 |
|
||||
+ AV_FUNC_AVUTIL_62)
|
||||
AV_FUNC_OPTION_SILENT(
|
||||
av_buffer_ref, AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
|
||||
AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62)
|
||||
@@ -0,0 +1,208 @@
|
||||
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Subject: [PATCH 3/4] dom/media/platforms/ffmpeg: route through libavcodec
|
||||
v4l2_request hwaccel for V4L2 stateless boards
|
||||
Date: 2026-04-27
|
||||
|
||||
Background
|
||||
----------
|
||||
Firefox's existing V4L2 init (`InitV4L2Decoder`) finds the codec by
|
||||
suffix lookup (`FindVideoHardwareAVCodec(mLib, mCodecID)`), which on
|
||||
Linux resolves to the **stateful** V4L2-M2M wrapper codec
|
||||
(`h264_v4l2m2m` etc). Mainline-Linux Rockchip boards (RK3399 rkvdec,
|
||||
RK3566/RK3588 hantro, RK3588 rkvdec2) only expose **stateless**
|
||||
V4L2 fourccs (`S264`, `S265`, `VP9F`); the stateful wrapper codec
|
||||
fails to open, Firefox falls all the way through to software.
|
||||
|
||||
This patch adds a sibling init path, `InitV4L2RequestDecoder`, that:
|
||||
|
||||
* uses the **generic** codec (e.g. plain `h264`, returned by
|
||||
`avcodec_find_decoder(AV_CODEC_ID_H264)`) rather than the stateful
|
||||
wrapper;
|
||||
* sanity-checks the codec's `hw_configs` for an `AV_HWDEVICE_TYPE_DRM`
|
||||
entry — that's how libavcodec surfaces the v4l2_request hwaccel
|
||||
upstream (no dedicated `_V4L2REQUEST` device type exists);
|
||||
* creates an `AV_HWDEVICE_TYPE_DRM` hwdevice context bound to
|
||||
`/dev/dri/renderD128` via the new `av_hwdevice_ctx_create` wrapper
|
||||
(patch 2/4) and attaches it to the codec context;
|
||||
* reuses the existing `ChooseV4L2PixelFormat` get-format callback
|
||||
(already returns `AV_PIX_FMT_DRM_PRIME`) and the existing
|
||||
`apply_cropping = 0` constraint.
|
||||
|
||||
`InitV4L2RequestDecoder` is invoked **before** `InitV4L2Decoder` in
|
||||
`InitHWDecoderIfAllowed`. On Rockchip mainline it succeeds. On Pi4 /
|
||||
Mediatek / vendor-MPP-stateful boards the codec's `hw_configs` lacks
|
||||
a DRM entry (the V4L2-M2M codecs don't register one), the sanity
|
||||
check fails, and the existing stateful `InitV4L2Decoder` runs as
|
||||
before. No regression of stateful boards.
|
||||
|
||||
`mDRMDeviceContext` is unconditionally `av_buffer_unref`'d in
|
||||
`ProcessShutdown` (no-op when null). Gated behind
|
||||
`media.ffmpeg.v4l2-request.enabled` from patch 4/4.
|
||||
|
||||
Bug 1969297.
|
||||
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h 2026-03-18 19:22:14.000000000 +0000
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h 2026-04-27 20:43:39.347992674 +0000
|
||||
@@ -225,7 +225,12 @@
|
||||
bool IsLinuxHDR() const;
|
||||
MediaResult InitVAAPIDecoder();
|
||||
MediaResult InitV4L2Decoder();
|
||||
+ // firefox-fourier: V4L2 stateless (request API) decode path. Uses
|
||||
+ // libavcodec's v4l2_request hwaccel, which it surfaces via
|
||||
+ // AV_HWDEVICE_TYPE_DRM rather than a dedicated _V4L2REQUEST type.
|
||||
+ MediaResult InitV4L2RequestDecoder();
|
||||
bool CreateVAAPIDeviceContext();
|
||||
+ bool CreateV4L2RequestDeviceContext();
|
||||
bool GetVAAPISurfaceDescriptor(VADRMPRIMESurfaceDescriptor* aVaDesc);
|
||||
void AddAcceleratedFormats(nsTArray<AVCodecID>& aCodecList,
|
||||
AVCodecID aCodecID, AVVAAPIHWConfig* hwconfig);
|
||||
@@ -239,7 +244,10 @@
|
||||
void AdjustHWDecodeLogging();
|
||||
|
||||
AVBufferRef* mVAAPIDeviceContext = nullptr;
|
||||
+ // firefox-fourier: DRM hwdevice ctx for the v4l2_request hwaccel.
|
||||
+ AVBufferRef* mDRMDeviceContext = nullptr;
|
||||
bool mUsingV4L2 = false;
|
||||
+ bool mUsingV4L2Request = false;
|
||||
// If video overlay is used we want to upload SW decoded frames to
|
||||
// DMABuf and present it as a external texture to rendering pipeline.
|
||||
bool mUploadSWDecodeToDMABuf = false;
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp 2026-03-18 19:22:14.000000000 +0000
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp 2026-04-27 20:44:33.280766228 +0000
|
||||
@@ -406,6 +406,105 @@
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
+// firefox-fourier: V4L2 stateless (request API) DRM hwdevice context.
|
||||
+// libavcodec's v4l2_request hwaccel binds via AV_HWDEVICE_TYPE_DRM —
|
||||
+// no dedicated _V4L2REQUEST type exists upstream.
|
||||
+bool FFmpegVideoDecoder<LIBAV_VER>::CreateV4L2RequestDeviceContext() {
|
||||
+ if (!mLib->av_hwdevice_ctx_create) {
|
||||
+ FFMPEG_LOG(" av_hwdevice_ctx_create not available (libavutil too old)");
|
||||
+ return false;
|
||||
+ }
|
||||
+ const char* drmDevice = "/dev/dri/renderD128";
|
||||
+ if (mLib->av_hwdevice_ctx_create(&mDRMDeviceContext,
|
||||
+ AV_HWDEVICE_TYPE_DRM, drmDevice,
|
||||
+ nullptr, 0) < 0) {
|
||||
+ FFMPEG_LOG(" av_hwdevice_ctx_create(DRM, %s) failed", drmDevice);
|
||||
+ return false;
|
||||
+ }
|
||||
+ mCodecContext->hw_device_ctx = mLib->av_buffer_ref(mDRMDeviceContext);
|
||||
+ FFMPEG_LOG(" DRM hwdevice ctx created on %s", drmDevice);
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+// firefox-fourier: try V4L2 stateless decode via libavcodec's
|
||||
+// v4l2_request hwaccel. Distinct from InitV4L2Decoder which uses the
|
||||
+// stateful h264_v4l2m2m wrapper codec. On Rockchip mainline boards
|
||||
+// (rkvdec / hantro / rkvdec2) only the stateless path exists.
|
||||
+MediaResult FFmpegVideoDecoder<LIBAV_VER>::InitV4L2RequestDecoder() {
|
||||
+ FFMPEG_LOG("Initialising V4L2 stateless (request API) FFmpeg decoder");
|
||||
+
|
||||
+ StaticMutexAutoLock mon(sMutex);
|
||||
+
|
||||
+ // Use the GENERIC codec (not the _v4l2m2m wrapper). libavcodec picks
|
||||
+ // the v4l2_request hwaccel internally by walking the codec's
|
||||
+ // hw_configs once an AV_HWDEVICE_TYPE_DRM ctx is attached.
|
||||
+ AVCodec* codec = mLib->avcodec_find_decoder(mCodecID);
|
||||
+ if (!codec) {
|
||||
+ FFMPEG_LOG(" generic codec for ID %d not found", mCodecID);
|
||||
+ return NS_ERROR_NOT_AVAILABLE;
|
||||
+ }
|
||||
+
|
||||
+ // Sanity-check: refuse when libavcodec was built without the
|
||||
+ // v4l2_request hwaccel (no DRM hwaccel registered against this
|
||||
+ // codec). Distro packagers occasionally drop --enable-v4l2-request.
|
||||
+ bool hasDrmHwaccel = false;
|
||||
+ for (int i = 0;; i++) {
|
||||
+ const AVCodecHWConfig* cfg = mLib->avcodec_get_hw_config(codec, i);
|
||||
+ if (!cfg) break;
|
||||
+ if (cfg->device_type == AV_HWDEVICE_TYPE_DRM) {
|
||||
+ hasDrmHwaccel = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!hasDrmHwaccel) {
|
||||
+ FFMPEG_LOG(" codec %s has no DRM hwaccel — libavcodec built "
|
||||
+ "without --enable-v4l2-request?", codec->name);
|
||||
+ return NS_ERROR_NOT_AVAILABLE;
|
||||
+ }
|
||||
+ FFMPEG_LOG(" V4L2 stateless: codec %s : %s", codec->name, codec->long_name);
|
||||
+
|
||||
+ if (!(mCodecContext = mLib->avcodec_alloc_context3(codec))) {
|
||||
+ FFMPEG_LOG(" couldn't init HW ffmpeg context");
|
||||
+ return NS_ERROR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+ mCodecContext->opaque = this;
|
||||
+
|
||||
+ // Reuse the existing V4L2 init helpers: pixel-format selector returns
|
||||
+ // AV_PIX_FMT_DRM_PRIME, cropping disabled (FFmpeg can't crop opaque
|
||||
+ // DRM buffers). Same constraints as the stateful V4L2 path.
|
||||
+ InitHWCodecContext(ContextType::V4L2);
|
||||
+ mCodecContext->apply_cropping = 0;
|
||||
+
|
||||
+ auto releaseDecoder = MakeScopeExit(
|
||||
+ [&]() MOZ_NO_THREAD_SAFETY_ANALYSIS { ReleaseCodecContext(); });
|
||||
+
|
||||
+ if (!CreateV4L2RequestDeviceContext()) {
|
||||
+ return NS_ERROR_NOT_AVAILABLE;
|
||||
+ }
|
||||
+
|
||||
+ MediaResult ret = AllocateExtraData();
|
||||
+ if (NS_FAILED(ret)) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (mLib->avcodec_open2(mCodecContext, codec, nullptr) < 0) {
|
||||
+ FFMPEG_LOG(" Couldn't open V4L2 stateless decoder");
|
||||
+ return NS_ERROR_DOM_MEDIA_FATAL_ERR;
|
||||
+ }
|
||||
+
|
||||
+ if (mAcceleratedFormats.IsEmpty()) {
|
||||
+ mAcceleratedFormats.AppendElement(mCodecID);
|
||||
+ }
|
||||
+
|
||||
+ AdjustHWDecodeLogging();
|
||||
+
|
||||
+ FFMPEG_LOG(" V4L2 stateless FFmpeg init successful");
|
||||
+ mUsingV4L2 = true;
|
||||
+ mUsingV4L2Request = true;
|
||||
+ releaseDecoder.release();
|
||||
+ return NS_OK;
|
||||
+}
|
||||
+
|
||||
MediaResult FFmpegVideoDecoder<LIBAV_VER>::InitV4L2Decoder() {
|
||||
FFMPEG_LOG("Initialising V4L2-DRM FFmpeg decoder");
|
||||
|
||||
@@ -659,6 +758,16 @@
|
||||
# endif // MOZ_ENABLE_VAAPI
|
||||
|
||||
# ifdef MOZ_ENABLE_V4L2
|
||||
+ // firefox-fourier: try V4L2 stateless (request API) first. On
|
||||
+ // mainline-Linux Rockchip boards (RK3399 rkvdec, RK3566/RK3588
|
||||
+ // hantro, RK3588 rkvdec2) the kernel exposes only stateless
|
||||
+ // fourccs, so the stateful path below would fail anyway. On
|
||||
+ // stateful boards (Pi4 / vendor MPP) this gracefully falls
|
||||
+ // through (no DRM hwaccel registered for the codec).
|
||||
+ if (StaticPrefs::media_ffmpeg_v4l2_request_enabled() &&
|
||||
+ NS_SUCCEEDED(InitV4L2RequestDecoder())) {
|
||||
+ return;
|
||||
+ }
|
||||
// VAAPI didn't work or is disabled, so try V4L2 with DRM
|
||||
if (NS_SUCCEEDED(InitV4L2Decoder())) {
|
||||
return;
|
||||
@@ -2046,6 +2155,11 @@
|
||||
if (IsHardwareAccelerated()) {
|
||||
mLib->av_buffer_unref(&mVAAPIDeviceContext);
|
||||
}
|
||||
+ // firefox-fourier: release the DRM hwdevice ctx for the v4l2_request
|
||||
+ // hwaccel. Always safe — av_buffer_unref no-ops on a null pointer.
|
||||
+ if (mDRMDeviceContext) {
|
||||
+ mLib->av_buffer_unref(&mDRMDeviceContext);
|
||||
+ }
|
||||
#endif
|
||||
#ifdef MOZ_ENABLE_D3D11VA
|
||||
if (IsHardwareAccelerated()) {
|
||||
@@ -0,0 +1,34 @@
|
||||
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||
Subject: [PATCH 4/4] modules/libpref: add media.ffmpeg.v4l2-request.enabled
|
||||
Date: 2026-04-27
|
||||
|
||||
Background
|
||||
----------
|
||||
Toggle for the V4L2 stateless (request API) decode path introduced
|
||||
in patch 3/4. Defaults on for Linux, mirroring the
|
||||
`media.ffmpeg.vaapi.enabled`-style shape. Users can flip to false to
|
||||
force the existing stateful `InitV4L2Decoder` (or VAAPI / software
|
||||
fallbacks) without rebuilding.
|
||||
|
||||
Bug 1969297.
|
||||
|
||||
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
|
||||
--- a/modules/libpref/init/StaticPrefList.yaml
|
||||
+++ b/modules/libpref/init/StaticPrefList.yaml
|
||||
@@ -12159,6 +12159,16 @@
|
||||
type: uint32_t
|
||||
value: 2
|
||||
mirror: once
|
||||
+
|
||||
+# firefox-fourier: route V4L2 stateless (request API) decode through
|
||||
+# libavcodec's v4l2_request hwaccel (AV_HWDEVICE_TYPE_DRM). Required
|
||||
+# for mainline-Linux Rockchip rkvdec / hantro / rkvdec2. On stateful
|
||||
+# boards (Pi4 / vendor MPP) the codec's hw_configs lacks a DRM entry
|
||||
+# and the path silently falls back to InitV4L2Decoder.
|
||||
+- name: media.ffmpeg.v4l2-request.enabled
|
||||
+ type: RelaxedAtomicBool
|
||||
+ value: true
|
||||
+ mirror: always
|
||||
#endif # MOZ_WIDGET_GTK
|
||||
|
||||
# Set to true in marionette tests to disable the sanity test
|
||||
Reference in New Issue
Block a user