Fix several issues with multistream argument validation.
[opus.git] / src / opus_multistream.c
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 typedef struct ChannelLayout {
41    int nb_channels;
42    int nb_streams;
43    int nb_coupled_streams;
44    unsigned char mapping[256];
45 } ChannelLayout;
46
47 struct OpusMSEncoder {
48    ChannelLayout layout;
49    int bitrate;
50    /* Encoder states go here */
51 };
52
53 struct OpusMSDecoder {
54    ChannelLayout layout;
55    /* Decoder states go here */
56 };
57
58 #ifdef FIXED_POINT
59 #define opus_encode_native opus_encode
60 #else
61 #define opus_encode_native opus_encode_float
62 #endif
63
64 static int validate_layout(const ChannelLayout *layout)
65 {
66    int i, max_channel;
67
68    max_channel = layout->nb_streams+layout->nb_coupled_streams;
69    if (max_channel>255)
70       return 0;
71    for (i=0;i<layout->nb_channels;i++)
72    {
73       if (layout->mapping[i] >= max_channel && layout->mapping[i] != 255)
74          return 0;
75    }
76    return 1;
77 }
78
79
80 static int get_left_channel(const ChannelLayout *layout, int stream_id, int prev)
81 {
82    int i;
83    i = (prev<0) ? 0 : prev+1;
84    for (;i<layout->nb_channels;i++)
85    {
86       if (layout->mapping[i]==stream_id*2)
87          return i;
88    }
89    return -1;
90 }
91
92 static int get_right_channel(const ChannelLayout *layout, int stream_id, int prev)
93 {
94    int i;
95    i = (prev<0) ? 0 : prev+1;
96    for (;i<layout->nb_channels;i++)
97    {
98       if (layout->mapping[i]==stream_id*2+1)
99          return i;
100    }
101    return -1;
102 }
103
104 static int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev)
105 {
106    int i;
107    i = (prev<0) ? 0 : prev+1;
108    for (;i<layout->nb_channels;i++)
109    {
110       if (layout->mapping[i]==stream_id+layout->nb_coupled_streams)
111          return i;
112    }
113    return -1;
114 }
115
116 static int validate_encoder_layout(const ChannelLayout *layout)
117 {
118    int s;
119    for (s=0;s<layout->nb_streams;s++)
120    {
121       if (s < layout->nb_coupled_streams)
122       {
123          if (get_left_channel(layout, s, -1)==-1)
124             return 0;
125          if (get_right_channel(layout, s, -1)==-1)
126             return 0;
127       } else {
128          if (get_mono_channel(layout, s, -1)==-1)
129             return 0;
130       }
131    }
132    return 1;
133 }
134
135 opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
136 {
137    int coupled_size;
138    int mono_size;
139
140    if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
141    coupled_size = opus_encoder_get_size(2);
142    mono_size = opus_encoder_get_size(1);
143    return align(sizeof(OpusMSEncoder))
144         + nb_coupled_streams * align(coupled_size)
145         + (nb_streams-nb_coupled_streams) * align(mono_size);
146 }
147
148
149
150 int opus_multistream_encoder_init(
151       OpusMSEncoder *st,
152       opus_int32 Fs,
153       int channels,
154       int streams,
155       int coupled_streams,
156       const unsigned char *mapping,
157       int application
158 )
159 {
160    int coupled_size;
161    int mono_size;
162    int i, ret;
163    char *ptr;
164
165    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
166        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
167       return OPUS_BAD_ARG;
168
169    st->layout.nb_channels = channels;
170    st->layout.nb_streams = streams;
171    st->layout.nb_coupled_streams = coupled_streams;
172
173    for (i=0;i<st->layout.nb_channels;i++)
174       st->layout.mapping[i] = mapping[i];
175    if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
176       return OPUS_BAD_ARG;
177    ptr = (char*)st + align(sizeof(OpusMSEncoder));
178    coupled_size = opus_encoder_get_size(2);
179    mono_size = opus_encoder_get_size(1);
180
181    for (i=0;i<st->layout.nb_coupled_streams;i++)
182    {
183       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
184       if(ret!=OPUS_OK)return ret;
185       ptr += align(coupled_size);
186    }
187    for (;i<st->layout.nb_streams;i++)
188    {
189       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
190       if(ret!=OPUS_OK)return ret;
191       ptr += align(mono_size);
192    }
193    return OPUS_OK;
194 }
195
196 OpusMSEncoder *opus_multistream_encoder_create(
197       opus_int32 Fs,
198       int channels,
199       int streams,
200       int coupled_streams,
201       const unsigned char *mapping,
202       int application,
203       int *error
204 )
205 {
206    int ret;
207    OpusMSEncoder *st;
208    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
209        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
210    {
211       if (error)
212          *error = OPUS_BAD_ARG;
213       return NULL;
214    }
215    st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
216    if (st==NULL)
217    {
218       if (error)
219          *error = OPUS_ALLOC_FAIL;
220       return NULL;
221    }
222    ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
223    if (ret != OPUS_OK)
224    {
225       opus_free(st);
226       st = NULL;
227    }
228    if (error)
229       *error = ret;
230    return st;
231 }
232
233 typedef void (*opus_copy_channel_in_func)(
234   opus_val16 *dst,
235   int dst_stride,
236   const void *src,
237   int src_stride,
238   int src_channel,
239   int frame_size
240 );
241
242 /* Max size in case the encoder decides to return three frames */
243 #define MS_FRAME_TMP (3*1275+7)
244 static int opus_multistream_encode_native
245 (
246     OpusMSEncoder *st,
247     opus_copy_channel_in_func copy_channel_in,
248     const void *pcm,
249     int frame_size,
250     unsigned char *data,
251     opus_int32 max_data_bytes
252 )
253 {
254    opus_int32 Fs;
255    int coupled_size;
256    int mono_size;
257    int s;
258    char *ptr;
259    int tot_size;
260    VARDECL(opus_val16, buf);
261    unsigned char tmp_data[MS_FRAME_TMP];
262    OpusRepacketizer rp;
263    ALLOC_STACK;
264
265    ptr = (char*)st + align(sizeof(OpusMSEncoder));
266    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
267    /* Validate frame_size before using it to allocate stack space.
268       This mirrors the checks in opus_encode[_float](). */
269    if (400*frame_size != Fs && 200*frame_size != Fs &&
270        100*frame_size != Fs &&  50*frame_size != Fs &&
271         25*frame_size != Fs &&  50*frame_size != 3*Fs)
272    {
273       RESTORE_STACK;
274       return OPUS_BAD_ARG;
275    }
276    ALLOC(buf, 2*frame_size, opus_val16);
277    coupled_size = opus_encoder_get_size(2);
278    mono_size = opus_encoder_get_size(1);
279
280    if (max_data_bytes < 4*st->layout.nb_streams-1)
281    {
282       RESTORE_STACK;
283       return OPUS_BUFFER_TOO_SMALL;
284    }
285    /* Counting ToC */
286    tot_size = 0;
287    for (s=0;s<st->layout.nb_streams;s++)
288    {
289       OpusEncoder *enc;
290       int len;
291       int curr_max;
292
293       opus_repacketizer_init(&rp);
294       enc = (OpusEncoder*)ptr;
295       if (s < st->layout.nb_coupled_streams)
296       {
297          int left, right;
298          left = get_left_channel(&st->layout, s, -1);
299          right = get_right_channel(&st->layout, s, -1);
300          (*copy_channel_in)(buf, 2,
301             pcm, st->layout.nb_channels, left, frame_size);
302          (*copy_channel_in)(buf+1, 2,
303             pcm, st->layout.nb_channels, right, frame_size);
304          ptr += align(coupled_size);
305       } else {
306          int chan = get_mono_channel(&st->layout, s, -1);
307          (*copy_channel_in)(buf, 1,
308             pcm, st->layout.nb_channels, chan, frame_size);
309          ptr += align(mono_size);
310       }
311       /* number of bytes left (+Toc) */
312       curr_max = max_data_bytes - tot_size;
313       /* Reserve three bytes for the last stream and four for the others */
314       curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
315       curr_max = IMIN(curr_max,MS_FRAME_TMP);
316       len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max);
317       if (len<0)
318       {
319          RESTORE_STACK;
320          return len;
321       }
322       /* We need to use the repacketizer to add the self-delimiting lengths
323          while taking into account the fact that the encoder can now return
324          more than one frame at a time (e.g. 60 ms CELT-only) */
325       opus_repacketizer_cat(&rp, tmp_data, len);
326       len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1);
327       data += len;
328       tot_size += len;
329    }
330    RESTORE_STACK;
331    return tot_size;
332
333 }
334
335 #if !defined(DISABLE_FLOAT_API)
336 static void opus_copy_channel_in_float(
337   opus_val16 *dst,
338   int dst_stride,
339   const void *src,
340   int src_stride,
341   int src_channel,
342   int frame_size
343 )
344 {
345    const float *float_src;
346    int i;
347    float_src = (const float *)src;
348    for (i=0;i<frame_size;i++)
349 #if defined(FIXED_POINT)
350       dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
351 #else
352       dst[i*dst_stride] = float_src[i*src_stride+src_channel];
353 #endif
354 }
355 #endif
356
357 static void opus_copy_channel_in_short(
358   opus_val16 *dst,
359   int dst_stride,
360   const void *src,
361   int src_stride,
362   int src_channel,
363   int frame_size
364 )
365 {
366    const opus_int16 *short_src;
367    int i;
368    short_src = (const opus_int16 *)src;
369    for (i=0;i<frame_size;i++)
370 #if defined(FIXED_POINT)
371       dst[i*dst_stride] = short_src[i*src_stride+src_channel];
372 #else
373       dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
374 #endif
375 }
376
377 #ifdef FIXED_POINT
378 int opus_multistream_encode(
379     OpusMSEncoder *st,
380     const opus_val16 *pcm,
381     int frame_size,
382     unsigned char *data,
383     opus_int32 max_data_bytes
384 )
385 {
386    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
387       pcm, frame_size, data, max_data_bytes);
388 }
389
390 #ifndef DISABLE_FLOAT_API
391 int opus_multistream_encode_float(
392     OpusMSEncoder *st,
393     const float *pcm,
394     int frame_size,
395     unsigned char *data,
396     opus_int32 max_data_bytes
397 )
398 {
399    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
400       pcm, frame_size, data, max_data_bytes);
401 }
402 #endif
403
404 #else
405
406 int opus_multistream_encode_float
407 (
408     OpusMSEncoder *st,
409     const opus_val16 *pcm,
410     int frame_size,
411     unsigned char *data,
412     opus_int32 max_data_bytes
413 )
414 {
415    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
416       pcm, frame_size, data, max_data_bytes);
417 }
418
419 int opus_multistream_encode(
420     OpusMSEncoder *st,
421     const opus_int16 *pcm,
422     int frame_size,
423     unsigned char *data,
424     opus_int32 max_data_bytes
425 )
426 {
427    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
428       pcm, frame_size, data, max_data_bytes);
429 }
430 #endif
431
432 int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
433 {
434    va_list ap;
435    int coupled_size, mono_size;
436    char *ptr;
437    int ret = OPUS_OK;
438
439    va_start(ap, request);
440
441    coupled_size = opus_encoder_get_size(2);
442    mono_size = opus_encoder_get_size(1);
443    ptr = (char*)st + align(sizeof(OpusMSEncoder));
444    switch (request)
445    {
446    case OPUS_SET_BITRATE_REQUEST:
447    {
448       int chan, s;
449       opus_int32 value = va_arg(ap, opus_int32);
450       chan = st->layout.nb_streams + st->layout.nb_coupled_streams;
451       value /= chan;
452       for (s=0;s<st->layout.nb_streams;s++)
453       {
454          OpusEncoder *enc;
455          enc = (OpusEncoder*)ptr;
456          if (s < st->layout.nb_coupled_streams)
457             ptr += align(coupled_size);
458          else
459             ptr += align(mono_size);
460          opus_encoder_ctl(enc, request, value * (s < st->layout.nb_coupled_streams ? 2 : 1));
461       }
462    }
463    break;
464    case OPUS_GET_BITRATE_REQUEST:
465    {
466       int s;
467       opus_int32 *value = va_arg(ap, opus_int32*);
468       *value = 0;
469       for (s=0;s<st->layout.nb_streams;s++)
470       {
471          opus_int32 rate;
472          OpusEncoder *enc;
473          enc = (OpusEncoder*)ptr;
474          if (s < st->layout.nb_coupled_streams)
475             ptr += align(coupled_size);
476          else
477             ptr += align(mono_size);
478          opus_encoder_ctl(enc, request, &rate);
479          *value += rate;
480       }
481    }
482    break;
483    case OPUS_GET_LSB_DEPTH_REQUEST:
484    case OPUS_GET_VBR_REQUEST:
485    case OPUS_GET_APPLICATION_REQUEST:
486    case OPUS_GET_BANDWIDTH_REQUEST:
487    case OPUS_GET_COMPLEXITY_REQUEST:
488    case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
489    case OPUS_GET_DTX_REQUEST:
490    case OPUS_GET_VOICE_RATIO_REQUEST:
491    case OPUS_GET_VBR_CONSTRAINT_REQUEST:
492    case OPUS_GET_SIGNAL_REQUEST:
493    case OPUS_GET_LOOKAHEAD_REQUEST:
494    case OPUS_GET_SAMPLE_RATE_REQUEST:
495    case OPUS_GET_INBAND_FEC_REQUEST:
496    case OPUS_GET_FORCE_CHANNELS_REQUEST:
497    {
498       OpusEncoder *enc;
499       /* For int32* GET params, just query the first stream */
500       opus_int32 *value = va_arg(ap, opus_int32*);
501       enc = (OpusEncoder*)ptr;
502       ret = opus_encoder_ctl(enc, request, value);
503    }
504    break;
505    case OPUS_GET_FINAL_RANGE_REQUEST:
506    {
507       int s;
508       opus_uint32 *value = va_arg(ap, opus_uint32*);
509       opus_uint32 tmp;
510       *value=0;
511       for (s=0;s<st->layout.nb_streams;s++)
512       {
513          OpusEncoder *enc;
514          enc = (OpusEncoder*)ptr;
515          if (s < st->layout.nb_coupled_streams)
516             ptr += align(coupled_size);
517          else
518             ptr += align(mono_size);
519          ret = opus_encoder_ctl(enc, request, &tmp);
520          if (ret != OPUS_OK) break;
521          *value ^= tmp;
522       }
523    }
524    break;
525    case OPUS_SET_LSB_DEPTH_REQUEST:
526    case OPUS_SET_COMPLEXITY_REQUEST:
527    case OPUS_SET_VBR_REQUEST:
528    case OPUS_SET_VBR_CONSTRAINT_REQUEST:
529    case OPUS_SET_BANDWIDTH_REQUEST:
530    case OPUS_SET_SIGNAL_REQUEST:
531    case OPUS_SET_APPLICATION_REQUEST:
532    case OPUS_SET_INBAND_FEC_REQUEST:
533    case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
534    case OPUS_SET_DTX_REQUEST:
535    case OPUS_SET_FORCE_MODE_REQUEST:
536    case OPUS_SET_FORCE_CHANNELS_REQUEST:
537    {
538       int s;
539       /* This works for int32 params */
540       opus_int32 value = va_arg(ap, opus_int32);
541       for (s=0;s<st->layout.nb_streams;s++)
542       {
543          OpusEncoder *enc;
544
545          enc = (OpusEncoder*)ptr;
546          if (s < st->layout.nb_coupled_streams)
547             ptr += align(coupled_size);
548          else
549             ptr += align(mono_size);
550          ret = opus_encoder_ctl(enc, request, value);
551          if (ret != OPUS_OK)
552             break;
553       }
554    }
555    break;
556    case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
557    {
558       int s;
559       opus_int32 stream_id;
560       OpusEncoder **value;
561       stream_id = va_arg(ap, opus_int32);
562       if (stream_id<0 || stream_id >= st->layout.nb_streams)
563          ret = OPUS_BAD_ARG;
564       value = va_arg(ap, OpusEncoder**);
565       for (s=0;s<stream_id;s++)
566       {
567          if (s < st->layout.nb_coupled_streams)
568             ptr += align(coupled_size);
569          else
570             ptr += align(mono_size);
571       }
572       *value = (OpusEncoder*)ptr;
573    }
574       break;
575    default:
576       ret = OPUS_UNIMPLEMENTED;
577       break;
578    }
579
580    va_end(ap);
581    return ret;
582 }
583
584 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
585 {
586     opus_free(st);
587 }
588
589
590 /* DECODER */
591
592 opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
593 {
594    int coupled_size;
595    int mono_size;
596
597    if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
598    coupled_size = opus_decoder_get_size(2);
599    mono_size = opus_decoder_get_size(1);
600    return align(sizeof(OpusMSDecoder))
601          + nb_coupled_streams * align(coupled_size)
602          + (nb_streams-nb_coupled_streams) * align(mono_size);
603 }
604
605 int opus_multistream_decoder_init(
606       OpusMSDecoder *st,
607       opus_int32 Fs,
608       int channels,
609       int streams,
610       int coupled_streams,
611       const unsigned char *mapping
612 )
613 {
614    int coupled_size;
615    int mono_size;
616    int i, ret;
617    char *ptr;
618
619    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
620        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
621       return OPUS_BAD_ARG;
622
623    st->layout.nb_channels = channels;
624    st->layout.nb_streams = streams;
625    st->layout.nb_coupled_streams = coupled_streams;
626
627    for (i=0;i<st->layout.nb_channels;i++)
628       st->layout.mapping[i] = mapping[i];
629    if (!validate_layout(&st->layout))
630       return OPUS_BAD_ARG;
631
632    ptr = (char*)st + align(sizeof(OpusMSDecoder));
633    coupled_size = opus_decoder_get_size(2);
634    mono_size = opus_decoder_get_size(1);
635
636    for (i=0;i<st->layout.nb_coupled_streams;i++)
637    {
638       ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2);
639       if(ret!=OPUS_OK)return ret;
640       ptr += align(coupled_size);
641    }
642    for (;i<st->layout.nb_streams;i++)
643    {
644       ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1);
645       if(ret!=OPUS_OK)return ret;
646       ptr += align(mono_size);
647    }
648    return OPUS_OK;
649 }
650
651
652 OpusMSDecoder *opus_multistream_decoder_create(
653       opus_int32 Fs,
654       int channels,
655       int streams,
656       int coupled_streams,
657       const unsigned char *mapping,
658       int *error
659 )
660 {
661    int ret;
662    OpusMSDecoder *st;
663    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
664        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
665    {
666       if (error)
667          *error = OPUS_BAD_ARG;
668       return NULL;
669    }
670    st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
671    if (st==NULL)
672    {
673       if (error)
674          *error = OPUS_ALLOC_FAIL;
675       return NULL;
676    }
677    ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping);
678    if (error)
679       *error = ret;
680    if (ret != OPUS_OK)
681    {
682       opus_free(st);
683       st = NULL;
684    }
685    return st;
686 }
687
688 typedef void (*opus_copy_channel_out_func)(
689   void *dst,
690   int dst_stride,
691   int dst_channel,
692   const opus_val16 *src,
693   int src_stride,
694   int frame_size
695 );
696
697 static int opus_multistream_decode_native(
698       OpusMSDecoder *st,
699       const unsigned char *data,
700       opus_int32 len,
701       void *pcm,
702       opus_copy_channel_out_func copy_channel_out,
703       int frame_size,
704       int decode_fec
705 )
706 {
707    opus_int32 Fs;
708    int coupled_size;
709    int mono_size;
710    int s, c;
711    char *ptr;
712    int do_plc=0;
713    VARDECL(opus_val16, buf);
714    ALLOC_STACK;
715
716    /* Limit frame_size to avoid excessive stack allocations. */
717    opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));
718    frame_size = IMIN(frame_size, Fs/25*3);
719    ALLOC(buf, 2*frame_size, opus_val16);
720    ptr = (char*)st + align(sizeof(OpusMSDecoder));
721    coupled_size = opus_decoder_get_size(2);
722    mono_size = opus_decoder_get_size(1);
723
724    if (len==0)
725       do_plc = 1;
726    if (len < 0)
727       return OPUS_BAD_ARG;
728    if (!do_plc && len < 2*st->layout.nb_streams-1)
729       return OPUS_INVALID_PACKET;
730    for (s=0;s<st->layout.nb_streams;s++)
731    {
732       OpusDecoder *dec;
733       int packet_offset, ret;
734
735       dec = (OpusDecoder*)ptr;
736       ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
737
738       if (!do_plc && len<=0)
739       {
740          RESTORE_STACK;
741          return OPUS_INVALID_PACKET;
742       }
743       packet_offset = 0;
744       ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset);
745       data += packet_offset;
746       len -= packet_offset;
747       if (ret > frame_size)
748       {
749          RESTORE_STACK;
750          return OPUS_BUFFER_TOO_SMALL;
751       }
752       if (s>0 && ret != frame_size)
753       {
754          RESTORE_STACK;
755          return OPUS_INVALID_PACKET;
756       }
757       if (ret <= 0)
758       {
759          RESTORE_STACK;
760          return ret;
761       }
762       frame_size = ret;
763       if (s < st->layout.nb_coupled_streams)
764       {
765          int chan, prev;
766          prev = -1;
767          /* Copy "left" audio to the channel(s) where it belongs */
768          while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
769          {
770             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
771                buf, 2, frame_size);
772             prev = chan;
773          }
774          prev = -1;
775          /* Copy "right" audio to the channel(s) where it belongs */
776          while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
777          {
778             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
779                buf+1, 2, frame_size);
780             prev = chan;
781          }
782       } else {
783          int chan, prev;
784          prev = -1;
785          /* Copy audio to the channel(s) where it belongs */
786          while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
787          {
788             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
789                buf, 1, frame_size);
790             prev = chan;
791          }
792       }
793    }
794    /* Handle muted channels */
795    for (c=0;c<st->layout.nb_channels;c++)
796    {
797       if (st->layout.mapping[c] == 255)
798       {
799          (*copy_channel_out)(pcm, st->layout.nb_channels, c,
800             NULL, 0, frame_size);
801       }
802    }
803    RESTORE_STACK;
804    return frame_size;
805 }
806
807 #if !defined(DISABLE_FLOAT_API)
808 static void opus_copy_channel_out_float(
809   void *dst,
810   int dst_stride,
811   int dst_channel,
812   const opus_val16 *src,
813   int src_stride,
814   int frame_size
815 )
816 {
817    float *float_dst;
818    int i;
819    float_dst = (float*)dst;
820    if (src != NULL)
821    {
822       for (i=0;i<frame_size;i++)
823 #if defined(FIXED_POINT)
824          float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];
825 #else
826          float_dst[i*dst_stride+dst_channel] = src[i*src_stride];
827 #endif
828    }
829    else
830    {
831       for (i=0;i<frame_size;i++)
832          float_dst[i*dst_stride+dst_channel] = 0;
833    }
834 }
835 #endif
836
837 static void opus_copy_channel_out_short(
838   void *dst,
839   int dst_stride,
840   int dst_channel,
841   const opus_val16 *src,
842   int src_stride,
843   int frame_size
844 )
845 {
846    opus_int16 *short_dst;
847    int i;
848    short_dst = (opus_int16*)dst;
849    if (src != NULL)
850    {
851       for (i=0;i<frame_size;i++)
852 #if defined(FIXED_POINT)
853          short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
854 #else
855          short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
856 #endif
857    }
858    else
859    {
860       for (i=0;i<frame_size;i++)
861          short_dst[i*dst_stride+dst_channel] = 0;
862    }
863 }
864
865
866
867 #ifdef FIXED_POINT
868 int opus_multistream_decode(
869       OpusMSDecoder *st,
870       const unsigned char *data,
871       opus_int32 len,
872       opus_int16 *pcm,
873       int frame_size,
874       int decode_fec
875 )
876 {
877    return opus_multistream_decode_native(st, data, len,
878        pcm, opus_copy_channel_out_short, frame_size, decode_fec);
879 }
880
881 #ifndef DISABLE_FLOAT_API
882 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
883       opus_int32 len, float *pcm, int frame_size, int decode_fec)
884 {
885    return opus_multistream_decode_native(st, data, len,
886        pcm, opus_copy_channel_out_float, frame_size, decode_fec);
887 }
888 #endif
889
890 #else
891
892 int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
893       opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
894 {
895    return opus_multistream_decode_native(st, data, len,
896        pcm, opus_copy_channel_out_short, frame_size, decode_fec);
897 }
898
899 int opus_multistream_decode_float(
900       OpusMSDecoder *st,
901       const unsigned char *data,
902       opus_int32 len,
903       float *pcm,
904       int frame_size,
905       int decode_fec
906 )
907 {
908    return opus_multistream_decode_native(st, data, len,
909        pcm, opus_copy_channel_out_float, frame_size, decode_fec);
910 }
911 #endif
912
913 int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
914 {
915    va_list ap;
916    int coupled_size, mono_size;
917    char *ptr;
918    int ret = OPUS_OK;
919
920    va_start(ap, request);
921
922    coupled_size = opus_decoder_get_size(2);
923    mono_size = opus_decoder_get_size(1);
924    ptr = (char*)st + align(sizeof(OpusMSDecoder));
925    switch (request)
926    {
927        case OPUS_GET_BANDWIDTH_REQUEST:
928        case OPUS_GET_SAMPLE_RATE_REQUEST:
929        {
930           OpusDecoder *dec;
931           /* For int32* GET params, just query the first stream */
932           opus_int32 *value = va_arg(ap, opus_int32*);
933           dec = (OpusDecoder*)ptr;
934           ret = opus_decoder_ctl(dec, request, value);
935        }
936        break;
937        case OPUS_GET_FINAL_RANGE_REQUEST:
938        {
939           int s;
940           opus_uint32 *value = va_arg(ap, opus_uint32*);
941           opus_uint32 tmp;
942           *value = 0;
943           for (s=0;s<st->layout.nb_streams;s++)
944           {
945              OpusDecoder *dec;
946              dec = (OpusDecoder*)ptr;
947              if (s < st->layout.nb_coupled_streams)
948                 ptr += align(coupled_size);
949              else
950                 ptr += align(mono_size);
951              ret = opus_decoder_ctl(dec, request, &tmp);
952              if (ret != OPUS_OK) break;
953              *value ^= tmp;
954           }
955        }
956        break;
957        case OPUS_RESET_STATE:
958        {
959           int s;
960           for (s=0;s<st->layout.nb_streams;s++)
961           {
962              OpusDecoder *dec;
963
964              dec = (OpusDecoder*)ptr;
965              if (s < st->layout.nb_coupled_streams)
966                 ptr += align(coupled_size);
967              else
968                 ptr += align(mono_size);
969              ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
970              if (ret != OPUS_OK)
971                 break;
972           }
973        }
974        break;
975        case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
976        {
977           int s;
978           opus_int32 stream_id;
979           OpusDecoder **value;
980           stream_id = va_arg(ap, opus_int32);
981           if (stream_id<0 || stream_id >= st->layout.nb_streams)
982              ret = OPUS_BAD_ARG;
983           value = va_arg(ap, OpusDecoder**);
984           for (s=0;s<stream_id;s++)
985           {
986              if (s < st->layout.nb_coupled_streams)
987                 ptr += align(coupled_size);
988              else
989                 ptr += align(mono_size);
990           }
991           *value = (OpusDecoder*)ptr;
992        }
993        break;
994        case OPUS_SET_GAIN_REQUEST:
995        {
996           int s;
997           /* This works for int32 params */
998           opus_int32 value = va_arg(ap, opus_int32);
999           for (s=0;s<st->layout.nb_streams;s++)
1000           {
1001              OpusDecoder *dec;
1002
1003              dec = (OpusDecoder*)ptr;
1004              if (s < st->layout.nb_coupled_streams)
1005                 ptr += align(coupled_size);
1006              else
1007                 ptr += align(mono_size);
1008              ret = opus_decoder_ctl(dec, request, value);
1009              if (ret != OPUS_OK)
1010                 break;
1011           }
1012        }
1013        break;
1014        default:
1015           ret = OPUS_UNIMPLEMENTED;
1016        break;
1017    }
1018
1019    va_end(ap);
1020    return ret;
1021 }
1022
1023
1024 void opus_multistream_decoder_destroy(OpusMSDecoder *st)
1025 {
1026     opus_free(st);
1027 }