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
//! Error type returned by every parser and builder in this crate.
use alloc::string::String;
use thiserror::Error;
/// Crate-wide result alias.
pub type Result<T> = core::result::Result<T, Error>;
/// Error variants that parsers + builders can return.
///
/// Spec references inside `#[error(...)]` strings quote clauses from
/// ISO/IEC 14496-12:2015 (§4.2) where applicable.
#[derive(Debug, Error, PartialEq, Eq)]
#[non_exhaustive]
pub enum Error {
/// Input buffer was shorter than the smallest valid encoding for the type.
#[error("buffer too short: need {need} bytes, have {have} (while parsing {what})")]
BufferTooShort {
/// Bytes required to proceed.
need: usize,
/// Bytes actually available.
have: usize,
/// Human-readable name of the type or field being parsed.
what: &'static str,
},
/// Box size was declared as 1 (triggers largesize) but fewer than 8 bytes available.
#[error("largesize indicated but buffer too short: need {need}, have {have}")]
LargesizeBufferTooShort {
/// Bytes required for largesize.
need: usize,
/// Bytes actually available.
have: usize,
},
/// Box type was 'uuid' but fewer than the required 16 bytes of usertype available.
#[error("uuid box indicated but buffer too short: need {need}, have {have}")]
UuidBufferTooShort {
/// Bytes required for usertype.
need: usize,
/// Bytes actually available.
have: usize,
},
/// A box claimed a size smaller than its header, which is impossible.
#[error("box size {size} is smaller than header ({header_size} bytes)")]
BoxSizeUnderflow {
/// Declared size.
size: u64,
/// Minimum header bytes.
header_size: usize,
},
/// Write buffer passed to `serialize_into` was smaller than `serialized_len()`.
#[error("serialize: output buffer too small — need {need}, have {have}")]
OutputBufferTooSmall {
/// Required size.
need: usize,
/// Actual size.
have: usize,
},
/// A field had an invalid or reserved value.
#[error("invalid {field}: {reason} (value: 0x{value:X})")]
InvalidValue {
/// Name of the field.
field: &'static str,
/// The parsed value.
value: u64,
/// Human-readable explanation.
reason: &'static str,
},
/// A box did not carry the four-CC the parser expected.
#[error("unexpected box: expected {expected}")]
UnexpectedBox {
/// The four-CC (or description) the parser required.
expected: &'static str,
},
/// A caller-supplied argument violated a documented precondition (e.g. an
/// empty track list or a non-positive segment duration passed to the
/// [`Segmenter`](crate::segmenter::Segmenter)).
#[error("invalid input: {0}")]
InvalidInput(&'static str),
/// A [`CodecConfig`](crate::pipeline::CodecConfig) has no ISOBMFF/fMP4
/// carriage in this crate (e.g. the WebM-native VP8 / Vorbis codecs, which
/// are carried in the IR for `{WebM} → IR → {WebM}` and inspection only).
#[error("codec {codec} has no ISOBMFF/fMP4 carriage in this crate")]
UnsupportedCodec {
/// The codec name (e.g. `"VP8"`, `"Vorbis"`).
codec: &'static str,
},
/// The MPEG-1/2 Program Stream framing could not be parsed
/// ([`PsDemux`](crate::PsDemux) input — ISO/IEC 13818-1 §2.5, via `mpeg_ps`).
#[error("program stream: {0}")]
Ps(#[from] mpeg_ps::Error),
/// An `emsg` (Event Message Box, ISO/IEC 23009-1 §5.10.3.3) could not be
/// serialized (e.g. the box would exceed the 4-byte `size` field range).
#[error("emsg serialize: {0}")]
EmsgSerialize(#[from] mp4_emsg::Error),
/// An HLS playlist (`.m3u8`, RFC 8216bis) tag could not be parsed —
/// [`crate::hls::MediaPlaylist::parse`] / [`crate::hls::MasterPlaylist::parse`]
/// (issue #717 slice 1, the `to_m3u8()` renderers' symmetric inverse).
/// Unrecognized tags are ignored (forward-compat); this variant is only
/// returned for a *known* tag whose required attribute is missing or
/// whose value fails to parse.
#[error("hls parse (line {line_no}): {reason}\n {line}")]
HlsParse {
/// 1-based line number within the input playlist text.
line_no: usize,
/// The offending line, verbatim.
line: String,
/// Human-readable explanation.
reason: String,
},
/// A streaming reassembly buffer (e.g.
/// [`rtp_stream`](crate::rtp_stream)'s per-track access-unit buffer)
/// grew past its configured cap while waiting for a completion signal
/// that never arrived (a dropped final FU-A fragment, a marker bit that
/// never comes, or any other malformed/hostile input) — issue #663 P5.2,
/// audit-ingest #4. The partial data was dropped rather than grown
/// without bound; the buffer's owner has already reset its internal
/// state, so the caller may simply continue feeding new input (it will
/// resync at the next natural boundary) or treat this as a recoverable
/// per-connection error, at its discretion.
#[error("{what} buffer exceeded its {cap}-byte cap and was dropped")]
BufferCapExceeded {
/// Human-readable name of the buffer that overflowed.
what: &'static str,
/// The configured cap, in bytes.
cap: usize,
},
}