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 Jpeg(Jpeg),
90
91 Hev1(Hev1),
93
94 Hvc1(Hvc1),
96
97 Vp08(Vp08),
99
100 Vp09(Vp09),
102
103 Av01(Av01),
105
106 Mp4a(Mp4a),
108
109 Mp3(Mp3),
111
112 Tx3g(Tx3g),
114
115 Opus(Opus),
117
118 Uncv(Uncv),
120
121 Flac(Flac),
123
124 Ac3(Ac3),
126
127 Eac3(Eac3),
129
130 Ipcm(Ipcm),
133 Fpcm(Fpcm),
134 Sowt(Sowt),
137 Twos(Twos),
138 Lpcm(Lpcm),
139 In24(In24),
140 In32(In32),
141 Fl32(Fl32),
142 Fl64(Fl64),
143 S16l(S16l),
144
145 Wvtt(Wvtt),
147
148 Samr(Samr),
150
151 Mett(Mett),
153
154 Metx(Metx),
156
157 Urim(Urim),
159
160 Camm(Camm),
162
163 Evte(Evte),
166
167 Mebx(Mebx),
169
170 Unknown(FourCC, Vec<u8>),
172}
173
174impl Decode for Codec {
175 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
176 let atom = Any::decode(buf)?;
177 Ok(match atom {
178 Any::Avc1(atom) => atom.into(),
179 Any::Jpeg(atom) => atom.into(),
180 Any::Hev1(atom) => atom.into(),
181 Any::Hvc1(atom) => atom.into(),
182 Any::Vp08(atom) => atom.into(),
183 Any::Vp09(atom) => atom.into(),
184 Any::Mp4a(atom) => atom.into(),
185 Any::Mp3(atom) => atom.into(),
186 Any::Tx3g(atom) => atom.into(),
187 Any::Av01(atom) => atom.into(),
188 Any::Opus(atom) => atom.into(),
189 Any::Uncv(atom) => atom.into(),
190 Any::Flac(atom) => atom.into(),
191 Any::Ac3(atom) => atom.into(),
192 Any::Eac3(atom) => atom.into(),
193 Any::Ipcm(atom) => atom.into(),
194 Any::Fpcm(atom) => atom.into(),
195 Any::Sowt(atom) => atom.into(),
196 Any::Twos(atom) => atom.into(),
197 Any::Lpcm(atom) => atom.into(),
198 Any::In24(atom) => atom.into(),
199 Any::In32(atom) => atom.into(),
200 Any::Fl32(atom) => atom.into(),
201 Any::Fl64(atom) => atom.into(),
202 Any::S16l(atom) => atom.into(),
203 Any::Wvtt(atom) => atom.into(),
204 Any::Samr(atom) => atom.into(),
205 Any::Mett(atom) => atom.into(),
206 Any::Metx(atom) => atom.into(),
207 Any::Urim(atom) => atom.into(),
208 Any::Camm(atom) => atom.into(),
209 Any::Evte(atom) => atom.into(),
210 Any::Mebx(atom) => atom.into(),
211 Any::Unknown(four_cc, body) => Self::Unknown(four_cc, body),
212 unknown => {
213 crate::decode_unknown(&unknown, Stsd::KIND)?;
214
215 let kind = unknown.kind();
218 let mut encoded = Vec::new();
219 unknown.encode(&mut encoded)?;
220 Self::Unknown(kind, encoded.split_off(8))
221 }
222 })
223 }
224}
225
226impl Encode for Codec {
227 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
228 match self {
229 Self::Unknown(..) => Err(Error::UnknownCodec),
230 Self::Avc1(atom) => atom.encode(buf),
231 Self::Jpeg(atom) => atom.encode(buf),
232 Self::Hev1(atom) => atom.encode(buf),
233 Self::Hvc1(atom) => atom.encode(buf),
234 Self::Vp08(atom) => atom.encode(buf),
235 Self::Vp09(atom) => atom.encode(buf),
236 Self::Mp4a(atom) => atom.encode(buf),
237 Self::Mp3(atom) => atom.encode(buf),
238 Self::Tx3g(atom) => atom.encode(buf),
239 Self::Av01(atom) => atom.encode(buf),
240 Self::Opus(atom) => atom.encode(buf),
241 Self::Uncv(atom) => atom.encode(buf),
242 Self::Flac(atom) => atom.encode(buf),
243 Self::Ac3(atom) => atom.encode(buf),
244 Self::Eac3(atom) => atom.encode(buf),
245 Self::Ipcm(atom) => atom.encode(buf),
246 Self::Fpcm(atom) => atom.encode(buf),
247 Self::Sowt(atom) => atom.encode(buf),
248 Self::Twos(atom) => atom.encode(buf),
249 Self::Lpcm(atom) => atom.encode(buf),
250 Self::In24(atom) => atom.encode(buf),
251 Self::In32(atom) => atom.encode(buf),
252 Self::Fl32(atom) => atom.encode(buf),
253 Self::Fl64(atom) => atom.encode(buf),
254 Self::S16l(atom) => atom.encode(buf),
255 Self::Wvtt(atom) => atom.encode(buf),
256 Self::Samr(atom) => atom.encode(buf),
257 Self::Mett(atom) => atom.encode(buf),
258 Self::Metx(atom) => atom.encode(buf),
259 Self::Urim(atom) => atom.encode(buf),
260 Self::Camm(atom) => atom.encode(buf),
261 Self::Evte(atom) => atom.encode(buf),
262 Self::Mebx(atom) => atom.encode(buf),
263 }
264 }
265}
266
267impl AtomExt for Stsd {
268 type Ext = ();
269
270 const KIND_EXT: FourCC = FourCC::new(b"stsd");
271
272 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
273 let codec_count = u32::decode(buf)?;
274 let mut codecs = Vec::new();
275
276 for _ in 0..codec_count {
277 let codec = Codec::decode(buf)?;
278 codecs.push(codec);
279 }
280
281 Ok(Stsd { codecs })
282 }
283
284 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
285 (self.codecs.len() as u32).encode(buf)?;
286 for codec in &self.codecs {
287 codec.encode(buf)?;
288 }
289
290 Ok(())
291 }
292}
293
294mod tests {
295 #![cfg(not(feature = "strict"))]
296
297 #[test]
298 fn unknown_codec_parses() {
299 use crate::{Codec, Decode, FourCC, Stsd};
300
301 let input = b"\0\0\0\x1cstsd\0\0\0\0\0\0\0\x01\0\0\0\x0cdvh9\x01\x02\x03\x04";
302 let mut buf = input.as_slice();
303
304 let stsd = Stsd::decode(&mut buf).unwrap();
305 assert_eq!(
306 stsd.codecs,
307 vec![Codec::Unknown(FourCC::new(b"dvh9"), vec![1, 2, 3, 4])]
308 );
309 }
310
311 #[test]
312
313 fn unknown_codec_not_emitted() {
314 use crate::{Codec, Encode, FourCC, Stsd};
315
316 let stsd = Stsd {
317 codecs: vec![Codec::Unknown(FourCC::new(b"dvh9"), vec![1, 2, 3, 4])],
318 };
319 assert_eq!(
320 stsd.codecs,
321 vec![Codec::Unknown(FourCC::new(b"dvh9"), vec![1, 2, 3, 4])]
322 );
323 let mut output = Vec::new();
324 assert!(matches!(
325 stsd.encode(&mut output),
326 Err(crate::Error::UnknownCodec)
327 ));
328 }
329}