Skip to main content

moq_mux/container/mkv/
mod.rs

1//! Matroska / WebM.
2//!
3//! An EBML-based file format. moq-mux uses it as an external interchange
4//! format only, not as a wire format: [`Import`] parses MKV byte streams
5//! into a broadcast and [`Export`] does the reverse.
6
7mod export;
8mod import;
9
10pub use export::*;
11pub use import::*;
12
13#[cfg(test)]
14mod export_test;
15#[cfg(test)]
16mod import_test;
17
18/// MKV parsing and emission errors.
19#[derive(Debug, Clone, thiserror::Error)]
20#[non_exhaustive]
21pub enum Error {
22	#[error("unsupported EBML DocType: {0}")]
23	UnsupportedDocType(String),
24
25	#[error("EBML header missing DocType")]
26	MissingDocType,
27
28	#[error("invalid SimpleBlock")]
29	InvalidSimpleBlock,
30
31	#[error("invalid Block payload")]
32	InvalidBlock,
33
34	#[error("negative block timestamp")]
35	NegativeBlockTimestamp,
36
37	#[error("timestamp overflow")]
38	TimestampOverflow,
39
40	#[error("TrackEntry missing TrackNumber")]
41	MissingTrackNumber,
42
43	#[error("TrackEntry missing TrackType")]
44	MissingTrackType,
45
46	#[error("TrackEntry missing CodecID")]
47	MissingCodecId,
48
49	#[error("unsupported video CodecID: {0}")]
50	UnsupportedVideoCodec(String),
51
52	#[error("unsupported audio CodecID: {0}")]
53	UnsupportedAudioCodec(String),
54
55	#[error("{codec_id} missing CodecPrivate ({purpose})")]
56	MissingCodecPrivate {
57		codec_id: &'static str,
58		purpose: &'static str,
59	},
60
61	#[error("invalid HEVCDecoderConfigurationRecord")]
62	InvalidHvcc,
63
64	#[error("invalid AV1CodecConfigurationRecord")]
65	InvalidAv1c,
66
67	#[error("MKV track layout changed after header was emitted: track '{0}' added")]
68	HeaderAddedTrack(String),
69
70	#[error("MKV track layout changed after header was emitted: track '{0}' removed")]
71	HeaderRemovedTrack(String),
72
73	#[error("MKV export does not support CMAF {kind} track '{name}'")]
74	UnsupportedCmafTrack { kind: String, name: String },
75
76	#[error("MKV export does not support video codec {0}")]
77	UnsupportedVideoExport(String),
78
79	#[error("MKV export does not support audio codec {0}")]
80	UnsupportedAudioExport(String),
81
82	#[error("AAC track missing AudioSpecificConfig (description)")]
83	MissingAacDescription,
84
85	#[error("FLAC track missing STREAMINFO (description)")]
86	MissingFlacDescription,
87
88	#[error("H.264 track missing AVCDecoderConfigurationRecord")]
89	MissingH264Avcc,
90
91	#[error("H.265 track missing HEVCDecoderConfigurationRecord")]
92	MissingH265Hvcc,
93
94	#[error("cluster underflow")]
95	ClusterUnderflow,
96
97	#[error("block timestamp doesn't fit in i16")]
98	BlockTimestampOverflow,
99
100	#[error("missing track")]
101	MissingTrack,
102
103	#[error("timestamp doesn't fit in u64 ms")]
104	TimestampU64,
105
106	#[error("video track {0} missing in tracks map")]
107	MissingVideoTrack(String),
108
109	#[error("audio track {0} missing in tracks map")]
110	MissingAudioTrack(String),
111
112	#[error("no catalog snapshot")]
113	NoCatalogSnapshot,
114
115	#[error("matroska parse error")]
116	MatroskaParse,
117
118	#[error("matroska write error: {0}")]
119	MatroskaWrite(std::sync::Arc<webm_iterable::errors::TagWriterError>),
120
121	/// Building the Opus codec-private OpusHead for an audio track failed.
122	#[error(transparent)]
123	Opus(#[from] crate::codec::opus::Error),
124}
125
126impl From<webm_iterable::errors::TagWriterError> for Error {
127	fn from(err: webm_iterable::errors::TagWriterError) -> Self {
128		Error::MatroskaWrite(std::sync::Arc::new(err))
129	}
130}
131
132pub type Result<T> = std::result::Result<T, Error>;