/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 | } |