Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/media/libopus/src/opus_multistream_encoder.c
Line
Count
Source (jump to first uncovered line)
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
#include "mathops.h"
40
#include "mdct.h"
41
#include "modes.h"
42
#include "bands.h"
43
#include "quant_bands.h"
44
#include "pitch.h"
45
46
typedef struct {
47
   int nb_streams;
48
   int nb_coupled_streams;
49
   unsigned char mapping[8];
50
} VorbisLayout;
51
52
/* Index is nb_channel-1*/
53
static const VorbisLayout vorbis_mappings[8] = {
54
      {1, 0, {0}},                      /* 1: mono */
55
      {1, 1, {0, 1}},                   /* 2: stereo */
56
      {2, 1, {0, 2, 1}},                /* 3: 1-d surround */
57
      {2, 2, {0, 1, 2, 3}},             /* 4: quadraphonic surround */
58
      {3, 2, {0, 4, 1, 2, 3}},          /* 5: 5-channel surround */
59
      {4, 2, {0, 4, 1, 2, 3, 5}},       /* 6: 5.1 surround */
60
      {4, 3, {0, 4, 1, 2, 3, 5, 6}},    /* 7: 6.1 surround */
61
      {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */
62
};
63
64
static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st)
65
0
{
66
0
   int s;
67
0
   char *ptr;
68
0
   int coupled_size, mono_size;
69
0
70
0
   coupled_size = opus_encoder_get_size(2);
71
0
   mono_size = opus_encoder_get_size(1);
72
0
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
73
0
   for (s=0;s<st->layout.nb_streams;s++)
74
0
   {
75
0
      if (s < st->layout.nb_coupled_streams)
76
0
         ptr += align(coupled_size);
77
0
      else
78
0
         ptr += align(mono_size);
79
0
   }
80
0
   /* void* cast avoids clang -Wcast-align warning */
81
0
   return (opus_val32*)(void*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32));
82
0
}
83
84
static opus_val32 *ms_get_window_mem(OpusMSEncoder *st)
85
0
{
86
0
   int s;
87
0
   char *ptr;
88
0
   int coupled_size, mono_size;
89
0
90
0
   coupled_size = opus_encoder_get_size(2);
91
0
   mono_size = opus_encoder_get_size(1);
92
0
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
93
0
   for (s=0;s<st->layout.nb_streams;s++)
94
0
   {
95
0
      if (s < st->layout.nb_coupled_streams)
96
0
         ptr += align(coupled_size);
97
0
      else
98
0
         ptr += align(mono_size);
99
0
   }
100
0
   /* void* cast avoids clang -Wcast-align warning */
101
0
   return (opus_val32*)(void*)ptr;
102
0
}
103
104
static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams)
105
0
{
106
0
   int order_plus_one;
107
0
   int acn_channels;
108
0
   int nondiegetic_channels;
109
0
110
0
   if (nb_channels < 1 || nb_channels > 227)
111
0
      return 0;
112
0
113
0
   order_plus_one = isqrt32(nb_channels);
114
0
   acn_channels = order_plus_one * order_plus_one;
115
0
   nondiegetic_channels = nb_channels - acn_channels;
116
0
117
0
   if (nondiegetic_channels != 0 && nondiegetic_channels != 2)
118
0
      return 0;
119
0
120
0
   if (nb_streams)
121
0
      *nb_streams = acn_channels + (nondiegetic_channels != 0);
122
0
   if (nb_coupled_streams)
123
0
      *nb_coupled_streams = nondiegetic_channels != 0;
124
0
   return 1;
125
0
}
126
127
static int validate_encoder_layout(const ChannelLayout *layout)
128
0
{
129
0
   int s;
130
0
   for (s=0;s<layout->nb_streams;s++)
131
0
   {
132
0
      if (s < layout->nb_coupled_streams)
133
0
      {
134
0
         if (get_left_channel(layout, s, -1)==-1)
135
0
            return 0;
136
0
         if (get_right_channel(layout, s, -1)==-1)
137
0
            return 0;
138
0
      } else {
139
0
         if (get_mono_channel(layout, s, -1)==-1)
140
0
            return 0;
141
0
      }
142
0
   }
143
0
   return 1;
144
0
}
145
146
static void channel_pos(int channels, int pos[8])
147
0
{
148
0
   /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
149
0
   if (channels==4)
150
0
   {
151
0
      pos[0]=1;
152
0
      pos[1]=3;
153
0
      pos[2]=1;
154
0
      pos[3]=3;
155
0
   } else if (channels==3||channels==5||channels==6)
156
0
   {
157
0
      pos[0]=1;
158
0
      pos[1]=2;
159
0
      pos[2]=3;
160
0
      pos[3]=1;
161
0
      pos[4]=3;
162
0
      pos[5]=0;
163
0
   } else if (channels==7)
164
0
   {
165
0
      pos[0]=1;
166
0
      pos[1]=2;
167
0
      pos[2]=3;
168
0
      pos[3]=1;
169
0
      pos[4]=3;
170
0
      pos[5]=2;
171
0
      pos[6]=0;
172
0
   } else if (channels==8)
173
0
   {
174
0
      pos[0]=1;
175
0
      pos[1]=2;
176
0
      pos[2]=3;
177
0
      pos[3]=1;
178
0
      pos[4]=3;
179
0
      pos[5]=1;
180
0
      pos[6]=3;
181
0
      pos[7]=0;
182
0
   }
183
0
}
184
185
#if 1
186
/* Computes a rough approximation of log2(2^a + 2^b) */
187
static opus_val16 logSum(opus_val16 a, opus_val16 b)
188
0
{
189
0
   opus_val16 max;
190
0
   opus_val32 diff;
191
0
   opus_val16 frac;
192
0
   static const opus_val16 diff_table[17] = {
193
0
         QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT),
194
0
         QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT),
195
0
         QCONST16(0.0028123f, DB_SHIFT)
196
0
   };
197
0
   int low;
198
0
   if (a>b)
