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 _ => 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}