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                unknown => Self::decode_unknown(&unknown)?,
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        self.btrt.encode(buf)?;
48        self.taic.encode(buf)?;
49
50        Ok(())
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_mp4a() {
60        let expected = Mp4a {
61            audio: Audio {
62                data_reference_index: 1,
63                channel_count: 2,
64                sample_size: 16,
65                sample_rate: 48000.into(),
66            },
67            esds: Esds {
68                es_desc: esds::EsDescriptor {
69                    es_id: 2,
70                    dec_config: esds::DecoderConfig {
71                        object_type_indication: 0x40,
72                        stream_type: 0x05,
73                        up_stream: 0,
74                        buffer_size_db: Default::default(),
75                        max_bitrate: 67695,
76                        avg_bitrate: 67695,
77                        dec_specific: esds::DecoderSpecific {
78                            profile: 2,
79                            freq_index: 4,
80                            chan_conf: 2,
81                        },
82                    },
83                    sl_config: esds::SLConfig::default(),
84                },
85            },
86            btrt: Some(Btrt {
87                buffer_size_db: 1,
88                max_bitrate: 2,
89                avg_bitrate: 3,
90            }),
91            taic: None,
92        };
93        let mut buf = Vec::new();
94        expected.encode(&mut buf).unwrap();
95
96        let mut buf = buf.as_ref();
97        let decoded = Mp4a::decode(&mut buf).unwrap();
98        assert_eq!(decoded, expected);
99    }
100
101    #[test]
102    fn test_mp4a_with_taic() {
103        let expected = Mp4a {
104            audio: Audio {
105                data_reference_index: 1,
106                channel_count: 2,
107                sample_size: 16,
108                sample_rate: 48000.into(),
109            },
110            esds: Esds {
111                es_desc: esds::EsDescriptor {
112                    es_id: 2,
113                    dec_config: esds::DecoderConfig {
114                        object_type_indication: 0x40,
115                        stream_type: 0x05,
116                        up_stream: 0,
117                        buffer_size_db: Default::default(),
118                        max_bitrate: 67695,
119                        avg_bitrate: 67695,
120                        dec_specific: esds::DecoderSpecific {
121                            profile: 2,
122                            freq_index: 4,
123                            chan_conf: 2,
124                        },
125                    },
126                    sl_config: esds::SLConfig::default(),
127                },
128            },
129            btrt: None,
130            taic: Some(Taic {
131                time_uncertainty: 1,
132                clock_resolution: 2,
133                clock_drift_rate: 4,
134                clock_type: ClockType::CanSync,
135            }),
136        };
137        let mut buf = Vec::new();
138        expected.encode(&mut buf).unwrap();
139
140        let mut buf = buf.as_ref();
141        let decoded = Mp4a::decode(&mut buf).unwrap();
142        assert_eq!(decoded, expected);
143    }
144}