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("H.264 track missing AVCDecoderConfigurationRecord")]
86	MissingH264Avcc,
87
88	#[error("H.265 track missing HEVCDecoderConfigurationRecord")]
89	MissingH265Hvcc,
90
91	#[error("cluster underflow")]
92	ClusterUnderflow,
93
94	#[error("block timestamp doesn't fit in i16")]
95	BlockTimestampOverflow,
96
97	#[error("missing track")]
98	MissingTrack,
99
100	#[error("timestamp doesn't fit in u64 ms")]
101	TimestampU64,
102
103	#[error("video track {0} missing in tracks map")]
104	MissingVideoTrack(String),
105
106	#[error("audio track {0} missing in tracks map")]
107	MissingAudioTrack(String),
108
109	#[error("no catalog snapshot")]
110	NoCatalogSnapshot,
111
112	#[error("matroska parse error")]
113	MatroskaParse,
114
115	#[error("matroska write error: {0}")]
116	MatroskaWrite(std::sync::Arc<webm_iterable::errors::TagWriterError>),
117
118	/// Building the Opus codec-private OpusHead for an audio track failed.
119	#[error(transparent)]
120	Opus(#[from] crate::codec::opus::Error),
121}
122
123impl From<webm_iterable::errors::TagWriterError> for Error {
124	fn from(err: webm_iterable::errors::TagWriterError) -> Self {
125		Error::MatroskaWrite(std::sync::Arc::new(err))
126	}
127}
128
129pub type Result<T> = std::result::Result<T, Error>;