mp4_atom/moov/trak/mdia/minf/stbl/stsd/
mod.rs1mod ac3;
2mod amr;
3mod audio;
4mod av01;
5mod btrt;
6mod camm;
7mod ccst;
8mod chnl;
9mod colr;
10mod eac3;
11mod evte;
12mod fiel;
13mod flac;
14mod ftab;
15mod h264;
16mod hevc;
17mod jpeg;
18mod mebx;
19mod metadata;
20mod mett;
21mod metx;
22mod mp3;
23mod mp4a;
24mod opus;
25mod pasp;
26mod pcm;
27mod plaintext;
28mod taic;
29mod tx3g;
30mod uncv;
31mod urim;
32mod visual;
33mod vp9;
34mod wvtt;
35
36pub use ac3::*;
37pub use amr::*;
38pub use audio::*;
39pub use av01::*;
40pub use btrt::*;
41pub use camm::*;
42pub use ccst::*;
43pub use chnl::*;
44pub use colr::*;
45pub use eac3::*;
46pub use evte::*;
47pub use fiel::*;
48pub use flac::*;
49pub use ftab::*;
50pub use h264::*;
51pub use hevc::*;
52pub use jpeg::*;
53pub use mebx::*;
54pub use metadata::*;
55pub use mett::*;
56pub use metx::*;
57pub use mp3::*;
58pub use mp4a::*;
59pub use opus::*;
60pub use pasp::*;
61pub use pcm::*;
62pub use plaintext::*;
63pub use taic::*;
64pub use tx3g::*;
65pub use uncv::*;
66pub use urim::*;
67pub use visual::*;
68pub use vp9::*;
69pub use wvtt::*;
70
71use crate::*;
72use derive_more::From;
73
74#[derive(Debug, Clone, PartialEq, Eq, Default)]
75#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
76pub struct Stsd {
77 pub codecs: Vec<Codec>,
78}
79
80#[derive(Debug, Clone, PartialEq, Eq, From)]
82#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
83#[non_exhaustive]
84pub enum Codec {
85 Avc1(Avc1),
87
88 Avc3(Avc3),
90
91 Jpeg(Jpeg),
93
94 Hev1(Hev1),
96
97 Hvc1(Hvc1),
99
100 Vp08(Vp08),
102
103 Vp09(Vp09),
105
106 Av01(Av01),
108
109 Mp4a(Mp4a),
111
112 Mp3(Mp3),
114
115 Tx3g(Tx3g),
117
118 Opus(Opus),
120
121 Uncv(Uncv),
123
124 Flac(Flac),
126
127 Ac3(Ac3),
129
130 Eac3(Eac3),
132
133 Ipcm(Ipcm),
136 Fpcm(Fpcm),
137 Sowt(Sowt),
140 Twos(Twos),
141 Lpcm(Lpcm),
142 In24(In24),
143 In32(In32),
144 Fl32(Fl32),
145 Fl64(Fl64),
146 S16l(S16l),
147
148 Wvtt(Wvtt),
150
151 Samr(Samr),
153
154 Mett(Mett),
156
157 Metx(Metx),
159
160 Urim(Urim),
162
163 Camm(Camm),
165
166 Evte(Evte),
169
170 Mebx(Mebx),
172
173 Unknown(FourCC, Vec<u8>),
175}
176
177impl Decode for Codec {
178 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
179 let atom = Any::decode(buf)?;
180 Ok(match atom {
181 Any::Avc1(atom) => atom.into(),
182 Any::Avc3(atom) => atom.into(),
183 Any::Jpeg(atom) => atom.into(),
184 Any::Hev1(atom) => atom.into(),
185 Any::Hvc1(atom) => atom.into(),
186 Any::Vp08(atom) => atom.into(),
187 Any::Vp09(atom) => atom.into(),
188 Any::Mp4a(atom) => atom.into(),
189 Any::Mp3(atom) => atom.into(),
190 Any::Tx3g(atom) => atom.into(),
191 Any::Av01(atom) => atom.into(),
192 Any::Opus(atom) => atom.into(),
193 Any::Uncv(atom) => atom.into(),
194 Any::Flac(atom) => atom.into(),
195 Any::Ac3(atom) => atom.into(),
196 Any::Eac3(atom) => atom.into(),
197 Any::Ipcm(atom) => atom.into(),
198 Any::Fpcm(atom) => atom.into(),
199 Any::Sowt(atom) => atom.into(),
200 Any::Twos(atom) => atom.into(),
201 Any::Lpcm(atom) => atom.into(),
202 Any::In24(atom) => atom.into(),
203 Any::In32(atom) => atom.into(),
204 Any::Fl32(atom) => atom.into(),
205 Any::Fl64(atom) => atom.into(),
206 Any::S16l(atom) => atom.into(),
207 Any::Wvtt(atom) => atom.into(),
208 Any::Samr(atom) => atom.into(),
209 Any::Mett(atom) => atom.into(),
210 Any::Metx(atom) => atom.into(),
211 Any::Urim(atom) => atom.into(),
212 Any::Camm(atom) => atom.into(),
213 Any::Evte(atom) => atom.into(),
214 Any::Mebx(atom) => atom.into(),
215 Any::Unknown(four_cc, body) => Self::Unknown(four_cc, body),
216 unknown => {
217 crate::decode_unknown(&unknown, Stsd::KIND)?;
218
219 let kind = unknown.kind();
222 let mut encoded = Vec::new();
223 unknown.encode(&mut encoded)?;
224 Self::Unknown(kind, encoded.split_off(8))
225 }
226 })
227 }
228}
229
230impl Encode for Codec {
231 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
232 match self {
233 Self::Unknown(..) => Err(Error::UnknownCodec),
234 Self::Avc1(atom) => atom.encode(buf),
235 Self::Avc3(atom) => atom.encode(buf),
236 Self::Jpeg(atom) => atom.encode(buf),
237 Self::Hev1(atom) => atom.encode(buf),
238 Self::Hvc1(atom) => atom.encode(buf),
239 Self::Vp08(atom) => atom.encode(buf),
240 Self::Vp09(atom) => atom.encode(buf),
241 Self::Mp4a(atom) => atom.encode(buf),
242 Self::Mp3(atom) => atom.encode(buf),
243 Self::Tx3g(atom) => atom.encode(buf),
244 Self::Av01(atom) => atom.encode(buf),
245 Self::Opus(atom) => atom.encode(buf),
246 Self::Uncv(atom) => atom.encode(buf),
247 Self::Flac(atom) => atom.encode(buf),
248 Self::Ac3(atom) => atom.encode(buf),
249 Self::Eac3(atom) => atom.encode(buf),
250 Self::Ipcm(atom) => atom.encode(buf),
251 Self::Fpcm(atom) => atom.encode(buf),
252 Self::Sowt(atom) => atom.encode(buf),
253 Self::Twos(atom) => atom.encode(buf),
254 Self::Lpcm(atom) => atom.encode(buf),
255 Self::In24(atom) => atom.encode(buf),
256 Self::In32(atom) => atom.encode(buf),
257 Self::Fl32(atom) => atom.encode(buf),
258 Self::Fl64(atom) => atom.encode(buf),
259 Self::S16l(atom) => atom.encode(buf),
260 Self::Wvtt(atom) => atom.encode(buf),
261 Self::Samr(atom) => atom.encode(buf),
262 Self::Mett(atom) => atom.encode(buf),
263 Self::Metx(atom) => atom.encode(buf),
264 Self::Urim(atom) => atom.encode(buf),
265 Self::Camm(atom) => atom.encode(buf),
266 Self::Evte(atom) => atom.encode(buf),
267 Self::Mebx(atom) => atom.encode(buf),
268 }
269 }
270}
271
272impl AtomExt for Stsd {
273 type Ext = ();
274
275 const KIND_EXT: FourCC = FourCC::new(b"stsd");
276
277 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
278 let codec_count = u32::decode(buf)?;
279 let mut codecs = Vec::new();
280
281 for _ in 0..codec_count {
282 let codec = Codec::decode(buf)?;
283 codecs.push(codec);
284 }
285
286 Ok(Stsd { codecs })
287 }
288
289 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
290 (self.codecs.len() as u32).encode(buf)?;
291 for codec in &self.codecs {
292 codec.encode(buf)?;
293 }
294
295 Ok(())
296 }
297}
298
299mod tests {
300 #![cfg(not(feature = "strict"))]
301
302 #[test]
303 fn unknown_codec_parses() {
304 use crate::{Codec, Decode, FourCC, Stsd};
305
306 let input = b"\0\0\0\x1cstsd\0\0\0\0\0\0\0\x01\0\0\0\x0cdvh9\x01\x02\x03\x04";
307 let mut buf = input.as_slice();
308
309 let stsd = Stsd::decode(&mut buf).unwrap();
310 assert_eq!(
311 stsd.codecs,
312 vec![Codec::Unknown(FourCC::new(b"dvh9"), vec![1, 2, 3, 4])]
313 );
314 }
315
316 #[test]
317
318 fn unknown_codec_not_emitted() {
319 use crate::{Codec, Encode, FourCC, Stsd};
320
321 let stsd = Stsd {
322 codecs: vec![Codec::Unknown(FourCC::new(b"dvh9"), vec![1, 2, 3, 4])],
323 };
324 assert_eq!(
325 stsd.codecs,
326 vec![Codec::Unknown(FourCC::new(b"dvh9"), vec![1, 2, 3, 4])]
327 );
328 let mut output = Vec::new();
329 assert!(matches!(
330 stsd.encode(&mut output),
331 Err(crate::Error::UnknownCodec)
332 ));
333 }
334}