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