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