Skip to main content

pito_codecs/opus/
multistream.rs

1use crate::media::{Error, Result};
2use crate::opus::decoder::StreamDecoder;
3use crate::opus::header::OpusHead;
4use crate::opus::packet::Packet;
5
6pub struct Decoder {
7    head: OpusHead,
8    rate: u32,
9    streams: Vec<StreamDecoder>,
10    trim_pre_skip: bool,
11    skip_remaining: usize,
12    scratch: Vec<Vec<f32>>,
13    reframed: Vec<u8>,
14}
15
16impl Decoder {
17    pub fn new(opus_head: &[u8]) -> Result<Decoder> {
18        Self::from_head(OpusHead::parse(opus_head)?, 48000)
19    }
20
21    pub fn simple(sample_rate: u32, channels: usize) -> Result<Decoder> {
22        Self::from_head(OpusHead::simple(channels)?, sample_rate)
23    }
24
25    pub fn from_head(head: OpusHead, sample_rate: u32) -> Result<Decoder> {
26        if head.channels == 0
27            || head.streams == 0
28            || head.coupled_streams > head.streams
29            || head.streams.saturating_add(head.coupled_streams) > 255
30            || head.mapping.len() != head.channels
31            || head
32                .mapping
33                .iter()
34                .any(|&m| m != 255 && m as usize >= head.streams + head.coupled_streams)
35        {
36            return Err(Error::Invalid("inconsistent Opus channel mapping".into()));
37        }
38        let mut streams = Vec::with_capacity(head.streams);
39        for s in 0..head.streams {
40            let ch = if s < head.coupled_streams { 2 } else { 1 };
41            let mut d = StreamDecoder::new(sample_rate, ch)?;
42            d.set_gain_q8(head.output_gain);
43            streams.push(d);
44        }
45        Ok(Decoder {
46            rate: sample_rate,
47            streams,
48            trim_pre_skip: false,
49            skip_remaining: 0,
50            scratch: vec![Vec::new(); head.streams],
51            reframed: Vec::new(),
52            head,
53        })
54    }
55
56    pub fn head(&self) -> &OpusHead {
57        &self.head
58    }
59
60    pub fn sample_rate(&self) -> u32 {
61        self.rate
62    }
63
64    pub fn channels(&self) -> usize {
65        self.head.channels
66    }
67
68    pub fn pre_skip(&self) -> usize {
69        self.head.pre_skip as usize * self.rate as usize / 48000
70    }
71
72    pub fn set_trim_pre_skip(&mut self, enable: bool) {
73        self.trim_pre_skip = enable;
74        self.skip_remaining = if enable { self.pre_skip() } else { 0 };
75    }
76
77    pub fn set_phase_inversion_disabled(&mut self, disabled: bool) {
78        for s in &mut self.streams {
79            s.set_phase_inversion_disabled(disabled);
80        }
81    }
82
83    pub fn final_range(&self) -> u32 {
84        self.streams.first().map_or(0, |s| s.final_range())
85    }
86
87    pub fn reset(&mut self) {
88        for s in &mut self.streams {
89            s.reset();
90        }
91        self.skip_remaining = if self.trim_pre_skip {
92            self.pre_skip()
93        } else {
94            0
95        };
96    }
97
98    pub fn decode_into(&mut self, packet: Option<&[u8]>, out: &mut Vec<f32>) -> Result<usize> {
99        let n = self.streams.len();
100        let mut samples = None;
101        if n == 1 {
102            let start = out.len();
103            let r = match packet {
104                Some(data) if !data.is_empty() => {
105                    self.streams[0].decode_interleaved(Some(data), out)?
106                }
107                _ => {
108                    let dur = self.conceal_len();
109                    self.streams[0].conceal(dur, out)?
110                }
111            };
112            if self.head.mapping_family != 0
113                || self.head.channels != self.streams[0].channels()
114                || self.head.mapping != [0, 1][..self.head.channels]
115            {
116                let ch = self.head.channels;
117                let tmp = &mut self.scratch[0];
118                tmp.clear();
119                tmp.extend_from_slice(&out[start..]);
120                out.resize(start + r * ch, 0.0);
121                let nch = self.streams[0].channels();
122                for i in 0..r {
123                    for c in 0..ch {
124                        let m = self.head.mapping[c] as usize;
125                        out[start + i * ch + c] = if m == 255 { 0.0 } else { tmp[i * nch + m] };
126                    }
127                }
128            }
129            return Ok(self.trim(out, start, r));
130        }
131        for b in &mut self.scratch {
132            b.clear();
133        }
134        match packet {
135            Some(data) if !data.is_empty() => {
136                let mut off = 0;
137                for s in 0..n {
138                    let rest = &data[off..];
139                    if rest.is_empty() {
140                        return Err(Error::Invalid("truncated multistream packet".into()));
141                    }
142                    let used = if s + 1 < n {
143                        Packet::parse_self_delimited(rest)?.1
144                    } else {
145                        rest.len()
146                    };
147                    let pkt = &rest[..used];
148                    let r = if s + 1 < n {
149                        let (p, _) = Packet::parse_self_delimited(pkt)?;
150                        reframe(&p, &mut self.reframed);
151                        self.streams[s]
152                            .decode_interleaved(Some(&self.reframed), &mut self.scratch[s])?
153                    } else {
154                        self.streams[s].decode_interleaved(Some(pkt), &mut self.scratch[s])?
155                    };
156                    if *samples.get_or_insert(r) != r {
157                        return Err(Error::Invalid("multistream frame durations differ".into()));
158                    }
159                    off += used;
160                }
161            }
162            _ => {
163                let dur = self.conceal_len();
164                for s in 0..n {
165                    self.streams[s].conceal(dur, &mut self.scratch[s])?;
166                }
167                samples = Some(dur);
168            }
169        }
170        let samples = samples.unwrap_or(0);
171        let ch = self.head.channels;
172        let start = out.len();
173        out.resize(start + samples * ch, 0.0);
174        for c in 0..ch {
175            let m = self.head.mapping[c] as usize;
176            if m == 255 {
177                continue;
178            }
179            let (s, sc, nch) = if m < 2 * self.head.coupled_streams {
180                (m / 2, m % 2, 2)
181            } else {
182                (m - self.head.coupled_streams, 0, 1)
183            };
184            let src = &self.scratch[s];
185            for i in 0..samples {
186                out[start + i * ch + c] = src[i * nch + sc];
187            }
188        }
189        Ok(self.trim(out, start, samples))
190    }
191
192    fn conceal_len(&self) -> usize {
193        match self.streams[0].last_packet_duration() {
194            0 => self.rate as usize / 50,
195            d => d,
196        }
197    }
198
199    fn trim(&mut self, out: &mut Vec<f32>, start: usize, samples: usize) -> usize {
200        if self.skip_remaining == 0 {
201            return samples;
202        }
203        let k = self.skip_remaining.min(samples);
204        let ch = self.head.channels;
205        out.drain(start..start + k * ch);
206        self.skip_remaining -= k;
207        samples - k
208    }
209}
210
211fn reframe(p: &Packet, v: &mut Vec<u8>) {
212    v.clear();
213    v.push((p.toc.config << 3) | if p.toc.stereo { 4 } else { 0 } | 3);
214    v.push(0x80 | p.frames.len() as u8);
215    for f in &p.frames[..p.frames.len() - 1] {
216        let s = f.len();
217        if s < 252 {
218            v.push(s as u8);
219        } else {
220            let b0 = 252 + (s & 3);
221            v.push(b0 as u8);
222            v.push(((s - b0) >> 2) as u8);
223        }
224    }
225    for f in &p.frames {
226        v.extend_from_slice(f);
227    }
228}