199
0
   {
200
0
      max = a;
201
0
      diff = SUB32(EXTEND32(a),EXTEND32(b));
202
0
   } else {
203
0
      max = b;
204
0
      diff = SUB32(EXTEND32(b),EXTEND32(a));
205
0
   }
206
0
   if (!(diff < QCONST16(8.f, DB_SHIFT)))  /* inverted to catch NaNs */
207
0
      return max;
208
#ifdef FIXED_POINT
209
   low = SHR32(diff, DB_SHIFT-1);
210
   frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT);
211
#else
212
0
   low = (int)floor(2*diff);
213
0
   frac = 2*diff - low;
214
0
#endif
215
0
   return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low]));
216
0
}
217
#else
218
opus_val16 logSum(opus_val16 a, opus_val16 b)
219
{
220
   return log2(pow(4, a)+ pow(4, b))/2;
221
}
222
#endif
223
224
void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,
225
      int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch
226
)
227
0
{
228
0
   int c;
229
0
   int i;
230
0
   int LM;
231
0
   int pos[8] = {0};
232
0
   int upsample;
233
0
   int frame_size;
234
0
   int freq_size;
235
0
   opus_val16 channel_offset;
236
0
   opus_val32 bandE[21];
237
0
   opus_val16 maskLogE[3][21];
238
0
   VARDECL(opus_val32, in);
239
0
   VARDECL(opus_val16, x);
240
0
   VARDECL(opus_val32, freq);
241
0
   SAVE_STACK;
242
0
243
0
   upsample = resampling_factor(rate);
244
0
   frame_size = len*upsample;
245
0
   freq_size = IMIN(960, frame_size);
246
0
247
0
   /* LM = log2(frame_size / 120) */
248
0
   for (LM=0;LM<celt_mode->maxLM;LM++)
249
0
      if (celt_mode->shortMdctSize<<LM==frame_size)
250
0
         break;
251
0
252
0
   ALLOC(in, frame_size+overlap, opus_val32);
253
0
   ALLOC(x, len, opus_val16);
254
0
   ALLOC(freq, freq_size, opus_val32);
255
0
256
0
   channel_pos(channels, pos);
257
0
258
0
   for (c=0;c<3;c++)
259
0
      for (i=0;i<21;i++)
260
0
         maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT);
261
0
262
0
   for (c=0;c<channels;c++)
263
0
   {
264
0
      int frame;
265
0
      int nb_frames = frame_size/freq_size;
266
0
      celt_assert(nb_frames*freq_size == frame_size);
267
0
      OPUS_COPY(in, mem+c*overlap, overlap);
268
0
      (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL);
269
0
      celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
270
0
#ifndef FIXED_POINT
271
0
      {
272
0
         opus_val32 sum;
273
0
         sum = celt_inner_prod(in, in, frame_size+overlap, 0);
274
0
         /* This should filter out both NaNs and ridiculous signals that could
275
0
            cause NaNs further down. */
276
0
         if (!(sum < 1e18f) || celt_isnan(sum))
277
0
         {
278
0
            OPUS_CLEAR(in, frame_size+overlap);
279
0
            preemph_mem[c] = 0;
280
0
         }
281
0
      }
282
0
#endif
283
0
      OPUS_CLEAR(bandE, 21);
284
0
      for (frame=0;frame<nb_frames;frame++)
285
0
      {
286
0
         opus_val32 tmpE[21];
287
0
         clt_mdct_forward(&celt_mode->mdct, in+960*frame, freq, celt_mode->window,
288
0
               overlap, celt_mode->maxLM-LM, 1, arch);
289
0
         if (upsample != 1)
290
0
         {
291
0
            int bound = freq_size/upsample;
292
0
            for (i=0;i<bound;i++)
293
0
               freq[i] *= upsample;
294
0
            for (;i<freq_size;i++)
295
0
               freq[i] = 0;
296
0
         }
297
0
298
0
         compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch);
299
0
         /* If we have multiple frames, take the max energy. */
300
0
         for (i=0;i<21;i++)
301
0
            bandE[i] = MAX32(bandE[i], tmpE[i]);
302
0
      }
303
0
      amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
304
0
      /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
305
0
      for (i=1;i<21;i++)
306
0
         bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT));
307
0
      for (i=19;i>=0;i--)
308
0
         bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT));
309
0
      if (pos[c]==1)
310
0
      {
311
0
         for (i=0;i<21;i++)
312
0
            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
313
0
      } else if (pos[c]==3)
314
0
      {
315
0
         for (i=0;i<21;i++)
316
0
            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
317
0
      } else if (pos[c]==2)
318
0
      {
319
0
         for (i=0;i<21;i++)
320
0
         {
321
0
            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
322
0
            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
323
0
         }
324
0
      }
325
#if 0
326
      for (i=0;i<21;i++)
327
         printf("%f ", bandLogE[21*c+i]);
328
      float sum=0;
329
      for (i=0;i<21;i++)
330
         sum += bandLogE[21*c+i];
331
      printf("%f ", sum/21);
332
#endif
333
0
      OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
334
0
   }
335
0
   for (i=0;i<21;i++)
336
0
      maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
337
0
   channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
338
0
   for (c=0;c<3;c++)
339
0
      for (i=0;i<21;i++)
340
0
         maskLogE[c][i] += channel_offset;
341
#if 0
342
   for (c=0;c<3;c++)
343
   {
344
      for (i=0;i<21;i++)
345
         printf("%f ", maskLogE[c][i]);
346
   }
347
#endif
348
0
   for (c=0;c<channels;c++)
349
0
   {
350
0
      opus_val16 *mask;
351
0
      if (pos[c]!=0)
352
0
      {
353
0
         mask = &maskLogE[pos[c]-1][0];
354
0
         for (i=0;i<21;i++)
355
0
            bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
356
0
      } else {
357
0
         for (i=0;i<21;i++)
358
0
            bandLogE[21*c+i] = 0;
359
0
      }
360
#if 0
361
      for (i=0;i<21;i++)
362
         printf("%f ", bandLogE[21*c+i]);
363
      printf("\n");
364
#endif
365
#if 0
366
      float sum=0;
367
      for (i=0;i<21;i++)
368
         sum += bandLogE[21*c+i];
369
      printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
370
      printf("\n");
371
#endif
372
   }
