Skip to main content

oxideav_h264/
lib.rs

1//! Pure-Rust **H.264 / AVC** codec for [`oxideav`].
2//!
3//! **This crate is currently empty.** A previous implementation lives on
4//! the [`old`](https://github.com/OxideAV/oxideav-h264/tree/old) branch
5//! but is being rewritten from scratch with the ITU-T Rec. H.264 |
6//! ISO/IEC 14496-10 specification (2024-08 edition) as the single
7//! authoritative source. No external decoder code is consulted while
8//! writing this implementation.
9//!
10//! The crate exposes a registration entry point so the workspace
11//! aggregator keeps building, but no decoder or encoder is registered
12//! yet — every packet routed here errors out with `Unsupported`.
13//!
14//! See `README.md` for the spec coverage matrix as it grows.
15
16pub(crate) mod bitstream;
17pub(crate) mod cabac;
18pub(crate) mod cabac_ctx;
19pub(crate) mod cavlc;
20#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
21pub mod deblock;
22#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
23pub mod decoder;
24#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
25pub mod dpb_output;
26#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
27pub mod inter_pred;
28#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
29pub mod intra_pred;
30#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
31pub mod macroblock_layer;
32#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
33pub mod mb_address;
34#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
35pub mod mb_grid;
36#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
37pub mod mv_deriv;
38#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
39pub mod nal;
40#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
41pub mod non_vcl;
42#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
43pub mod picture;
44#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
45pub mod poc;
46#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
47pub mod pps;
48#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
49pub mod reconstruct;
50#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
51pub mod ref_list;
52#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
53pub mod ref_store;
54#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
55pub mod scaling_list;
56pub mod sei;
57#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
58pub mod simd;
59#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
60pub mod slice_data;
61#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
62pub mod slice_header;
63#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
64pub mod sp_transform;
65#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
66pub mod sps;
67#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
68pub mod sps_extension;
69#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
70pub mod subset_sps;
71#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
72pub mod transform;
73#[doc(hidden)] // internal — exposed for tests/fuzz; not part of the stable API
74pub mod vui;
75
76pub mod avcc;
77
78pub mod h264_decoder;
79
80pub mod h264_encoder;
81
82pub mod encoder;
83
84pub mod es_demux;
85
86use oxideav_core::{CodecCapabilities, CodecId, CodecTag};
87use oxideav_core::{CodecInfo, CodecRegistry, RuntimeContext};
88
89/// Codec id constant — matches the historical `"h264"` id used by
90/// containers (MKV `V_MPEG4/ISO/AVC`, MP4 `avc1`, AVI `H264`/`X264`).
91pub const CODEC_ID_STR: &str = "h264";
92
93/// Register the H.264 decoder with a codec registry.
94///
95/// Claims the historical FourCCs used by MKV (`V_MPEG4/ISO/AVC` maps
96/// to `AVC1`), MP4 (`avc1`, `avc3`), and AVI (`H264`, `X264`, `h264`).
97pub fn register_codecs(reg: &mut CodecRegistry) {
98    let caps = CodecCapabilities::video("h264_sw")
99        .with_lossy(true)
100        // Round-475 — `lossless=true` (High 4:4:4 Predictive transform
101        // bypass) on the High-family encoder path.
102        .with_lossless(true)
103        .with_intra_only(false)
104        .with_max_size(8192, 8192)
105        // Round-475 — the encoder input layouts (8 / 10 / 12-bit 4:2:0 /
106        // 4:2:2 / 4:4:4 and grey); the gateway ladder reads this list.
107        .with_pixel_formats(h264_encoder::accepted_pixel_formats().to_vec());
108    reg.register(
109        CodecInfo::new(CodecId::new(CODEC_ID_STR))
110            .capabilities(caps)
111            .decoder(h264_decoder::make_decoder)
112            .encoder(h264_encoder::make_encoder)
113            .encoder_options::<h264_encoder::H264EncoderOptions>()
114            .tags([
115                CodecTag::fourcc(b"H264"),
116                CodecTag::fourcc(b"h264"),
117                CodecTag::fourcc(b"AVC1"),
118                CodecTag::fourcc(b"avc1"),
119                CodecTag::fourcc(b"avc3"),
120                CodecTag::fourcc(b"X264"),
121                CodecTag::fourcc(b"x264"),
122            ]),
123    );
124}
125
126/// Unified registration entry point: install the H.264 codec factories
127/// into the codec sub-registry of a [`RuntimeContext`], plus the raw
128/// Annex-B byte-stream demuxer ([`es_demux`], `.h264` / `.264`).
129///
130/// This is the preferred entry point for new code — it matches the
131/// convention every sibling crate now follows. Direct callers that need
132/// only the codec sub-registry can keep using [`register_codecs`].
133///
134/// Also wired into [`oxideav_meta::register_all`] via the
135/// [`oxideav_core::register!`] macro below.
136pub fn register(ctx: &mut RuntimeContext) {
137    register_codecs(&mut ctx.codecs);
138    es_demux::register(&mut ctx.containers);
139}
140
141oxideav_core::register!("h264", register);
142
143#[cfg(test)]
144mod tests {
145    use super::*;
146    use oxideav_core::{CodecId, CodecParameters, RuntimeContext};
147
148    #[test]
149    fn register_via_runtime_context_installs_codec_factory() {
150        let mut ctx = RuntimeContext::new();
151        register(&mut ctx);
152        let params = CodecParameters::video(CodecId::new(CODEC_ID_STR));
153        let dec = ctx
154            .codecs
155            .first_decoder(&params)
156            .expect("h264 decoder factory");
157        assert_eq!(dec.codec_id().as_str(), CODEC_ID_STR);
158    }
159}