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