373
0
   RESTORE_STACK;
374
0
}
375
376
opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
377
0
{
378
0
   int coupled_size;
379
0
   int mono_size;
380
0
381
0
   if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
382
0
   coupled_size = opus_encoder_get_size(2);
383
0
   mono_size = opus_encoder_get_size(1);
384
0
   return align(sizeof(OpusMSEncoder))
385
0
        + nb_coupled_streams * align(coupled_size)
386
0
        + (nb_streams-nb_coupled_streams) * align(mono_size);
387
0
}
388
389
opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)
390
0
{
391
0
   int nb_streams;
392
0
   int nb_coupled_streams;
393
0
   opus_int32 size;
394
0
395
0
   if (mapping_family==0)
396
0
   {
397
0
      if (channels==1)
398
0
      {
399
0
         nb_streams=1;
400
0
         nb_coupled_streams=0;
401
0
      } else if (channels==2)
402
0
      {
403
0
         nb_streams=1;
404
0
         nb_coupled_streams=1;
405
0
      } else
406
0
         return 0;
407
0
   } else if (mapping_family==1 && channels<=8 && channels>=1)
408
0
   {
409
0
      nb_streams=vorbis_mappings[channels-1].nb_streams;
410
0
      nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
411
0
   } else if (mapping_family==255)
412
0
   {
413
0
      nb_streams=channels;
414
0
      nb_coupled_streams=0;
415
0
   } else if (mapping_family==2)
416
0
   {
417
0
      if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams))
418
0
         return 0;
419
0
   } else
420
0
      return 0;
421
0
   size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
422
0
   if (channels>2)
423
0
   {
424
0
      size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32));
425
0
   }
426
0
   return size;
