Skip to main content

mp4_atom/moov/trak/mdia/minf/stbl/stsd/
mod.rs

1mod ac3;
2mod amr;
3mod audio;
4mod av01;
5mod btrt;
6mod ccst;
7mod chnl;
8mod colr;
9mod eac3;
10mod fiel;
11mod flac;
12mod ftab;
13mod h264;
14mod hevc;
15mod mp4a;
16mod opus;
17mod pasp;
18mod pcm;
19mod plaintext;
20mod taic;
21mod tx3g;
22mod uncv;
23mod visual;
24mod vp9;
25mod wvtt;
26
27pub use ac3::*;
28pub use amr::*;
29pub use audio::*;
30pub use av01::*;
31pub use btrt::*;
32pub use ccst::*;
33pub use chnl::*;
34pub use colr::*;
35pub use eac3::*;
36pub use fiel::*;
37pub use flac::*;
38pub use ftab::*;
39pub use h264::*;
40pub use hevc::*;
41pub use mp4a::*;
42pub use opus::*;
43pub use pasp::*;
44pub use pcm::*;
45pub use plaintext::*;
46pub use taic::*;
47pub use tx3g::*;
48pub use uncv::*;
49pub use visual::*;
50pub use vp9::*;
51pub use wvtt::*;
52
53use crate::*;
54use derive_more::From;
55
56#[derive(Debug, Clone, PartialEq, Eq, Default)]
57#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
58pub struct Stsd {
59    pub codecs: Vec<Codec>,
60}
61
62/// Called a "sample entry" in the ISOBMFF specification.
63#[derive(Debug, Clone, PartialEq, Eq, From)]
64#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
65#[non_exhaustive]
66pub enum Codec {
67    // H264
68    Avc1(Avc1),
69
70    // HEVC: SPS/PPS/VPS is inline
71    Hev1(Hev1),
72
73    // HEVC: SPS/PPS/VPS is in a separate atom
74    Hvc1(Hvc1),
75
76    // VP8
77    Vp08(Vp08),
78
79    // VP9
80    Vp09(Vp09),
81
82    // AV1
83    Av01(Av01),
84
85    // AAC
86    Mp4a(Mp4a),
87
88    // Text
89    Tx3g(Tx3g),
90
91    // Opus
92    Opus(Opus),
93
94    // Uncompressed video
95    Uncv(Uncv),
96
97    // FLAC audio
98    Flac(Flac),
99
100    // AC-3 audio
101    Ac3(Ac3),
102
103    // EAC-3 audio
104    Eac3(Eac3),
105
106    // Uncompressed audio
107    // ipcm and fpcm are from 23003-5.
108    Ipcm(Ipcm),
109    Fpcm(Fpcm),
110    // sowt / twos and in24 / in32 / fl32 / fl64 / lpcm are Quicktime (QTFF-2001).
111    // s16l seems to be something that VLC produced at some point.
112    Sowt(Sowt),
113    Twos(Twos),
114    Lpcm(Lpcm),
115    In24(In24),
116    In32(In32),
117    Fl32(Fl32),
118    Fl64(Fl64),
119    S16l(S16l),
120
121    // WebVTT, ISO/IEC 14496-30
122    Wvtt(Wvtt),
123
124    // 3GPP Narrowband audio (3GPP TS 26.244 or ETSI TS 126 244)
125    Samr(Samr),
126
127    // Unknown
128    Unknown(FourCC),
129}
130
131impl Decode for Codec {
132    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
133        let atom = Any::decode(buf)?;
134        Ok(match atom {
135            Any::Avc1(atom) => atom.into(),
136            Any::Hev1(atom) => atom.into(),
137            Any::Hvc1(atom) => atom.into(),
138            Any::Vp08(atom) => atom.into(),
139            Any::Vp09(atom) => atom.into(),
140            Any::Mp4a(atom) => atom.into(),
141            Any::Tx3g(atom) => atom.into(),
142            Any::Av01(atom) => atom.into(),
143            Any::Opus(atom) => atom.into(),
144            Any::Uncv(atom) => atom.into(),
145            Any::Flac(atom) => atom.into(),
146            Any::Ac3(atom) => atom.into(),
147            Any::Eac3(atom) => atom.into(),
148            Any::Ipcm(atom) => atom.into(),
149            Any::Fpcm(atom) => atom.into(),
150            Any::Sowt(atom) => atom.into(),
151            Any::Twos(atom) => atom.into(),
152            Any::Lpcm(atom) => atom.into(),
153            Any::In24(atom) => atom.into(),
154            Any::In32(atom) => atom.into(),
155            Any::Fl32(atom) => atom.into(),
156            Any::Fl64(atom) => atom.into(),
157            Any::S16l(atom) => atom.into(),
158            Any::Wvtt(atom) => atom.into(),
159            Any::Samr(atom) => atom.into(),
160            unknown => {
161                crate::decode_unknown(&unknown, Stsd::KIND)?;
162                Self::Unknown(unknown.kind())
163            }
164        })
165    }
166}
167
168impl Encode for Codec {
169    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
170        match self {
171            Self::Unknown(kind) => kind.encode(buf),
172            Self::Avc1(atom) => atom.encode(buf),
173            Self::Hev1(atom) => atom.encode(buf),
174            Self::Hvc1(atom) => atom.encode(buf),
175            Self::Vp08(atom) => atom.encode(buf),
176            Self::Vp09(atom) => atom.encode(buf),
177            Self::Mp4a(atom) => atom.encode(buf),
178            Self::Tx3g(atom) => atom.encode(buf),
179            Self::Av01(atom) => atom.encode(buf),
180            Self::Opus(atom) => atom.encode(buf),
181            Self::Uncv(atom) => atom.encode(buf),
182            Self::Flac(atom) => atom.encode(buf),
183            Self::Ac3(atom) => atom.encode(buf),
184            Self::Eac3(atom) => atom.encode(buf),
185            Self::Ipcm(atom) => atom.encode(buf),
186            Self::Fpcm(atom) => atom.encode(buf),
187            Self::Sowt(atom) => atom.encode(buf),
188            Self::Twos(atom) => atom.encode(buf),
189            Self::Lpcm(atom) => atom.encode(buf),
190            Self::In24(atom) => atom.encode(buf),
191            Self::In32(atom) => atom.encode(buf),
192            Self::Fl32(atom) => atom.encode(buf),
193            Self::Fl64(atom) => atom.encode(buf),
194            Self::S16l(atom) => atom.encode(buf),
195            Self::Wvtt(atom) => atom.encode(buf),
196            Self::Samr(atom) => atom.encode(buf),
197        }
198    }
199}
200
201impl AtomExt for Stsd {
202    type Ext = ();
203
204    const KIND_EXT: FourCC = FourCC::new(b"stsd");
205
206    fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
207        let codec_count = u32::decode(buf)?;
208        let mut codecs = Vec::new();
209
210        for _ in 0..codec_count {
211            let codec = Codec::decode(buf)?;
212            codecs.push(codec);
213        }
214
215        Ok(Stsd { codecs })
216    }
217
218    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
219        (self.codecs.len() as u32).encode(buf)?;
220        for codec in &self.codecs {
221            codec.encode(buf)?;
222        }
223
224        Ok(())
225    }
226}