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 audio: Audio,
11    pub esds: Esds,
12    pub btrt: Option<Btrt>,
13    pub taic: Option<Taic>,
14}
15
16impl Atom for Mp4a {
17    const KIND: FourCC = FourCC::new(b"mp4a");
18
19    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
20        let audio = Audio::decode(buf)?;
21
22        let mut btrt = None;
23        let mut esds = None;
24        let mut taic = None;
25
26        // Find esds in mp4a or wave
27        while let Some(atom) = Any::decode_maybe(buf)? {
28            match atom {
29                Any::Btrt(atom) => btrt = atom.into(),
30                Any::Esds(atom) => esds = atom.into(),
31                Any::Taic(atom) => taic = atom.into(),
32                _ => tracing::warn!("unknown atom: {:?}", atom),
33            }
34        }
35
36        Ok(Mp4a {
37            audio,
38            esds: esds.ok_or(Error::MissingBox(Esds::KIND))?,
39            btrt,
40            taic,
41        })
42    }
43
44    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
45        self.audio.encode(buf)?;
46        self.esds.encode(buf)?;
47        if self.btrt.is_some() {
48            self.btrt.encode(buf)?;
49        }
50
51        Ok(())
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_mp4a() {
61        let expected = Mp4a {
62            audio: Audio {
63                data_reference_index: 1,
64                channel_count: 2,
65                sample_size: 16,
66                sample_rate: 48000.into(),
67            },
68            esds: Esds {
69                es_desc: esds::EsDescriptor {
70                    es_id: 2,
71                    dec_config: esds::DecoderConfig {
72                        object_type_indication: 0x40,
73                        stream_type: 0x05,
74                        up_stream: 0,
75                        buffer_size_db: Default::default(),
76                        max_bitrate: 67695,
77                        avg_bitrate: 67695,
78                        dec_specific: esds::DecoderSpecific {
79                            profile: 2,
80                            freq_index: 4,
81                            chan_conf: 2,
82                        },
83                    },
84                    sl_config: esds::SLConfig::default(),
85                },
86            },
87            btrt: Some(Btrt {
88                buffer_size_db: 1,
89                max_bitrate: 2,
90                avg_bitrate: 3,
91            }),
92            taic: None,
93        };
94        let mut buf = Vec::new();
95        expected.encode(&mut buf).unwrap();
96
97        let mut buf = buf.as_ref();
98        let decoded = Mp4a::decode(&mut buf).unwrap();
99        assert_eq!(decoded, expected);
100    }
101}