427
0
}
428
429
static int opus_multistream_encoder_init_impl(
430
      OpusMSEncoder *st,
431
      opus_int32 Fs,
432
      int channels,
433
      int streams,
434
      int coupled_streams,
435
      const unsigned char *mapping,
436
      int application,
437
      MappingType mapping_type
438
)
439
0
{
440
0
   int coupled_size;
441
0
   int mono_size;
442
0
   int i, ret;
443
0
   char *ptr;
444
0
445
0
   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
446
0
       (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
447
0
      return OPUS_BAD_ARG;
448
0
449
0
   st->arch = opus_select_arch();
450
0
   st->layout.nb_channels = channels;
451
0
   st->layout.nb_streams = streams;
452
0
   st->layout.nb_coupled_streams = coupled_streams;
453
0
   if (mapping_type != MAPPING_TYPE_SURROUND)
454
0
      st->lfe_stream = -1;
455
0
   st->bitrate_bps = OPUS_AUTO;
456
0
   st->application = application;
457
0
   st->variable_duration = OPUS_FRAMESIZE_ARG;
458
0
   for (i=0;i<st->layout.nb_channels;i++)
459
0
      st->layout.mapping[i] = mapping[i];
460
0
   if (!validate_layout(&st->layout))
461
0
      return OPUS_BAD_ARG;
462
0
   if (mapping_type == MAPPING_TYPE_SURROUND &&
463
0
       !validate_encoder_layout(&st->layout))
464
0
      return OPUS_BAD_ARG;
465
0
   if (mapping_type == MAPPING_TYPE_AMBISONICS &&
466
0
       !validate_ambisonics(st->layout.nb_channels, NULL, NULL))
467
0
      return OPUS_BAD_ARG;
468
0
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
469
0
   coupled_size = opus_encoder_get_size(2);
470
0
   mono_size = opus_encoder_get_size(1);
471
0
472
0
   for (i=0;i<st->layout.nb_coupled_streams;i++)
473
0
   {
474
0
      ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
475
0
      if(ret!=OPUS_OK)return ret;
476
0
      if (i==st->lfe_stream)
477
0
         opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
478
0
      ptr += align(coupled_size);
479
0
   }
480
0
   for (;i<st->layout.nb_streams;i++)
481
0
   {
482
0
      ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
483
0
      if (i==st->lfe_stream)
484
0
         opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
485
0
      if(ret!=OPUS_OK)return ret;
486
0
      ptr += align(mono_size);
487
0
   }
488
0
   if (mapping_type == MAPPING_TYPE_SURROUND)
489
0
   {
490
0
      OPUS_CLEAR(ms_get_preemph_mem(st), channels);
491
0
      OPUS_CLEAR(ms_get_window_mem(st), channels*120);
492
0
   }
493
0
   st->mapping_type = mapping_type;
494
0
   return OPUS_OK;
495
0
}
496
497
int opus_multistream_encoder_init(
498
      OpusMSEncoder *st,
499
      opus_int32 Fs,
500
      int channels,
501
      int streams,
502
      int coupled_streams,
503
      const unsigned char *mapping,
504
      int application
505
)
506
0
{
507
0
   return opus_multistream_encoder_init_impl(st, Fs, channels, streams,
508
0
                                             coupled_streams, mapping,
509
0
                                             application, MAPPING_TYPE_NONE);
510
0
}
511
512
int opus_multistream_surround_encoder_init(
513
      OpusMSEncoder *st,
514
      opus_int32 Fs,
515
      int channels,
516
      int mapping_family,
517
      int *streams,
518
      int *coupled_streams,
519
      unsigned char *mapping,
520
      int application
521
)
522
0
{
523
0
   MappingType mapping_type;
524
0
525
0
   if ((channels>255) || (channels<1))
526
0
      return OPUS_BAD_ARG;
527
0
   st->lfe_stream = -1;
528
0
   if (mapping_family==0)
529
0
   {
530
0
      if (channels==1)
531
0
      {
532
0
         *streams=1;
533
0
         *coupled_streams=0;
534
0
         mapping[0]=0;
535
0
      } else if (channels==2)
536
0
      {
537
0
         *streams=1;
538
0
         *coupled_streams=1;
539
0
         mapping[0]=0;
540
0
         mapping[1]=1;
541
0
      } else
542
0
         return OPUS_UNIMPLEMENTED;
543
0
   } else if (mapping_family==1 && channels<=8 && channels>=1)
544
0
   {
545
0
      int i;
546
0
      *streams=vorbis_mappings[channels-1].nb_streams;
547
0
      *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
548
0
      for (i=0;i<channels;i++)
549
0
         mapping[i] = vorbis_mappings[channels-1].mapping[i];
550
0
      if (channels>=6)
551
0
         st->lfe_stream = *streams-1;
552
0
   } else if (mapping_family==255)
553
0
   {
554
0
      int i;
555
0
      *streams=channels;
556
0
      *coupled_streams=0;
557
0
      for(i=0;i<channels;i++)
558
0
         mapping[i] = i;
559
0
   } else if (mapping_family==2)
560
0
   {
561
0
      int i;
562
0
      if (!validate_ambisonics(channels, streams, coupled_streams))
563
0
         return OPUS_BAD_ARG;
564
0
      for(i = 0; i < (*streams - *coupled_streams); i++)
565
0
         mapping[i] = i + (*coupled_streams * 2);
566
0
      for(i = 0; i < *coupled_streams * 2; i++)
567
0
         mapping[i + (*streams - *coupled_streams)] = i;
568
0
   } else
569
0
      return OPUS_UNIMPLEMENTED;
570
0
571
0
   if (channels>2 && mapping_family==1) {
572
0
      mapping_type = MAPPING_TYPE_SURROUND;
573
0
   } else if (mapping_family==2)
574
0
   {
575
0
      mapping_type = MAPPING_TYPE_AMBISONICS;
576
0
   } else
577
0
   {
578
0
      mapping_type = MAPPING_TYPE_NONE;
579
0
   }
580
0
   return opus_multistream_encoder_init_impl(st, Fs, channels, *streams,
581
0
                                             *coupled_streams, mapping,
582
0
                                             application, mapping_type);
583
0
}
584
585
OpusMSEncoder *opus_multistream_encoder_create(
586
      opus_int32 Fs,
587
      int channels,
588
      int streams,
589
      int coupled_streams,
590
      const unsigned char *mapping,
591
      int application,
592
      int *error
593
)
594
0
{
595
0
   int ret;
596
0
   OpusMSEncoder *st;
597
0
   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
598
0
       (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
599
0
   {
600
0
      if (error)
601
0
         *error = OPUS_BAD_ARG;
602
0
      return NULL;
603
0
   }
604
0
   st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
605
0
   if (st==NULL)
606
0
   {
607
0
      if (error)
608
0
         *error = OPUS_ALLOC_FAIL;
609
0
      return NULL;
610
0
   }
611
0
   ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
612
0
   if (ret != OPUS_OK)
613
0
   {
614
0
      opus_free(st);
615
0
      st = NULL;
616
0
   }
617
0
   if (error)
618
0
      *error = ret;
619
0
   return st;
620
0
}
621
622
OpusMSEncoder *opus_multistream_surround_encoder_create(
623
      opus_int32 Fs,
624
      int channels,
625
      int mapping_family,
626
      int *streams,
627
      int *coupled_streams,
628
      unsigned char *mapping,
629
      int application,
630
      int *error
631
)
632
0
{
633
0
   int ret;
634
0
   opus_int32 size;
635
0
   OpusMSEncoder *st;
636
0
   if ((channels>255) || (channels<1))
637
0
   {
638
0
      if (error)
639
0
         *error = OPUS_BAD_ARG;
640
0
      return NULL;
641
0
   }
642
0
   size = opus_multistream_surround_encoder_get_size(channels, mapping_family);
643
0
   if (!size)
644
0
   {
645
0
      if (error)
646
0
         *error = OPUS_UNIMPLEMENTED;
647
0
      return NULL;
648
0
   }
649
0
   st = (OpusMSEncoder *)opus_alloc(size);
650
0
   if (st==NULL)
651
0
   {
652
0
      if (error)
653
0
         *error = OPUS_ALLOC_FAIL;
654
0
      return NULL;
655
0
   }
656
0
   ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
657
0
   if (ret != OPUS_OK)
658
0
   {
659
0
      opus_free(st);
660
0
      st = NULL;
661
0
   }
662
0
   if (error)
663
0
      *error = ret;
664
0
   return st;
665
0
}
666
667
static void surround_rate_allocation(
668
      OpusMSEncoder *st,
669
      opus_int32 *rate,
670
      int frame_size,
671
      opus_int32 Fs
672
      )
673
0
{
674
0
   int i;
675
0
   opus_int32 channel_rate;
676
0
   int stream_offset;
677
0
   int lfe_offset;
678
0
   int coupled_ratio; /* Q8 */
679
0
   int lfe_ratio;     /* Q8 */
680
0
   int nb_lfe;
681
0
   int nb_uncoupled;
682
0
   int nb_coupled;
683
0
   int nb_normal;
684
0
   opus_int32 channel_offset;
685
0
   opus_int32 bitrate;
686
0
   int total;
687
0
688
0
   nb_lfe = (st->lfe_stream!=-1);
689
0
   nb_coupled = st->layout.nb_coupled_streams;
690
0
   nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
691
0
   nb_normal = 2*nb_coupled + nb_uncoupled;
692
0
693
0
   /* Give each non-LFE channel enough bits per channel for coding band energy. */
694
0
   channel_offset = 40*IMAX(50, Fs/frame_size);
695
0
696
0
   if (st->bitrate_bps==OPUS_AUTO)
697
0
   {
698
0
      bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe;
699
0
   } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
700
0
   {
701
0
      bitrate = nb_normal*300000 + nb_lfe*128000;
702
0
   } else {
703
0
      bitrate = st->bitrate_bps;
704
0
   }
705
0
706
0
   /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the
707
0
      total rate for the non-energy part to avoid problems at really low rate. */
708
0
   lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size);
709
0
710
0
   /* We give each stream (coupled or uncoupled) a starting bitrate.
711
0
      This models the main saving of coupled channels over uncoupled. */
712
0
   stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2;
713
0
   stream_offset = IMAX(0, IMIN(20000, stream_offset));
714
0
715
0
   /* Coupled streams get twice the mono rate after the offset is allocated. */
716
0
   coupled_ratio = 512;
717
0
   /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
718
0
   lfe_ratio = 32;
719
0
720
0
   total = (nb_uncoupled<<8)         /* mono */
721
0
         + coupled_ratio*nb_coupled /* stereo */
722
0
         + nb_lfe*lfe_ratio;
723
0
   channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total;
724
0
725
0
   for (i=0;i<st->layout.nb_streams;i++)
726
0
   {
727
0
      if (i<st->layout.nb_coupled_streams)
728
0
         rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8));
729
0
      else if (i!=st->lfe_stream)
730
0
         rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate);
