Splits out the Opus multi-stream encoder and decoder
[opus.git] / src / opus_multistream_encoder.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 OpusMSEncoder {
41    ChannelLayout layout;
42    int bitrate;
43    /* Encoder states go here */
44 };
45
46 #ifdef FIXED_POINT
47 #define opus_encode_native opus_encode
48 #else
49 #define opus_encode_native opus_encode_float
50 #endif
51
52 static int validate_encoder_layout(const ChannelLayout *layout)
53 {
54    int s;
55    for (s=0;s<layout->nb_streams;s++)
56    {
57       if (s < layout->nb_coupled_streams)
58       {
59          if (get_left_channel(layout, s, -1)==-1)
60             return 0;
61          if (get_right_channel(layout, s, -1)==-1)
62             return 0;
63       } else {
64          if (get_mono_channel(layout, s, -1)==-1)
65             return 0;
66       }
67    }
68    return 1;
69 }
70
71
72 opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
73 {
74    int coupled_size;
75    int mono_size;
76
77    if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
78    coupled_size = opus_encoder_get_size(2);
79    mono_size = opus_encoder_get_size(1);
80    return align(sizeof(OpusMSEncoder))
81         + nb_coupled_streams * align(coupled_size)
82         + (nb_streams-nb_coupled_streams) * align(mono_size);
83 }
84
85
86
87 int opus_multistream_encoder_init(
88       OpusMSEncoder *st,
89       opus_int32 Fs,
90       int channels,
91       int streams,
92       int coupled_streams,
93       const unsigned char *mapping,
94       int application
95 )
96 {
97    int coupled_size;
98    int mono_size;
99    int i, ret;
100    char *ptr;
101
102    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
103        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
104       return OPUS_BAD_ARG;
105
106    st->layout.nb_channels = channels;
107    st->layout.nb_streams = streams;
108    st->layout.nb_coupled_streams = coupled_streams;
109
110    for (i=0;i<st->layout.nb_channels;i++)
111       st->layout.mapping[i] = mapping[i];
112    if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
113       return OPUS_BAD_ARG;
114    ptr = (char*)st + align(sizeof(OpusMSEncoder));
115    coupled_size = opus_encoder_get_size(2);
116    mono_size = opus_encoder_get_size(1);
117
118    for (i=0;i<st->layout.nb_coupled_streams;i++)
119    {
120       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
121       if(ret!=OPUS_OK)return ret;
122       ptr += align(coupled_size);
123    }
124    for (;i<st->layout.nb_streams;i++)
125    {
126       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
127       if(ret!=OPUS_OK)return ret;
128       ptr += align(mono_size);
129    }
130    return OPUS_OK;
131 }
132
133 OpusMSEncoder *opus_multistream_encoder_create(
134       opus_int32 Fs,
135       int channels,
136       int streams,
137       int coupled_streams,
138       const unsigned char *mapping,
139       int application,
140       int *error
141 )
142 {
143    int ret;
144    OpusMSEncoder *st;
145    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
146        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
147    {
148       if (error)
149          *error = OPUS_BAD_ARG;
150       return NULL;
151    }
152    st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
153    if (st==NULL)
154    {
155       if (error)
156          *error = OPUS_ALLOC_FAIL;
157       return NULL;
158    }
159    ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
160    if (ret != OPUS_OK)
161    {
162       opus_free(st);
163       st = NULL;
164    }
165    if (error)
166       *error = ret;
167    return st;
168 }
169
170 typedef void (*opus_copy_channel_in_func)(
171   opus_val16 *dst,
172   int dst_stride,
173   const void *src,
174   int src_stride,
175   int src_channel,
176   int frame_size
177 );
178
179 /* Max size in case the encoder decides to return three frames */
180 #define MS_FRAME_TMP (3*1275+7)
181 static int opus_multistream_encode_native
182 (
183     OpusMSEncoder *st,
184     opus_copy_channel_in_func copy_channel_in,
185     const void *pcm,
186     int frame_size,
187     unsigned char *data,
188     opus_int32 max_data_bytes
189 )
190 {
191    opus_int32 Fs;
192    int coupled_size;
193    int mono_size;
194    int s;
195    char *ptr;
196    int tot_size;
197    VARDECL(opus_val16, buf);
198    unsigned char tmp_data[MS_FRAME_TMP];
199    OpusRepacketizer rp;
200    ALLOC_STACK;
201
202    ptr = (char*)st + align(sizeof(OpusMSEncoder));
203    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
204    /* Validate frame_size before using it to allocate stack space.
205       This mirrors the checks in opus_encode[_float](). */
206    if (400*frame_size != Fs && 200*frame_size != Fs &&
207        100*frame_size != Fs &&  50*frame_size != Fs &&
208         25*frame_size != Fs &&  50*frame_size != 3*Fs)
209    {
210       RESTORE_STACK;
211       return OPUS_BAD_ARG;
212    }
213    ALLOC(buf, 2*frame_size, opus_val16);
214    coupled_size = opus_encoder_get_size(2);
215    mono_size = opus_encoder_get_size(1);
216
217    if (max_data_bytes < 4*st->layout.nb_streams-1)
218    {
219       RESTORE_STACK;
220       return OPUS_BUFFER_TOO_SMALL;
221    }
222    /* Counting ToC */
223    tot_size = 0;
224    for (s=0;s<st->layout.nb_streams;s++)
225    {
226       OpusEncoder *enc;
227       int len;
228       int curr_max;
229
230       opus_repacketizer_init(&rp);
231       enc = (OpusEncoder*)ptr;
232       if (s < st->layout.nb_coupled_streams)
233       {
234          int left, right;
235          left = get_left_channel(&st->layout, s, -1);
236          right = get_right_channel(&st->layout, s, -1);
237          (*copy_channel_in)(buf, 2,
238             pcm, st->layout.nb_channels, left, frame_size);
239          (*copy_channel_in)(buf+1, 2,
240             pcm, st->layout.nb_channels, right, frame_size);
241          ptr += align(coupled_size);
242       } else {
243          int chan = get_mono_channel(&st->layout, s, -1);
244          (*copy_channel_in)(buf, 1,
245             pcm, st->layout.nb_channels, chan, frame_size);
246          ptr += align(mono_size);
247       }
248       /* number of bytes left (+Toc) */
249       curr_max = max_data_bytes - tot_size;
250       /* Reserve three bytes for the last stream and four for the others */
251       curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
252       curr_max = IMIN(curr_max,MS_FRAME_TMP);
253       len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max);
254       if (len<0)
255       {
256          RESTORE_STACK;
257          return len;
258       }
259       /* We need to use the repacketizer to add the self-delimiting lengths
260          while taking into account the fact that the encoder can now return
261          more than one frame at a time (e.g. 60 ms CELT-only) */
262       opus_repacketizer_cat(&rp, tmp_data, len);
263       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);
264       data += len;
265       tot_size += len;
266    }
267    RESTORE_STACK;
268    return tot_size;
269
270 }
271
272 #if !defined(DISABLE_FLOAT_API)
273 static void opus_copy_channel_in_float(
274   opus_val16 *dst,
275   int dst_stride,
276   const void *src,
277   int src_stride,
278   int src_channel,
279   int frame_size
280 )
281 {
282    const float *float_src;
283    int i;
284    float_src = (const float *)src;
285    for (i=0;i<frame_size;i++)
286 #if defined(FIXED_POINT)
287       dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
288 #else
289       dst[i*dst_stride] = float_src[i*src_stride+src_channel];
290 #endif
291 }
292 #endif
293
294 static void opus_copy_channel_in_short(
295   opus_val16 *dst,
296   int dst_stride,
297   const void *src,
298   int src_stride,
299   int src_channel,
300   int frame_size
301 )
302 {
303    const opus_int16 *short_src;
304    int i;
305    short_src = (const opus_int16 *)src;
306    for (i=0;i<frame_size;i++)
307 #if defined(FIXED_POINT)
308       dst[i*dst_stride] = short_src[i*src_stride+src_channel];
309 #else
310       dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
311 #endif
312 }
313
314 #ifdef FIXED_POINT
315 int opus_multistream_encode(
316     OpusMSEncoder *st,
317     const opus_val16 *pcm,
318     int frame_size,
319     unsigned char *data,
320     opus_int32 max_data_bytes
321 )
322 {
323    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
324       pcm, frame_size, data, max_data_bytes);
325 }
326
327 #ifndef DISABLE_FLOAT_API
328 int opus_multistream_encode_float(
329     OpusMSEncoder *st,
330     const float *pcm,
331     int frame_size,
332     unsigned char *data,
333     opus_int32 max_data_bytes
334 )
335 {
336    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
337       pcm, frame_size, data, max_data_bytes);
338 }
339 #endif
340
341 #else
342
343 int opus_multistream_encode_float
344 (
345     OpusMSEncoder *st,
346     const opus_val16 *pcm,
347     int frame_size,
348     unsigned char *data,
349     opus_int32 max_data_bytes
350 )
351 {
352    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
353       pcm, frame_size, data, max_data_bytes);
354 }
355
356 int opus_multistream_encode(
357     OpusMSEncoder *st,
358     const opus_int16 *pcm,
359     int frame_size,
360     unsigned char *data,
361     opus_int32 max_data_bytes
362 )
363 {
364    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
365       pcm, frame_size, data, max_data_bytes);
366 }
367 #endif
368
369 int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
370 {
371    va_list ap;
372    int coupled_size, mono_size;
373    char *ptr;
374    int ret = OPUS_OK;
375
376    va_start(ap, request);
377
378    coupled_size = opus_encoder_get_size(2);
379    mono_size = opus_encoder_get_size(1);
380    ptr = (char*)st + align(sizeof(OpusMSEncoder));
381    switch (request)
382    {
383    case OPUS_SET_BITRATE_REQUEST:
384    {
385       int chan, s;
386       opus_int32 value = va_arg(ap, opus_int32);
387       chan = st->layout.nb_streams + st->layout.nb_coupled_streams;
388       value /= chan;
389       for (s=0;s<st->layout.nb_streams;s++)
390       {
391          OpusEncoder *enc;
392          enc = (OpusEncoder*)ptr;
393          if (s < st->layout.nb_coupled_streams)
394             ptr += align(coupled_size);
395          else
396             ptr += align(mono_size);
397          opus_encoder_ctl(enc, request, value * (s < st->layout.nb_coupled_streams ? 2 : 1));
398       }
399    }
400    break;
401    case OPUS_GET_BITRATE_REQUEST:
402    {
403       int s;
404       opus_int32 *value = va_arg(ap, opus_int32*);
405       *value = 0;
406       for (s=0;s<st->layout.nb_streams;s++)
407       {
408          opus_int32 rate;
409          OpusEncoder *enc;
410          enc = (OpusEncoder*)ptr;
411          if (s < st->layout.nb_coupled_streams)
412             ptr += align(coupled_size);
413          else
414             ptr += align(mono_size);
415          opus_encoder_ctl(enc, request, &rate);
416          *value += rate;
417       }
418    }
419    break;
420    case OPUS_GET_LSB_DEPTH_REQUEST:
421    case OPUS_GET_VBR_REQUEST:
422    case OPUS_GET_APPLICATION_REQUEST:
423    case OPUS_GET_BANDWIDTH_REQUEST:
424    case OPUS_GET_COMPLEXITY_REQUEST:
425    case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
426    case OPUS_GET_DTX_REQUEST:
427    case OPUS_GET_VOICE_RATIO_REQUEST:
428    case OPUS_GET_VBR_CONSTRAINT_REQUEST:
429    case OPUS_GET_SIGNAL_REQUEST:
430    case OPUS_GET_LOOKAHEAD_REQUEST:
431    case OPUS_GET_SAMPLE_RATE_REQUEST:
432    case OPUS_GET_INBAND_FEC_REQUEST:
433    case OPUS_GET_FORCE_CHANNELS_REQUEST:
434    {
435       OpusEncoder *enc;
436       /* For int32* GET params, just query the first stream */
437       opus_int32 *value = va_arg(ap, opus_int32*);
438       enc = (OpusEncoder*)ptr;
439       ret = opus_encoder_ctl(enc, request, value);
440    }
441    break;
442    case OPUS_GET_FINAL_RANGE_REQUEST:
443    {
444       int s;
445       opus_uint32 *value = va_arg(ap, opus_uint32*);
446       opus_uint32 tmp;
447       *value=0;
448       for (s=0;s<st->layout.nb_streams;s++)
449       {
450          OpusEncoder *enc;
451          enc = (OpusEncoder*)ptr;
452          if (s < st->layout.nb_coupled_streams)
453             ptr += align(coupled_size);
454          else
455             ptr += align(mono_size);
456          ret = opus_encoder_ctl(enc, request, &tmp);
457          if (ret != OPUS_OK) break;
458          *value ^= tmp;
459       }
460    }
461    break;
462    case OPUS_SET_LSB_DEPTH_REQUEST:
463    case OPUS_SET_COMPLEXITY_REQUEST:
464    case OPUS_SET_VBR_REQUEST:
465    case OPUS_SET_VBR_CONSTRAINT_REQUEST:
466    case OPUS_SET_BANDWIDTH_REQUEST:
467    case OPUS_SET_SIGNAL_REQUEST:
468    case OPUS_SET_APPLICATION_REQUEST:
469    case OPUS_SET_INBAND_FEC_REQUEST:
470    case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
471    case OPUS_SET_DTX_REQUEST:
472    case OPUS_SET_FORCE_MODE_REQUEST:
473    case OPUS_SET_FORCE_CHANNELS_REQUEST:
474    {
475       int s;
476       /* This works for int32 params */
477       opus_int32 value = va_arg(ap, opus_int32);
478       for (s=0;s<st->layout.nb_streams;s++)
479       {
480          OpusEncoder *enc;
481
482          enc = (OpusEncoder*)ptr;
483          if (s < st->layout.nb_coupled_streams)
484             ptr += align(coupled_size);
485          else
486             ptr += align(mono_size);
487          ret = opus_encoder_ctl(enc, request, value);
488          if (ret != OPUS_OK)
489             break;
490       }
491    }
492    break;
493    case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
494    {
495       int s;
496       opus_int32 stream_id;
497       OpusEncoder **value;
498       stream_id = va_arg(ap, opus_int32);
499       if (stream_id<0 || stream_id >= st->layout.nb_streams)
500          ret = OPUS_BAD_ARG;
501       value = va_arg(ap, OpusEncoder**);
502       for (s=0;s<stream_id;s++)
503       {
504          if (s < st->layout.nb_coupled_streams)
505             ptr += align(coupled_size);
506          else
507             ptr += align(mono_size);
508       }
509       *value = (OpusEncoder*)ptr;
510    }
511       break;
512    default:
513       ret = OPUS_UNIMPLEMENTED;
514       break;
515    }
516
517    va_end(ap);
518    return ret;
519 }
520
521 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
522 {
523     opus_free(st);
524 }
525
526