1use byteorder::{BigEndian, WriteBytesExt};
2use serde::Serialize;
3use std::io::Write;
4
5use crate::mp4box::*;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
8pub struct Mp4aBox {
9 pub data_reference_index: u16,
10 pub channelcount: u16,
11 pub samplesize: u16,
12
13 #[serde(with = "value_u32")]
14 pub samplerate: FixedPointU16,
15 pub esds: Option<EsdsBox>,
16}
17
18impl Default for Mp4aBox {
19 fn default() -> Self {
20 Self {
21 data_reference_index: 0,
22 channelcount: 2,
23 samplesize: 16,
24 samplerate: FixedPointU16::new(48000),
25 esds: Some(EsdsBox::default()),
26 }
27 }
28}
29
30impl Mp4aBox {
31 pub fn new(config: &AacConfig) -> Self {
32 Self {
33 data_reference_index: 1,
34 channelcount: config.chan_conf as u16,
35 samplesize: 16,
36 samplerate: FixedPointU16::new(config.freq_index.freq() as u16),
37 esds: Some(EsdsBox::new(config)),
38 }
39 }
40
41 pub fn get_type(&self) -> BoxType {
42 BoxType::Mp4aBox
43 }
44
45 pub fn get_size(&self) -> u64 {
46 let mut size = HEADER_SIZE + 8 + 20;
47 if let Some(ref esds) = self.esds {
48 size += esds.box_size();
49 }
50 size
51 }
52}
53
54impl Mp4Box for Mp4aBox {
55 const TYPE: BoxType = BoxType::Mp4aBox;
56
57 fn box_size(&self) -> u64 {
58 self.get_size()
59 }
60
61 fn to_json(&self) -> Result<String, Error> {
62 Ok(serde_json::to_string(&self).unwrap())
63 }
64
65 fn summary(&self) -> Result<String, Error> {
66 let s = format!(
67 "channel_count={} sample_size={} sample_rate={}",
68 self.channelcount,
69 self.samplesize,
70 self.samplerate.value()
71 );
72 Ok(s)
73 }
74}
75
76impl BlockReader for Mp4aBox {
77 fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
78 reader.get_u32(); reader.get_u16(); let data_reference_index = reader.get_u16();
82 let version = reader.get_u16();
83
84 reader.get_u16(); reader.get_u32(); let channelcount = reader.get_u16();
88 let samplesize = reader.get_u16();
89
90 reader.get_u32(); let samplerate = FixedPointU16::new_raw(reader.get_u32());
93
94 if version == 1 {
95 if reader.remaining() < 16 {
96 return Err(Error::InvalidData("expected at least 16 bytes more"));
97 }
98
99 reader.get_u64();
101 reader.get_u64();
102 }
103
104 Ok(Mp4aBox {
105 data_reference_index,
106 channelcount,
107 samplesize,
108 samplerate,
109 esds: reader.try_find_box::<EsdsBox>()?,
110 })
111 }
112
113 fn size_hint() -> usize {
114 28
115 }
116}
117
118impl<W: Write> WriteBox<&mut W> for Mp4aBox {
119 fn write_box(&self, writer: &mut W) -> Result<u64, Error> {
120 let size = self.box_size();
121 BoxHeader::new(Self::TYPE, size).write(writer)?;
122
123 writer.write_u32::<BigEndian>(0)?; writer.write_u16::<BigEndian>(0)?; writer.write_u16::<BigEndian>(self.data_reference_index)?;
126
127 writer.write_u64::<BigEndian>(0)?; writer.write_u16::<BigEndian>(self.channelcount)?;
129 writer.write_u16::<BigEndian>(self.samplesize)?;
130 writer.write_u32::<BigEndian>(0)?; writer.write_u32::<BigEndian>(self.samplerate.raw_value())?;
132
133 if let Some(ref esds) = self.esds {
134 esds.write_box(writer)?;
135 }
136
137 Ok(size)
138 }
139}
140
141#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
142pub struct EsdsBox {
143 pub version: u8,
144 pub flags: u32,
145 pub es_desc: ESDescriptor,
146}
147
148impl EsdsBox {
149 pub fn new(config: &AacConfig) -> Self {
150 Self {
151 version: 0,
152 flags: 0,
153 es_desc: ESDescriptor::new(config),
154 }
155 }
156}
157
158impl Mp4Box for EsdsBox {
159 const TYPE: BoxType = BoxType::EsdsBox;
160
161 fn box_size(&self) -> u64 {
162 HEADER_SIZE
163 + HEADER_EXT_SIZE
164 + 1
165 + size_of_length(ESDescriptor::desc_size()) as u64
166 + ESDescriptor::desc_size() as u64
167 }
168
169 fn to_json(&self) -> Result<String, Error> {
170 Ok(serde_json::to_string(&self).unwrap())
171 }
172
173 fn summary(&self) -> Result<String, Error> {
174 Ok(String::new())
175 }
176}
177
178impl BlockReader for EsdsBox {
179 fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
180 let (version, flags) = read_box_header_ext(reader);
181
182 let mut es_desc = None;
183
184 while let Some((desc_tag, desc_size)) = read_desc(reader) {
185 match desc_tag {
186 0x03 => {
187 es_desc = Some(ESDescriptor::read_block(&mut reader.take(desc_size as _)?)?);
188 }
189 _ => break,
190 }
191 }
192
193 if es_desc.is_none() {
194 return Err(Error::InvalidData("ESDescriptor not found"));
195 }
196
197 Ok(EsdsBox {
198 version,
199 flags,
200 es_desc: es_desc.unwrap(),
201 })
202 }
203
204 fn size_hint() -> usize {
205 4 + ESDescriptor::size_hint()
206 }
207}
208
209impl<W: Write> WriteBox<&mut W> for EsdsBox {
210 fn write_box(&self, writer: &mut W) -> Result<u64, Error> {
211 let size = self.box_size();
212 BoxHeader::new(Self::TYPE, size).write(writer)?;
213
214 write_box_header_ext(writer, self.version, self.flags)?;
215
216 self.es_desc.write_desc(writer)?;
217
218 Ok(size)
219 }
220}
221
222trait Descriptor: Sized {
223 fn desc_tag() -> u8;
224 fn desc_size() -> u32;
225}
226
227trait WriteDesc<T>: Sized {
228 fn write_desc(&self, _: T) -> Result<u32, Error>;
229}
230
231fn read_desc<'a, R: Reader<'a>>(reader: &mut R) -> Option<(u8, u32)> {
232 let tag = reader.try_get_u8().ok()?;
233
234 let mut size: u32 = 0;
235 for _ in 0..4 {
236 let b = reader.try_get_u8().ok()?;
237 size = (size << 7) | (b & 0x7F) as u32;
238
239 if b & 0x80 == 0 {
240 break;
241 }
242 }
243
244 Some((tag, size))
245}
246
247fn size_of_length(size: u32) -> u32 {
248 match size {
249 0x0..=0x7F => 1,
250 0x80..=0x3FFF => 2,
251 0x4000..=0x1FFFFF => 3,
252 _ => 4,
253 }
254}
255
256fn write_desc<W: Write>(writer: &mut W, tag: u8, size: u32) -> Result<u64, Error> {
257 writer.write_u8(tag)?;
258
259 if size as u64 > std::u32::MAX as u64 {
260 return Err(Error::InvalidData("invalid descriptor length range"));
261 }
262
263 let nbytes = size_of_length(size);
264
265 for i in 0..nbytes {
266 let mut b = (size >> ((nbytes - i - 1) * 7)) as u8 & 0x7F;
267 if i < nbytes - 1 {
268 b |= 0x80;
269 }
270 writer.write_u8(b)?;
271 }
272
273 Ok(1 + nbytes as u64)
274}
275
276#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
277pub struct ESDescriptor {
278 pub es_id: u16,
279
280 pub dec_config: DecoderConfigDescriptor,
281 pub sl_config: SLConfigDescriptor,
282}
283
284impl ESDescriptor {
285 pub fn new(config: &AacConfig) -> Self {
286 Self {
287 es_id: 1,
288 dec_config: DecoderConfigDescriptor::new(config),
289 sl_config: SLConfigDescriptor::new(),
290 }
291 }
292}
293
294impl Descriptor for ESDescriptor {
295 fn desc_tag() -> u8 {
296 0x03
297 }
298
299 fn desc_size() -> u32 {
300 3 + 1
301 + size_of_length(DecoderConfigDescriptor::desc_size())
302 + DecoderConfigDescriptor::desc_size()
303 + 1
304 + size_of_length(SLConfigDescriptor::desc_size())
305 + SLConfigDescriptor::desc_size()
306 }
307}
308
309impl BlockReader for ESDescriptor {
310 fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
311 let es_id = reader.get_u16();
312 reader.get_u8(); let mut dec_config = None;
315 let mut sl_config = None;
316
317 while let Some((desc_tag, desc_size)) = read_desc(reader) {
318 match desc_tag {
319 0x04 => {
320 let mut rdr = reader.take(desc_size as _)?;
321 dec_config = Some(DecoderConfigDescriptor::read_block(&mut rdr)?);
322 rdr.skip(rdr.remaining());
323 }
324 0x06 => {
325 let mut rdr = reader.take(desc_size as _)?;
326 sl_config = Some(SLConfigDescriptor::read_block(&mut rdr)?);
327 rdr.skip(rdr.remaining());
328 }
329 _ => reader.skip(desc_size as _),
330 }
331 }
332
333 Ok(ESDescriptor {
334 es_id,
335 dec_config: dec_config.unwrap_or_default(),
336 sl_config: sl_config.unwrap_or_default(),
337 })
338 }
339
340 fn size_hint() -> usize {
341 3
342 }
343}
344
345impl<W: Write> WriteDesc<&mut W> for ESDescriptor {
346 fn write_desc(&self, writer: &mut W) -> Result<u32, Error> {
347 let size = Self::desc_size();
348 write_desc(writer, Self::desc_tag(), size)?;
349
350 writer.write_u16::<BigEndian>(self.es_id)?;
351 writer.write_u8(0)?;
352
353 self.dec_config.write_desc(writer)?;
354 self.sl_config.write_desc(writer)?;
355
356 Ok(size)
357 }
358}
359
360#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
361pub struct DecoderConfigDescriptor {
362 pub object_type_indication: u8,
363 pub stream_type: u8,
364 pub up_stream: u8,
365 pub buffer_size_db: u32,
366 pub max_bitrate: u32,
367 pub avg_bitrate: u32,
368
369 pub dec_specific: DecoderSpecificDescriptor,
370}
371
372impl DecoderConfigDescriptor {
373 pub fn new(config: &AacConfig) -> Self {
374 Self {
375 object_type_indication: 0x40, stream_type: 0x05, up_stream: 0,
378 buffer_size_db: 0,
379 max_bitrate: config.bitrate, avg_bitrate: config.bitrate,
381 dec_specific: DecoderSpecificDescriptor::new(config),
382 }
383 }
384}
385
386impl Descriptor for DecoderConfigDescriptor {
387 fn desc_tag() -> u8 {
388 0x04
389 }
390
391 fn desc_size() -> u32 {
392 13 + 1
393 + size_of_length(DecoderSpecificDescriptor::desc_size())
394 + DecoderSpecificDescriptor::desc_size()
395 }
396}
397
398impl BlockReader for DecoderConfigDescriptor {
399 fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
400 let object_type_indication = reader.get_u8();
401 let byte_a = reader.get_u8();
402 let stream_type = (byte_a & 0xFC) >> 2;
403 let up_stream = byte_a & 0x02;
404 let buffer_size_db = reader.get_u24();
405 let max_bitrate = reader.get_u32();
406 let avg_bitrate = reader.get_u32();
407
408 let mut dec_specific = None;
409
410 while let Some((desc_tag, desc_size)) = read_desc(reader) {
411 match desc_tag {
412 0x05 => {
413 let mut rdr = reader.take(desc_size as _)?;
414 let r = DecoderSpecificDescriptor::read_block(&mut rdr)?;
415 rdr.skip(rdr.remaining());
416 dec_specific = Some(r);
417 }
418 _ => reader.skip(desc_size as _),
419 }
420 }
421
422 Ok(DecoderConfigDescriptor {
423 object_type_indication,
424 stream_type,
425 up_stream,
426 buffer_size_db,
427 max_bitrate,
428 avg_bitrate,
429 dec_specific: dec_specific.unwrap_or_default(),
430 })
431 }
432
433 fn size_hint() -> usize {
434 13
435 }
436}
437
438impl<W: Write> WriteDesc<&mut W> for DecoderConfigDescriptor {
439 fn write_desc(&self, writer: &mut W) -> Result<u32, Error> {
440 let size = Self::desc_size();
441 write_desc(writer, Self::desc_tag(), size)?;
442
443 writer.write_u8(self.object_type_indication)?;
444 writer.write_u8((self.stream_type << 2) + (self.up_stream & 0x02) + 1)?; writer.write_u24::<BigEndian>(self.buffer_size_db)?;
446 writer.write_u32::<BigEndian>(self.max_bitrate)?;
447 writer.write_u32::<BigEndian>(self.avg_bitrate)?;
448
449 self.dec_specific.write_desc(writer)?;
450
451 Ok(size)
452 }
453}
454
455#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
456pub struct DecoderSpecificDescriptor {
457 pub profile: u8,
458 pub freq_index: u8,
459 pub chan_conf: u8,
460}
461
462impl DecoderSpecificDescriptor {
463 pub fn new(config: &AacConfig) -> Self {
464 Self {
465 profile: config.profile as u8,
466 freq_index: config.freq_index as u8,
467 chan_conf: config.chan_conf as u8,
468 }
469 }
470}
471
472impl Descriptor for DecoderSpecificDescriptor {
473 fn desc_tag() -> u8 {
474 0x05
475 }
476
477 fn desc_size() -> u32 {
478 2
479 }
480}
481
482fn get_audio_object_type(byte_a: u8, byte_b: u8) -> u8 {
483 let mut profile = byte_a >> 3;
484 if profile == 31 {
485 profile = 32 + ((byte_a & 7) | (byte_b >> 5));
486 }
487
488 profile
489}
490
491fn get_chan_conf<'a, R: Reader<'a>>(
492 reader: &mut R,
493 byte_b: u8,
494 freq_index: u8,
495 extended_profile: bool,
496) -> Result<u8, Error> {
497 let chan_conf;
498 if freq_index == 15 {
499 let sample_rate = reader.try_get_u24()?;
501 chan_conf = ((sample_rate >> 4) & 0x0F) as u8;
502 } else if extended_profile {
503 let byte_c = reader.try_get_u8()?;
504 chan_conf = (byte_b & 1) | (byte_c & 0xE0);
505 } else {
506 chan_conf = (byte_b >> 3) & 0x0F;
507 }
508
509 Ok(chan_conf)
510}
511
512impl BlockReader for DecoderSpecificDescriptor {
513 fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
514 let byte_a = reader.get_u8();
515 let byte_b = reader.get_u8();
516 let profile = get_audio_object_type(byte_a, byte_b);
517
518 let freq_index;
519 let chan_conf;
520 if profile > 31 {
521 freq_index = (byte_b >> 1) & 0x0F;
522 chan_conf = get_chan_conf(reader, byte_b, freq_index, true)?;
523 } else {
524 freq_index = ((byte_a & 0x07) << 1) + (byte_b >> 7);
525 chan_conf = get_chan_conf(reader, byte_b, freq_index, false)?;
526 }
527
528 Ok(DecoderSpecificDescriptor {
529 profile,
530 freq_index,
531 chan_conf,
532 })
533 }
534
535 fn size_hint() -> usize {
536 2
537 }
538}
539
540impl<W: Write> WriteDesc<&mut W> for DecoderSpecificDescriptor {
541 fn write_desc(&self, writer: &mut W) -> Result<u32, Error> {
542 let size = Self::desc_size();
543 write_desc(writer, Self::desc_tag(), size)?;
544
545 writer.write_u8((self.profile << 3) + (self.freq_index >> 1))?;
546 writer.write_u8((self.freq_index << 7) + (self.chan_conf << 3))?;
547
548 Ok(size)
549 }
550}
551
552#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
553pub struct SLConfigDescriptor {}
554
555impl SLConfigDescriptor {
556 pub fn new() -> Self {
557 SLConfigDescriptor {}
558 }
559}
560
561impl Descriptor for SLConfigDescriptor {
562 fn desc_tag() -> u8 {
563 0x06
564 }
565
566 fn desc_size() -> u32 {
567 1
568 }
569}
570
571impl BlockReader for SLConfigDescriptor {
572 fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
573 reader.get_u8(); Ok(SLConfigDescriptor {})
576 }
577
578 fn size_hint() -> usize {
579 1
580 }
581}
582
583impl<W: Write> WriteDesc<&mut W> for SLConfigDescriptor {
584 fn write_desc(&self, writer: &mut W) -> Result<u32, Error> {
585 let size = Self::desc_size();
586 write_desc(writer, Self::desc_tag(), size)?;
587
588 writer.write_u8(2)?; Ok(size)
590 }
591}
592
593#[cfg(test)]
594mod tests {
595 use super::*;
596 use crate::mp4box::BoxHeader;
597
598 #[tokio::test]
599 async fn test_mp4a() {
600 let src_box = Mp4aBox {
601 data_reference_index: 1,
602 channelcount: 2,
603 samplesize: 16,
604 samplerate: FixedPointU16::new(48000),
605 esds: Some(EsdsBox {
606 version: 0,
607 flags: 0,
608 es_desc: ESDescriptor {
609 es_id: 2,
610 dec_config: DecoderConfigDescriptor {
611 object_type_indication: 0x40,
612 stream_type: 0x05,
613 up_stream: 0,
614 buffer_size_db: 0,
615 max_bitrate: 67695,
616 avg_bitrate: 67695,
617 dec_specific: DecoderSpecificDescriptor {
618 profile: 2,
619 freq_index: 3,
620 chan_conf: 1,
621 },
622 },
623 sl_config: SLConfigDescriptor::default(),
624 },
625 }),
626 };
627 let mut buf = Vec::new();
628 src_box.write_box(&mut buf).unwrap();
629 assert_eq!(buf.len(), src_box.box_size() as usize);
630
631 let mut reader = buf.as_slice();
632 let header = BoxHeader::read(&mut reader, &mut 0).await.unwrap().unwrap();
633 assert_eq!(header.kind, BoxType::Mp4aBox);
634 assert_eq!(src_box.box_size(), header.size);
635
636 let dst_box = Mp4aBox::read_block(&mut reader).unwrap();
637 assert_eq!(src_box, dst_box);
638 }
639
640 #[tokio::test]
641 async fn test_mp4a_no_esds() {
642 let src_box = Mp4aBox {
643 data_reference_index: 1,
644 channelcount: 2,
645 samplesize: 16,
646 samplerate: FixedPointU16::new(48000),
647 esds: None,
648 };
649 let mut buf = Vec::new();
650 src_box.write_box(&mut buf).unwrap();
651 assert_eq!(buf.len(), src_box.box_size() as usize);
652
653 let mut reader = buf.as_slice();
654 let header = BoxHeader::read(&mut reader, &mut 0).await.unwrap().unwrap();
655 assert_eq!(header.kind, BoxType::Mp4aBox);
656 assert_eq!(src_box.box_size(), header.size);
657
658 let dst_box = Mp4aBox::read_block(&mut reader).unwrap();
659 assert_eq!(src_box, dst_box);
660 }
661}