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(¶ms)
156 .expect("h264 decoder factory");
157 assert_eq!(dec.codec_id().as_str(), CODEC_ID_STR);
158 }
159}