731
0
      else
732
0
         rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8));
733
0
   }
734
0
}
735
736
static void ambisonics_rate_allocation(
737
      OpusMSEncoder *st,
738
      opus_int32 *rate,
739
      int frame_size,
740
      opus_int32 Fs
741
      )
742
0
{
743
0
   int i;
744
0
   opus_int32 total_rate;
745
0
   opus_int32 per_stream_rate;
746
0
747
0
   const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
748
0
749
0
   if (st->bitrate_bps==OPUS_AUTO)
750
0
   {
751
0
      total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) *
752
0
         (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000;
753
0
   } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
754
0
   {
755
0
      total_rate = nb_channels * 320000;
756
0
   } else
757
0
   {
758
0
      total_rate = st->bitrate_bps;
759
0
   }
760
0
761
0
   /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic
762
0
    * (coupled) streams */
763
0
   per_stream_rate = total_rate / st->layout.nb_streams;
764
0
   for (i = 0; i < st->layout.nb_streams; i++)
765
0
   {
766
0
     rate[i] = per_stream_rate;
767
0
   }
768
0
}
769
770
static opus_int32 rate_allocation(
771
      OpusMSEncoder *st,
772
      opus_int32 *rate,
773
      int frame_size
774
      )
775
0
{
776
0
   int i;
777
0
   opus_int32 rate_sum=0;
778
0
   opus_int32 Fs;
779
0
   char *ptr;
780
0
781
0
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
782
0
   opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
783
0
784
0
   if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
785
0
     ambisonics_rate_allocation(st, rate, frame_size, Fs);
786
0
   } else
787
0
   {
788
0
     surround_rate_allocation(st, rate, frame_size, Fs);
789
0
   }
790
0
791
0
   for (i=0;i<st->layout.nb_streams;i++)
792
0
   {
793
0
      rate[i] = IMAX(rate[i], 500);
794
0
      rate_sum += rate[i];
795
0
   }
796
0
   return rate_sum;
797
0
}
798
799
/* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */
800
#define MS_FRAME_TMP (6*1275+12)
801
int opus_multistream_encode_native
802
(
803
    OpusMSEncoder *st,
804
    opus_copy_channel_in_func copy_channel_in,
805
    const void *pcm,
806
    int analysis_frame_size,
807
    unsigned char *data,
808
    opus_int32 max_data_bytes,
809
    int lsb_depth,
810
    downmix_func downmix,
811
    int float_api,
812
    void *user_data
813
)
814
0
{
815
0
   opus_int32 Fs;
816
0
   int coupled_size;
817
0
   int mono_size;
818
0
   int s;
819
0
   char *ptr;
820
0
   int tot_size;
821
0
   VARDECL(opus_val16, buf);
822
0
   VARDECL(opus_val16, bandSMR);
823
0
   unsigned char tmp_data[MS_FRAME_TMP];
824
0
   OpusRepacketizer rp;
825
0
   opus_int32 vbr;
826
0
   const CELTMode *celt_mode;
827
0
   opus_int32 bitrates[256];
828
0
   opus_val16 bandLogE[42];
829
0
   opus_val32 *mem = NULL;
830
0
   opus_val32 *preemph_mem=NULL;
831
0
   int frame_size;
832
0
   opus_int32 rate_sum;
833
0
   opus_int32 smallest_packet;
834
0
   ALLOC_STACK;
835
0
836
0
   if (st->mapping_type == MAPPING_TYPE_SURROUND)
837
0
   {
838
0
      preemph_mem = ms_get_preemph_mem(st);
839
0
      mem = ms_get_window_mem(st);
840
0
   }
841
0
842
0
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
843
0
   opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
844
0
   opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
845
0
   opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
846
0
847
0
   frame_size = frame_size_select(analysis_frame_size, st->variable_duration, Fs);
848
0
   if (frame_size <= 0)
849
0
   {
850
0
      RESTORE_STACK;
851
0
      return OPUS_BAD_ARG;
852
0
   }
853
0
854
0
   /* Smallest packet the encoder can produce. */
855
0
   smallest_packet = st->layout.nb_streams*2-1;
856
0
   /* 100 ms needs an extra byte per stream for the ToC. */
857
0
   if (Fs/frame_size == 10)
858
0
     smallest_packet += st->layout.nb_streams;
859
0
   if (max_data_bytes < smallest_packet)
860
0
   {
861
0
      RESTORE_STACK;
862
0
      return OPUS_BUFFER_TOO_SMALL;
863
0
   }
864
0
   ALLOC(buf, 2*frame_size, opus_val16);
865
0
   coupled_size = opus_encoder_get_size(2);
866
0
   mono_size = opus_encoder_get_size(1);
867
0
868
0
   ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
869
0
   if (st->mapping_type == MAPPING_TYPE_SURROUND)
870
0
   {
871
0
      surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch);
872
0
   }
