1use crate::packet;
7use crate::{OpusDecoder, OpusError};
8
9pub struct OpusMultistreamDecoder {
14 decoders: Vec<OpusDecoder>,
16 nb_channels: usize,
18 nb_streams: usize,
20 nb_coupled_streams: usize,
22 mapping: Vec<u8>,
25 sample_rate: u32,
27}
28
29impl OpusMultistreamDecoder {
30 pub fn new(
46 sample_rate: u32,
47 nb_channels: usize,
48 nb_streams: usize,
49 nb_coupled_streams: usize,
50 mapping: &[u8],
51 ) -> Result<Self, OpusError> {
52 if nb_channels == 0 || nb_channels > 255 {
53 return Err(OpusError::InvalidArgument("nb_channels"));
54 }
55 if nb_streams == 0 {
56 return Err(OpusError::InvalidArgument("nb_streams"));
57 }
58 if nb_coupled_streams > nb_streams {
59 return Err(OpusError::InvalidArgument("nb_coupled_streams"));
60 }
61 if nb_streams > 255usize.saturating_sub(nb_coupled_streams) {
62 return Err(OpusError::InvalidArgument("nb_streams"));
63 }
64 if mapping.len() != nb_channels {
65 return Err(OpusError::InvalidArgument("mapping"));
66 }
67
68 let total_decoded_channels = (2 * nb_coupled_streams) + (nb_streams - nb_coupled_streams);
69 for &slot in mapping {
70 if slot != 255 && usize::from(slot) >= total_decoded_channels {
71 return Err(OpusError::InvalidArgument("mapping"));
72 }
73 }
74
75 let mut decoders = Vec::with_capacity(nb_streams);
76 for stream_idx in 0..nb_streams {
77 let channels = if stream_idx < nb_coupled_streams {
78 2
79 } else {
80 1
81 };
82 decoders.push(OpusDecoder::new(sample_rate, channels)?);
83 }
84
85 Ok(Self {
86 decoders,
87 nb_channels,
88 nb_streams,
89 nb_coupled_streams,
90 mapping: mapping.to_vec(),
91 sample_rate,
92 })
93 }
94
95 pub fn decode(
116 &mut self,
117 packet: &[u8],
118 pcm: &mut [i16],
119 fec: bool,
120 ) -> Result<usize, OpusError> {
121 let sub_packets = if packet.is_empty() || fec {
122 vec![&[][..]; self.nb_streams]
123 } else {
124 split_multistream_packet(packet, self.nb_streams)?
125 };
126 let frame_size = self.expected_frame_size(&sub_packets, fec)?;
127 let needed = frame_size * self.nb_channels;
128 if pcm.len() < needed {
129 return Err(OpusError::BufferTooSmall);
130 }
131 if frame_size == 0 {
132 return Ok(0);
133 }
134
135 let mut stream_pcm = Vec::with_capacity(self.nb_streams);
136 for (stream_idx, sub_packet) in sub_packets.iter().enumerate() {
137 let channels = self.stream_channels(stream_idx);
138 let mut buf = vec![0i16; frame_size * channels];
139 let written = self.decoders[stream_idx].decode(sub_packet, &mut buf, fec)?;
140 if written != frame_size {
141 return Err(OpusError::InvalidPacket);
142 }
143 stream_pcm.push(buf);
144 }
145
146 for (channel_idx, &slot) in self.mapping.iter().enumerate() {
147 if slot == 255 {
148 zero_output_channel_i16(pcm, self.nb_channels, channel_idx, frame_size);
149 continue;
150 }
151
152 let (stream_idx, source_channel) = self.slot_to_stream_channel(usize::from(slot));
153 copy_output_channel_i16(
154 pcm,
155 self.nb_channels,
156 channel_idx,
157 &stream_pcm[stream_idx],
158 self.stream_channels(stream_idx),
159 source_channel,
160 frame_size,
161 );
162 }
163
164 Ok(frame_size)
165 }
166
167 pub fn decode_float(
188 &mut self,
189 packet: &[u8],
190 pcm: &mut [f32],
191 fec: bool,
192 ) -> Result<usize, OpusError> {
193 let sub_packets = if packet.is_empty() || fec {
194 vec![&[][..]; self.nb_streams]
195 } else {
196 split_multistream_packet(packet, self.nb_streams)?
197 };
198 let frame_size = self.expected_frame_size(&sub_packets, fec)?;
199 let needed = frame_size * self.nb_channels;
200 if pcm.len() < needed {
201 return Err(OpusError::BufferTooSmall);
202 }
203 if frame_size == 0 {
204 return Ok(0);
205 }
206
207 let mut stream_pcm = Vec::with_capacity(self.nb_streams);
208 for (stream_idx, sub_packet) in sub_packets.iter().enumerate() {
209 let channels = self.stream_channels(stream_idx);
210 let mut buf = vec![0.0f32; frame_size * channels];
211 let written = self.decoders[stream_idx].decode_float(sub_packet, &mut buf, fec)?;
212 if written != frame_size {
213 return Err(OpusError::InvalidPacket);
214 }
215 stream_pcm.push(buf);
216 }
217
218 for (channel_idx, &slot) in self.mapping.iter().enumerate() {
219 if slot == 255 {
220 zero_output_channel_f32(pcm, self.nb_channels, channel_idx, frame_size);
221 continue;
222 }
223
224 let (stream_idx, source_channel) = self.slot_to_stream_channel(usize::from(slot));
225 copy_output_channel_f32(
226 pcm,
227 self.nb_channels,
228 channel_idx,
229 &stream_pcm[stream_idx],
230 self.stream_channels(stream_idx),
231 source_channel,
232 frame_size,
233 );
234 }
235
236 Ok(frame_size)
237 }
238
239 pub fn reset(&mut self) {
244 for decoder in &mut self.decoders {
245 decoder.reset();
246 }
247 }
248
249 fn expected_frame_size(&self, sub_packets: &[&[u8]], fec: bool) -> Result<usize, OpusError> {
254 if fec || sub_packets.iter().all(|packet| packet.is_empty()) {
255 return Ok(self
256 .decoders
257 .first()
258 .map(|decoder| decoder.last_packet_duration)
259 .unwrap_or(0));
260 }
261
262 let mut frame_size = None;
263 for sub_packet in sub_packets.iter().filter(|packet| !packet.is_empty()) {
264 let samples = packet::parse_packet(sub_packet)
265 .map_err(OpusError::from)?
266 .samples_per_channel(self.sample_rate);
267 if let Some(expected) = frame_size {
268 if expected != samples {
269 return Err(OpusError::InvalidPacket);
270 }
271 } else {
272 frame_size = Some(samples);
273 }
274 }
275
276 Ok(frame_size.unwrap_or(0))
277 }
278
279 fn stream_channels(&self, stream_idx: usize) -> usize {
284 if stream_idx < self.nb_coupled_streams {
285 2
286 } else {
287 1
288 }
289 }
290
291 fn slot_to_stream_channel(&self, slot: usize) -> (usize, usize) {
296 let coupled_slots = 2 * self.nb_coupled_streams;
297 if slot < coupled_slots {
298 (slot / 2, slot % 2)
299 } else {
300 (self.nb_coupled_streams + (slot - coupled_slots), 0)
301 }
302 }
303}
304
305fn split_multistream_packet(packet: &[u8], nb_streams: usize) -> Result<Vec<&[u8]>, OpusError> {
310 if nb_streams == 0 {
311 return Err(OpusError::InvalidArgument("nb_streams"));
312 }
313 if packet.is_empty() {
314 return Ok(vec![packet; nb_streams]);
315 }
316
317 let mut out = Vec::with_capacity(nb_streams);
318 let mut offset = 0usize;
319 for _stream_idx in 0..nb_streams.saturating_sub(1) {
320 let (packet_len, used) = parse_self_delimited_size(&packet[offset..])?;
321 offset += used;
322 if offset + packet_len > packet.len() {
323 return Err(OpusError::InvalidPacket);
324 }
325 out.push(&packet[offset..offset + packet_len]);
326 offset += packet_len;
327 }
328
329 if offset > packet.len() {
330 return Err(OpusError::InvalidPacket);
331 }
332 out.push(&packet[offset..]);
333 Ok(out)
334}
335
336fn parse_self_delimited_size(data: &[u8]) -> Result<(usize, usize), OpusError> {
341 if data.is_empty() {
342 return Err(OpusError::InvalidPacket);
343 }
344
345 let first = usize::from(data[0]);
346 if first < 252 {
347 Ok((first, 1))
348 } else {
349 if data.len() < 2 {
350 return Err(OpusError::InvalidPacket);
351 }
352 Ok((first + (4 * usize::from(data[1])), 2))
353 }
354}
355
356fn copy_output_channel_i16(
363 pcm: &mut [i16],
364 dst_stride: usize,
365 dst_channel: usize,
366 src: &[i16],
367 src_stride: usize,
368 src_channel: usize,
369 frame_size: usize,
370) {
371 for sample_idx in 0..frame_size {
372 pcm[sample_idx * dst_stride + dst_channel] = src[sample_idx * src_stride + src_channel];
373 }
374}
375
376fn zero_output_channel_i16(
382 pcm: &mut [i16],
383 dst_stride: usize,
384 dst_channel: usize,
385 frame_size: usize,
386) {
387 for sample_idx in 0..frame_size {
388 pcm[sample_idx * dst_stride + dst_channel] = 0;
389 }
390}
391
392fn copy_output_channel_f32(
399 pcm: &mut [f32],
400 dst_stride: usize,
401 dst_channel: usize,
402 src: &[f32],
403 src_stride: usize,
404 src_channel: usize,
405 frame_size: usize,
406) {
407 for sample_idx in 0..frame_size {
408 pcm[sample_idx * dst_stride + dst_channel] = src[sample_idx * src_stride + src_channel];
409 }
410}
411
412fn zero_output_channel_f32(
418 pcm: &mut [f32],
419 dst_stride: usize,
420 dst_channel: usize,
421 frame_size: usize,
422) {
423 for sample_idx in 0..frame_size {
424 pcm[sample_idx * dst_stride + dst_channel] = 0.0;
425 }
426}
427
428#[cfg(test)]
429mod tests {
430 use super::*;
431
432 #[test]
437 fn split_two_stream_packet_with_short_prefix() {
438 let packet = [3u8, 10, 11, 12, 20, 21];
439 let sub_packets = split_multistream_packet(&packet, 2).unwrap();
440 assert_eq!(sub_packets, vec![&[10, 11, 12][..], &[20, 21][..]]);
441 }
442
443 #[test]
448 fn split_empty_packet_for_plc() {
449 let sub_packets = split_multistream_packet(&[], 3).unwrap();
450 assert_eq!(sub_packets, vec![&[][..], &[][..], &[][..]]);
451 }
452}