1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub struct Eac3 {
8 pub audio: Audio,
9 pub dec3: Ec3SpecificBox,
10}
11
12impl Atom for Eac3 {
13 const KIND: FourCC = FourCC::new(b"ec-3");
14
15 fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
16 let audio = Audio::decode(buf)?;
17
18 let mut dec3 = None;
19
20 while let Some(atom) = Any::decode_maybe(buf)? {
21 match atom {
22 Any::Ec3SpecificBox(atom) => dec3 = atom.into(),
23 _ => tracing::warn!("unknown atom: {:?}", atom),
24 }
25 }
26
27 Ok(Self {
28 audio,
29 dec3: dec3.ok_or(Error::MissingBox(Ec3SpecificBox::KIND))?,
30 })
31 }
32
33 fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
34 self.audio.encode(buf)?;
35 self.dec3.encode(buf)?;
36 Ok(())
37 }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq)]
42#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
43pub struct Ec3IndependentSubstream {
44 pub fscod: u8,
45 pub bsid: u8,
46 pub asvc: bool,
47 pub bsmod: u8,
48 pub acmod: u8,
49 pub lfeon: bool,
50 pub num_dep_sub: u8,
51 pub chan_loc: Option<u16>,
52}
53
54#[derive(Debug, Clone, PartialEq, Eq)]
55#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
56pub struct Ec3SpecificBox {
57 pub data_rate: u16,
58 pub substreams: Vec<Ec3IndependentSubstream>,
59}
60
61impl Atom for Ec3SpecificBox {
62 const KIND: FourCC = FourCC::new(b"dec3");
63
64 fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
65 let header = u16::decode(buf)?;
66 let data_rate = header >> 3;
67 let num_ind_sub = header & 0b111;
68 let mut substreams = Vec::with_capacity(num_ind_sub as usize + 1);
69 for _ in 0..num_ind_sub + 1 {
70 let b0 = u8::decode(buf)?;
71 let fscod = b0 >> 6;
72 let bsid = (b0 >> 1) & 0b11111;
73 let b1 = u8::decode(buf)?;
75 let asvc = (b1 & 0x80) == 0x80;
76 let bsmod = (b1 >> 4) & 0b111;
77 let acmod = (b1 >> 1) & 0b111;
78 let lfeon = (b1 & 0b1) == 0b1;
79 let b2 = u8::decode(buf)?;
80 let num_dep_sub = (b2 >> 1) & 0b1111;
82 if num_dep_sub > 0 {
83 let b3 = u8::decode(buf)? as u16;
84 let chan_loc = ((b2 as u16 & 0x01) << 8) | b3;
85 substreams.push(Ec3IndependentSubstream {
86 fscod,
87 bsid,
88 asvc,
89 bsmod,
90 acmod,
91 lfeon,
92 num_dep_sub,
93 chan_loc: Some(chan_loc),
94 });
95 } else {
96 substreams.push(Ec3IndependentSubstream {
98 fscod,
99 bsid,
100 asvc,
101 bsmod,
102 acmod,
103 lfeon,
104 num_dep_sub,
105 chan_loc: None,
106 });
107 }
108 }
109
110 buf.advance(buf.remaining());
112 Ok(Self {
113 data_rate,
114 substreams,
115 })
116 }
117
118 fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
119 let header = self.data_rate << 3 | self.substreams.len().saturating_sub(1) as u16;
120 header.encode(buf)?;
121 for substream in &self.substreams {
122 let b = (substream.fscod << 6) | (substream.bsid << 1);
124 b.encode(buf)?;
125 let b = (if substream.asvc { 0x80 } else { 0x00 })
126 | (substream.bsmod << 4)
127 | (substream.acmod << 1)
128 | (if substream.lfeon { 0x01 } else { 0x00 });
129 b.encode(buf)?;
130 if substream.num_dep_sub > 0 {
131 let b: u16 =
132 ((substream.num_dep_sub as u16) << 9) | (substream.chan_loc.unwrap_or(0u16));
133 b.encode(buf)?;
134 } else {
135 let b = substream.num_dep_sub << 1;
137 b.encode(buf)?;
138 }
139 }
140 Ok(())
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 const ENCODED_EAC3: &[u8] = &[
150 0x00, 0x00, 0x00, 0x31, 0x65, 0x63, 0x2d, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00,
152 0x00, 0x00, 0xac, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x64, 0x65, 0x63, 0x33, 0x5f,
153 0xc0, 0x60, 0x04, 0x00,
154 ];
155
156 #[test]
157 fn test_eac3_decode() {
158 let buf: &mut std::io::Cursor<&[u8]> = &mut std::io::Cursor::new(ENCODED_EAC3);
159
160 let eac3 = Eac3::decode(buf).expect("failed to decode eac-3");
161
162 assert_eq!(
163 eac3,
164 Eac3 {
165 audio: Audio {
166 data_reference_index: 1,
167 channel_count: 2,
168 sample_size: 16,
169 sample_rate: 44100.into()
170 },
171 dec3: Ec3SpecificBox {
172 data_rate: 3064,
173 substreams: vec![Ec3IndependentSubstream {
174 fscod: 1,
175 bsid: 16,
176 asvc: false,
177 bsmod: 0,
178 acmod: 2,
179 lfeon: false,
180 num_dep_sub: 0,
181 chan_loc: None
182 }]
183 }
184 }
185 );
186 }
187
188 #[test]
189 fn test_eac3_encode() {
190 let eac3 = Eac3 {
191 audio: Audio {
192 data_reference_index: 1,
193 channel_count: 2,
194 sample_size: 16,
195 sample_rate: 44100.into(),
196 },
197 dec3: Ec3SpecificBox {
198 data_rate: 3064,
199 substreams: vec![Ec3IndependentSubstream {
200 fscod: 1,
201 bsid: 16,
202 asvc: false,
203 bsmod: 0,
204 acmod: 2,
205 lfeon: false,
206 num_dep_sub: 0,
207 chan_loc: None,
208 }],
209 },
210 };
211
212 let mut buf = Vec::new();
213 eac3.encode(&mut buf).unwrap();
214
215 assert_eq!(buf.as_slice(), ENCODED_EAC3);
216 }
217
218 #[test]
219 fn test_eac3_with_dependent_substreams() {
220 let eac3 = Eac3 {
222 audio: Audio {
223 data_reference_index: 1,
224 channel_count: 6,
225 sample_size: 16,
226 sample_rate: 48000.into(),
227 },
228 dec3: Ec3SpecificBox {
229 data_rate: 768,
230 substreams: vec![Ec3IndependentSubstream {
231 fscod: 0, bsid: 16,
233 asvc: true,
234 bsmod: 1,
235 acmod: 7, lfeon: true,
237 num_dep_sub: 2,
238 chan_loc: Some(0x1FF),
239 }],
240 },
241 };
242
243 let mut buf = Vec::new();
245 eac3.encode(&mut buf).unwrap();
246
247 let mut cursor = std::io::Cursor::new(&buf);
249 let decoded = Eac3::decode(&mut cursor).expect("failed to decode eac-3");
250
251 assert_eq!(decoded, eac3);
252 assert_eq!(decoded.dec3.substreams[0].chan_loc, Some(0x1FF));
253 }
254
255 #[test]
256 fn test_eac3_multiple_substreams() {
257 let eac3 = Eac3 {
259 audio: Audio {
260 data_reference_index: 1,
261 channel_count: 8,
262 sample_size: 16,
263 sample_rate: 48000.into(),
264 },
265 dec3: Ec3SpecificBox {
266 data_rate: 1536,
267 substreams: vec![
268 Ec3IndependentSubstream {
269 fscod: 0, bsid: 16,
271 asvc: false,
272 bsmod: 0,
273 acmod: 7, lfeon: true,
275 num_dep_sub: 0,
276 chan_loc: None,
277 },
278 Ec3IndependentSubstream {
279 fscod: 0, bsid: 16,
281 asvc: false,
282 bsmod: 0,
283 acmod: 2, lfeon: false,
285 num_dep_sub: 0,
286 chan_loc: None,
287 },
288 ],
289 },
290 };
291
292 let mut buf = Vec::new();
294 eac3.encode(&mut buf).unwrap();
295
296 let mut cursor = std::io::Cursor::new(&buf);
298 let decoded = Eac3::decode(&mut cursor).expect("failed to decode eac-3");
299
300 assert_eq!(decoded, eac3);
301 assert_eq!(decoded.dec3.substreams.len(), 2);
302 }
303
304 #[test]
305 fn test_eac3_with_reserved_bits() {
306 let encoded_with_reserved: &[u8] = &[
309 0x00, 0x00, 0x00, 0x33, 0x65, 0x63, 0x2d, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xac, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x64, 0x65, 0x63, 0x33, 0x5f, 0xc0, 0x60, 0x04, 0x00, 0xAB, 0xCD, ];
319
320 let mut cursor = std::io::Cursor::new(encoded_with_reserved);
321 let decoded = Eac3::decode(&mut cursor).expect("failed to decode eac-3 with reserved bits");
322
323 assert_eq!(
325 decoded,
326 Eac3 {
327 audio: Audio {
328 data_reference_index: 1,
329 channel_count: 2,
330 sample_size: 16,
331 sample_rate: 44100.into()
332 },
333 dec3: Ec3SpecificBox {
334 data_rate: 3064,
335 substreams: vec![Ec3IndependentSubstream {
336 fscod: 1,
337 bsid: 16,
338 asvc: false,
339 bsmod: 0,
340 acmod: 2,
341 lfeon: false,
342 num_dep_sub: 0,
343 chan_loc: None
344 }]
345 }
346 }
347 );
348 }
349}