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

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