upstream-submissions/firefox-fourier: bugzilla 1969297 comment draft
Independent firefox-fourier campaign (RK3399 H.264 stateless via rkvdec) overlaps significantly with David's HEVC work outlined in comment #3 — same gfxinfo / FFmpeg / sandbox plumbing. Posting our findings, including a non-obvious sandbox/libudev interaction (Mozilla's OpenAtTrap rejects fd-relative openat used by systemd's chase() inside udev_enumerate_scan_devices), would save duplicate effort. Draft is the proposed comment text plus upload notes. Final submission still needs human review + bugzilla account to post. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
# bugzilla.mozilla.org bug 1969297 — comment draft
|
||||
|
||||
**Bug**: https://bugzilla.mozilla.org/show_bug.cgi?id=1969297
|
||||
**Title**: Implement hardware decoding of h.265/HEVC with v4l2-stateless
|
||||
**Owner**: david.turner@raspberrypi.com
|
||||
**Status**: ASSIGNED, Linux/ARM64, Core :: Audio/Video: Playback
|
||||
|
||||
This bug tracks H.265/HEVC stateless. Our work targeted H.264
|
||||
stateless on Rockchip RK3399 (Pinebook Pro, mainline kernel, rkvdec
|
||||
driver) but the plumbing — gfxinfo fourcc detection, libavcodec
|
||||
hwaccel routing, RDD sandbox carve-out — is identical in shape to
|
||||
what David outlined in comment #3 ("work that needs doing"). Posting
|
||||
findings here in case it saves duplicate effort and to flag a sandbox
|
||||
interaction that any V4L2 stateless implementation will hit.
|
||||
|
||||
---
|
||||
|
||||
## Comment to post (markdown — Bugzilla renders ` ``` ` blocks)
|
||||
|
||||
Posting independent findings from a parallel firefox-fourier
|
||||
campaign on Rockchip RK3399 / Pinebook Pro / mainline rkvdec (H.264
|
||||
stateless). The plumbing is identical to what David described in
|
||||
comment #3 for HEVC, so this should fold into bug 1969297 cleanly
|
||||
once H.265-specific bits are layered on.
|
||||
|
||||
**Patch series** (validated end-to-end, RDD CPU 78% software → 5%
|
||||
hardware on bbb 1080p30 H.264, default RDD sandbox enabled, no env
|
||||
overrides):
|
||||
|
||||
1. `widget/gtk/GfxInfo.cpp` — recognize V4L2 stateless fourccs
|
||||
`S264`, `S265`, `VP9F` alongside the existing stateful set
|
||||
2. `dom/media/platforms/ffmpeg/FFmpegLibWrapper` — silent
|
||||
`av_hwdevice_ctx_create` wrapper (suppresses libavutil's stderr
|
||||
spam when the autodetect tries unsupported devices)
|
||||
3. `dom/media/platforms/ffmpeg/FFmpegVideoDecoder` — split V4L2
|
||||
stateless init (`InitV4L2RequestDecoder`) from stateful
|
||||
(`InitV4L2Decoder`), with a two-pass codec-name-first /
|
||||
`hw_configs`-fallback probe so it works against both legacy
|
||||
(`AV_HWDEVICE_TYPE_DRM`) and modern (`AV_HWDEVICE_TYPE_V4L2REQUEST`,
|
||||
value 15 in Kwiboo's fork) FFmpeg vintages
|
||||
4. `modules/libpref/init/StaticPrefList.yaml` — gate behind
|
||||
`media.ffmpeg.v4l2-request.enabled` (default true)
|
||||
5. `security/sandbox/linux/{broker/SandboxBrokerPolicyFactory,SandboxFilter}.cpp`
|
||||
— RDD sandbox extension: `/dev/media*` (driver-matched against
|
||||
the existing `/dev/video*` walk), MEDIA_IOC_* ioctl family `'|'`,
|
||||
plus AddTree on `/sys/class`, `/sys/bus`, `/sys/dev/char`,
|
||||
`/sys/devices/platform`, `/run/udev`, `/etc/udev/udev.conf`,
|
||||
`/proc/self`, `/dev/dma_heap`
|
||||
|
||||
The series is published on git.reauktion.de/marfrit/marfrit-packages
|
||||
under `arch/firefox-fourier/patches/`.
|
||||
|
||||
**The non-obvious finding worth surfacing here:**
|
||||
`udev_enumerate_scan_devices()` returns `-EUNATCH` (-49) inside
|
||||
RDD's sandbox even with all the broker carve-outs above in place.
|
||||
Mozilla's `OpenAtTrap` in `security/sandbox/linux/SandboxFilter.cpp`
|
||||
explicitly rejects fd-relative `openat()`:
|
||||
|
||||
```c
|
||||
if (fd != AT_FDCWD && path[0] != '/') {
|
||||
SANDBOX_LOG("unsupported fd-relative openat(%d, \"%s\", 0%o)", fd, path, flags);
|
||||
return BlockedSyscallTrap(aArgs, nullptr); // returns -ENOSYS
|
||||
}
|
||||
```
|
||||
|
||||
systemd v255+ uses fd-relative `openat()` extensively inside its
|
||||
`chase()` symlink-resolver for TOCTOU safety, and `chase()` is the
|
||||
spine of `udev_enumerate_scan_devices`. So libudev fails inside the
|
||||
sandbox no matter how permissive the broker policy is — the calls
|
||||
never reach the broker. Confirmed by bpftrace comparison
|
||||
(sandbox-on vs sandbox-off): full `openat("/")`, `openat("sys")`,
|
||||
`openat("bus")`, `openat("..")` chase flurry under sandbox-off,
|
||||
zero `openat()` events under sandbox-on.
|
||||
|
||||
**Workaround we shipped** (in our ffmpeg-v4l2-request fork): a
|
||||
brute-force fallback inside `libavutil/hwcontext_v4l2request.c`'s
|
||||
`v4l2request_open_decoder` that enumerates `/dev/media[0..15]`
|
||||
directly via absolute paths plus `MEDIA_IOC_DEVICE_INFO` and
|
||||
`MEDIA_IOC_G_TOPOLOGY`, with stat()-based major/minor matching to
|
||||
resolve `/dev/videoN` paths. The fallback only activates when
|
||||
libudev's scan returns negative. Same approach Chromium uses in
|
||||
`media/gpu/v4l2/stateless/` for ChromeOS where the sandbox has the
|
||||
same constraint.
|
||||
|
||||
This is a libavcodec-side fix, not a Firefox-side one — so it'd be
|
||||
appropriate either to upstream to FFmpeg (the v4l2_request hwaccel
|
||||
predates wider sandboxed-Linux deployment, so the libudev assumption
|
||||
was reasonable at the time) or carry it as a Firefox-bundled
|
||||
libavcodec patch.
|
||||
|
||||
The alternative — teaching Mozilla's broker to handle fd-relative
|
||||
`openat()` via `/proc/self/fd/<fd>/<path>` resolution — would close
|
||||
the gap for any future libudev consumer in the sandbox, but has
|
||||
TOCTOU implications I haven't audited; the libavcodec-side bypass
|
||||
felt cheaper to ship.
|
||||
|
||||
Validation log on RK3399 / Pinebook Pro / mainline rkvdec, default
|
||||
RDD sandbox, `MOZ_LOG=FFmpegLib:5`:
|
||||
|
||||
```
|
||||
V4L2 stateless FFmpeg init successful
|
||||
Format drm_prime chosen by get_format().
|
||||
Format drm_prime requires hwaccel h264_v4l2request initialisation.
|
||||
libudev probe failed (-2), falling back to brute-force /dev/media*
|
||||
Using V4L2 media driver rkvdec (brute-force) for S264
|
||||
Reinit context to 1920x1088, pix_fmt: drm_prime
|
||||
```
|
||||
|
||||
Happy to coordinate / split work / share patches if that helps the
|
||||
HEVC track. None of patches 1-4 above are H.264-specific; 5 is
|
||||
codec-agnostic. The libavcodec libudev-bypass has zero codec
|
||||
coupling.
|
||||
|
||||
---
|
||||
|
||||
## Notes for upload
|
||||
|
||||
- This is just the comment text. Don't attach the patches — Mozilla
|
||||
prefers Phabricator (D-numbers) for code review. If the H.264 work
|
||||
is upstreamed it should go through Phabricator with David tagged.
|
||||
- Suggest emailing David first (david.turner@raspberrypi.com) before
|
||||
pasting in the bug, in case he's already half-implemented something
|
||||
similar — saves a thrash if there's overlap.
|
||||
- The /proc/self/fd/ trick mentioned at the end is real (and is how
|
||||
Chromium handles its own broker for some paths). If pursued upstream
|
||||
in Mozilla, see security/sandbox/linux/broker/SandboxBroker.cpp
|
||||
RealPath() + SymlinkPermissions() for the existing precedent.
|
||||
Reference in New Issue
Block a user