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

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