Files
marfrit 8756ce38be
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 r2 + firefox-fourier 150.0.1 + KWIN_PIVOT.md
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.
2026-04-28 12:02:18 +00:00

211 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` (~L10301110): 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 L173174) 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~258270 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.