oxideav-bitstream
Minimal IDR / keyframe header parsing for H.264, HEVC and AV1, used by the
oxideav framework's hardware-accel
bridge crates (oxideav-vaapi,
oxideav-vdpau,
oxideav-vulkan-video)
to populate slice-data API parameter buffers.
Why a parser-only crate?
VA-API, VDPAU and Vulkan Video all expect the host application to do
the header parsing itself and submit a fully-populated parameter
buffer (VAPictureParameterBufferH264, VdpPictureInfoH264,
VkVideoDecodeH264PictureInfoKHR, and the analogous structs for HEVC
and AV1). The GPU only handles the slice data once the parameters are
in hand.
That parser layer is universal across the three back-ends — the
underlying bitstream syntax is the same — but the full SW codec
crates (oxideav-h264, oxideav-h265, oxideav-av1) drag in DCT,
entropy decode, motion compensation and filtering. Linking those just
to recover a few dozen integer fields is wasteful.
So this crate exists to host the minimal parsing logic that all three HW bridges share, without the SW-codec baggage.
Scope
| H.264 | HEVC | H.266 | AV1 | |
|---|---|---|---|---|
| Annex-B / OBU framing | yes | yes | yes | yes (leb128 sizes) |
| NAL header decode | yes | yes | yes | n/a |
| Sequence header (SPS / VPS+SPS / Sequence-Header OBU) | yes | yes | structural VPS (7.3.2.3, single-layer) + SPS (7.3.2.4 + 7.3.3) | yes |
| Picture header (PPS / Frame-Header OBU) | yes | yes | structural (7.3.2.5 prefix) | yes |
| Minimal slice header (IDR / I-slice / KEY_FRAME) | yes | yes | deferred | yes |
| DCT, entropy decode, motion compensation, in-loop filtering | no | no | no | no |
| Scaling lists | rejected | rejected | n/a | n/a |
| FMO / ASO / multiple slice groups | rejected | n/a | n/a | n/a |
| Tiles / WPP | n/a | rejected | n/a | n/a |
| AV1 decoder model / operating points beyond [0] / film grain | n/a | n/a | n/a | rejected |
The crate refuses inputs that fall outside the supported envelope with
BitstreamError::Unsupported(reason) rather than silently producing
garbage parameter buffers.
H.266 (VVC), VP9, VP8, MPEG-2 and VC-1 have landed as additional modules; their scope is incremental — see each module's rustdoc for what's parsed today versus deferred.
Module layout
src/
├── lib.rs # re-exports each codec module + BitstreamError
├── bit_reader.rs # shared u(n) / ue(v) / se(v) reader, peek_bits,
│ # more_rbsp_data, read_rbsp_trailing_bits
├── bit_writer.rs # MSB-first writer — inverse of bit_reader
├── h264.rs # H.264 SPS / PPS / minimal slice header
├── hevc.rs # HEVC VPS / SPS / PPS / minimal slice header
├── h266.rs # H.266 Annex-B walker + NAL header + structural SPS + PPS
├── mpeg2.rs # MPEG-2 sequence + picture + extension headers
├── vc1.rs # VC-1 sequence + entry-point + picture header
├── vp8.rs # VP8 keyframe header + IVF demuxer
├── vp9.rs # VP9 uncompressed header
├── ivf.rs # IVF frame demuxer (VP8 / VP9 / AV1 fixtures)
└── av1.rs # AV1 leb128 reader+writer, OBU walker+emitter, key-frame headers
There is no cross-codec abstraction in v0. Each codec sub-module
exposes its own parse_* entry points and result structs, and a
convenience parse_idr_only (parse_keyframe_only for AV1) that
walks a complete Annex-B / OBU stream, finds the first
IDR / keyframe access unit, and returns the parsed parameters
plus a slice (or set of slices) of bytes the HW decoder consumes.
No unsafe
This crate contains zero unsafe blocks. Bit reading is software,
no FFI involved.
Workspace clean-room policy
The bitstream-syntax tables in this crate are written from the relevant spec PDFs:
- ITU-T H.264 (a.k.a. ISO/IEC 14496-10 — AVC),
- ITU-T H.265 (a.k.a. ISO/IEC 23008-2 — HEVC),
- ITU-T H.266 (a.k.a. ISO/IEC 23090-3 — VVC),
- ITU-T H.262 (a.k.a. ISO/IEC 13818-2 — MPEG-2),
- SMPTE ST 421 (VC-1),
- AV1 Bitstream & Decoding Process Specification (av1.org),
- RFC 6386 (VP8 Data Format and Decoding Guide).
Following a public spec PDF is the canonical clean-room move and is allowed under the workspace policy. We deliberately do not consult ffmpeg / libavcodec, x264, x265, libde265, libaom, dav1d, rav1e or libgav1 source. ffmpeg and aomenc are used only as black-box CLI tools to generate test fixtures.
License
MIT.