panvk-bifrost campaigns (r1..r4 Vulkan compositor + r5.video1 Vulkan
video decode) shipped before this repo existed; the deliverable
patches live in marfrit-packages, but the reasoning chain, phase docs,
and source-state evidence lived only in local working trees on the
development host.
This retrofit imports:
- mesa-panvk-bifrost/ — r1..r4 era phase docs (iter1..iter18)
(libmali stub blobs at iter18/blob/ excluded
— 109MB of RE artifacts replaced with a README
pointer)
- mesa-panvk-bifrost-video/ — sibling campaign phase docs + probe
- evidence/ — frozen .tgz source snapshots at each milestone
(basis for the 0005 patch diff generation)
Future iterations should branch off here from day one, so each iter is
a commit rather than a snapshot. See [[feedback-session-local-process-pins]]
for the process drift this retrofit closes.
Total: 1.9 MB across 124 files.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4.1 KiB
Phase 8 close — iter14: Brave VAAPI engagement attempt — investigation, not delivery
Result: STRUCTURAL WALL hit. Lower-stack proven green; Brave/Chromium ARM64 binary doesn't have VAAPI compiled into its dispatch. iter14 ends as a documented dead-end so future iterations don't repeat the bounce.
What iter14 actually proved
1. libva-v4l2-request-fourier + hantro-vpu chain is END-TO-END GREEN
Standalone test with ffmpeg-v4l2-request-fourier:
$ LIBVA_DRIVER_NAME=v4l2_request ffmpeg -hwaccel v4l2request \
-i /home/mfritsche/fourier-test/bbb_1080p30_h264.mp4 -t 5 -f null -
[...]
[AVHWFramesContext @ ...] Using V4L2 media driver hantro-vpu (7.0.0) for S264
frame= 120 fps= 28 q=-0.0 Lsize=N/A time=00:00:05.00 bitrate=N/A speed=1.16x
$ lsof /dev/video1
COMMAND PID USER FD TYPE DEVICE
ffmpeg 15261 mfritsche mem CHR 81,1 /dev/video1
ffmpeg 15261 mfritsche 5u CHR 81,1 /dev/video1
$ lsof /dev/media0
COMMAND PID USER FD TYPE DEVICE
ffmpeg 15261 mfritsche 4u CHR 242,0 /dev/media0
ffmpeg explicitly opens /dev/video1 (hantro-vpu) + /dev/media0 (media controller), announces the hantro driver name, and decodes 1080p30 H.264 at 1.16× realtime with ~25% of total quad-A55 CPU (bulk from audio re-encode + format conversion, not video decode). The hardware decoder is engaged.
2. Brave / Chromium ARM64 packages don't compile VAAPI into dispatch
Three signals converged:
a) chrome://gpu "Video Acceleration Information" panel shows empty Decoding and Encoding sections, even with --enable-features=Vulkan,AcceleratedVideoDecodeLinuxGL,AcceleratedVideoDecodeLinuxZeroCopyGL,VaapiVideoDecoder,VaapiIgnoreDriverChecks,V4L2VideoDecoder and LIBVA_DRIVER_NAME=v4l2_request env.
b) chrome://media-internals reports Cannot select VaapiVideoDecoder for video decoding. status=DecoderStatus::Codes::kUnsupportedConfig → Selected FFmpegVideoDecoder — VaapiVideoDecoder factory exists but rejects every config because its internal supported-profiles set is empty (libva was never queried).
c) Direct /proc/<gpu-pid>/maps inspection: the GPU process has zero libva libraries loaded. No libva.so.2, no v4l2_request_drv_video.so. VaapiWrapper code paths are never invoked.
The Arch upstream chromium PKGBUILD (which informs the Brave binary's build flavour) does not set use_vaapi=true in its GN flags, and Chromium's GN defaults use_vaapi=false on aarch64. Linux ARM64 chromium-family browsers shipped in package repos are universally built without VAAPI in dispatch.
What iter14 ruled out
- ✗ Not a libva backend bug — vainfo + ffmpeg-fourier confirm v4l2_request is healthy
- ✗ Not a hardware bug — hantro-vpu engages fine
- ✗ Not a flag-combo bug — all known Brave/Chromium VAAPI feature flags tried; LIBVA_DRIVER_NAME set;
--no-zygoteused to bypass env-stripping;VaapiIgnoreDriverChecksenabled; nothing changes the empty dispatch - ✗ Not an ANGLE-Vulkan bug — iter13 confirmed ANGLE-Vulkan engages on PanVk-Bifrost
- ✗ Not env-stripping across process boundary — libva isn't loaded in ANY child process either, not just stripped along the way
What iter14 leaves open
For a future "VAAPI in chromium on PanVk-Bifrost" goal: the path forward is building chromium from source for aarch64 with use_vaapi=true and use_v4l2_codec=true, packaged as e.g. chromium-vaapi-bifrost in marfrit-packages. This is multi-hour aarch64 CI work (chromium aarch64 build is 6-12 hours even with distcc) and a substantial PKGBUILD undertaking. Not in scope for this iteration.
iter13 close stands: the Vulkan compositor + ANGLE-Vulkan stack delivers everything the original campaign charter asked for. HW video decode in Brave was always a stretch beyond charter scope (operator framing on iter11 open: "is the vulkan output used for video display? yup").
Decision
iter14 closes as investigation complete; structural wall documented. Anyone returning to "make Brave do VAAPI HW decode" should start from this doc, NOT redo the flag-combo exhaustion that iter11/12/14 each independently bounced off.
— claude-noether, 2026-05-20