Validate multistream/projection decoder frame_size
[opus.git] / src / opus_multistream_decoder.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 /* DECODER */
41
42 #if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
43 static void validate_ms_decoder(OpusMSDecoder *st)
44 {
45    validate_layout(&st->layout);
46 #ifdef OPUS_ARCHMASK
47    celt_assert(st->arch >= 0);
48    celt_assert(st->arch <= OPUS_ARCHMASK);
49 #endif
50 }
51 #define VALIDATE_MS_DECODER(st) validate_ms_decoder(st)
52 #else
53 #define VALIDATE_MS_DECODER(st)
54 #endif
55
56
57 opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
58 {
59    int coupled_size;
60    int mono_size;
61
62    if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
63    coupled_size = opus_decoder_get_size(2);
64    mono_size = opus_decoder_get_size(1);
65    return align(sizeof(OpusMSDecoder))
66          + nb_coupled_streams * align(coupled_size)
67          + (nb_streams-nb_coupled_streams) * align(mono_size);
68 }
69
70 int opus_multistream_decoder_init(
71       OpusMSDecoder *st,
72       opus_int32 Fs,
73       int channels,
74       int streams,
75       int coupled_streams,
76       const unsigned char *mapping
77 )
78 {
79    int coupled_size;
80    int mono_size;
81    int i, ret;
82    char *ptr;
83
84    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
85        (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
86       return OPUS_BAD_ARG;
87
88    st->layout.nb_channels = channels;
89    st->layout.nb_streams = streams;
90    st->layout.nb_coupled_streams = coupled_streams;
91
92    for (i=0;i<st->layout.nb_channels;i++)
93       st->layout.mapping[i] = mapping[i];
94    if (!validate_layout(&st->layout))
95       return OPUS_BAD_ARG;
96
97    ptr = (char*)st + align(sizeof(OpusMSDecoder));
98    coupled_size = opus_decoder_get_size(2);
99    mono_size = opus_decoder_get_size(1);
100
101    for (i=0;i<st->layout.nb_coupled_streams;i++)
102    {
103       ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2);
104       if(ret!=OPUS_OK)return ret;
105       ptr += align(coupled_size);
106    }
107    for (;i<st->layout.nb_streams;i++)
108    {
109       ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1);
110       if(ret!=OPUS_OK)return ret;
111       ptr += align(mono_size);
112    }
113    return OPUS_OK;
114 }
115
116
117 OpusMSDecoder *opus_multistream_decoder_create(
118       opus_int32 Fs,
119       int channels,
120       int streams,
121       int coupled_streams,
122       const unsigned char *mapping,
123       int *error
124 )
125 {
126    int ret;
127    OpusMSDecoder *st;
128    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
129        (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
130    {
131       if (error)
132          *error = OPUS_BAD_ARG;
133       return NULL;
134    }
135    st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
136    if (st==NULL)
137    {
138       if (error)
139          *error = OPUS_ALLOC_FAIL;
140       return NULL;
141    }
142    ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping);
143    if (error)
144       *error = ret;
145    if (ret != OPUS_OK)
146    {
147       opus_free(st);
148       st = NULL;
149    }
150    return st;
151 }
152
153 static int opus_multistream_packet_validate(const unsigned char *data,
154       opus_int32 len, int nb_streams, opus_int32 Fs)
155 {
156    int s;
157    int count;
158    unsigned char toc;
159    opus_int16 size[48];
160    int samples=0;
161    opus_int32 packet_offset;
162
163    for (s=0;s<nb_streams;s++)
164    {
165       int tmp_samples;
166       if (len<=0)
167          return OPUS_INVALID_PACKET;
168       count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL,
169                                      size, NULL, &packet_offset);
170       if (count<0)
171          return count;
172       tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs);
173       if (s!=0 && samples != tmp_samples)
174          return OPUS_INVALID_PACKET;
175       samples = tmp_samples;
176       data += packet_offset;
177       len -= packet_offset;
178    }
179    return samples;
180 }
181
182 int opus_multistream_decode_native(
183       OpusMSDecoder *st,
184       const unsigned char *data,
185       opus_int32 len,
186       void *pcm,
187       opus_copy_channel_out_func copy_channel_out,
188       int frame_size,
189       int decode_fec,
190       int soft_clip,
191       void *user_data
192 )
193 {
194    opus_int32 Fs;
195    int coupled_size;
196    int mono_size;
197    int s, c;
198    char *ptr;
199    int do_plc=0;
200    VARDECL(opus_val16, buf);
201    ALLOC_STACK;
202
203    VALIDATE_MS_DECODER(st);
204    if (frame_size <= 0)
205    {
206       RESTORE_STACK;
207       return OPUS_BAD_ARG;
208    }
209    /* Limit frame_size to avoid excessive stack allocations. */
210    MUST_SUCCEED(opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)));
211    frame_size = IMIN(frame_size, Fs/25*3);
212    ALLOC(buf, 2*frame_size, opus_val16);
213    ptr = (char*)st + align(sizeof(OpusMSDecoder));
214    coupled_size = opus_decoder_get_size(2);
215    mono_size = opus_decoder_get_size(1);
216
217    if (len==0)
218       do_plc = 1;
219    if (len < 0)
220    {
221       RESTORE_STACK;
222       return OPUS_BAD_ARG;
223    }
224    if (!do_plc && len < 2*st->layout.nb_streams-1)
225    {
226       RESTORE_STACK;
227       return OPUS_INVALID_PACKET;
228    }
229    if (!do_plc)
230    {
231       int ret = opus_multistream_packet_validate(data, len, st->layout.nb_streams, Fs);
232       if (ret < 0)
233       {
234          RESTORE_STACK;
235          return ret;
236       } else if (ret > frame_size)
237       {
238          RESTORE_STACK;
239          return OPUS_BUFFER_TOO_SMALL;
240       }
241    }
242    for (s=0;s<st->layout.nb_streams;s++)
243    {
244       OpusDecoder *dec;
245       opus_int32 packet_offset;
246       int ret;
247
248       dec = (OpusDecoder*)ptr;
249       ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
250
251       if (!do_plc && len<=0)
252       {
253          RESTORE_STACK;
254          return OPUS_INTERNAL_ERROR;
255       }
256       packet_offset = 0;
257       ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip);
258       data += packet_offset;
259       len -= packet_offset;
260       if (ret <= 0)
261       {
262          RESTORE_STACK;
263          return ret;
264       }
265       frame_size = ret;
266       if (s < st->layout.nb_coupled_streams)
267       {
268          int chan, prev;
269          prev = -1;
270          /* Copy "left" audio to the channel(s) where it belongs */
271          while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
272          {
273             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
274                buf, 2, frame_size, user_data);
275             prev = chan;
276          }
277          prev = -1;
278          /* Copy "right" audio to the channel(s) where it belongs */
279          while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
280          {
281             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
282                buf+1, 2, frame_size, user_data);
283             prev = chan;
284          }
285       } else {
286          int chan, prev;
287          prev = -1;
288          /* Copy audio to the channel(s) where it belongs */
289          while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
290          {
291             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
292                buf, 1, frame_size, user_data);
293             prev = chan;
294          }
295       }
296    }
297    /* Handle muted channels */
298    for (c=0;c<st->layout.nb_channels;c++)
299    {
300       if (st->layout.mapping[c] == 255)
301       {
302          (*copy_channel_out)(pcm, st->layout.nb_channels, c,
303             NULL, 0, frame_size, user_data);
304       }
305    }
306    RESTORE_STACK;
307    return frame_size;
308 }
309
310 #if !defined(DISABLE_FLOAT_API)
311 static void opus_copy_channel_out_float(
312   void *dst,
313   int dst_stride,
314   int dst_channel,
315   const opus_val16 *src,
316   int src_stride,
317   int frame_size,
318   void *user_data
319 )
320 {
321    float *float_dst;
322    opus_int32 i;
323    (void)user_data;
324    float_dst = (float*)dst;
325    if (src != NULL)
326    {
327       for (i=0;i<frame_size;i++)
328 #if defined(FIXED_POINT)
329          float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];
330 #else
331          float_dst[i*dst_stride+dst_channel] = src[i*src_stride];
332 #endif
333    }
334    else
335    {
336       for (i=0;i<frame_size;i++)
337          float_dst[i*dst_stride+dst_channel] = 0;
338    }
339 }
340 #endif
341
342 static void opus_copy_channel_out_short(
343   void *dst,
344   int dst_stride,
345   int dst_channel,
346   const opus_val16 *src,
347   int src_stride,
348   int frame_size,
349   void *user_data
350 )
351 {
352    opus_int16 *short_dst;
353    opus_int32 i;
354    (void)user_data;
355    short_dst = (opus_int16*)dst;
356    if (src != NULL)
357    {
358       for (i=0;i<frame_size;i++)
359 #if defined(FIXED_POINT)
360          short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
361 #else
362          short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
363 #endif
364    }
365    else
366    {
367       for (i=0;i<frame_size;i++)
368          short_dst[i*dst_stride+dst_channel] = 0;
369    }
370 }
371
372
373
374 #ifdef FIXED_POINT
375 int opus_multistream_decode(
376       OpusMSDecoder *st,
377       const unsigned char *data,
378       opus_int32 len,
379       opus_int16 *pcm,
380       int frame_size,
381       int decode_fec
382 )
383 {
384    return opus_multistream_decode_native(st, data, len,
385        pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0, NULL);
386 }
387
388 #ifndef DISABLE_FLOAT_API
389 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
390       opus_int32 len, float *pcm, int frame_size, int decode_fec)
391 {
392    return opus_multistream_decode_native(st, data, len,
393        pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
394 }
395 #endif
396
397 #else
398
399 int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
400       opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
401 {
402    return opus_multistream_decode_native(st, data, len,
403        pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1, NULL);
404 }
405
406 int opus_multistream_decode_float(
407       OpusMSDecoder *st,
408       const unsigned char *data,
409       opus_int32 len,
410       opus_val16 *pcm,
411       int frame_size,
412       int decode_fec
413 )
414 {
415    return opus_multistream_decode_native(st, data, len,
416        pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
417 }
418 #endif
419
420 int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
421                                          va_list ap)
422 {
423    int coupled_size, mono_size;
424    char *ptr;
425    int ret = OPUS_OK;
426
427    coupled_size = opus_decoder_get_size(2);
428    mono_size = opus_decoder_get_size(1);
429    ptr = (char*)st + align(sizeof(OpusMSDecoder));
430    switch (request)
431    {
432        case OPUS_GET_BANDWIDTH_REQUEST:
433        case OPUS_GET_SAMPLE_RATE_REQUEST:
434        case OPUS_GET_GAIN_REQUEST:
435        case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
436        case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
437        {
438           OpusDecoder *dec;
439           /* For int32* GET params, just query the first stream */
440           opus_int32 *value = va_arg(ap, opus_int32*);
441           dec = (OpusDecoder*)ptr;
442           ret = opus_decoder_ctl(dec, request, value);
443        }
444        break;
445        case OPUS_GET_FINAL_RANGE_REQUEST:
446        {
447           int s;
448           opus_uint32 *value = va_arg(ap, opus_uint32*);
449           opus_uint32 tmp;
450           if (!value)
451           {
452              goto bad_arg;
453           }
454           *value = 0;
455           for (s=0;s<st->layout.nb_streams;s++)
456           {
457              OpusDecoder *dec;
458              dec = (OpusDecoder*)ptr;
459              if (s < st->layout.nb_coupled_streams)
460                 ptr += align(coupled_size);
461              else
462                 ptr += align(mono_size);
463              ret = opus_decoder_ctl(dec, request, &tmp);
464              if (ret != OPUS_OK) break;
465              *value ^= tmp;
466           }
467        }
468        break;
469        case OPUS_RESET_STATE:
470        {
471           int s;
472           for (s=0;s<st->layout.nb_streams;s++)
473           {
474              OpusDecoder *dec;
475
476              dec = (OpusDecoder*)ptr;
477              if (s < st->layout.nb_coupled_streams)
478                 ptr += align(coupled_size);
479              else
480                 ptr += align(mono_size);
481              ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
482              if (ret != OPUS_OK)
483                 break;
484           }
485        }
486        break;
487        case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
488        {
489           int s;
490           opus_int32 stream_id;
491           OpusDecoder **value;
492           stream_id = va_arg(ap, opus_int32);
493           if (stream_id<0 || stream_id >= st->layout.nb_streams)
494              ret = OPUS_BAD_ARG;
495           value = va_arg(ap, OpusDecoder**);
496           if (!value)
497           {
498              goto bad_arg;
499           }
500           for (s=0;s<stream_id;s++)
501           {
502              if (s < st->layout.nb_coupled_streams)
503                 ptr += align(coupled_size);
504              else
505                 ptr += align(mono_size);
506           }
507           *value = (OpusDecoder*)ptr;
508        }
509        break;
510        case OPUS_SET_GAIN_REQUEST:
511        case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
512        {
513           int s;
514           /* This works for int32 params */
515           opus_int32 value = va_arg(ap, opus_int32);
516           for (s=0;s<st->layout.nb_streams;s++)
517           {
518              OpusDecoder *dec;
519
520              dec = (OpusDecoder*)ptr;
521              if (s < st->layout.nb_coupled_streams)
522                 ptr += align(coupled_size);
523              else
524                 ptr += align(mono_size);
525              ret = opus_decoder_ctl(dec, request, value);
526              if (ret != OPUS_OK)
527                 break;
528           }
529        }
530        break;
531        default:
532           ret = OPUS_UNIMPLEMENTED;
533        break;
534    }
535    return ret;
536 bad_arg:
537    return OPUS_BAD_ARG;
538 }
539
540 int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
541 {
542    int ret;
543    va_list ap;
544    va_start(ap, request);
545    ret = opus_multistream_decoder_ctl_va_list(st, request, ap);
546    va_end(ap);
547    return ret;
548 }
549
550 void opus_multistream_decoder_destroy(OpusMSDecoder *st)
551 {
552     opus_free(st);
553 }