1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//! Decoder side of the crate.
//!
//! One decode surface remains as of r428: the **spec-faithful frame
//! driver** ([`decode_av1_spec`] / [`SpecDecodeSession`]), the
//! conformance-corpus-validated decoder that wires the parsing
//! modules (`obu`, `sequence_header`, `frame_header`,
//! `tile_group_obu`), the §5.11 `PartitionWalker` syntax walk, the
//! §7.11/§7.12/§7.13 reconstruction chain, and the full §7.4 post
//! chain (deblock, CDEF, superres, loop restoration, film grain)
//! into a pixel-out entry point.
//!
//! ## The r428 mirror-path retirement
//!
//! Until r428 a second surface existed: the "encoder-mirror" decode
//! path, the exact writer-inverse of this crate's HISTORICAL
//! constrained intra encoders (fixed 16×16 and dyn-extent drivers
//! from the early encoder arcs). Those encoders emitted
//! NON-conformant streams — their leaves coded `y_mode` with the
//! §5.11.22 non-keyframe CDFs on intra frames — so their streams
//! could only be decoded by inverting the writer bug-for-bug, and
//! [`decode_av1`] tried that mirror arm first. The conformance-grade
//! encoders (r409 onward) made the mirror emit arms redundant:
//! `encode_av1` has produced spec-conformant streams ever since, and
//! every corpus stream rides the spec driver. r428 retires the whole
//! mirror surface — emit arms, mirror decode arm, and the historical
//! `Frame::Yuv420_16x16` / `Frame::Yuv420Dyn` / `Frame::YDyn`
//! variants (the [`Frame`] enum is `#[non_exhaustive]`, so match
//! sites already carried a wildcard arm). Every stream now decodes
//! through the spec driver and surfaces as [`Frame::Spec`].
// internal — exposed for tests/fuzz; not part of the stable API
pub use ;
pub use ;
use crateError;
/// One decoded (shown) frame surfaced by [`decode_av1`].
///
/// As of the r428 mirror-path retirement every stream decodes through
/// the spec-faithful driver, so [`Frame::Spec`] is the only variant
/// constructed. The enum stays `#[non_exhaustive]` (as it has been
/// since its introduction), so downstream match sites are unaffected.
/// Decode an AV1 IVF v0 buffer.
///
/// Every stream rides the spec-faithful driver
/// ([`decode_av1_spec`] — the conformance-corpus-validated decoder);
/// each SHOWN frame surfaces as [`Frame::Spec`]. The historical
/// encoder-mirror acceptance arm was retired in r428 (see the module
/// docs) — the non-conformant streams it accepted could only be
/// produced by this crate's own retired mirror emit arms, never by
/// the conformance-grade encoders behind [`crate::encode_av1`].
///
/// Returns one [`Frame`] per shown frame, in output order.
///
/// ## Errors
///
/// * Buffer ends mid-IVF-header or mid-frame — [`Error::UnexpectedEnd`].
/// * Any spec-driver parse/decode failure — the driver's typed
/// [`Error`].
/// r430 — [`decode_av1`] at an externally selected operating point
/// (§6.7.5 `choose_operating_point()`).
///
/// `operating_point` indexes the sequence header's operating-point
/// list (`0..=operating_points_cnt_minus_1`). With a non-zero
/// `OperatingPointIdc` the §5.3.1 `drop_obu()` rule skips every OBU
/// that carries an extension header and lies outside the point's
/// temporal/spatial layer set, so a temporally scalable stream
/// decodes to exactly the shown frames of the surviving layers —
/// `operating_point = 0` reproduces [`decode_av1`] byte for byte on
/// every stream.
///
/// ## Errors
///
/// * [`Error::OperatingPointOutOfRange`] — the index exceeds the
/// sequence header's list.
/// * Every [`decode_av1`] error surface otherwise.
/// Decode an **Annex B length-delimited** AV1 bitstream (r428).
///
/// The input is the raw Annex B packing (`temporal_unit_size` /
/// `frame_unit_size` / `obu_length` `leb128` nesting per Annex B.2 —
/// no IVF container). Each temporal unit is converted to its §5.2
/// low-overhead equivalent by [`crate::annexb::split_temporal_units`]
/// (enforcing the Annex B.3 consistency + temporal-delimiter
/// placement rules) and decoded through the same
/// [`SpecDecodeSession`] the IVF path drives — reference state and
/// CDF carry work identically, so a stream repacked between the two
/// formats decodes to identical pixels.
///
/// ## Errors
///
/// * [`Error::AnnexBInvalid`] / [`Error::UnexpectedEnd`] — malformed
/// Annex B framing (see [`crate::annexb::split_temporal_units`]).
/// * Any spec-driver parse/decode failure — the driver's typed
/// [`Error`].