873
0
874
0
   /* Compute bitrate allocation between streams (this could be a lot better) */
875
0
   rate_sum = rate_allocation(st, bitrates, frame_size);
876
0
877
0
   if (!vbr)
878
0
   {
879
0
      if (st->bitrate_bps == OPUS_AUTO)
880
0
      {
881
0
         max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size));
882
0
      } else if (st->bitrate_bps != OPUS_BITRATE_MAX)
883
0
      {
884
0
         max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,
885
0
                          3*st->bitrate_bps/(3*8*Fs/frame_size)));
886
0
      }
887
0
   }
888
0
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
889
0
   for (s=0;s<st->layout.nb_streams;s++)
890
0
   {
891
0
      OpusEncoder *enc;
892
0
      enc = (OpusEncoder*)ptr;
893
0
      if (s < st->layout.nb_coupled_streams)
894
0
         ptr += align(coupled_size);
895
0
      else
896
0
         ptr += align(mono_size);
897
0
      opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
898
0
      if (st->mapping_type == MAPPING_TYPE_SURROUND)
899
0
      {
900
0
         opus_int32 equiv_rate;
901
0
         equiv_rate = st->bitrate_bps;
902
0
         if (frame_size*50 < Fs)
903
0
            equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
904
0
         if (equiv_rate > 10000*st->layout.nb_channels)
905
0
            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
906
0
         else if (equiv_rate > 7000*st->layout.nb_channels)
907
0
            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
908
0
         else if (equiv_rate > 5000*st->layout.nb_channels)
909
0
            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
910
0
         else
911
0
            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
912
0
         if (s < st->layout.nb_coupled_streams)
913
0
         {
914
0
            /* To preserve the spatial image, force stereo CELT on coupled streams */
915
0
            opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
916
0
            opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
917
0
         }
918
0
      }
919
0
      else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
920
0
        opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
921
0
      }
922
0
   }
923
0
924
0
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
925
0
   /* Counting ToC */
926
0
   tot_size = 0;
927
0
   for (s=0;s<st->layout.nb_streams;s++)
928
0
   {
929
0
      OpusEncoder *enc;
930
0
      int len;
931
0
      int curr_max;
932
0
      int c1, c2;
933
0
      int ret;
934
0
935
0
      opus_repacketizer_init(&rp);
936
0
      enc = (OpusEncoder*)ptr;
937
0
      if (s < st->layout.nb_coupled_streams)
938
0
      {
939
0
         int i;
940
0
         int left, right;
941
0
         left = get_left_channel(&st->layout, s, -1);
942
0
         right = get_right_channel(&st->layout, s, -1);
943
0
         (*copy_channel_in)(buf, 2,
944
0
            pcm, st->layout.nb_channels, left, frame_size, user_data);
945
0
         (*copy_channel_in)(buf+1, 2,
946
0
            pcm, st->layout.nb_channels, right, frame_size, user_data);
947
0
         ptr += align(coupled_size);
948
0
         if (st->mapping_type == MAPPING_TYPE_SURROUND)
949
0
         {
950
0
            for (i=0;i<21;i++)
951
0
            {
952
0
               bandLogE[i] = bandSMR[21*left+i];
953
0
               bandLogE[21+i] = bandSMR[21*right+i];
954
0
            }
955
0
         }
956
0
         c1 = left;
957
0
         c2 = right;
958
0
      } else {
959
0
         int i;
960
0
         int chan = get_mono_channel(&st->layout, s, -1);
961
0
         (*copy_channel_in)(buf, 1,
962
0
            pcm, st->layout.nb_channels, chan, frame_size, user_data);
963
0
         ptr += align(mono_size);
964
0
         if (st->mapping_type == MAPPING_TYPE_SURROUND)
965
0
         {
966
0
            for (i=0;i<21;i++)
967
0
               bandLogE[i] = bandSMR[21*chan+i];
968
0
         }
969
0
         c1 = chan;
970
0
         c2 = -1;
971
0
      }
972
0
      if (st->mapping_type == MAPPING_TYPE_SURROUND)
973
0
         opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
974
0
      /* number of bytes left (+Toc) */
975
0
      curr_max = max_data_bytes - tot_size;
976
0
      /* Reserve one byte for the last stream and two for the others */
977
0
      curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
978
0
      /* For 100 ms, reserve an extra byte per stream for the ToC */
979
0
      if (Fs/frame_size == 10)
980
0
        curr_max -= st->layout.nb_streams-s-1;
981
0
      curr_max = IMIN(curr_max,MS_FRAME_TMP);
982
0
      /* Repacketizer will add one or two bytes for self-delimited frames */
983
0
      if (s != st->layout.nb_streams-1) curr_max -=  curr_max>253 ? 2 : 1;
984
0
      if (!vbr && s == st->layout.nb_streams-1)
985
0
         opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
986
0
      len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
987
0
            pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
988
0
      if (len<0)
989
0
      {
990
0
         RESTORE_STACK;
991
0
         return len;
992
0
      }
993
0
      /* We need to use the repacketizer to add the self-delimiting lengths
994
0
         while taking into account the fact that the encoder can now return
995
0
         more than one frame at a time (e.g. 60 ms CELT-only) */
996
0
      ret = opus_repacketizer_cat(&rp, tmp_data, len);
997
0
      /* If the opus_repacketizer_cat() fails, then something's seriously wrong
998
0
         with the encoder. */
999
0
      if (ret != OPUS_OK)
1000
0
      {
1001
0
         RESTORE_STACK;
1002
0
         return OPUS_INTERNAL_ERROR;
1003
0
      }
1004
0
      len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
1005
0
            data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1);
1006
0
      data += len;
1007
0
      tot_size += len;
1008
0
   }
1009
0
   /*printf("\n");*/
1010
0
   RESTORE_STACK;
1011
0
   return tot_size;
