Skip to main content

pito_codecs/aac/
config.rs

1use crate::aac::bits::{BitReader, BitWriter};
2
3use crate::aac::tables::{SAMPLE_RATES, table_index_for_rate};
4use crate::media::{Error, Result};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum ElementType {
8    Sce,
9    Cpe,
10    Lfe,
11}
12
13impl ElementType {
14    pub fn channels(self) -> usize {
15        if self == ElementType::Cpe { 2 } else { 1 }
16    }
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, Default)]
20pub struct ProgramConfig {
21    pub element_instance_tag: u8,
22    pub object_type: u8,
23    pub sf_index: u8,
24    pub front: Vec<(bool, u8)>,
25    pub side: Vec<(bool, u8)>,
26    pub back: Vec<(bool, u8)>,
27    pub lfe: Vec<u8>,
28    pub assoc_data: Vec<u8>,
29    pub cc: Vec<(bool, u8)>,
30    pub comment: Vec<u8>,
31}
32
33impl ProgramConfig {
34    pub fn parse(br: &mut BitReader) -> Result<ProgramConfig> {
35        let mut p = ProgramConfig {
36            element_instance_tag: br.read_bits(4)? as u8,
37            object_type: br.read_bits(2)? as u8,
38            sf_index: br.read_bits(4)? as u8,
39            ..Default::default()
40        };
41        let nf = br.read_bits(4)?;
42        let ns = br.read_bits(4)?;
43        let nb = br.read_bits(4)?;
44        let nl = br.read_bits(2)?;
45        let na = br.read_bits(3)?;
46        let nc = br.read_bits(4)?;
47        if br.read_bits(1)? == 1 {
48            br.skip(4)?;
49        }
50        if br.read_bits(1)? == 1 {
51            br.skip(4)?;
52        }
53        if br.read_bits(1)? == 1 {
54            br.skip(3)?;
55        }
56        for (n, v) in [(nf, &mut p.front), (ns, &mut p.side), (nb, &mut p.back)] {
57            for _ in 0..n {
58                let cpe = br.read_bits(1)? == 1;
59                v.push((cpe, br.read_bits(4)? as u8));
60            }
61        }
62        for _ in 0..nl {
63            p.lfe.push(br.read_bits(4)? as u8);
64        }
65        for _ in 0..na {
66            p.assoc_data.push(br.read_bits(4)? as u8);
67        }
68        for _ in 0..nc {
69            let ind = br.read_bits(1)? == 1;
70            p.cc.push((ind, br.read_bits(4)? as u8));
71        }
72        br.byte_align();
73        let len = br.read_bits(8)?;
74        for _ in 0..len {
75            p.comment.push(br.read_bits(8)? as u8);
76        }
77        Ok(p)
78    }
79
80    pub fn write(&self, bw: &mut BitWriter) {
81        bw.write_bits(self.element_instance_tag as u32, 4);
82        bw.write_bits(self.object_type as u32, 2);
83        bw.write_bits(self.sf_index as u32, 4);
84        bw.write_bits(self.front.len() as u32, 4);
85        bw.write_bits(self.side.len() as u32, 4);
86        bw.write_bits(self.back.len() as u32, 4);
87        bw.write_bits(self.lfe.len() as u32, 2);
88        bw.write_bits(self.assoc_data.len() as u32, 3);
89        bw.write_bits(self.cc.len() as u32, 4);
90        bw.write_bits(0, 3);
91        for v in [&self.front, &self.side, &self.back] {
92            for &(cpe, tag) in v {
93                bw.write_bits(cpe as u32, 1);
94                bw.write_bits(tag as u32, 4);
95            }
96        }
97        for &t in &self.lfe {
98            bw.write_bits(t as u32, 4);
99        }
100        for &t in &self.assoc_data {
101            bw.write_bits(t as u32, 4);
102        }
103        for &(ind, t) in &self.cc {
104            bw.write_bits(ind as u32, 1);
105            bw.write_bits(t as u32, 4);
106        }
107        bw.align_zero();
108        bw.write_bits(self.comment.len().min(255) as u32, 8);
109        for &b in self.comment.iter().take(255) {
110            bw.write_bits(b as u32, 8);
111        }
112    }
113
114    pub fn layout(&self) -> Vec<(ElementType, u8)> {
115        let mut out = Vec::new();
116        for v in [&self.front, &self.side, &self.back] {
117            for &(cpe, tag) in v {
118                out.push((
119                    if cpe {
120                        ElementType::Cpe
121                    } else {
122                        ElementType::Sce
123                    },
124                    tag,
125                ));
126            }
127        }
128        for &t in &self.lfe {
129            out.push((ElementType::Lfe, t));
130        }
131        out
132    }
133}
134
135pub fn config_layout(channel_config: u8) -> Option<Vec<(ElementType, u8)>> {
136    use ElementType::*;
137    Some(match channel_config {
138        1 => vec![(Sce, 0)],
139        2 => vec![(Cpe, 0)],
140        3 => vec![(Sce, 0), (Cpe, 0)],
141        4 => vec![(Sce, 0), (Cpe, 0), (Sce, 1)],
142        5 => vec![(Sce, 0), (Cpe, 0), (Cpe, 1)],
143        6 => vec![(Sce, 0), (Cpe, 0), (Cpe, 1), (Lfe, 0)],
144        7 => vec![(Sce, 0), (Cpe, 0), (Cpe, 1), (Cpe, 2), (Lfe, 0)],
145        _ => return None,
146    })
147}
148
149#[derive(Debug, Clone, PartialEq, Eq)]
150pub struct AudioSpecificConfig {
151    pub object_type: u8,
152    pub sample_rate: u32,
153    pub sf_index: u8,
154    pub channel_config: u8,
155    pub frame_length_flag: bool,
156    pub sbr: bool,
157    pub ps: bool,
158    pub extension_sample_rate: Option<u32>,
159    pub pce: Option<ProgramConfig>,
160}
161
162fn read_aot(br: &mut BitReader) -> Result<u8> {
163    let a = br.read_bits(5)? as u8;
164    Ok(if a == 31 {
165        32 + br.read_bits(6)? as u8
166    } else {
167        a
168    })
169}
170
171fn read_rate(br: &mut BitReader) -> Result<(u8, u32)> {
172    let i = br.read_bits(4)? as u8;
173    if i == 15 {
174        let r = br.read_bits(24)?;
175        return Ok((table_index_for_rate(r), r));
176    }
177    let r = *SAMPLE_RATES
178        .get(i as usize)
179        .ok_or(Error::Invalid("reserved sampling frequency index".into()))?;
180    Ok((i, r))
181}
182
183impl AudioSpecificConfig {
184    pub fn lc(sf_index: u8, channel_config: u8) -> AudioSpecificConfig {
185        AudioSpecificConfig {
186            object_type: 2,
187            sample_rate: SAMPLE_RATES.get(sf_index as usize).copied().unwrap_or(0),
188            sf_index,
189            channel_config,
190            frame_length_flag: false,
191            sbr: false,
192            ps: false,
193            extension_sample_rate: None,
194            pce: None,
195        }
196    }
197
198    pub fn parse(data: &[u8]) -> Result<AudioSpecificConfig> {
199        let mut br = BitReader::new(data);
200        let mut aot = read_aot(&mut br)?;
201        let (sf_index, sample_rate) = read_rate(&mut br)?;
202        let channel_config = br.read_bits(4)? as u8;
203        let (mut sbr, mut ps, mut extension_sample_rate) = (false, false, None);
204        if aot == 5 || aot == 29 {
205            sbr = true;
206            ps = aot == 29;
207            let (_, ext) = read_rate(&mut br)?;
208            extension_sample_rate = Some(ext);
209            aot = read_aot(&mut br)?;
210        }
211        if aot != 2 {
212            return Err(Error::Unsupported(
213                match aot {
214                    1 => "AAC Main profile",
215                    3 => "AAC SSR profile",
216                    4 => "AAC LTP profile",
217                    23 => "AAC-LD",
218                    39 => "AAC-ELD",
219                    _ => "audio object type other than AAC LC",
220                }
221                .into(),
222            ));
223        }
224        let frame_length_flag = br.read_bits(1)? == 1;
225        if br.read_bits(1)? == 1 {
226            br.skip(14)?;
227        }
228        let _extension_flag = br.read_bits(1)?;
229        let pce = if channel_config == 0 {
230            Some(ProgramConfig::parse(&mut br)?)
231        } else {
232            None
233        };
234        if frame_length_flag {
235            return Err(Error::Unsupported("960-sample frames".into()));
236        }
237        let cfg = AudioSpecificConfig {
238            object_type: aot,
239            sample_rate,
240            sf_index,
241            channel_config,
242            frame_length_flag,
243            sbr,
244            ps,
245            extension_sample_rate,
246            pce,
247        };
248        if cfg.channels() == 0 {
249            return Err(Error::Invalid("no channels".into()));
250        }
251        Ok(cfg)
252    }
253
254    pub fn to_bytes(&self) -> Vec<u8> {
255        let mut bw = BitWriter::new();
256        bw.write_bits(self.object_type as u32, 5);
257        match crate::aac::tables::sample_rate_index(self.sample_rate) {
258            Some(i) => bw.write_bits(i as u32, 4),
259            None => {
260                bw.write_bits(15, 4);
261                bw.write_bits(self.sample_rate, 24);
262            }
263        }
264        bw.write_bits(self.channel_config as u32, 4);
265        bw.write_bits(0, 3);
266        if self.channel_config == 0
267            && let Some(p) = &self.pce
268        {
269            p.write(&mut bw);
270        }
271        bw.finish()
272    }
273
274    pub fn layout(&self) -> Vec<(ElementType, u8)> {
275        match &self.pce {
276            Some(p) if self.channel_config == 0 => p.layout(),
277            _ => config_layout(self.channel_config).unwrap_or_default(),
278        }
279    }
280
281    pub fn channels(&self) -> usize {
282        self.layout().iter().map(|e| e.0.channels()).sum()
283    }
284}
285
286#[derive(Debug, Clone, Copy, PartialEq, Eq)]
287pub struct AdtsHeader {
288    pub object_type: u8,
289    pub sf_index: u8,
290    pub channel_config: u8,
291    pub frame_length: usize,
292    pub buffer_fullness: u16,
293    pub header_length: usize,
294    pub raw_data_blocks: u8,
295}
296
297impl AdtsHeader {
298    pub fn parse(data: &[u8]) -> Result<AdtsHeader> {
299        let mut br = BitReader::new(data);
300        if br.read_bits(12)? != 0xFFF {
301            return Err(Error::Invalid("missing ADTS syncword".into()));
302        }
303        br.skip(1)?;
304        if br.read_bits(2)? != 0 {
305            return Err(Error::Invalid("ADTS layer must be 0".into()));
306        }
307        let protection_absent = br.read_bits(1)? == 1;
308        let object_type = br.read_bits(2)? as u8 + 1;
309        let sf_index = br.read_bits(4)? as u8;
310        if sf_index as usize >= SAMPLE_RATES.len() {
311            return Err(Error::Invalid(
312                "invalid ADTS sampling frequency index".into(),
313            ));
314        }
315        br.skip(1)?;
316        let channel_config = br.read_bits(3)? as u8;
317        br.skip(4)?;
318        let frame_length = br.read_bits(13)? as usize;
319        let buffer_fullness = br.read_bits(11)? as u16;
320        let raw_data_blocks = br.read_bits(2)? as u8 + 1;
321        let header_length = if protection_absent { 7 } else { 9 };
322        if frame_length < header_length {
323            return Err(Error::Invalid("ADTS frame shorter than its header".into()));
324        }
325        Ok(AdtsHeader {
326            object_type,
327            sf_index,
328            channel_config,
329            frame_length,
330            buffer_fullness,
331            header_length,
332            raw_data_blocks,
333        })
334    }
335
336    pub fn to_asc(&self) -> AudioSpecificConfig {
337        AudioSpecificConfig {
338            object_type: self.object_type,
339            ..AudioSpecificConfig::lc(self.sf_index, self.channel_config)
340        }
341    }
342
343    pub fn write(
344        object_type: u8,
345        sf_index: u8,
346        channel_config: u8,
347        payload_len: usize,
348        buffer_fullness: u16,
349    ) -> [u8; 7] {
350        let len = (payload_len + 7) as u32;
351        let mut bw = BitWriter::new();
352        bw.write_bits(0xFFF, 12);
353        bw.write_bits(0, 1);
354        bw.write_bits(0, 2);
355        bw.write_bits(1, 1);
356        bw.write_bits((object_type.max(1) - 1) as u32 & 3, 2);
357        bw.write_bits(sf_index as u32, 4);
358        bw.write_bits(0, 1);
359        bw.write_bits(channel_config as u32 & 7, 3);
360        bw.write_bits(0, 4);
361        bw.write_bits(len & 0x1FFF, 13);
362        bw.write_bits(buffer_fullness as u32 & 0x7FF, 11);
363        bw.write_bits(0, 2);
364        let v = bw.finish();
365        let mut out = [0u8; 7];
366        out.copy_from_slice(&v);
367        out
368    }
369}
370
371pub fn split_adts(mut data: &[u8]) -> Result<Vec<(AdtsHeader, &[u8])>> {
372    let mut out = Vec::new();
373    while data.len() >= 7 {
374        let h = match AdtsHeader::parse(data) {
375            Ok(h) => h,
376            Err(e) => {
377                if out.is_empty() {
378                    return Err(e);
379                }
380                break;
381            }
382        };
383        if h.frame_length > data.len() {
384            break;
385        }
386        out.push((h, &data[h.header_length..h.frame_length]));
387        data = &data[h.frame_length..];
388    }
389    if out.is_empty() {
390        return Err(Error::Invalid("no ADTS frames".into()));
391    }
392    Ok(out)
393}