⚠️ 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.
- 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. - Loads system libva at runtime on Linux. The generated
Vafunction table loadslibva/libva-drmwithlibloading. Building needs no system libva, and a binary can start without it; opening a display reports a missing driver or library. The crate also compiles on macOS for development.
Last checked 2026-10-31, starting from the Discord vendor baselines:
| Source | Vendored baseline | ChromeOS default branch checked |
|---|---|---|
| cros-libva | discord-0.0.13, 896a248e |
59384456ac2ae78c0c3e5515f41ef1efd9b802cf |
| cros-codecs | discord-0.0.5, 9cdecb19 |
a050c6cde530e563197ee9e3e72ab01f48a0c41f |
The forks diverge, so compare commits reachable from the checked head but not the baseline, rather than replacing Discord's additions with the upstream tree. This run checked all five cros-libva commits and the one cros-codecs commit:
| Commit | Disposition |
|---|---|
cros-libva 838808ce, protected-content headers |
Not needed: no protected-content consumer or Android build in this crate. |
cros-libva 89454d66, explicit image lifetimes |
Already present in Image::create_from and Picture::{derive_image,create_image}. |
cros-libva 9f3c0d92, packed-header bindings |
Already present in bindgen_gen.rs, buffer.rs, and the H.264 encoder. |
cros-libva ed9c63b7, borrowed input buffers |
Optional copy avoidance, not a correctness fix. Keep the existing owned-buffer API; no new public API or optimization without measurement. |
cros-libva 59384456, libva 2.23 VP9 fields |
Build compatibility already covered by ..Default::default() in the retained VP9 wrapper against pinned 2.23 headers. The codec drivers support H.264 only, so no VP9 segmentation control is needed. |
cros-codecs a050c6cd, release log filtering |
Ported: remove log/release_max_level_debug, which conflicts with a consumer selecting another release level. just ci checks feature unification with log/release_max_level_trace. |
GitHub's published security-advisory endpoints for
chromeos/cros-libva,
chromeos/cros-codecs,
discord/cros-libva, and
discord/cros-codecs
all returned empty lists on this date. GitHub's global Rust advisory queries for
cros-libva and cros-codecs also returned none. This records the published
advisories checked, not a guarantee that no undisclosed vulnerabilities exist.
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.
Recipes run inside the nix devShell:
nix develop --command just check # clippy + fmt
nix develop --command just ci # check + cargo-deny
nix develop --command just vendor # refresh libva/ headers from upstreamThe crate compiles on macOS for development, with no link-time dependency on libva.
BSD-3-Clause (see LICENSE). Vendored upstreams keep their notices:
LICENSE.cros-codecs and the vendored libva headers
under LICENSE.libva (MIT).