Files
test0r f4bdd54543
build and publish packages / distcc-avahi-aarch64 (push) Successful in 46s
build and publish packages / lmcp-any (push) Successful in 8s
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 12m20s
build and publish packages / claude-his-debian (push) Successful in 15s
arch/chromium-fourier: workspace + STUDY.md (no PKGBUILD yet)
Stage the next side-project: patch upstream Chromium to do HW video
decode through VaapiVideoDecoder + our marfrit/libva-v4l2-request-fourier
backend on a mainline Linux Wayland system, instead of going through
the chromeos pipeline that fails on Brave today.

STUDY.md captures:
- The exact failure stack we're fixing (PickDecoderOutputFormat ->
  ImageProcessor init failure in media/gpu/chromeos/video_decoder_pipeline.cc)
- Three candidate patches (chromeos pipeline bypass, V4L2VideoDecoder
  factory un-gate, libva backend default)
- Reference forks (JeffyCN, igel-oss, 7Ji-PKGBUILDs/chromium-mpp,
  amazingfate/chromium-debian-build) — all use the older V4L2VDA path
  with vendor MPP, not VAAPI; useful for PKGBUILD shape and
  factory-un-gating patterns but not directly applicable
- Build plan on fermi (depot_tools, ~30 GB fetch, 6-10 h initial build,
  distcc-avahi acceleration through CT108 + tesla)
- Phase order — workspace done now, build env next session,
  patches after that, package after that, brave-fourier rebase last

No PKGBUILD added yet; one will land when there's something to actually
package. Build artifacts intentionally not in repo (chromium tree is
~100 GB).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 22:51:01 +00:00