1012
0
}
1013
1014
#if !defined(DISABLE_FLOAT_API)
1015
static void opus_copy_channel_in_float(
1016
  opus_val16 *dst,
1017
  int dst_stride,
1018
  const void *src,
1019
  int src_stride,
1020
  int src_channel,
1021
  int frame_size,
1022
  void *user_data
1023
)
1024
0
{
1025
0
   const float *float_src;
1026
0
   opus_int32 i;
1027
0
   (void)user_data;
1028
0
   float_src = (const float *)src;
1029
0
   for (i=0;i<frame_size;i++)
1030
#if defined(FIXED_POINT)
1031
      dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
1032
#else
1033
0
      dst[i*dst_stride] = float_src[i*src_stride+src_channel];
1034
0
#endif
1035
0
}
1036
#endif
1037
1038
static void opus_copy_channel_in_short(
1039
  opus_val16 *dst,
1040
  int dst_stride,
1041
  const void *src,
1042
  int src_stride,
1043
  int src_channel,
1044
  int frame_size,
1045
  void *user_data
1046
)
1047
0
{
1048
0
   const opus_int16 *short_src;
1049
0
   opus_int32 i;
1050
0
   (void)user_data;
1051
0
   short_src = (const opus_int16 *)src;
1052
0
   for (i=0;i<frame_size;i++)
1053
#if defined(FIXED_POINT)
1054
      dst[i*dst_stride] = short_src[i*src_stride+src_channel];
1055
#else
1056
0
      dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
1057
0
#endif
1058
0
}
1059
1060
1061
#ifdef FIXED_POINT
1062
int opus_multistream_encode(
1063
    OpusMSEncoder *st,
1064
    const opus_val16 *pcm,
1065
    int frame_size,
1066
    unsigned char *data,
1067
    opus_int32 max_data_bytes
1068
)
1069
{
1070
   return opus_multistream_encode_native(st, opus_copy_channel_in_short,
1071
      pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
1072
}
1073
1074
#ifndef DISABLE_FLOAT_API
1075
int opus_multistream_encode_float(
1076
    OpusMSEncoder *st,
1077
    const float *pcm,
1078
    int frame_size,
1079
    unsigned char *data,
1080
    opus_int32 max_data_bytes
1081
)
1082
{
1083
   return opus_multistream_encode_native(st, opus_copy_channel_in_float,
1084
      pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1, NULL);
1085
}
1086
#endif
1087
1088
#else
1089
1090
int opus_multistream_encode_float
1091
(
1092
    OpusMSEncoder *st,
1093
    const opus_val16 *pcm,
1094
    int frame_size,
1095
    unsigned char *data,
1096
    opus_int32 max_data_bytes
1097
)
1098
0
{
1099
0
   return opus_multistream_encode_native(st, opus_copy_channel_in_float,
1100
0
      pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1, NULL);
1101
0
}
1102
1103
int opus_multistream_encode(
1104
    OpusMSEncoder *st,
1105
    const opus_int16 *pcm,
1106
    int frame_size,
1107
    unsigned char *data,
1108
    opus_int32 max_data_bytes
1109
)
1110
0
{
1111
0
   return opus_multistream_encode_native(st, opus_copy_channel_in_short,
1112
0
      pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
1113
0
}
1114
#endif
1115
1116
int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
1117
                                         va_list ap)
1118
0
{
1119
0
   int coupled_size, mono_size;
1120
0
   char *ptr;
1121
0
   int ret = OPUS_OK;
1122
0
1123
0
   coupled_size = opus_encoder_get_size(2);
1124
0
   mono_size = opus_encoder_get_size(1);
1125
0
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
1126
0
   switch (request)
1127
0
   {
1128
0
   case OPUS_SET_BITRATE_REQUEST:
1129
0
   {
1130
0
      opus_int32 value = va_arg(ap, opus_int32);
1131
0
      if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
1132
0
      {
1133
0
         if (value <= 0)
1134
0
            goto bad_arg;
1135
0
         value = IMIN(300000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value));
1136
0
      }
1137
0
      st->bitrate_bps = value;
1138
0
   }
1139
0
   break;
1140
0
   case OPUS_GET_BITRATE_REQUEST:
1141
0
   {
1142
0
      int s;
1143
0
      opus_int32 *value = va_arg(ap, opus_int32*);
1144
0
      if (!value)
1145
0
      {
1146
0
         goto bad_arg;
1147
0
      }
1148
0
      *value = 0;
1149
0
      for (s=0;s<st->layout.nb_streams;s++)
1150
0
      {
1151
0
         opus_int32 rate;
1152
0
         OpusEncoder *enc;
1153
0
         enc = (OpusEncoder*)ptr;
1154
0
         if (s < st->layout.nb_coupled_streams)
1155
0
            ptr += align(coupled_size);
1156
0
         else
1157
0
            ptr += align(mono_size);
1158
0
         opus_encoder_ctl(enc, request, &rate);
1159
0
         *value += rate;
1160
0
      }
1161
0
   }
1162
0
   break;
1163
0
   case OPUS_GET_LSB_DEPTH_REQUEST:
1164
0
   case OPUS_GET_VBR_REQUEST:
1165
0
   case OPUS_GET_APPLICATION_REQUEST:
1166
0
   case OPUS_GET_BANDWIDTH_REQUEST:
1167
0
   case OPUS_GET_COMPLEXITY_REQUEST:
1168
0
   case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1169
0
   case OPUS_GET_DTX_REQUEST:
1170
0
   case OPUS_GET_VOICE_RATIO_REQUEST:
1171
0
   case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1172
0
   case OPUS_GET_SIGNAL_REQUEST:
1173
0
   case OPUS_GET_LOOKAHEAD_REQUEST:
1174
0
   case OPUS_GET_SAMPLE_RATE_REQUEST:
1175
0
   case OPUS_GET_INBAND_FEC_REQUEST:
1176
0
   case OPUS_GET_FORCE_CHANNELS_REQUEST:
1177
0
   case OPUS_GET_PREDICTION_DISABLED_REQUEST:
1178
0
   case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
1179
0
   {
1180
0
      OpusEncoder *enc;
1181
0
      /* For int32* GET params, just query the first stream */
1182
0
      opus_int32 *value = va_arg(ap, opus_int32*);
1183
0
      enc = (OpusEncoder*)ptr;
1184
0
      ret = opus_encoder_ctl(enc, request, value);
1185
0
   }
1186
0
   break;
1187
0
   case OPUS_GET_FINAL_RANGE_REQUEST:
1188
0
   {
1189
0
      int s;
1190
0
      opus_uint32 *value = va_arg(ap, opus_uint32*);
1191
0
      opus_uint32 tmp;
1192
0
      if (!value)
1193
0
      {
1194
0
         goto bad_arg;
1195
0
      }
1196
0
      *value=0;
1197
0
      for (s=0;s<st->layout.nb_streams;s++)
1198
0
      {
1199
0
         OpusEncoder *enc;
1200
0
         enc = (OpusEncoder*)ptr;
1201
0
         if (s < st->layout.nb_coupled_streams)
1202
0
            ptr += align(coupled_size);
1203
0
         else
1204
0
            ptr += align(mono_size);
1205
0
         ret = opus_encoder_ctl(enc, request, &tmp);
1206
0
         if (ret != OPUS_OK) break;
1207
0
         *value ^= tmp;
1208
0
      }
1209
0
   }
1210
0
   break;
1211
0
   case OPUS_SET_LSB_DEPTH_REQUEST:
1212
0
   case OPUS_SET_COMPLEXITY_REQUEST:
1213
0
   case OPUS_SET_VBR_REQUEST:
1214
0
   case OPUS_SET_VBR_CONSTRAINT_REQUEST:
1215
0
   case OPUS_SET_MAX_BANDWIDTH_REQUEST:
1216
0
   case OPUS_SET_BANDWIDTH_REQUEST:
1217
0
   case OPUS_SET_SIGNAL_REQUEST:
1218
0
   case OPUS_SET_APPLICATION_REQUEST:
1219
0
   case OPUS_SET_INBAND_FEC_REQUEST:
1220
0
   case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1221
0
   case OPUS_SET_DTX_REQUEST:
1222
0
   case OPUS_SET_FORCE_MODE_REQUEST:
1223
0
   case OPUS_SET_FORCE_CHANNELS_REQUEST:
1224
0
   case OPUS_SET_PREDICTION_DISABLED_REQUEST:
1225
0
   case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
1226
0
   {
1227
0
      int s;
1228
0
      /* This works for int32 params */
1229
0
      opus_int32 value = va_arg(ap, opus_int32);
1230
0
      for (s=0;s<st->layout.nb_streams;s++)
1231
0
      {
1232
0
         OpusEncoder *enc;
1233
0
1234
0
         enc = (OpusEncoder*)ptr;
1235
0
         if (s < st->layout.nb_coupled_streams)
1236
0
            ptr += align(coupled_size);
1237
0
         else
1238
0
            ptr += align(mono_size);
1239
0
         ret = opus_encoder_ctl(enc, request, value);
1240
0
         if (ret != OPUS_OK)
1241
0
            break;
1242
0
      }
1243
0
   }
1244
0
   break;
1245
0
   case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1246
0
   {
1247
0
      int s;
1248
0
      opus_int32 stream_id;
1249
0
      OpusEncoder **value;
1250
0
      stream_id = va_arg(ap, opus_int32);
1251
0
      if (stream_id<0 || stream_id >= st->layout.nb_streams)
1252
0
         ret = OPUS_BAD_ARG;
1253
0
      value = va_arg(ap, OpusEncoder**);
1254
0
      if (!value)
1255
0
      {
1256
0
         goto bad_arg;
1257
0
      }
1258
0
      for (s=0;s<stream_id;s++)
1259
0
      {
1260
0
         if (s < st->layout.nb_coupled_streams)
1261
0
            ptr += align(coupled_size);
1262
0
         else
1263
0
            ptr += align(mono_size);
1264
0
      }
1265
0
      *value = (OpusEncoder*)ptr;
1266
0
   }
1267
0
   break;
1268
0
   case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
1269
0
   {
1270
0
       opus_int32 value = va_arg(ap, opus_int32);
1271
0
       st->variable_duration = value;
1272
0
   }
1273
0
   break;
1274
0
   case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
1275
0
   {
1276
0
       opus_int32 *value = va_arg(ap, opus_int32*);
1277
0
       if (!value)
1278
0
       {
1279
0
          goto bad_arg;
1280
0
       }
1281
0
       *value = st->variable_duration;
1282
0
   }
1283
0
   break;
1284
0
   case OPUS_RESET_STATE:
1285
0
   {
1286
0
      int s;
1287
0
      if (st->mapping_type == MAPPING_TYPE_SURROUND)
1288
0
      {
1289
0
         OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1290
0
         OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
1291
0
      }
1292
0
      for (s=0;s<st->layout.nb_streams;s++)
1293
0
      {
1294
0
         OpusEncoder *enc;
1295
0
         enc = (OpusEncoder*)ptr;
1296
0
         if (s < st->layout.nb_coupled_streams)
1297
0
            ptr += align(coupled_size);
1298
0
         else
1299
0
            ptr += align(mono_size);
1300
0
         ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1301
0
         if (ret != OPUS_OK)
1302
0
            break;
1303
0
      }
1304
0
   }
1305
0
   break;
1306
0
   default:
1307
0
      ret = OPUS_UNIMPLEMENTED;
1308
0
      break;
1309
0
   }
1310
0
   return ret;
1311
0
bad_arg:
1312
0
   return OPUS_BAD_ARG;
1313
0
}
1314
1315
int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
1316
0
{
1317
0
   int ret;
1318
0
   va_list ap;
1319
0
   va_start(ap, request);
1320
0
   ret = opus_multistream_encoder_ctl_va_list(st, request, ap);
1321
0
   va_end(ap);
1322
0
   return ret;
1323
0
}
1324
1325
void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1326
0
{
1327
0
    opus_free(st);
1328
0
}