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))]
29pub enum Codec {
30    // H264
31    Avc1(Avc1),
32
33    // HEVC: SPS/PPS/VPS is inline
34    Hev1(Hev1),
35
36    // HEVC: SPS/PPS/VPS is in a separate atom
37    Hvc1(Hvc1),
38
39    // VP8
40    Vp08(Vp08),
41
42    // VP9
43    Vp09(Vp09),
44
45    // AV1
46    Av01(Av01),
47
48    // AAC
49    Mp4a(Mp4a),
50
51    // Text
52    Tx3g(Tx3g),
53
54    // Unknown
55    Unknown(FourCC),
56}
57
58impl Decode for Codec {
59    fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
60        let atom = Any::decode(buf)?;
61        Ok(match atom {
62            Any::Avc1(atom) => atom.into(),
63            Any::Hev1(atom) => atom.into(),
64            Any::Hvc1(atom) => atom.into(),
65            Any::Vp08(atom) => atom.into(),
66            Any::Vp09(atom) => atom.into(),
67            Any::Mp4a(atom) => atom.into(),
68            Any::Tx3g(atom) => atom.into(),
69            Any::Av01(atom) => atom.into(),
70            Any::Unknown(kind, _) => Self::Unknown(kind),
71            _ => return Err(Error::UnexpectedBox(atom.kind())),
72        })
73    }
74}
75
76impl Encode for Codec {
77    fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
78        match self {
79            Self::Unknown(kind) => kind.encode(buf),
80            Self::Avc1(atom) => atom.encode(buf),
81            Self::Hev1(atom) => atom.encode(buf),
82            Self::Hvc1(atom) => atom.encode(buf),
83            Self::Vp08(atom) => atom.encode(buf),
84            Self::Vp09(atom) => atom.encode(buf),
85            Self::Mp4a(atom) => atom.encode(buf),
86            Self::Tx3g(atom) => atom.encode(buf),
87            Self::Av01(atom) => atom.encode(buf),
88        }
89    }
90}
91
92impl AtomExt for Stsd {
93    type Ext = ();
94
95    const KIND_EXT: FourCC = FourCC::new(b"stsd");
96
97    fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
98        let codec_count = u32::decode(buf)?;
99        let mut codecs = Vec::new();
100
101        for _ in 0..codec_count {
102            let codec = Codec::decode(buf)?;
103            codecs.push(codec);
104        }
105
106        Ok(Stsd { codecs })
107    }
108
109    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
110        (self.codecs.len() as u32).encode(buf)?;
111        for codec in &self.codecs {
112            codec.encode(buf)?;
113        }
114
115        Ok(())
116    }
117}