Do up-front validation of multistream packets
[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 struct OpusMSDecoder {
41    ChannelLayout layout;
42    /* Decoder states go here */
43 };
44
45
46
47
48 /* DECODER */
49
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
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        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
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
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        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
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
155 static int opus_multistream_packet_validate(const unsigned char *data,
156       opus_int32 len, int nb_streams)
157 {
158    int s;
159    int i;
160    int count;
161    unsigned char toc;
162    opus_int16 size[48];
163    int offset;
164    int samples=0;
165
166    for (s=0;s<nb_streams;s++)
167    {
168       int tmp_samples;
169       if (len<=0)
170          return OPUS_INVALID_PACKET;
171       count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL, size, &offset);
172       if (count<0)
173          return count;
174       for (i=0;i<count;i++)
175          offset += size[i];
176       tmp_samples = opus_packet_get_nb_samples(data, offset, 48000);
177       if (s!=0 && samples != tmp_samples)
178          return OPUS_INVALID_PACKET;
179       samples = tmp_samples;
180       data += offset;
181       len -= offset;
182    }
183    return OPUS_OK;
184 }
185
186 static int opus_multistream_decode_native(
187       OpusMSDecoder *st,
188       const unsigned char *data,
189       opus_int32 len,
190       void *pcm,
191       opus_copy_channel_out_func copy_channel_out,
192       int frame_size,
193       int decode_fec,
194       int soft_clip
195 )
196 {
197    opus_int32 Fs;
198    int coupled_size;
199    int mono_size;
200    int s, c;
201    char *ptr;
202    int do_plc=0;
203    VARDECL(opus_val16, buf);
204    ALLOC_STACK;
205
206    /* Limit frame_size to avoid excessive stack allocations. */
207    opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));
208    frame_size = IMIN(frame_size, Fs/25*3);
209    ALLOC(buf, 2*frame_size, opus_val16);
210    ptr = (char*)st + align(sizeof(OpusMSDecoder));
211    coupled_size = opus_decoder_get_size(2);
212    mono_size = opus_decoder_get_size(1);
213
214    if (len==0)
215       do_plc = 1;
216    if (len < 0)
217    {
218       RESTORE_STACK;
219       return OPUS_BAD_ARG;
220    }
221    if (!do_plc && len < 2*st->layout.nb_streams-1)
222    {
223       RESTORE_STACK;
224       return OPUS_INVALID_PACKET;
225    }
226    if (!do_plc)
227    {
228       int ret = opus_multistream_packet_validate(data, len, st->layout.nb_coupled_streams);
229       if (ret < 0)
230       {
231          RESTORE_STACK;
232          return ret;
233       }
234    }
235    for (s=0;s<st->layout.nb_streams;s++)
236    {
237       OpusDecoder *dec;
238       int packet_offset, ret;
239
240       dec = (OpusDecoder*)ptr;
241       ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
242
243       if (!do_plc && len<=0)
244       {
245          RESTORE_STACK;
246          return OPUS_INVALID_PACKET;
247       }
248       packet_offset = 0;
249       ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip);
250       data += packet_offset;
251       len -= packet_offset;
252       if (ret > frame_size)
253       {
254          RESTORE_STACK;
255          return OPUS_BUFFER_TOO_SMALL;
256       }
257       if (s>0 && ret != frame_size)
258       {
259          RESTORE_STACK;
260          return OPUS_INVALID_PACKET;
261       }
262       if (ret <= 0)
263       {
264          RESTORE_STACK;
265          return ret;
266       }
267       frame_size = ret;
268       if (s < st->layout.nb_coupled_streams)
269       {
270          int chan, prev;
271          prev = -1;
272          /* Copy "left" audio to the channel(s) where it belongs */
273          while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
274          {
275             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
276                buf, 2, frame_size);
277             prev = chan;
278          }
279          prev = -1;
280          /* Copy "right" audio to the channel(s) where it belongs */
281          while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
282          {
283             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
284                buf+1, 2, frame_size);
285             prev = chan;
286          }
287       } else {
288          int chan, prev;
289          prev = -1;
290          /* Copy audio to the channel(s) where it belongs */
291          while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
292          {
293             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
294                buf, 1, frame_size);
295             prev = chan;
296          }
297       }
298    }
299    /* Handle muted channels */
300    for (c=0;c<st->layout.nb_channels;c++)
301    {
302       if (st->layout.mapping[c] == 255)
303       {
304          (*copy_channel_out)(pcm, st->layout.nb_channels, c,
305             NULL, 0, frame_size);
306       }
307    }
308    RESTORE_STACK;
309    return frame_size;
310 }
311
312 #if !defined(DISABLE_FLOAT_API)
313 static void opus_copy_channel_out_float(
314   void *dst,
315   int dst_stride,
316   int dst_channel,
317   const opus_val16 *src,
318   int src_stride,
319   int frame_size
320 )
321 {
322    float *float_dst;
323    opus_int32 i;
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 )
350 {
351    opus_int16 *short_dst;
352    opus_int32 i;
353    short_dst = (opus_int16*)dst;
354    if (src != NULL)
355    {
356       for (i=0;i<frame_size;i++)
357 #if defined(FIXED_POINT)
358          short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
359 #else
360          short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
361 #endif
362    }
363    else
364    {
365       for (i=0;i<frame_size;i++)
366          short_dst[i*dst_stride+dst_channel] = 0;
367    }
368 }
369
370
371
372 #ifdef FIXED_POINT
373 int opus_multistream_decode(
374       OpusMSDecoder *st,
375       const unsigned char *data,
376       opus_int32 len,
377       opus_int16 *pcm,
378       int frame_size,
379       int decode_fec
380 )
381 {
382    return opus_multistream_decode_native(st, data, len,
383        pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0);
384 }
385
386 #ifndef DISABLE_FLOAT_API
387 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
388       opus_int32 len, float *pcm, int frame_size, int decode_fec)
389 {
390    return opus_multistream_decode_native(st, data, len,
391        pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
392 }
393 #endif
394
395 #else
396
397 int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
398       opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
399 {
400    return opus_multistream_decode_native(st, data, len,
401        pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1);
402 }
403
404 int opus_multistream_decode_float(
405       OpusMSDecoder *st,
406       const unsigned char *data,
407       opus_int32 len,
408       float *pcm,
409       int frame_size,
410       int decode_fec
411 )
412 {
413    return opus_multistream_decode_native(st, data, len,
414        pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
415 }
416 #endif
417
418 int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
419 {
420    va_list ap;
421    int coupled_size, mono_size;
422    char *ptr;
423    int ret = OPUS_OK;
424
425    va_start(ap, request);
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        {
437           OpusDecoder *dec;
438           /* For int32* GET params, just query the first stream */
439           opus_int32 *value = va_arg(ap, opus_int32*);
440           dec = (OpusDecoder*)ptr;
441           ret = opus_decoder_ctl(dec, request, value);
442        }
443        break;
444        case OPUS_GET_FINAL_RANGE_REQUEST:
445        {
446           int s;
447           opus_uint32 *value = va_arg(ap, opus_uint32*);
448           opus_uint32 tmp;
449           if (!value)
450           {
451              goto bad_arg;
452           }
453           *value = 0;
454           for (s=0;s<st->layout.nb_streams;s++)
455           {
456              OpusDecoder *dec;
457              dec = (OpusDecoder*)ptr;
458              if (s < st->layout.nb_coupled_streams)
459                 ptr += align(coupled_size);
460              else
461                 ptr += align(mono_size);
462              ret = opus_decoder_ctl(dec, request, &tmp);
463              if (ret != OPUS_OK) break;
464              *value ^= tmp;
465           }
466        }
467        break;
468        case OPUS_RESET_STATE:
469        {
470           int s;
471           for (s=0;s<st->layout.nb_streams;s++)
472           {
473              OpusDecoder *dec;
474
475              dec = (OpusDecoder*)ptr;
476              if (s < st->layout.nb_coupled_streams)
477                 ptr += align(coupled_size);
478              else
479                 ptr += align(mono_size);
480              ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
481              if (ret != OPUS_OK)
482                 break;
483           }
484        }
485        break;
486        case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
487        {
488           int s;
489           opus_int32 stream_id;
490           OpusDecoder **value;
491           stream_id = va_arg(ap, opus_int32);
492           if (stream_id<0 || stream_id >= st->layout.nb_streams)
493              ret = OPUS_BAD_ARG;
494           value = va_arg(ap, OpusDecoder**);
495           if (!value)
496           {
497              goto bad_arg;
498           }
499           for (s=0;s<stream_id;s++)
500           {
501              if (s < st->layout.nb_coupled_streams)
502                 ptr += align(coupled_size);
503              else
504                 ptr += align(mono_size);
505           }
506           *value = (OpusDecoder*)ptr;
507        }
508        break;
509        case OPUS_SET_GAIN_REQUEST:
510        {
511           int s;
512           /* This works for int32 params */
513           opus_int32 value = va_arg(ap, opus_int32);
514           for (s=0;s<st->layout.nb_streams;s++)
515           {
516              OpusDecoder *dec;
517
518              dec = (OpusDecoder*)ptr;
519              if (s < st->layout.nb_coupled_streams)
520                 ptr += align(coupled_size);
521              else
522                 ptr += align(mono_size);
523              ret = opus_decoder_ctl(dec, request, value);
524              if (ret != OPUS_OK)
525                 break;
526           }
527        }
528        break;
529        default:
530           ret = OPUS_UNIMPLEMENTED;
531        break;
532    }
533
534    va_end(ap);
535    return ret;
536 bad_arg:
537    va_end(ap);
538    return OPUS_BAD_ARG;
539 }
540
541
542 void opus_multistream_decoder_destroy(OpusMSDecoder *st)
543 {
544     opus_free(st);
545 }