1 /* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3 /*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "opus_multistream.h"
33 #include "opus.h"
34 #include "opus_private.h"
35 #include "stack_alloc.h"
36 #include <stdarg.h>
37 #include "float_cast.h"
38 #include "os_support.h"
39
40 struct OpusMSDecoder {
41 ChannelLayout layout;
42 /* Decoder states go here */
43 };
44
45
46
47
48 /* DECODER */
49
opus_multistream_decoder_get_size(int nb_streams,int nb_coupled_streams)50 opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
51 {
52 int coupled_size;
53 int mono_size;
54
55 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
56 coupled_size = opus_decoder_get_size(2);
57 mono_size = opus_decoder_get_size(1);
58 return align(sizeof(OpusMSDecoder))
59 + nb_coupled_streams * align(coupled_size)
60 + (nb_streams-nb_coupled_streams) * align(mono_size);
61 }
62
opus_multistream_decoder_init(OpusMSDecoder * st,opus_int32 Fs,int channels,int streams,int coupled_streams,const unsigned char * mapping)63 int opus_multistream_decoder_init(
64 OpusMSDecoder *st,
65 opus_int32 Fs,
66 int channels,
67 int streams,
68 int coupled_streams,
69 const unsigned char *mapping
70 )
71 {
72 int coupled_size;
73 int mono_size;
74 int i, ret;
75 char *ptr;
76
77 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
78 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
79 return OPUS_BAD_ARG;
80
81 st->layout.nb_channels = channels;
82 st->layout.nb_streams = streams;
83 st->layout.nb_coupled_streams = coupled_streams;
84
85 for (i=0;i<st->layout.nb_channels;i++)
86 st->layout.mapping[i] = mapping[i];
87 if (!validate_layout(&st->layout))
88 return OPUS_BAD_ARG;
89
90 ptr = (char*)st + align(sizeof(OpusMSDecoder));
91 coupled_size = opus_decoder_get_size(2);
92 mono_size = opus_decoder_get_size(1);
93
94 for (i=0;i<st->layout.nb_coupled_streams;i++)
95 {
96 ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2);
97 if(ret!=OPUS_OK)return ret;
98 ptr += align(coupled_size);
99 }
100 for (;i<st->layout.nb_streams;i++)
101 {
102 ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1);
103 if(ret!=OPUS_OK)return ret;
104 ptr += align(mono_size);
105 }
106 return OPUS_OK;
107 }
108
109
opus_multistream_decoder_create(opus_int32 Fs,int channels,int streams,int coupled_streams,const unsigned char * mapping,int * error)110 OpusMSDecoder *opus_multistream_decoder_create(
111 opus_int32 Fs,
112 int channels,
113 int streams,
114 int coupled_streams,
115 const unsigned char *mapping,
116 int *error
117 )
118 {
119 int ret;
120 OpusMSDecoder *st;
121 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
122 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
123 {
124 if (error)
125 *error = OPUS_BAD_ARG;
126 return NULL;
127 }
128 st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
129 if (st==NULL)
130 {
131 if (error)
132 *error = OPUS_ALLOC_FAIL;
133 return NULL;
134 }
135 ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping);
136 if (error)
137 *error = ret;
138 if (ret != OPUS_OK)
139 {
140 opus_free(st);
141 st = NULL;
142 }
143 return st;
144 }
145
146 typedef void (*opus_copy_channel_out_func)(
147 void *dst,
148 int dst_stride,
149 int dst_channel,
150 const opus_val16 *src,
151 int src_stride,
152 int frame_size
153 );
154
opus_multistream_packet_validate(const unsigned char * data,opus_int32 len,int nb_streams,opus_int32 Fs)155 static int opus_multistream_packet_validate(const unsigned char *data,
156 opus_int32 len, int nb_streams, opus_int32 Fs)
157 {
158 int s;
159 int count;
160 unsigned char toc;
161 opus_int16 size[48];
162 int samples=0;
163 opus_int32 packet_offset;
164
165 for (s=0;s<nb_streams;s++)
166 {
167 int tmp_samples;
168 if (len<=0)
169 return OPUS_INVALID_PACKET;
170 count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL,
171 size, NULL, &packet_offset);
172 if (count<0)
173 return count;
174 tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs);
175 if (s!=0 && samples != tmp_samples)
176 return OPUS_INVALID_PACKET;
177 samples = tmp_samples;
178 data += packet_offset;
179 len -= packet_offset;
180 }
181 return samples;
182 }
183
opus_multistream_decode_native(OpusMSDecoder * st,const unsigned char * data,opus_int32 len,void * pcm,opus_copy_channel_out_func copy_channel_out,int frame_size,int decode_fec,int soft_clip)184 static int opus_multistream_decode_native(
185 OpusMSDecoder *st,
186 const unsigned char *data,
187 opus_int32 len,
188 void *pcm,
189 opus_copy_channel_out_func copy_channel_out,
190 int frame_size,
191 int decode_fec,
192 int soft_clip
193 )
194 {
195 opus_int32 Fs;
196 int coupled_size;
197 int mono_size;
198 int s, c;
199 char *ptr;
200 int do_plc=0;
201 VARDECL(opus_val16, buf);
202 ALLOC_STACK;
203
204 /* Limit frame_size to avoid excessive stack allocations. */
205 opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));
206 frame_size = IMIN(frame_size, Fs/25*3);
207 ALLOC(buf, 2*frame_size, opus_val16);
208 ptr = (char*)st + align(sizeof(OpusMSDecoder));
209 coupled_size = opus_decoder_get_size(2);
210 mono_size = opus_decoder_get_size(1);
211
212 if (len==0)
213 do_plc = 1;
214 if (len < 0)
215 {
216 RESTORE_STACK;
217 return OPUS_BAD_ARG;
218 }
219 if (!do_plc && len < 2*st->layout.nb_streams-1)
220 {
221 RESTORE_STACK;
222 return OPUS_INVALID_PACKET;
223 }
224 if (!do_plc)
225 {
226 int ret = opus_multistream_packet_validate(data, len, st->layout.nb_streams, Fs);
227 if (ret < 0)
228 {
229 RESTORE_STACK;
230 return ret;
231 } else if (ret > frame_size)
232 {
233 RESTORE_STACK;
234 return OPUS_BUFFER_TOO_SMALL;
235 }
236 }
237 for (s=0;s<st->layout.nb_streams;s++)
238 {
239 OpusDecoder *dec;
240 opus_int32 packet_offset;
241 int ret;
242
243 dec = (OpusDecoder*)ptr;
244 ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
245
246 if (!do_plc && len<=0)
247 {
248 RESTORE_STACK;
249 return OPUS_INTERNAL_ERROR;
250 }
251 packet_offset = 0;
252 ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip);
253 data += packet_offset;
254 len -= packet_offset;
255 if (ret <= 0)
256 {
257 RESTORE_STACK;
258 return ret;
259 }
260 frame_size = ret;
261 if (s < st->layout.nb_coupled_streams)
262 {
263 int chan, prev;
264 prev = -1;
265 /* Copy "left" audio to the channel(s) where it belongs */
266 while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
267 {
268 (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
269 buf, 2, frame_size);
270 prev = chan;
271 }
272 prev = -1;
273 /* Copy "right" audio to the channel(s) where it belongs */
274 while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
275 {
276 (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
277 buf+1, 2, frame_size);
278 prev = chan;
279 }
280 } else {
281 int chan, prev;
282 prev = -1;
283 /* Copy audio to the channel(s) where it belongs */
284 while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
285 {
286 (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
287 buf, 1, frame_size);
288 prev = chan;
289 }
290 }
291 }
292 /* Handle muted channels */
293 for (c=0;c<st->layout.nb_channels;c++)
294 {
295 if (st->layout.mapping[c] == 255)
296 {
297 (*copy_channel_out)(pcm, st->layout.nb_channels, c,
298 NULL, 0, frame_size);
299 }
300 }
301 RESTORE_STACK;
302 return frame_size;
303 }
304
305 #if !defined(DISABLE_FLOAT_API)
opus_copy_channel_out_float(void * dst,int dst_stride,int dst_channel,const opus_val16 * src,int src_stride,int frame_size)306 static void opus_copy_channel_out_float(
307 void *dst,
308 int dst_stride,
309 int dst_channel,
310 const opus_val16 *src,
311 int src_stride,
312 int frame_size
313 )
314 {
315 float *float_dst;
316 opus_int32 i;
317 float_dst = (float*)dst;
318 if (src != NULL)
319 {
320 for (i=0;i<frame_size;i++)
321 #if defined(FIXED_POINT)
322 float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];
323 #else
324 float_dst[i*dst_stride+dst_channel] = src[i*src_stride];
325 #endif
326 }
327 else
328 {
329 for (i=0;i<frame_size;i++)
330 float_dst[i*dst_stride+dst_channel] = 0;
331 }
332 }
333 #endif
334
opus_copy_channel_out_short(void * dst,int dst_stride,int dst_channel,const opus_val16 * src,int src_stride,int frame_size)335 static void opus_copy_channel_out_short(
336 void *dst,
337 int dst_stride,
338 int dst_channel,
339 const opus_val16 *src,
340 int src_stride,
341 int frame_size
342 )
343 {
344 opus_int16 *short_dst;
345 opus_int32 i;
346 short_dst = (opus_int16*)dst;
347 if (src != NULL)
348 {
349 for (i=0;i<frame_size;i++)
350 #if defined(FIXED_POINT)
351 short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
352 #else
353 short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
354 #endif
355 }
356 else
357 {
358 for (i=0;i<frame_size;i++)
359 short_dst[i*dst_stride+dst_channel] = 0;
360 }
361 }
362
363
364
365 #ifdef FIXED_POINT
opus_multistream_decode(OpusMSDecoder * st,const unsigned char * data,opus_int32 len,opus_int16 * pcm,int frame_size,int decode_fec)366 int opus_multistream_decode(
367 OpusMSDecoder *st,
368 const unsigned char *data,
369 opus_int32 len,
370 opus_int16 *pcm,
371 int frame_size,
372 int decode_fec
373 )
374 {
375 return opus_multistream_decode_native(st, data, len,
376 pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0);
377 }
378
379 #ifndef DISABLE_FLOAT_API
opus_multistream_decode_float(OpusMSDecoder * st,const unsigned char * data,opus_int32 len,float * pcm,int frame_size,int decode_fec)380 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
381 opus_int32 len, float *pcm, int frame_size, int decode_fec)
382 {
383 return opus_multistream_decode_native(st, data, len,
384 pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
385 }
386 #endif
387
388 #else
389
opus_multistream_decode(OpusMSDecoder * st,const unsigned char * data,opus_int32 len,opus_int16 * pcm,int frame_size,int decode_fec)390 int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
391 opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
392 {
393 return opus_multistream_decode_native(st, data, len,
394 pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1);
395 }
396
opus_multistream_decode_float(OpusMSDecoder * st,const unsigned char * data,opus_int32 len,float * pcm,int frame_size,int decode_fec)397 int opus_multistream_decode_float(
398 OpusMSDecoder *st,
399 const unsigned char *data,
400 opus_int32 len,
401 float *pcm,
402 int frame_size,
403 int decode_fec
404 )
405 {
406 return opus_multistream_decode_native(st, data, len,
407 pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
408 }
409 #endif
410
opus_multistream_decoder_ctl(OpusMSDecoder * st,int request,...)411 int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
412 {
413 va_list ap;
414 int coupled_size, mono_size;
415 char *ptr;
416 int ret = OPUS_OK;
417
418 va_start(ap, request);
419
420 coupled_size = opus_decoder_get_size(2);
421 mono_size = opus_decoder_get_size(1);
422 ptr = (char*)st + align(sizeof(OpusMSDecoder));
423 switch (request)
424 {
425 case OPUS_GET_BANDWIDTH_REQUEST:
426 case OPUS_GET_SAMPLE_RATE_REQUEST:
427 case OPUS_GET_GAIN_REQUEST:
428 case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
429 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
430 {
431 OpusDecoder *dec;
432 /* For int32* GET params, just query the first stream */
433 opus_int32 *value = va_arg(ap, opus_int32*);
434 dec = (OpusDecoder*)ptr;
435 ret = opus_decoder_ctl(dec, request, value);
436 }
437 break;
438 case OPUS_GET_FINAL_RANGE_REQUEST:
439 {
440 int s;
441 opus_uint32 *value = va_arg(ap, opus_uint32*);
442 opus_uint32 tmp;
443 if (!value)
444 {
445 goto bad_arg;
446 }
447 *value = 0;
448 for (s=0;s<st->layout.nb_streams;s++)
449 {
450 OpusDecoder *dec;
451 dec = (OpusDecoder*)ptr;
452 if (s < st->layout.nb_coupled_streams)
453 ptr += align(coupled_size);
454 else
455 ptr += align(mono_size);
456 ret = opus_decoder_ctl(dec, request, &tmp);
457 if (ret != OPUS_OK) break;
458 *value ^= tmp;
459 }
460 }
461 break;
462 case OPUS_RESET_STATE:
463 {
464 int s;
465 for (s=0;s<st->layout.nb_streams;s++)
466 {
467 OpusDecoder *dec;
468
469 dec = (OpusDecoder*)ptr;
470 if (s < st->layout.nb_coupled_streams)
471 ptr += align(coupled_size);
472 else
473 ptr += align(mono_size);
474 ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
475 if (ret != OPUS_OK)
476 break;
477 }
478 }
479 break;
480 case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
481 {
482 int s;
483 opus_int32 stream_id;
484 OpusDecoder **value;
485 stream_id = va_arg(ap, opus_int32);
486 if (stream_id<0 || stream_id >= st->layout.nb_streams)
487 ret = OPUS_BAD_ARG;
488 value = va_arg(ap, OpusDecoder**);
489 if (!value)
490 {
491 goto bad_arg;
492 }
493 for (s=0;s<stream_id;s++)
494 {
495 if (s < st->layout.nb_coupled_streams)
496 ptr += align(coupled_size);
497 else
498 ptr += align(mono_size);
499 }
500 *value = (OpusDecoder*)ptr;
501 }
502 break;
503 case OPUS_SET_GAIN_REQUEST:
504 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
505 {
506 int s;
507 /* This works for int32 params */
508 opus_int32 value = va_arg(ap, opus_int32);
509 for (s=0;s<st->layout.nb_streams;s++)
510 {
511 OpusDecoder *dec;
512
513 dec = (OpusDecoder*)ptr;
514 if (s < st->layout.nb_coupled_streams)
515 ptr += align(coupled_size);
516 else
517 ptr += align(mono_size);
518 ret = opus_decoder_ctl(dec, request, value);
519 if (ret != OPUS_OK)
520 break;
521 }
522 }
523 break;
524 default:
525 ret = OPUS_UNIMPLEMENTED;
526 break;
527 }
528
529 va_end(ap);
530 return ret;
531 bad_arg:
532 va_end(ap);
533 return OPUS_BAD_ARG;
534 }
535
536
opus_multistream_decoder_destroy(OpusMSDecoder * st)537 void opus_multistream_decoder_destroy(OpusMSDecoder *st)
538 {
539 opus_free(st);
540 }
541