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

1mod audio;
2mod av01;
3mod btrt;
4mod ccst;
5mod colr;
6mod h264;
7mod hevc;
8mod mp4a;
9mod opus;
10mod pasp;
11mod taic;
12mod tx3g;
13mod uncv;
14mod visual;
15mod vp9;
16
17pub use audio::*;
18pub use av01::*;
19pub use btrt::*;
20pub use ccst::*;
21pub use colr::*;
22pub use h264::*;
23pub use hevc::*;
24pub use mp4a::*;
25pub use opus::*;
26pub use pasp::*;
27pub use taic::*;
28pub use tx3g::*;
29pub use uncv::*;
30pub use visual::*;
31pub use vp9::*;
32
33use crate::*;
34use derive_more::From;
35
36#[derive(Debug, Clone, PartialEq, Eq, Default)]
37#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
38pub struct Stsd {
39    pub codecs: Vec<Codec>,
40}
41
42/// Called a "sample entry" in the ISOBMFF specification.
43#[derive(Debug, Clone, PartialEq, Eq, From)]
44#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
45pub enum Codec {
46    // H264
47    Avc1(Avc1),
48
49    // HEVC: SPS/PPS/VPS is inline
50    Hev1(Hev1),
51
52    // HEVC: SPS/PPS/VPS is in a separate atom
53    Hvc1(Hvc1),
54
55    // VP8
56    Vp08(Vp08),
57
58    // VP9
59    Vp09(Vp09),
60
61    // AV1
62    Av01(Av01),
63
64    // AAC
65    Mp4a(Mp4a),
66
67    // Text
68    Tx3g(Tx3g),
69
70    // Opus
71    Opus(Opus),
72
73    // Uncompressed video
74    Uncv(Uncv),
75
76    // Unknown
77    Unknown(FourCC),
78}
79
80impl Decode for Codec {
81    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
82        let atom = Any::decode(buf)?;
83        Ok(match atom {
84            Any::Avc1(atom) => atom.into(),
85            Any::Hev1(atom) => atom.into(),
86            Any::Hvc1(atom) => atom.into(),
87            Any::Vp08(atom) => atom.into(),
88            Any::Vp09(atom) => atom.into(),
89            Any::Mp4a(atom) => atom.into(),
90            Any::Tx3g(atom) => atom.into(),
91            Any::Av01(atom) => atom.into(),
92            Any::Opus(atom) => atom.into(),
93            Any::Uncv(atom) => atom.into(),
94            Any::Unknown(kind, _) => Self::Unknown(kind),
95            _ => return Err(Error::UnexpectedBox(atom.kind())),
96        })
97    }
98}
99
100impl Encode for Codec {
101    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
102        match self {
103            Self::Unknown(kind) => kind.encode(buf),
104            Self::Avc1(atom) => atom.encode(buf),
105            Self::Hev1(atom) => atom.encode(buf),
106            Self::Hvc1(atom) => atom.encode(buf),
107            Self::Vp08(atom) => atom.encode(buf),
108            Self::Vp09(atom) => atom.encode(buf),
109            Self::Mp4a(atom) => atom.encode(buf),
110            Self::Tx3g(atom) => atom.encode(buf),
111            Self::Av01(atom) => atom.encode(buf),
112            Self::Opus(atom) => atom.encode(buf),
113            Self::Uncv(atom) => atom.encode(buf),
114        }
115    }
116}
117
118impl AtomExt for Stsd {
119    type Ext = ();
120
121    const KIND_EXT: FourCC = FourCC::new(b"stsd");
122
123    fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
124        let codec_count = u32::decode(buf)?;
125        let mut codecs = Vec::new();
126
127        for _ in 0..codec_count {
128            let codec = Codec::decode(buf)?;
129            codecs.push(codec);
130        }
131
132        Ok(Stsd { codecs })
133    }
134
135    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
136        (self.codecs.len() as u32).encode(buf)?;
137        for codec in &self.codecs {
138            codec.encode(buf)?;
139        }
140
141        Ok(())
142    }
143}