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))]
59#[non_exhaustive]
60pub enum Codec {
61    // H264
62    Avc1(Avc1),
63
64    // HEVC: SPS/PPS/VPS is inline
65    Hev1(Hev1),
66
67    // HEVC: SPS/PPS/VPS is in a separate atom
68    Hvc1(Hvc1),
69
70    // VP8
71    Vp08(Vp08),
72
73    // VP9
74    Vp09(Vp09),
75
76    // AV1
77    Av01(Av01),
78
79    // AAC
80    Mp4a(Mp4a),
81
82    // Text
83    Tx3g(Tx3g),
84
85    // Opus
86    Opus(Opus),
87
88    // Uncompressed video
89    Uncv(Uncv),
90
91    // FLAC audio
92    Flac(Flac),
93
94    // AC-3 audio
95    Ac3(Ac3),
96
97    // EAC-3 audio
98    Eac3(Eac3),
99
100    // Uncompressed audio
101    // ipcm and fpcm are from 23003-5.
102    Ipcm(Ipcm),
103    Fpcm(Fpcm),
104    // sowt / twos and in24 / in32 / fl32 / fl64 / lpcm are Quicktime (QTFF-2001).
105    // s16l seems to be something that VLC produced at some point.
106    Sowt(Sowt),
107    Twos(Twos),
108    Lpcm(Lpcm),
109    In24(In24),
110    In32(In32),
111    Fl32(Fl32),
112    Fl64(Fl64),
113    S16l(S16l),
114
115    // Unknown
116    Unknown(FourCC),
117}
118
119impl Decode for Codec {
120    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
121        let atom = Any::decode(buf)?;
122        Ok(match atom {
123            Any::Avc1(atom) => atom.into(),
124            Any::Hev1(atom) => atom.into(),
125            Any::Hvc1(atom) => atom.into(),
126            Any::Vp08(atom) => atom.into(),
127            Any::Vp09(atom) => atom.into(),
128            Any::Mp4a(atom) => atom.into(),
129            Any::Tx3g(atom) => atom.into(),
130            Any::Av01(atom) => atom.into(),
131            Any::Opus(atom) => atom.into(),
132            Any::Uncv(atom) => atom.into(),
133            Any::Flac(atom) => atom.into(),
134            Any::Ac3(atom) => atom.into(),
135            Any::Eac3(atom) => atom.into(),
136            Any::Ipcm(atom) => atom.into(),
137            Any::Fpcm(atom) => atom.into(),
138            Any::Sowt(atom) => atom.into(),
139            Any::Twos(atom) => atom.into(),
140            Any::Lpcm(atom) => atom.into(),
141            Any::In24(atom) => atom.into(),
142            Any::In32(atom) => atom.into(),
143            Any::Fl32(atom) => atom.into(),
144            Any::Fl64(atom) => atom.into(),
145            Any::S16l(atom) => atom.into(),
146            unknown => {
147                crate::decode_unknown(&unknown, Stsd::KIND)?;
148                Self::Unknown(unknown.kind())
149            }
150        })
151    }
152}
153
154impl Encode for Codec {
155    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
156        match self {
157            Self::Unknown(kind) => kind.encode(buf),
158            Self::Avc1(atom) => atom.encode(buf),
159            Self::Hev1(atom) => atom.encode(buf),
160            Self::Hvc1(atom) => atom.encode(buf),
161            Self::Vp08(atom) => atom.encode(buf),
162            Self::Vp09(atom) => atom.encode(buf),
163            Self::Mp4a(atom) => atom.encode(buf),
164            Self::Tx3g(atom) => atom.encode(buf),
165            Self::Av01(atom) => atom.encode(buf),
166            Self::Opus(atom) => atom.encode(buf),
167            Self::Uncv(atom) => atom.encode(buf),
168            Self::Flac(atom) => atom.encode(buf),
169            Self::Ac3(atom) => atom.encode(buf),
170            Self::Eac3(atom) => atom.encode(buf),
171            Self::Ipcm(atom) => atom.encode(buf),
172            Self::Fpcm(atom) => atom.encode(buf),
173            Self::Sowt(atom) => atom.encode(buf),
174            Self::Twos(atom) => atom.encode(buf),
175            Self::Lpcm(atom) => atom.encode(buf),
176            Self::In24(atom) => atom.encode(buf),
177            Self::In32(atom) => atom.encode(buf),
178            Self::Fl32(atom) => atom.encode(buf),
179            Self::Fl64(atom) => atom.encode(buf),
180            Self::S16l(atom) => atom.encode(buf),
181        }
182    }
183}
184
185impl AtomExt for Stsd {
186    type Ext = ();
187
188    const KIND_EXT: FourCC = FourCC::new(b"stsd");
189
190    fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
191        let codec_count = u32::decode(buf)?;
192        let mut codecs = Vec::new();
193
194        for _ in 0..codec_count {
195            let codec = Codec::decode(buf)?;
196            codecs.push(codec);
197        }
198
199        Ok(Stsd { codecs })
200    }
201
202    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
203        (self.codecs.len() as u32).encode(buf)?;
204        for codec in &self.codecs {
205            codec.encode(buf)?;
206        }
207
208        Ok(())
209    }
210}