pito_codecs/opus/
multistream.rs1use 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}