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