# rusty_h264-decoder
[](https://crates.io/crates/rusty_h264-decoder)
[](https://docs.rs/rusty_h264-decoder)
[](https://github.com/remade-with-rust/rusty_h264/actions/workflows/ci.yml)
[](https://github.com/remade-with-rust/rusty_h264/blob/main/LICENSE)
[](https://github.com/Remade-With-Rust)
[](https://www.mata.network/)
> **The decode pipeline** of the pure-Rust [`rusty_h264`](https://crates.io/crates/rusty_h264)
> codec — Constrained Baseline **+ B-slices + most of High profile**, CAVLC and
> **CABAC**. Validated **bit-exact against Cisco's `h264dec`** over openh264's
> conformance corpus and **pixel-exact vs ffmpeg** on the CABAC paths.
> `#![forbid(unsafe_code)]`, BSD-2, no C in the dependency tree.
**Most users want the facade — [`rusty_h264`](https://crates.io/crates/rusty_h264)**,
which re-exports `Decoder`, `YuvFrame` and the encoder. Depend on this crate
directly only if you want a decoder with no encoder pulled in.
Part of **[Remade With Rust](https://github.com/Remade-With-Rust)** by
**[Mata Network](https://www.mata.network/)** — the H.264 decoder inside
**[remade_ffmpeg_rs](https://github.com/Remade-With-Rust/remade_ffmpeg_rs)**.
---
## Install
```sh
cargo add rusty_h264-decoder rusty_h264-common
```
```rust
use rusty_h264_decoder::Decoder;
// One call: splits access units, assembles multi-slice pictures,
// and returns frames in DISPLAY order (POC-reordered).
let frames = Decoder::new().decode_stream(&annex_b_bytes)?;
// Or stream it — one picture per access unit, in DECODE order:
let mut dec = Decoder::new();
if let Some(pic) = dec.decode(&access_unit)? {
let poc = dec.last_poc(); // pair with this to reorder yourself
}
```
Input is **Annex-B** (start codes). `YuvFrame` carries raw planar 4:2:0 (I420).
## What it decodes
- **Constrained Baseline** — `I_16x16` / `I_4x4` / `I_PCM` intra, `P_Skip`,
P 16×16 / 16×8 / 8×16 / `P_8x8`, quarter-pel motion compensation, in-loop
deblocking, a multi-reference DPB with POC reordering and MMCO.
- **B-slices** — temporal *and* spatial direct, implicit *and* explicit weighted
prediction, the L0 / L1 / Bi partitions, `B_Skip` and `B_Direct`.
- **Most of High profile (CAVLC)** — the 8×8 integer transform and 8×8 intra
prediction, sequence and picture **scaling matrices**,
`transform_size_8x8_flag`, the second chroma QP offset.
- **CABAC (Main profile)** — I slices (`I_4x4`, `I_16x16` incl. all four 16×16
modes, luma DC + AC), P slices (`P_Skip`, every partition type and sub-type,
mvd, MC, residual) and B slices (`B_Skip`, `B_Direct_16x16`, L0/L1/Bi
16×16 / 16×8 / 8×16, `B_8x8` with per-sub-partition direction, spatial +
temporal direct). Baseline/Main I + P + B streams decode fully pixel-exact
end to end.
Not yet: CABAC `I_PCM` (errors gracefully), High-profile 8×8 CABAC residual,
and full JVT-suite conformance.
## How correctness is enforced
- **35 of 35** clean streams from openh264's conformance corpus decode
**byte-for-byte identical** to Cisco's `h264dec`.
- The CABAC bring-up was verified **symbol-by-symbol** against an instrumented
openh264 oracle (comparing the arithmetic decoder's `dif`/`rng`/`cnt` state),
then gated **pixel-exact vs ffmpeg**.
- The reconstruction path is shared with the encoder via
[`rusty_h264-common`](https://crates.io/crates/rusty_h264-common), so the two
halves agree bit-for-bit by construction.
## Hardening
A decoder is a parser for hostile input, so it is **fuzzed to never panic and
never hang**. The mutation fuzzer carries committed CABAC seeds covering every
macroblock type and runs thousands of mutations per seed. Three DoS-class bugs
found that way are fixed and regression-gated: an infinite `cabac_unary` loop
(the engine zero-fills past EOF and keeps yielding 1-bins), an out-of-bounds
`cabac_init_idc` context-table index, and an unbounded frame-num-gap allocation
(`log2_max_frame_num` / `log2_max_pic_order_cnt_lsb` are now bounded too).
Errors surface as `DecodeError::{Truncated, MissingParameterSet, Unsupported}` —
never a panic.
## Performance
1080p, single core, bit-exact:
| default SIMD kernels (`asm`) | **~145 Mpx/s** |
| 100% safe Rust (`--no-default-features`) | **~109 Mpx/s** |
Reference: ffmpeg's *native* `h264` software decoder at ~590 Mpx/s on the same
machine — the fastest widely-available SW H.264 decoder, and a deliberately
tougher bar than openh264's own `h264dec`. Most of the recent gain came from
**byte-identical redundancy elimination** in the pure-Rust glue rather than new
asm: skipping B-only motion/ref work on Baseline streams (+12%), move-not-clone
on the DPB reference frame, and passing the deblock filter the empty grids it
doesn't use. Reproduce with
[`bench/decode_speedtest.sh`](https://github.com/remade-with-rust/rusty_h264/blob/main/bench/decode_speedtest.sh).
## Features
| `asm` | — | Route MC, deblocking and the inverse DCT through the vendored openh264 SIMD asm in [`rusty_h264-accel`](https://crates.io/crates/rusty_h264-accel). The `unsafe` FFI stays quarantined there; this crate remains `forbid(unsafe)`. x86-64 + `nasm`. |
| `profile` | — | Dev-only `rdtsc` stage profiler (used by the `profile_decode` test) — zero cost when off. |
SIMD is enabled through the facade's default `asm` feature; standalone, the
scalar path is the default.
## Where this sits
| [`rusty_h264`](https://crates.io/crates/rusty_h264) | the public, safe facade API — **depend on this** |
| [`rusty_h264-common`](https://crates.io/crates/rusty_h264-common) | bitstream I/O, transforms, prediction, MC, deblock |
| [`rusty_h264-encoder`](https://crates.io/crates/rusty_h264-encoder) | the encode pipeline |
| **[`rusty_h264-decoder`](https://crates.io/crates/rusty_h264-decoder)** | **← you are here** — the decode pipeline |
| [`rusty_h264-accel`](https://crates.io/crates/rusty_h264-accel) | optional openh264 SIMD asm — the one `unsafe` crate |
## The Remade With Rust ecosystem
**Remade With Rust** is an initiative by **[Mata Network](https://www.mata.network/)**
to rebuild essential C and C++ tools in Rust — for the memory safety, the
predictable performance, and the freedom of a permissive license. Each project
is a reimplementation, not a fork: same wire protocols and file formats, new
code you can actually depend on. No copyleft. No surprises.
| 🎬 **[remade_ffmpeg_rs](https://github.com/Remade-With-Rust/remade_ffmpeg_rs)** | **Our FFmpeg alternative.** Drop-in `ffmpeg` and `ffprobe` binaries — demux → decode → filter → encode → mux, rebuilt as composable Rust crates with **zero GPL/LGPL**. Apache-2.0. `rusty_h264` is its H.264 codec. |
| 🧠 **[FFAI](https://github.com/Remade-With-Rust/FFAI)** | **Our sister project: media *for* AI.** "The AI media toolkit, remade with rust." Embedded ASR + TTS (**Mercury**), OCR (**Carmenta**) and vision-language captioning (**Argus**) behind an ffmpeg-style, swap-by-name architecture — no Python, no CUDA. MIT OR Apache-2.0. |
| 🌐 **[Mata Network](https://www.mata.network/)** | **The home page.** *"Stop sacrificing your privacy for convenience."* Sovereign, self-hostable privacy infrastructure — wallet & identity, password manager, contact manager, and a browser extension that stops information leaking as you browse. Remade With Rust is its open-source arm. |
→ All projects: **[github.com/Remade-With-Rust](https://github.com/Remade-With-Rust)**
## License
BSD-2-Clause — see [LICENSE](https://github.com/remade-with-rust/rusty_h264/blob/main/LICENSE).