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

1use crate::*;
2
3// We're trying not to pollute the global namespace
4pub mod esds;
5pub use esds::Esds;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct Mp4a {
10    pub data_reference_index: u16,
11    pub channelcount: u16,
12    pub samplesize: u16,
13    pub samplerate: FixedPoint<u16>,
14    pub esds: Option<Esds>,
15}
16
17impl Default for Mp4a {
18    fn default() -> Self {
19        Self {
20            data_reference_index: 0,
21            channelcount: 2,
22            samplesize: 16,
23            samplerate: 48000.into(),
24            esds: Some(Esds::default()),
25        }
26    }
27}
28
29impl Atom for Mp4a {
30    const KIND: FourCC = FourCC::new(b"mp4a");
31
32    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
33        u32::decode(buf)?; // reserved
34        u16::decode(buf)?; // reserved
35        let data_reference_index = u16::decode(buf)?;
36        let version = u16::decode(buf)?;
37        u16::decode(buf)?; // reserved
38        u32::decode(buf)?; // reserved
39        let channelcount = u16::decode(buf)?;
40        let samplesize = u16::decode(buf)?;
41        u32::decode(buf)?; // pre-defined, reserved
42        let samplerate = FixedPoint::decode(buf)?;
43
44        if version == 1 {
45            // Skip QTFF
46            u64::decode(buf)?;
47            u64::decode(buf)?;
48        }
49
50        let mut esds = None;
51
52        // Find esds in mp4a or wave
53        while let Some(atom) = Any::decode_maybe(buf)? {
54            match atom {
55                Any::Esds(atom) => esds = atom.into(),
56                _ => tracing::warn!("unknown atom: {:?}", atom),
57            }
58        }
59
60        Ok(Mp4a {
61            data_reference_index,
62            channelcount,
63            samplesize,
64            samplerate,
65            esds,
66        })
67    }
68
69    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
70        0u32.encode(buf)?; // reserved
71        0u16.encode(buf)?; // reserved
72        self.data_reference_index.encode(buf)?;
73        0u16.encode(buf)?; // version
74        0u16.encode(buf)?; // reserved
75        0u32.encode(buf)?; // reserved
76        self.channelcount.encode(buf)?;
77        self.samplesize.encode(buf)?;
78        0u32.encode(buf)?; // reserved
79        self.samplerate.encode(buf)?;
80
81        self.esds.encode(buf)?;
82
83        Ok(())
84    }
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90
91    #[test]
92    fn test_mp4a() {
93        let expected = Mp4a {
94            data_reference_index: 1,
95            channelcount: 2,
96            samplesize: 16,
97            samplerate: 48000.into(),
98            esds: Some(Esds {
99                es_desc: esds::EsDescriptor {
100                    es_id: 2,
101                    dec_config: esds::DecoderConfig {
102                        object_type_indication: 0x40,
103                        stream_type: 0x05,
104                        up_stream: 0,
105                        buffer_size_db: Default::default(),
106                        max_bitrate: 67695,
107                        avg_bitrate: 67695,
108                        dec_specific: esds::DecoderSpecific {
109                            profile: 2,
110                            freq_index: 4,
111                            chan_conf: 2,
112                        },
113                    },
114                    sl_config: esds::SLConfig::default(),
115                },
116            }),
117        };
118        let mut buf = Vec::new();
119        expected.encode(&mut buf).unwrap();
120
121        let mut buf = buf.as_ref();
122        let decoded = Mp4a::decode(&mut buf).unwrap();
123        assert_eq!(decoded, expected);
124    }
125
126    #[test]
127    fn test_mp4a_no_esds() {
128        let expected = Mp4a {
129            data_reference_index: 1,
130            channelcount: 2,
131            samplesize: 16,
132            samplerate: 48000.into(),
133            esds: None,
134        };
135        let mut buf = Vec::new();
136        expected.encode(&mut buf).unwrap();
137
138        let mut buf = buf.as_ref();
139        let decoded = Mp4a::decode(&mut buf).unwrap();
140        assert_eq!(decoded, expected);
141    }
142}