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