mp4_atom/moov/trak/mdia/minf/stbl/stsd/mp4a/
mod.rs1use crate::*;
2
3pub 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 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}