moq-vaapi
⚠️ AI GENERATED. This crate was written by an AI agent (Claude), using the repositories below as references. How closely individual files track upstream varies, so treat the whole thing as derived work and review before relying on it. The encoder and the decoder have both been checked against ffmpeg's software codecs on Intel hardware (see below).
A small, self-contained VA-API H.264 hardware codec for Linux (Intel / AMD), derived from discord/cros-libva @ discord-0.0.13 and discord/cros-codecs @ discord-0.0.5 — both BSD-3-Clause, themselves forks of Intel's cros-libva (ChromiumOS).
It exists to give moq's moq-video a thin,
crates.io-publishable VA-API codec brick instead of a multi-backend framework
pulled in as a git dependency.
What it does
- H.264 encode over VA-API: an Annex-B elementary stream out (packed SPS/PPS + slice headers, low-latency IPPP, CBR rate control whose bitrate can change between frames, the color space labelled in the VUI). Three inputs: tightly-packed NV12 from the CPU, an NV12 DMA-BUF at the encoder's size encoded in place, and any other importable DMA-BUF (packed RGB, YUYV, NV12 at another size or in another color space) converted and scaled into the encoder's surface on the GPU. NV12 and BGRX input are tested; the other formats go through the same video processor call untested. Checked on Intel Meteor Lake (iHD 26.1.5) by decoding with ffmpeg: luma above 35 dB PSNR against the source, and RGB converted to BT.601 and BT.709 to within a few code values. These run as tests wherever ffmpeg and a VA-API device are both present.
- DMA-BUF import and video post-processing.
dmabufwraps a DRM PRIME buffer as a surface without copying it;vppblits one surface into another throughVAEntrypointVideoProc, scaling, converting, and re-tiling on the way. - H.264 decode over VA-API: one Annex-B access unit in, tightly-packed NV12 out, with in-stream parameter sets, a conformant DPB (reference marking, reordering, frame_num gaps), and mid-stream resolution changes. Progressive 8-bit 4:2:0 only, with right/bottom cropping supported and left/top cropping rejected. Verified bit-exact against ffmpeg's software decoder on Intel Meteor Lake (iHD 26.1.5) for constrained baseline, main with B-frames, high at 720p, and a cropped non-macroblock-aligned size. The main-with-B-frames case runs as a test wherever ffmpeg and a VA-API device are both present.
- Pinned, vendored headers. libva's headers are vendored into
libva/(seejust vendor) and fed to bindgen, so generating the bindings needs no system libva-dev — onlylibclang— and the pinned version means a system libva bump can't drift the bindings. - Links system libva on Linux. The generated
va*symbols are resolved by linking the systemlibva/libva-drm(via pkg-config), so avaapi-enabled binary requireslibva.sopresent at runtime — fine for a build that targets VA-API hardware. VA-API's ABI is stable, so a newer system libva links against the pinned bindings. (On non-Linux hosts the crate only builds as an rlib, which leaves the symbols for the final binary, so it stays compilable for development.)
Layout
src/— libva bindings (bindings,display,surface,buffer, ...), the H.264 bitstream layer (bitstream_utils,codec::h264), the thin encode and decode drivers (encode,decode), DMA-BUF import (dmabuf), video post-processing (vpp), and the color space both share (color).libva/— vendored libva headers (checked in; refreshed byjust vendor).build.rs+bindgen_gen.rs+libva-wrapper.h— bindgen setup.
Development
Recipes run inside the nix devShell:
The crate compiles on any OS (macOS included) — the rlib build is header-only and defers the libva link to the final binary, which is Linux-only.
Licensing
BSD-3-Clause (see LICENSE). Vendored upstreams keep their notices:
LICENSE.cros-codecs and the vendored libva headers
under LICENSE.libva (MIT).