1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq, Default)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub struct Esds {
6 pub es_desc: EsDescriptor,
7}
8
9impl AtomExt for Esds {
10 type Ext = ();
11
12 const KIND_EXT: FourCC = FourCC::new(b"esds");
13
14 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
15 let mut es_desc = None;
16
17 while let Some(desc) = Descriptor::decode_maybe(buf)? {
18 match desc {
19 Descriptor::EsDescriptor(desc) => es_desc = Some(desc),
20 Descriptor::Unknown(tag, _) => {
21 tracing::warn!("unknown descriptor: {:02X}", tag)
22 }
23 _ => return Err(Error::UnexpectedDescriptor(desc.tag())),
24 }
25 }
26
27 Ok(Esds {
28 es_desc: es_desc.ok_or(Error::MissingDescriptor(EsDescriptor::TAG))?,
29 })
30 }
31
32 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
33 encode_descriptor(EsDescriptor::TAG, &self.es_desc, buf)
34 }
35}
36
37fn decode_descriptor_body<T: Decode, B: Buf>(buf: &mut B, size: usize) -> Result<T> {
48 if buf.remaining() < size {
49 return Err(Error::OutOfBounds);
50 }
51 let mut inner = buf.slice(size);
52 let res = T::decode(&mut inner)?;
53 buf.advance(size);
54 Ok(res)
55}
56
57fn encode_descriptor<T: Encode, B: BufMut>(tag: u8, body: &T, buf: &mut B) -> Result<()> {
61 tag.encode(buf)?;
62
63 let mut tmp = Vec::new();
65 body.encode(&mut tmp)?;
66
67 let size = tmp.len() as u32;
72 let mut groups = 1;
73 let mut s = size >> 7;
74 while s > 0 {
75 groups += 1;
76 s >>= 7;
77 }
78 for i in (0..groups).rev() {
79 let mut b = ((size >> (7 * i)) & 0x7F) as u8;
80 if i > 0 {
81 b |= 0x80;
82 }
83 b.encode(buf)?;
84 }
85
86 tmp.encode(buf)
87}
88
89macro_rules! descriptors {
90 ($($name:ident,)*) => {
91 #[derive(Debug, Clone, PartialEq, Eq)]
92 pub enum Descriptor {
93 $(
94 $name($name),
95 )*
96 Unknown(u8, Vec<u8>),
97 }
98
99 impl Decode for Descriptor {
100 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
101 let tag = u8::decode(buf)?;
102
103 let mut size: u32 = 0;
104 for _ in 0..4 {
105 let b = u8::decode(buf)?;
106 size = (size << 7) | (b & 0x7F) as u32;
107 if b & 0x80 == 0 {
108 break;
109 }
110 }
111
112 match tag {
113 $(
114 $name::TAG => Ok(decode_descriptor_body::<$name, _>(buf, size as _)?.into()),
115 )*
116 _ => Ok(Descriptor::Unknown(tag, Vec::decode_exact(buf, size as _)?)),
117 }
118 }
119 }
120
121 impl DecodeMaybe for Descriptor {
122 fn decode_maybe<B: Buf>(buf: &mut B) -> Result<Option<Self>> {
123 match buf.has_remaining() {
124 true => Descriptor::decode(buf).map(Some),
125 false => Ok(None),
126 }
127 }
128 }
129
130 impl Encode for Descriptor {
131 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
132 match self {
133 $(
134 Descriptor::$name(t) => encode_descriptor($name::TAG, t, buf),
135 )*
136 Descriptor::Unknown(tag, data) => encode_descriptor(*tag, data, buf),
137 }
138 }
139 }
140
141 impl Descriptor {
142 pub const fn tag(&self) -> u8 {
143 match self {
144 $(
145 Descriptor::$name(_) => $name::TAG,
146 )*
147 Descriptor::Unknown(tag, _) => *tag,
148 }
149 }
150 }
151
152 $(
153 impl From<$name> for Descriptor {
154 fn from(desc: $name) -> Self {
155 Descriptor::$name(desc)
156 }
157 }
158 )*
159 };
160}
161
162descriptors! {
163 EsDescriptor,
164 DecoderConfig,
165 DecoderSpecific,
166 SLConfig,
167}
168
169#[derive(Debug, Clone, PartialEq, Eq, Default)]
170#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
171pub struct EsDescriptor {
172 pub es_id: u16,
173
174 pub dec_config: DecoderConfig,
175 pub sl_config: SLConfig,
176}
177
178impl EsDescriptor {
179 pub const TAG: u8 = 0x03;
180}
181
182impl Decode for EsDescriptor {
183 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
184 let es_id = u16::decode(buf)?;
185 u8::decode(buf)?; let mut dec_config = None;
188 let mut sl_config = None;
189
190 while let Some(desc) = Descriptor::decode_maybe(buf)? {
191 match desc {
192 Descriptor::DecoderConfig(desc) => dec_config = Some(desc),
193 Descriptor::SLConfig(desc) => sl_config = Some(desc),
194 Descriptor::Unknown(tag, _) => tracing::warn!("unknown descriptor: {:02X}", tag),
195 desc => return Err(Error::UnexpectedDescriptor(desc.tag())),
196 }
197 }
198
199 Ok(EsDescriptor {
200 es_id,
201 dec_config: dec_config.ok_or(Error::MissingDescriptor(DecoderConfig::TAG))?,
202 sl_config: sl_config.ok_or(Error::MissingDescriptor(SLConfig::TAG))?,
203 })
204 }
205}
206
207impl Encode for EsDescriptor {
208 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
209 self.es_id.encode(buf)?;
210 0u8.encode(buf)?;
211
212 encode_descriptor(DecoderConfig::TAG, &self.dec_config, buf)?;
213 encode_descriptor(SLConfig::TAG, &self.sl_config, buf)?;
214
215 Ok(())
216 }
217}
218
219#[derive(Debug, Clone, PartialEq, Eq, Default)]
220#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
221pub struct DecoderConfig {
222 pub object_type_indication: u8,
223 pub stream_type: u8,
224 pub up_stream: u8,
225 pub buffer_size_db: u24,
226 pub max_bitrate: u32,
227 pub avg_bitrate: u32,
228 pub dec_specific: Option<DecoderSpecific>,
234}
235
236impl DecoderConfig {
237 pub const TAG: u8 = 0x04;
238}
239
240impl Decode for DecoderConfig {
241 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
242 let object_type_indication = u8::decode(buf)?;
243 let byte_a = u8::decode(buf)?;
244 let stream_type = (byte_a & 0xFC) >> 2;
245 let up_stream = byte_a & 0x02;
246 let buffer_size_db = u24::decode(buf)?;
247 let max_bitrate = u32::decode(buf)?;
248 let avg_bitrate = u32::decode(buf)?;
249
250 let mut dec_specific = None;
251
252 while let Some(desc) = Descriptor::decode_maybe(buf)? {
253 match desc {
254 Descriptor::DecoderSpecific(desc) => dec_specific = Some(desc),
255 Descriptor::Unknown(tag, _) => tracing::warn!("unknown descriptor: {:02X}", tag),
256 desc => return Err(Error::UnexpectedDescriptor(desc.tag())),
257 }
258 }
259
260 Ok(DecoderConfig {
261 object_type_indication,
262 stream_type,
263 up_stream,
264 buffer_size_db,
265 max_bitrate,
266 avg_bitrate,
267 dec_specific,
268 })
269 }
270}
271
272impl Encode for DecoderConfig {
273 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
274 self.object_type_indication.encode(buf)?;
275 ((self.stream_type << 2) + (self.up_stream & 0x02) + 1).encode(buf)?; self.buffer_size_db.encode(buf)?;
277 self.max_bitrate.encode(buf)?;
278 self.avg_bitrate.encode(buf)?;
279
280 if let Some(dec_specific) = &self.dec_specific {
281 encode_descriptor(DecoderSpecific::TAG, dec_specific, buf)?;
282 }
283
284 Ok(())
285 }
286}
287
288#[derive(Debug, Clone, PartialEq, Eq, Default)]
289#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
290pub struct DecoderSpecific {
291 pub profile: u8,
292 pub freq_index: u8,
293 pub chan_conf: u8,
294 pub raw: Vec<u8>,
303}
304
305impl DecoderSpecific {
306 pub const TAG: u8 = 0x05;
307}
308
309fn parse_audio_specific_config(raw: &[u8]) -> (u8, u8, u8) {
314 if raw.len() < 2 {
315 return (0, 0, 0);
316 }
317 let byte_a = raw[0];
318 let byte_b = raw[1];
319
320 let mut profile = byte_a >> 3;
321 if profile == 31 {
322 profile = 32 + (((byte_a & 7) << 3) | (byte_b >> 5));
324 }
325
326 let freq_index = if profile > 31 {
327 (byte_b >> 1) & 0x0F
328 } else {
329 ((byte_a & 0x07) << 1) + (byte_b >> 7)
330 };
331
332 let chan_conf = if freq_index == 15 {
333 if raw.len() >= 5 {
335 let sample_rate =
336 (u32::from(raw[2]) << 16) | (u32::from(raw[3]) << 8) | u32::from(raw[4]);
337 ((sample_rate >> 4) & 0x0F) as u8
338 } else {
339 0
340 }
341 } else if profile > 31 {
342 if raw.len() >= 3 {
343 ((byte_b & 1) << 3) | (raw[2] >> 5)
345 } else {
346 0
347 }
348 } else {
349 (byte_b >> 3) & 0x0F
350 };
351
352 (profile, freq_index, chan_conf)
353}
354
355impl Decode for DecoderSpecific {
356 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
357 let raw = Vec::decode(buf)?;
361 let (profile, freq_index, chan_conf) = parse_audio_specific_config(&raw);
362
363 Ok(DecoderSpecific {
364 profile,
365 freq_index,
366 chan_conf,
367 raw,
368 })
369 }
370}
371
372impl Encode for DecoderSpecific {
373 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
374 if self.raw.is_empty() {
375 ((self.profile << 3) + (self.freq_index >> 1)).encode(buf)?;
378 ((self.freq_index << 7) + (self.chan_conf << 3)).encode(buf)?;
379 } else {
380 self.raw.encode(buf)?;
382 }
383
384 Ok(())
385 }
386}
387
388#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
389#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
390pub struct SLConfig {}
391
392impl SLConfig {
393 pub const TAG: u8 = 0x06;
394}
395
396impl Decode for SLConfig {
397 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
398 u8::decode(buf)?; Ok(SLConfig {})
400 }
401}
402
403impl Encode for SLConfig {
404 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
405 2u8.encode(buf)?; Ok(())
407 }
408}
409
410#[cfg(test)]
411mod tests {
412 use super::*;
413
414 const ESDS_2BYTE_SLCONFIG: &[u8] = &[
422 0x00, 0x00, 0x00, 0x28, b'e', b's', b'd', b's', 0x00, 0x00, 0x00, 0x00, 0x03, 0x1a, 0x00, 0x01, 0x00, 0x04, 0x11, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x02, 0x11, 0x90, 0x06, 0x02, 0x02, 0x15, ];
432
433 #[test]
434 fn test_esds_two_byte_slconfig() {
435 let esds =
436 Esds::decode(&mut &ESDS_2BYTE_SLCONFIG[..]).expect("2-byte SLConfig must be tolerated");
437 let dec = esds
438 .es_desc
439 .dec_config
440 .dec_specific
441 .expect("DecoderSpecificInfo present");
442 assert_eq!(dec.profile, 2, "AAC-LC");
443 assert_eq!(dec.freq_index, 3, "48 kHz");
444 }
445
446 const ESDS_NO_DEC_SPECIFIC: &[u8] = &[
453 0x00, 0x00, 0x00, 0x23, b'e', b's', b'd', b's', 0x00, 0x00, 0x00, 0x00, 0x03, 0x15, 0x00, 0x01, 0x00, 0x04, 0x0d, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, ];
462
463 #[test]
464 fn test_esds_missing_dec_specific() {
465 let esds = Esds::decode(&mut &ESDS_NO_DEC_SPECIFIC[..])
466 .expect("a DecoderConfig without a DecoderSpecificInfo must be tolerated");
467 assert_eq!(esds.es_desc.dec_config.object_type_indication, 0x40);
468 assert!(
469 esds.es_desc.dec_config.dec_specific.is_none(),
470 "no tag-5 child decodes to None, not an error"
471 );
472
473 let mut buf = Vec::new();
475 esds.encode(&mut buf).unwrap();
476 let again = Esds::decode(&mut buf.as_slice()).unwrap();
477 assert_eq!(again, esds);
478 }
479
480 #[test]
485 fn test_unknown_descriptor_empty_body_roundtrips() {
486 let mut buf = Vec::new();
487 Descriptor::Unknown(0x7F, Vec::new())
488 .encode(&mut buf)
489 .unwrap();
490 Descriptor::from(SLConfig {}).encode(&mut buf).unwrap();
493
494 assert_eq!(&buf[..2], &[0x7F, 0x00], "empty body still emits a length");
495
496 let mut cur = buf.as_slice();
497 assert_eq!(
498 Descriptor::decode(&mut cur).unwrap(),
499 Descriptor::Unknown(0x7F, Vec::new())
500 );
501 assert_eq!(
502 Descriptor::decode(&mut cur).unwrap().tag(),
503 SLConfig::TAG,
504 "the following descriptor is intact"
505 );
506 }
507
508 #[test]
512 fn test_descriptor_multibyte_length_roundtrips() {
513 let body = vec![0xABu8; 200];
514 let mut buf = Vec::new();
515 Descriptor::Unknown(0x7F, body.clone())
516 .encode(&mut buf)
517 .unwrap();
518 assert_eq!(
519 &buf[..3],
520 &[0x7F, 0x81, 0x48],
521 "length 200, MSB group first"
522 );
523
524 let mut cur = buf.as_slice();
525 assert_eq!(
526 Descriptor::decode(&mut cur).unwrap(),
527 Descriptor::Unknown(0x7F, body)
528 );
529 }
530
531 #[test]
536 fn test_asc_escape_bit_packing() {
537 let (profile, freq_index, chan_conf) = parse_audio_specific_config(&[0xF9, 0x49, 0x20]);
538 assert_eq!(profile, 42, "32 + ((0xF9 & 7) << 3 | 0x49 >> 5)");
539 assert_eq!(freq_index, 4, "(0x49 >> 1) & 0x0F");
540 assert_eq!(chan_conf, 9, "((0x49 & 1) << 3) | (0x20 >> 5)");
541 }
542}