defcom5-rockchip / rockchip-vaapi · update 2026-10-11

AV1 in hardware. Plaid Number Nine.

v3.0.0 RK3588 / RK3588S ubuntu-rockchip BSP H.264 · HEVC · VP9 · AV1

3.0.0 "Plaid Number Nine" adds AV1 Main, 8- and 10-bit, in hardware: VA-API clients hand the driver parsed parameters and tile data, Rockchip MPP wants a complete OBU stream, so the driver rebuilds the sequence and frame headers in between. Matches the Fluster reference checksums on 213/242 libaom and 31/36 Chromium conformance vectors (the rest is explained in KI-13; film grain is not applied). Verified in ffmpeg, mpv, Chrome and Firefox. The VP9 odd-width fix below still ships. Named after Number Nine's Pepper boards, the co-processor graphics cards of the late 1980s.

Firefox playing the video as a solid green frame — the bug
Before 2970×2160 · vp09 · solid green
Same video decoding cleanly in 4K after the fix
After vp09 · HW ✓ · RDD ~9% CPU

Same Orange Pi 5B · same video · same 2160p — green box → clean 4K, hardware-decoded.

Install

  1. Confirm you're on the BSP kernel

    The fix uses the RK3588 VPU, which needs the vendor BSP kernel.

    check
    ls /dev/mpp_service   # must exist. "No such file" = mainline; guide doesn't apply.
  2. Install the packaged VA-API driver

    Release 3.0.0 "Plaid Number Nine". Grab it from the release.

    bash
    cd /tmp
    wget https://github.com/defcom5-rockchip/rockchip-vaapi/releases/download/v3.0.0/rockchip-vaapi_3.0.0-1_arm64.deb
    sudo apt install ./rockchip-vaapi_3.0.0-1_arm64.deb

    If apt says librga2 or librockchip-mpp1 is not installable, add your image's Rockchip multimedia repository first. Or download from the Releases page.

  3. Use the real Firefox .deb, not the snap

    The snap build won't hardware-decode here — use the mozillateam PPA build if needed.

    check
    firefox --version   # if it says "snap", switch to the .deb build
  4. Turn on hardware decode

    Wrap Firefox so it always gets the two required env vars:

    /usr/local/bin/firefox-hw
    sudo tee /usr/local/bin/firefox-hw >/dev/null <<'EOF'
    #!/bin/sh
    export LIBVA_DRIVER_NAME=rockchip
    export MOZ_DISABLE_RDD_SANDBOX=1
    exec /usr/bin/firefox "$@"
    EOF
    sudo chmod +x /usr/local/bin/firefox-hw

    Then set these in Firefox about:config:

    about:config
    media.ffmpeg.vaapi.enabled                  = true
    media.hardware-video-decoding.enabled       = true
    media.hardware-video-decoding.force-enabled = true
  5. Launch through the wrapper

    Run firefox-hw (or point your dock/menu shortcut at it). No logout needed — it sets the env every launch.

  6. Verify AV1

    Play an AV1 title (YouTube serves most 4K as AV1; Stats for nerds shows av01…). Then:

    while it plays
    vainfo | grep -E 'Driver version|AV1'   # 3.0.0 "Plaid Number Nine", VAProfileAV1Profile0
    grep av1d /proc/interrupts            # the AV1 engine's interrupt count climbs, one per frame
    sudo fuser /dev/mpp_service           # the browser's media process holds the decoder
  7. Verify on the video that used to break (VP9)

    Play Simple Minds — Don't You (Forget About Me) at 2160p. Right-click → Stats for nerds: codec reads vp09… at 2970×2160@25 — the exact odd-width stream that used to render green.

    while it plays
    sudo fuser /dev/mpp_service   # a Firefox RDD process, single-digit %CPU = real HW decode

Keep it on the fast path

Optional · YouTube

From 3.0.0 AV1 decodes in hardware too, so the old advice to block AV1 with enhanced-h264ify no longer applies — remove that block if you set it for 2.x. (Firefox needs media.av1.enabled on.)

Advanced · alternative to the wrapper

Instead of firefox-hw you can bake the env into the launcher — but /usr/share/applications/firefox.desktop is overwritten on Firefox updates, so copy it to your user dir and edit that:

bash
mkdir -p ~/.local/share/applications
sed 's|^Exec=/usr/bin/firefox|Exec=env LIBVA_DRIVER_NAME=rockchip MOZ_DISABLE_RDD_SANDBOX=1 /usr/bin/firefox|' \
  /usr/share/applications/firefox.desktop > ~/.local/share/applications/firefox.desktop

Then fully quit and reopen Firefox from the menu. If your build's Exec= path differs, adjust it.

What 3.0.0 adds

An AV1 OBU re-serialiser (src/av1.c with a vendored copy of GStreamer's AV1 bit writer, five bugs fixed in it and segmentation implemented). The one value VA-API never passes, refresh_frame_flags, is read from the next picture's reference map, so each picture is held until its successor arrives — or decoded at once when the player syncs it, with the slot refresh following as a hidden frame. Hidden frames are shown through a synthesised show_existing_frame; hidden key frames through a second decode as an intra-only frame. Details in DEVELOPMENT.md, limits in KNOWN-ISSUES KI-13.

What the 2.x VP9 fix was

The driver exported its NV12 surface at a 16-aligned stride. For a coded width that isn't a multiple of 16 (2970 → 2976), the RK3588 Mali/EGL DMA-BUF importer expects a 64-aligned pitch, so the chroma plane landed at the wrong offset → green. The fix aligns the export stride to 64 (2970 → 3008), matching the canonical Rockchip pattern.

Layer-isolated: clean via mppvideodec (MPP core) & software; green only via VA-API → the bug was the shim, not the VPU or the file. Verified: Orange Pi 5B (RK3588S) · panfork Mesa 23 · Firefox 154 · kernel 6.1.0-1027.