166 lines
7.7 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.
# chromium-fourier — Chromium with V4L2-stateless / VAAPI HW decode on mainline-kernel ARM Linux
## Goal
Patch upstream Chromium so it can do hardware video decode through
`VaapiVideoDecoder` on a plain Linux Wayland system on Rockchip
(RK3566 / RK3588), via our `marfrit/libva-v4l2-request-fourier` libva
backend. Target consumers: Brave (rebuilt from the same patched
Chromium), upstream Chromium itself for Arch Linux ARM, and any other
Blink-based browser that picks up the patches.
This fills a niche **no shipping fork** currently fills — every existing
ARM-Linux Chromium with HW decode (7Ji's `chromium-mpp`, Ubuntu's
`liujianfeng1994/rockchip-multimedia` PPA, JeffyCN's recipe, etc.) goes
through the **vendor MPP path** on **5.10 BSP kernel + X11 + Mali blob
+ panfork**. We're going for **mainline kernel + V4L2 stateless +
Wayland + panfrost / panthor**, the direction Fourier is heading anyway.
## What's actually broken in stock Chromium 147+
1. **`media/gpu/chromeos/video_decoder_pipeline.cc`** is selected on Linux
when it shouldn't be. It then tries to initialize a V4L2
`ImageProcessor` (a ChromeOS-specific m2m chip block for color
conversion / scaling) that doesn't exist on a plain Linux Wayland
system. Failure surface:
```
PickDecoderOutputFormat(): Initializing ImageProcessor; max buffers: 16
ERROR: failed Initialize()ing the frame pool
```
2. **`VaapiVideoDecoder`** *is* compiled into stock Chromium / brave-bin
(verified: `strings /opt/brave-bin/brave | grep VaapiVideoDecoder`),
but the chromeos pipeline preempts it. Once the pipeline fails, the
decoder selection bails — it never falls back to direct
`VaapiVideoDecoder`.
3. **`V4L2VideoDecoder`** factory is `BUILDFLAG(IS_CHROMEOS)`-gated.
Feature flags `UseChromeOSDirectVideoDecoder` /
`V4L2FlatStatelessVideoDecoder` are no-ops on a non-ChromeOS build —
their flag strings don't even appear in the binary.
## The patch shape (sketch)
### Patch 1 — bypass the chromeos pipeline on Linux
`media/gpu/chromeos/video_decoder_pipeline.cc` is reached from
`media/gpu/vaapi/vaapi_video_decoder.cc` somewhere in
`ApplyResolutionChangeWithScreenSizes`. Either:
- Skip the chromeos pipeline entirely on Linux non-ChromeOS, going
straight to `VaapiVideoDecoder::CreateContextAndScopedVASurfaces` for
frame allocation, OR
- Replace `PickDecoderOutputFormat`'s ImageProcessor probing with a
no-op that just trusts the VAAPI surface format (since on real
ChromeOS the IP does color conversion that we don't need in our
dmabuf-passthrough path).
Reference: [crbug 40192819] "VaapiVideoDecoder on linux"
(<https://issues.chromium.org/issues/40192819>).
### Patch 2 — un-gate `V4L2VideoDecoder` factory for non-ChromeOS Linux
Optional but useful as a fallback. The class is compiled in; only the
factory registration is `IS_CHROMEOS`-gated. The `igel-oss/meta-browser-hwdecode`
patch <https://github.com/igel-oss/meta-browser-hwdecode/blob/master/recipes-chromium/chromium/files/0001-Add-support-for-V4L2VDA-on-Linux.patch>
shows the historical pattern for the V4L2VDA factory; the modern factory
is in `media/gpu/v4l2/v4l2_video_decoder.{h,cc}`.
This is **plan B** if Patch 1 turns out harder than expected — V4L2VDA
talks to `/dev/videoN` directly without going through libva, which means
we don't depend on the `libva-v4l2-request-fourier` decode-submission
path either. Shorter end-to-end critical path, but a more invasive
factory change.
### Patch 3 — point libva at our backend (build-time)
Already configurable at runtime via `LIBVA_DRIVER_NAME=v4l2_request`,
but a Brave/Chromium binary that defaults to it would be cleaner. Could
patch the GPU process startup to set the env var if not already set.
Cosmetic, optional.
## Reference forks (read these side-by-side with our patch)
- **JeffyCN/meta-rockchip chromium recipe** — the upstream of the V4L2VDA
factory un-gating and `libv4l-rkmpp` shim that every shipping fork
uses. <https://github.com/JeffyCN/meta-rockchip/tree/master/dynamic-layers/recipes-browser/chromium>
Caveat: targets the V4L2VDA path (Plan B), not the modern
`VaapiVideoDecoder` (Plan A) we want.
- **igel-oss/meta-browser-hwdecode** — Yocto layer with the original
`0001-Add-support-for-V4L2VDA-on-Linux.patch`. 2017-vintage but the
pattern still applies. <https://github.com/igel-oss/meta-browser-hwdecode>
- **7Ji-PKGBUILDs/chromium-mpp** — the most recent ALARM-shipping
variant, Chromium 132 with MPP. Useful for the **PKGBUILD shape** and
the patch-set list, even though we're not using MPP.
<https://github.com/7Ji-PKGBUILDs/chromium-mpp>
- **amazingfate/chromium-debian-build** — Debian flavour of the same
approach, for reference. <https://github.com/amazingfate/chromium-debian-build>
## Build environment
- **Source tree**: `gn` / `depot_tools`, hosted on **fermi** (Arch ARM
aarch64 LXC on hertz). Fetch is ~30 GB; full chromium tree is ~100 GB
with build artifacts. Fermi's storage budget needs checking — may
need to bind-mount a hertz path with more headroom.
- **Build acceleration**: `distcc-avahi` is already deployed. Wire the
chromium build to use distcc through CT108 + tesla as compile workers.
Pump mode can shave further; chromium's ninja will accept distcc'd
cc/c++ via wrappers.
- **First build wall time estimate**: 610 hours initial on fermi alone;
35 hours with distcc-avahi if the network throughput holds. After
the first build, incrementals on small patches are ~1015 min.
- **Configure flags**: `gn args` — start from Arch's `chromium`
PKGBUILD, add `use_vaapi=true use_v4l2_codec=true is_official_build=false`.
- **Output**: `chromium-fourier-<chromium-ver>-1-aarch64.pkg.tar.zst`
shipping `/usr/bin/chromium`. `provides=(chromium) conflicts=(chromium)`
shape, same as `ffmpeg-v4l2-request-git`'s replacement of stock ffmpeg.
## Validation path
Once a patched binary builds:
1. Launch with the same env we use for mpv-vaapi:
`LIBVA_DRIVER_NAME=v4l2_request LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video0`
2. Open `chrome://gpu` — should show "Video Decode: Hardware accelerated"
(not "Disabled" or "Software only").
3. Open a 1080p H.264 file:// URL, watch CPU on `/dev/video0` openers,
measure Brave's GPU process CPU% during playback.
4. Cross-reference with `mpv --hwdec=vaapi` numbers once the
libva-v4l2-request-fourier decode-submission path also lands.
## Order of operations
Phase A (this session): workspace + STUDY.md (this file). **Done.**
Phase B: build environment — install `depot_tools` on fermi, run
`fetch chromium`, get a baseline (unpatched) build to confirm fermi can
build chromium at all. ~one full day.
Phase C: identify the exact line to flip for Patch 1 by reading
`media/gpu/chromeos/video_decoder_pipeline.cc` +
`media/gpu/vaapi/vaapi_video_decoder.cc` against current Chromium
master. Iterate the patch on a real build.
Phase D: package as `chromium-fourier` PKGBUILD, hook into
marfrit-packages CI on fermi (already has the pattern from
ffmpeg-v4l2-request-git).
Phase E: rebase Patch 1 (and Patch 2 if needed) onto Brave's source
tree, ship as `brave-fourier` next to `chromium-fourier`. Brave's tree
adds ~50 patches on top of upstream Chromium; the chromeos-pipeline
seam should be unchanged across that delta, so this should be a
mechanical rebase.
## Out of scope
- HW video **encode** (cameras, webcam streams). RK3566 has a separate
encoder block on `/dev/video2`; not a Fourier priority.
- HEVC / VP9 / AV1 — RK3566 has no HW for these. RK3588 has VDPU381
but our libva backend doesn't speak HEVC yet.
- WebGL / WebGPU performance — separate concern, not part of video
decode.
- Brave-specific features (Shields, Wallet, etc.) — they all live in
Brave's source tree on top of Chromium and are unaffected by our
decode patches.