oxideav-bitstream 0.0.2

Minimal IDR/keyframe header parsing for H.264, HEVC, AV1 — used by oxideav HW-accel bridge crates (vaapi, vdpau, vulkan-video) to populate slice-data API parameter buffers without pulling a full SW codec
Documentation
  • Coverage
  • 47.48%
    302 out of 636 items documented0 out of 139 items with examples
  • Size
  • Source code size: 387.8 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 3.2 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 3s Average build duration of successful builds.
  • all releases: 5s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • OxideAV/oxideav-bitstream
    1 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • MagicalTux

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.