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 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)?; u16::decode(buf)?; let data_reference_index = u16::decode(buf)?;
36 let version = u16::decode(buf)?;
37 u16::decode(buf)?; u32::decode(buf)?; let channelcount = u16::decode(buf)?;
40 let samplesize = u16::decode(buf)?;
41 u32::decode(buf)?; let samplerate = FixedPoint::decode(buf)?;
43
44 if version == 1 {
45 u64::decode(buf)?;
47 u64::decode(buf)?;
48 }
49
50 let mut esds = None;
51
52 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)?; 0u16.encode(buf)?; self.data_reference_index.encode(buf)?;
73 0u16.encode(buf)?; 0u16.encode(buf)?; 0u32.encode(buf)?; self.channelcount.encode(buf)?;
77 self.samplesize.encode(buf)?;
78 0u32.encode(buf)?; 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}