Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(498)

Side by Side Diff: src/opus_multistream_encoder.c

Issue 28553003: Updating Opus to a pre-release of 1.1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/opus
Patch Set: Removing failing file Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/opus_multistream_decoder.c ('k') | src/opus_private.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
45 typedef struct {
46 int nb_streams;
47 int nb_coupled_streams;
48 unsigned char mapping[8];
49 } VorbisLayout;
50
51 /* Index is nb_channel-1*/
52 static const VorbisLayout vorbis_mappings[8] = {
53 {1, 0, {0}}, /* 1: mono */
54 {1, 1, {0, 1}}, /* 2: stereo */
55 {2, 1, {0, 2, 1}}, /* 3: 1-d surround */
56 {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */
57 {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */
58 {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */
59 {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */
60 {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */
61 };
62
63 typedef void (*opus_copy_channel_in_func)(
64 opus_val16 *dst,
65 int dst_stride,
66 const void *src,
67 int src_stride,
68 int src_channel,
69 int frame_size
70 );
71
72 struct OpusMSEncoder {
73 ChannelLayout layout;
74 int lfe_stream;
75 int application;
76 int variable_duration;
77 int surround;
78 opus_int32 bitrate_bps;
79 opus_val32 subframe_mem[3];
80 /* Encoder states go here */
81 /* then opus_val32 window_mem[channels*120]; */
82 /* then opus_val32 preemph_mem[channels]; */
83 };
84
85 static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st)
86 {
87 int s;
88 char *ptr;
89 int coupled_size, mono_size;
90
91 coupled_size = opus_encoder_get_size(2);
92 mono_size = opus_encoder_get_size(1);
93 ptr = (char*)st + align(sizeof(OpusMSEncoder));
94 for (s=0;s<st->layout.nb_streams;s++)
95 {
96 if (s < st->layout.nb_coupled_streams)
97 ptr += align(coupled_size);
98 else
99 ptr += align(mono_size);
100 }
101 return (opus_val32*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32));
102 }
103
104 static opus_val32 *ms_get_window_mem(OpusMSEncoder *st)
105 {
106 int s;
107 char *ptr;
108 int coupled_size, mono_size;
109
110 coupled_size = opus_encoder_get_size(2);
111 mono_size = opus_encoder_get_size(1);
112 ptr = (char*)st + align(sizeof(OpusMSEncoder));
113 for (s=0;s<st->layout.nb_streams;s++)
114 {
115 if (s < st->layout.nb_coupled_streams)
116 ptr += align(coupled_size);
117 else
118 ptr += align(mono_size);
119 }
120 return (opus_val32*)ptr;
121 }
122
123 static int validate_encoder_layout(const ChannelLayout *layout)
124 {
125 int s;
126 for (s=0;s<layout->nb_streams;s++)
127 {
128 if (s < layout->nb_coupled_streams)
129 {
130 if (get_left_channel(layout, s, -1)==-1)
131 return 0;
132 if (get_right_channel(layout, s, -1)==-1)
133 return 0;
134 } else {
135 if (get_mono_channel(layout, s, -1)==-1)
136 return 0;
137 }
138 }
139 return 1;
140 }
141
142 static void channel_pos(int channels, int pos[8])
143 {
144 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
145 if (channels==4)
146 {
147 pos[0]=1;
148 pos[1]=3;
149 pos[2]=1;
150 pos[3]=3;
151 } else if (channels==3||channels==5||channels==6)
152 {
153 pos[0]=1;
154 pos[1]=2;
155 pos[2]=3;
156 pos[3]=1;
157 pos[4]=3;
158 pos[5]=0;
159 } else if (channels==7)
160 {
161 pos[0]=1;
162 pos[1]=2;
163 pos[2]=3;
164 pos[3]=1;
165 pos[4]=3;
166 pos[5]=2;
167 pos[6]=0;
168 } else if (channels==8)
169 {
170 pos[0]=1;
171 pos[1]=2;
172 pos[2]=3;
173 pos[3]=1;
174 pos[4]=3;
175 pos[5]=1;
176 pos[6]=3;
177 pos[7]=0;
178 }
179 }
180
181 #if 1
182 /* Computes a rough approximation of log2(2^a + 2^b) */
183 static opus_val16 logSum(opus_val16 a, opus_val16 b)
184 {
185 opus_val16 max;
186 opus_val32 diff;
187 opus_val16 frac;
188 static const opus_val16 diff_table[17] = {
189 QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST1 6(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT),
190 QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST1 6(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT),
191 QCONST16(0.0028123f, DB_SHIFT)
192 };
193 int low;
194 if (a>b)
195 {
196 max = a;
197 diff = SUB32(EXTEND32(a),EXTEND32(b));
198 } else {
199 max = b;
200 diff = SUB32(EXTEND32(b),EXTEND32(a));
201 }
202 if (diff >= QCONST16(8.f, DB_SHIFT))
203 return max;
204 #ifdef FIXED_POINT
205 low = SHR32(diff, DB_SHIFT-1);
206 frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT);
207 #else
208 low = floor(2*diff);
209 frac = 2*diff - low;
210 #endif
211 return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], d iff_table[low]));
212 }
213 #else
214 opus_val16 logSum(opus_val16 a, opus_val16 b)
215 {
216 return log2(pow(4, a)+ pow(4, b))/2;
217 }
218 #endif
219
220 void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b andLogE, opus_val32 *mem, opus_val32 *preemph_mem,
221 int len, int overlap, int channels, int rate, opus_copy_channel_in_func co py_channel_in
222 )
223 {
224 int c;
225 int i;
226 int LM;
227 int pos[8] = {0};
228 int upsample;
229 int frame_size;
230 opus_val16 channel_offset;
231 opus_val32 bandE[21];
232 opus_val16 maskLogE[3][21];
233 VARDECL(opus_val32, in);
234 VARDECL(opus_val16, x);
235 VARDECL(opus_val32, freq);
236 SAVE_STACK;
237
238 upsample = resampling_factor(rate);
239 frame_size = len*upsample;
240
241 for (LM=0;LM<=celt_mode->maxLM;LM++)
242 if (celt_mode->shortMdctSize<<LM==frame_size)
243 break;
244
245 ALLOC(in, frame_size+overlap, opus_val32);
246 ALLOC(x, len, opus_val16);
247 ALLOC(freq, frame_size, opus_val32);
248
249 channel_pos(channels, pos);
250
251 for (c=0;c<3;c++)
252 for (i=0;i<21;i++)
253 maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT);
254
255 for (c=0;c<channels;c++)
256 {
257 OPUS_COPY(in, mem+c*overlap, overlap);
258 (*copy_channel_in)(x, 1, pcm, channels, c, len);
259 preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, pr eemph_mem+c, 0);
260 clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window, overlap, c elt_mode->maxLM-LM, 1);
261 if (upsample != 1)
262 {
263 int bound = len;
264 for (i=0;i<bound;i++)
265 freq[i] *= upsample;
266 for (;i<frame_size;i++)
267 freq[i] = 0;
268 }
269
270 compute_band_energies(celt_mode, freq, bandE, 21, 1, 1<<LM);
271 amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
272 /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
273 for (i=1;i<21;i++)
274 bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16( 1.f, DB_SHIFT));
275 for (i=19;i>=0;i--)
276 bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16( 2.f, DB_SHIFT));
277 if (pos[c]==1)
278 {
279 for (i=0;i<21;i++)
280 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
281 } else if (pos[c]==3)
282 {
283 for (i=0;i<21;i++)
284 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
285 } else if (pos[c]==2)
286 {
287 for (i=0;i<21;i++)
288 {
289 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5 f, DB_SHIFT));
290 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5 f, DB_SHIFT));
291 }
292 }
293 #if 0
294 for (i=0;i<21;i++)
295 printf("%f ", bandLogE[21*c+i]);
296 float sum=0;
297 for (i=0;i<21;i++)
298 sum += bandLogE[21*c+i];
299 printf("%f ", sum/21);
300 #endif
301 OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
302 }
303 for (i=0;i<21;i++)
304 maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
305 channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
306 for (c=0;c<3;c++)
307 for (i=0;i<21;i++)
308 maskLogE[c][i] += channel_offset;
309 #if 0
310 for (c=0;c<3;c++)
311 {
312 for (i=0;i<21;i++)
313 printf("%f ", maskLogE[c][i]);
314 }
315 #endif
316 for (c=0;c<channels;c++)
317 {
318 opus_val16 *mask;
319 if (pos[c]!=0)
320 {
321 mask = &maskLogE[pos[c]-1][0];
322 for (i=0;i<21;i++)
323 bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
324 } else {
325 for (i=0;i<21;i++)
326 bandLogE[21*c+i] = 0;
327 }
328 #if 0
329 for (i=0;i<21;i++)
330 printf("%f ", bandLogE[21*c+i]);
331 printf("\n");
332 #endif
333 #if 0
334 float sum=0;
335 for (i=0;i<21;i++)
336 sum += bandLogE[21*c+i];
337 printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
338 printf("\n");
339 #endif
340 }
341 RESTORE_STACK;
342 }
343
344 opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_stre ams)
345 {
346 int coupled_size;
347 int mono_size;
348
349 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0 ;
350 coupled_size = opus_encoder_get_size(2);
351 mono_size = opus_encoder_get_size(1);
352 return align(sizeof(OpusMSEncoder))
353 + nb_coupled_streams * align(coupled_size)
354 + (nb_streams-nb_coupled_streams) * align(mono_size);
355 }
356
357 opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_ family)
358 {
359 int nb_streams;
360 int nb_coupled_streams;
361 opus_int32 size;
362
363 if (mapping_family==0)
364 {
365 if (channels==1)
366 {
367 nb_streams=1;
368 nb_coupled_streams=0;
369 } else if (channels==2)
370 {
371 nb_streams=1;
372 nb_coupled_streams=1;
373 } else
374 return 0;
375 } else if (mapping_family==1 && channels<=8 && channels>=1)
376 {
377 nb_streams=vorbis_mappings[channels-1].nb_streams;
378 nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
379 } else if (mapping_family==255)
380 {
381 nb_streams=channels;
382 nb_coupled_streams=0;
383 } else
384 return 0;
385 size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
386 if (channels>2)
387 {
388 size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32));
389 }
390 return size;
391 }
392
393
394 static int opus_multistream_encoder_init_impl(
395 OpusMSEncoder *st,
396 opus_int32 Fs,
397 int channels,
398 int streams,
399 int coupled_streams,
400 const unsigned char *mapping,
401 int application,
402 int surround
403 )
404 {
405 int coupled_size;
406 int mono_size;
407 int i, ret;
408 char *ptr;
409
410 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
411 (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
412 return OPUS_BAD_ARG;
413
414 st->layout.nb_channels = channels;
415 st->layout.nb_streams = streams;
416 st->layout.nb_coupled_streams = coupled_streams;
417 st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
418 if (!surround)
419 st->lfe_stream = -1;
420 st->bitrate_bps = OPUS_AUTO;
421 st->application = application;
422 st->variable_duration = OPUS_FRAMESIZE_ARG;
423 for (i=0;i<st->layout.nb_channels;i++)
424 st->layout.mapping[i] = mapping[i];
425 if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
426 return OPUS_BAD_ARG;
427 ptr = (char*)st + align(sizeof(OpusMSEncoder));
428 coupled_size = opus_encoder_get_size(2);
429 mono_size = opus_encoder_get_size(1);
430
431 for (i=0;i<st->layout.nb_coupled_streams;i++)
432 {
433 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
434 if(ret!=OPUS_OK)return ret;
435 if (i==st->lfe_stream)
436 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
437 ptr += align(coupled_size);
438 }
439 for (;i<st->layout.nb_streams;i++)
440 {
441 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
442 if (i==st->lfe_stream)
443 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
444 if(ret!=OPUS_OK)return ret;
445 ptr += align(mono_size);
446 }
447 if (surround)
448 {
449 OPUS_CLEAR(ms_get_preemph_mem(st), channels);
450 OPUS_CLEAR(ms_get_window_mem(st), channels*120);
451 }
452 st->surround = surround;
453 return OPUS_OK;
454 }
455
456 int opus_multistream_encoder_init(
457 OpusMSEncoder *st,
458 opus_int32 Fs,
459 int channels,
460 int streams,
461 int coupled_streams,
462 const unsigned char *mapping,
463 int application
464 )
465 {
466 return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_ streams, mapping, application, 0);
467 }
468
469 int opus_multistream_surround_encoder_init(
470 OpusMSEncoder *st,
471 opus_int32 Fs,
472 int channels,
473 int mapping_family,
474 int *streams,
475 int *coupled_streams,
476 unsigned char *mapping,
477 int application
478 )
479 {
480 if ((channels>255) || (channels<1))
481 return OPUS_BAD_ARG;
482 st->lfe_stream = -1;
483 if (mapping_family==0)
484 {
485 if (channels==1)
486 {
487 *streams=1;
488 *coupled_streams=0;
489 mapping[0]=0;
490 } else if (channels==2)
491 {
492 *streams=1;
493 *coupled_streams=1;
494 mapping[0]=0;
495 mapping[1]=1;
496 } else
497 return OPUS_UNIMPLEMENTED;
498 } else if (mapping_family==1 && channels<=8 && channels>=1)
499 {
500 int i;
501 *streams=vorbis_mappings[channels-1].nb_streams;
502 *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
503 for (i=0;i<channels;i++)
504 mapping[i] = vorbis_mappings[channels-1].mapping[i];
505 if (channels>=6)
506 st->lfe_stream = *streams-1;
507 } else if (mapping_family==255)
508 {
509 int i;
510 *streams=channels;
511 *coupled_streams=0;
512 for(i=0;i<channels;i++)
513 mapping[i] = i;
514 } else
515 return OPUS_UNIMPLEMENTED;
516 return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *couple d_streams,
517 mapping, application, channels>2&&mapping_family==1);
518 }
519
520 OpusMSEncoder *opus_multistream_encoder_create(
521 opus_int32 Fs,
522 int channels,
523 int streams,
524 int coupled_streams,
525 const unsigned char *mapping,
526 int application,
527 int *error
528 )
529 {
530 int ret;
531 OpusMSEncoder *st;
532 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
533 (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
534 {
535 if (error)
536 *error = OPUS_BAD_ARG;
537 return NULL;
538 }
539 st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, c oupled_streams));
540 if (st==NULL)
541 {
542 if (error)
543 *error = OPUS_ALLOC_FAIL;
544 return NULL;
545 }
546 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_stream s, mapping, application);
547 if (ret != OPUS_OK)
548 {
549 opus_free(st);
550 st = NULL;
551 }
552 if (error)
553 *error = ret;
554 return st;
555 }
556
557 OpusMSEncoder *opus_multistream_surround_encoder_create(
558 opus_int32 Fs,
559 int channels,
560 int mapping_family,
561 int *streams,
562 int *coupled_streams,
563 unsigned char *mapping,
564 int application,
565 int *error
566 )
567 {
568 int ret;
569 OpusMSEncoder *st;
570 if ((channels>255) || (channels<1))
571 {
572 if (error)
573 *error = OPUS_BAD_ARG;
574 return NULL;
575 }
576 st = (OpusMSEncoder *)opus_alloc(opus_multistream_surround_encoder_get_size(c hannels, mapping_family));
577 if (st==NULL)
578 {
579 if (error)
580 *error = OPUS_ALLOC_FAIL;
581 return NULL;
582 }
583 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family , streams, coupled_streams, mapping, application);
584 if (ret != OPUS_OK)
585 {
586 opus_free(st);
587 st = NULL;
588 }
589 if (error)
590 *error = ret;
591 return st;
592 }
593
594 static void surround_rate_allocation(
595 OpusMSEncoder *st,
596 opus_int32 *rate,
597 int frame_size
598 )
599 {
600 int i;
601 opus_int32 channel_rate;
602 opus_int32 Fs;
603 char *ptr;
604 int stream_offset;
605 int lfe_offset;
606 int coupled_ratio; /* Q8 */
607 int lfe_ratio; /* Q8 */
608
609 ptr = (char*)st + align(sizeof(OpusMSEncoder));
610 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
611
612 if (st->bitrate_bps > st->layout.nb_channels*40000)
613 stream_offset = 20000;
614 else
615 stream_offset = st->bitrate_bps/st->layout.nb_channels/2;
616 /* We start by giving each stream (coupled or uncoupled) the same bitrate.
617 This models the main saving of coupled channels over uncoupled. */
618 /* The LFE stream is an exception to the above and gets fewer bits. */
619 lfe_offset = 3500;
620 /* Coupled streams get twice the mono rate after the first 20 kb/s. */
621 coupled_ratio = 512;
622 /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of m ono */
623 lfe_ratio = 32;
624
625 /* Compute bitrate allocation between streams */
626 if (st->bitrate_bps==OPUS_AUTO)
627 {
628 channel_rate = Fs+60*Fs/frame_size;
629 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
630 {
631 channel_rate = 300000;
632 } else {
633 int nb_lfe;
634 int nb_uncoupled;
635 int nb_coupled;
636 int total;
637 nb_lfe = (st->lfe_stream!=-1);
638 nb_coupled = st->layout.nb_coupled_streams;
639 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
640 total = (nb_uncoupled<<8) /* mono */
641 + coupled_ratio*nb_coupled /* stereo */
642 + nb_lfe*lfe_ratio;
643 channel_rate = 256*(st->bitrate_bps-lfe_offset*nb_lfe-stream_offset*(nb_co upled+nb_uncoupled))/total;
644 }
645 #ifndef FIXED_POINT
646 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
647 {
648 opus_int32 bonus;
649 bonus = 60*(Fs/frame_size-50);
650 channel_rate += bonus;
651 }
652 #endif
653
654 for (i=0;i<st->layout.nb_streams;i++)
655 {
656 if (i<st->layout.nb_coupled_streams)
657 rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
658 else if (i!=st->lfe_stream)
659 rate[i] = stream_offset+channel_rate;
660 else
661 rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
662 }
663 }
664
665 /* Max size in case the encoder decides to return three frames */
666 #define MS_FRAME_TMP (3*1275+7)
667 static int opus_multistream_encode_native
668 (
669 OpusMSEncoder *st,
670 opus_copy_channel_in_func copy_channel_in,
671 const void *pcm,
672 int analysis_frame_size,
673 unsigned char *data,
674 opus_int32 max_data_bytes,
675 int lsb_depth,
676 downmix_func downmix
677 )
678 {
679 opus_int32 Fs;
680 int coupled_size;
681 int mono_size;
682 int s;
683 char *ptr;
684 int tot_size;
685 VARDECL(opus_val16, buf);
686 VARDECL(opus_val16, bandSMR);
687 unsigned char tmp_data[MS_FRAME_TMP];
688 OpusRepacketizer rp;
689 opus_int32 complexity;
690 const CELTMode *celt_mode;
691 opus_int32 bitrates[256];
692 opus_val16 bandLogE[42];
693 opus_val32 *mem = NULL;
694 opus_val32 *preemph_mem=NULL;
695 int frame_size;
696 ALLOC_STACK;
697
698 if (st->surround)
699 {
700 preemph_mem = ms_get_preemph_mem(st);
701 mem = ms_get_window_mem(st);
702 }
703
704 ptr = (char*)st + align(sizeof(OpusMSEncoder));
705 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
706 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_COMPLEXITY(&complexity));
707 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
708
709 {
710 opus_int32 delay_compensation;
711 int channels;
712
713 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
714 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation ));
715 delay_compensation -= Fs/400;
716 frame_size = compute_frame_size(pcm, analysis_frame_size,
717 st->variable_duration, channels, Fs, st->bitrate_bps,
718 delay_compensation, downmix, st->subframe_mem);
719 }
720
721 if (400*frame_size < Fs)
722 {
723 RESTORE_STACK;
724 return OPUS_BAD_ARG;
725 }
726 /* Validate frame_size before using it to allocate stack space.
727 This mirrors the checks in opus_encode[_float](). */
728 if (400*frame_size != Fs && 200*frame_size != Fs &&
729 100*frame_size != Fs && 50*frame_size != Fs &&
730 25*frame_size != Fs && 50*frame_size != 3*Fs)
731 {
732 RESTORE_STACK;
733 return OPUS_BAD_ARG;
734 }
735 ALLOC(buf, 2*frame_size, opus_val16);
736 coupled_size = opus_encoder_get_size(2);
737 mono_size = opus_encoder_get_size(1);
738
739 ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
740 if (st->surround)
741 {
742 surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 1 20, st->layout.nb_channels, Fs, copy_channel_in);
743 }
744
745 if (max_data_bytes < 4*st->layout.nb_streams-1)
746 {
747 RESTORE_STACK;
748 return OPUS_BUFFER_TOO_SMALL;
749 }
750
751 /* Compute bitrate allocation between streams (this could be a lot better) */
752 surround_rate_allocation(st, bitrates, frame_size);
753
754 ptr = (char*)st + align(sizeof(OpusMSEncoder));
755 for (s=0;s<st->layout.nb_streams;s++)
756 {
757 OpusEncoder *enc;
758 enc = (OpusEncoder*)ptr;
759 if (s < st->layout.nb_coupled_streams)
760 ptr += align(coupled_size);
761 else
762 ptr += align(mono_size);
763 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
764 if (st->surround)
765 {
766 opus_int32 equiv_rate;
767 equiv_rate = st->bitrate_bps;
768 if (frame_size*50 < Fs)
769 equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
770 if (equiv_rate > 112000)
771 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
772 else if (equiv_rate > 76000)
773 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAN D));
774 else if (equiv_rate > 48000)
775 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
776 else
777 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)) ;
778 if (s < st->layout.nb_coupled_streams)
779 {
780 /* To preserve the spatial image, force stereo CELT on coupled strea ms */
781 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
782 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
783 }
784 }
785 }
786
787 ptr = (char*)st + align(sizeof(OpusMSEncoder));
788 /* Counting ToC */
789 tot_size = 0;
790 for (s=0;s<st->layout.nb_streams;s++)
791 {
792 OpusEncoder *enc;
793 int len;
794 int curr_max;
795 int c1, c2;
796
797 opus_repacketizer_init(&rp);
798 enc = (OpusEncoder*)ptr;
799 if (s < st->layout.nb_coupled_streams)
800 {
801 int i;
802 int left, right;
803 left = get_left_channel(&st->layout, s, -1);
804 right = get_right_channel(&st->layout, s, -1);
805 (*copy_channel_in)(buf, 2,
806 pcm, st->layout.nb_channels, left, frame_size);
807 (*copy_channel_in)(buf+1, 2,
808 pcm, st->layout.nb_channels, right, frame_size);
809 ptr += align(coupled_size);
810 if (st->surround)
811 {
812 for (i=0;i<21;i++)
813 {
814 bandLogE[i] = bandSMR[21*left+i];
815 bandLogE[21+i] = bandSMR[21*right+i];
816 }
817 }
818 c1 = left;
819 c2 = right;
820 } else {
821 int i;
822 int chan = get_mono_channel(&st->layout, s, -1);
823 (*copy_channel_in)(buf, 1,
824 pcm, st->layout.nb_channels, chan, frame_size);
825 ptr += align(mono_size);
826 if (st->surround)
827 {
828 for (i=0;i<21;i++)
829 bandLogE[i] = bandSMR[21*chan+i];
830 }
831 c1 = chan;
832 c2 = -1;
833 }
834 if (st->surround)
835 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
836 /* number of bytes left (+Toc) */
837 curr_max = max_data_bytes - tot_size;
838 /* Reserve three bytes for the last stream and four for the others */
839 curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
840 curr_max = IMIN(curr_max,MS_FRAME_TMP);
841 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_dep th,
842 pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix);
843 if (len<0)
844 {
845 RESTORE_STACK;
846 return len;
847 }
848 /* We need to use the repacketizer to add the self-delimiting lengths
849 while taking into account the fact that the encoder can now return
850 more than one frame at a time (e.g. 60 ms CELT-only) */
851 opus_repacketizer_cat(&rp, tmp_data, len);
852 len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_fr ames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1);
853 data += len;
854 tot_size += len;
855 }
856 /*printf("\n");*/
857 RESTORE_STACK;
858 return tot_size;
859
860 }
861
862 #if !defined(DISABLE_FLOAT_API)
863 static void opus_copy_channel_in_float(
864 opus_val16 *dst,
865 int dst_stride,
866 const void *src,
867 int src_stride,
868 int src_channel,
869 int frame_size
870 )
871 {
872 const float *float_src;
873 opus_int32 i;
874 float_src = (const float *)src;
875 for (i=0;i<frame_size;i++)
876 #if defined(FIXED_POINT)
877 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
878 #else
879 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
880 #endif
881 }
882 #endif
883
884 static void opus_copy_channel_in_short(
885 opus_val16 *dst,
886 int dst_stride,
887 const void *src,
888 int src_stride,
889 int src_channel,
890 int frame_size
891 )
892 {
893 const opus_int16 *short_src;
894 opus_int32 i;
895 short_src = (const opus_int16 *)src;
896 for (i=0;i<frame_size;i++)
897 #if defined(FIXED_POINT)
898 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
899 #else
900 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
901 #endif
902 }
903
904
905 #ifdef FIXED_POINT
906 int opus_multistream_encode(
907 OpusMSEncoder *st,
908 const opus_val16 *pcm,
909 int frame_size,
910 unsigned char *data,
911 opus_int32 max_data_bytes
912 )
913 {
914 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
915 pcm, frame_size, data, max_data_bytes, 16, downmix_int);
916 }
917
918 #ifndef DISABLE_FLOAT_API
919 int opus_multistream_encode_float(
920 OpusMSEncoder *st,
921 const float *pcm,
922 int frame_size,
923 unsigned char *data,
924 opus_int32 max_data_bytes
925 )
926 {
927 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
928 pcm, frame_size, data, max_data_bytes, 16, downmix_float);
929 }
930 #endif
931
932 #else
933
934 int opus_multistream_encode_float
935 (
936 OpusMSEncoder *st,
937 const opus_val16 *pcm,
938 int frame_size,
939 unsigned char *data,
940 opus_int32 max_data_bytes
941 )
942 {
943 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
944 pcm, frame_size, data, max_data_bytes, 24, downmix_float);
945 }
946
947 int opus_multistream_encode(
948 OpusMSEncoder *st,
949 const opus_int16 *pcm,
950 int frame_size,
951 unsigned char *data,
952 opus_int32 max_data_bytes
953 )
954 {
955 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
956 pcm, frame_size, data, max_data_bytes, 16, downmix_int);
957 }
958 #endif
959
960 int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
961 {
962 va_list ap;
963 int coupled_size, mono_size;
964 char *ptr;
965 int ret = OPUS_OK;
966
967 va_start(ap, request);
968
969 coupled_size = opus_encoder_get_size(2);
970 mono_size = opus_encoder_get_size(1);
971 ptr = (char*)st + align(sizeof(OpusMSEncoder));
972 switch (request)
973 {
974 case OPUS_SET_BITRATE_REQUEST:
975 {
976 opus_int32 value = va_arg(ap, opus_int32);
977 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
978 {
979 goto bad_arg;
980 }
981 st->bitrate_bps = value;
982 }
983 break;
984 case OPUS_GET_BITRATE_REQUEST:
985 {
986 int s;
987 opus_int32 *value = va_arg(ap, opus_int32*);
988 if (!value)
989 {
990 goto bad_arg;
991 }
992 *value = 0;
993 for (s=0;s<st->layout.nb_streams;s++)
994 {
995 opus_int32 rate;
996 OpusEncoder *enc;
997 enc = (OpusEncoder*)ptr;
998 if (s < st->layout.nb_coupled_streams)
999 ptr += align(coupled_size);
1000 else
1001 ptr += align(mono_size);
1002 opus_encoder_ctl(enc, request, &rate);
1003 *value += rate;
1004 }
1005 }
1006 break;
1007 case OPUS_GET_LSB_DEPTH_REQUEST:
1008 case OPUS_GET_VBR_REQUEST:
1009 case OPUS_GET_APPLICATION_REQUEST:
1010 case OPUS_GET_BANDWIDTH_REQUEST:
1011 case OPUS_GET_COMPLEXITY_REQUEST:
1012 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1013 case OPUS_GET_DTX_REQUEST:
1014 case OPUS_GET_VOICE_RATIO_REQUEST:
1015 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1016 case OPUS_GET_SIGNAL_REQUEST:
1017 case OPUS_GET_LOOKAHEAD_REQUEST:
1018 case OPUS_GET_SAMPLE_RATE_REQUEST:
1019 case OPUS_GET_INBAND_FEC_REQUEST:
1020 case OPUS_GET_FORCE_CHANNELS_REQUEST:
1021 {
1022 OpusEncoder *enc;
1023 /* For int32* GET params, just query the first stream */
1024 opus_int32 *value = va_arg(ap, opus_int32*);
1025 enc = (OpusEncoder*)ptr;
1026 ret = opus_encoder_ctl(enc, request, value);
1027 }
1028 break;
1029 case OPUS_GET_FINAL_RANGE_REQUEST:
1030 {
1031 int s;
1032 opus_uint32 *value = va_arg(ap, opus_uint32*);
1033 opus_uint32 tmp;
1034 if (!value)
1035 {
1036 goto bad_arg;
1037 }
1038 *value=0;
1039 for (s=0;s<st->layout.nb_streams;s++)
1040 {
1041 OpusEncoder *enc;
1042 enc = (OpusEncoder*)ptr;
1043 if (s < st->layout.nb_coupled_streams)
1044 ptr += align(coupled_size);
1045 else
1046 ptr += align(mono_size);
1047 ret = opus_encoder_ctl(enc, request, &tmp);
1048 if (ret != OPUS_OK) break;
1049 *value ^= tmp;
1050 }
1051 }
1052 break;
1053 case OPUS_SET_LSB_DEPTH_REQUEST:
1054 case OPUS_SET_COMPLEXITY_REQUEST:
1055 case OPUS_SET_VBR_REQUEST:
1056 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
1057 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
1058 case OPUS_SET_BANDWIDTH_REQUEST:
1059 case OPUS_SET_SIGNAL_REQUEST:
1060 case OPUS_SET_APPLICATION_REQUEST:
1061 case OPUS_SET_INBAND_FEC_REQUEST:
1062 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1063 case OPUS_SET_DTX_REQUEST:
1064 case OPUS_SET_FORCE_MODE_REQUEST:
1065 case OPUS_SET_FORCE_CHANNELS_REQUEST:
1066 {
1067 int s;
1068 /* This works for int32 params */
1069 opus_int32 value = va_arg(ap, opus_int32);
1070 for (s=0;s<st->layout.nb_streams;s++)
1071 {
1072 OpusEncoder *enc;
1073
1074 enc = (OpusEncoder*)ptr;
1075 if (s < st->layout.nb_coupled_streams)
1076 ptr += align(coupled_size);
1077 else
1078 ptr += align(mono_size);
1079 ret = opus_encoder_ctl(enc, request, value);
1080 if (ret != OPUS_OK)
1081 break;
1082 }
1083 }
1084 break;
1085 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1086 {
1087 int s;
1088 opus_int32 stream_id;
1089 OpusEncoder **value;
1090 stream_id = va_arg(ap, opus_int32);
1091 if (stream_id<0 || stream_id >= st->layout.nb_streams)
1092 ret = OPUS_BAD_ARG;
1093 value = va_arg(ap, OpusEncoder**);
1094 if (!value)
1095 {
1096 goto bad_arg;
1097 }
1098 for (s=0;s<stream_id;s++)
1099 {
1100 if (s < st->layout.nb_coupled_streams)
1101 ptr += align(coupled_size);
1102 else
1103 ptr += align(mono_size);
1104 }
1105 *value = (OpusEncoder*)ptr;
1106 }
1107 break;
1108 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
1109 {
1110 opus_int32 value = va_arg(ap, opus_int32);
1111 st->variable_duration = value;
1112 }
1113 break;
1114 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
1115 {
1116 opus_int32 *value = va_arg(ap, opus_int32*);
1117 if (!value)
1118 {
1119 goto bad_arg;
1120 }
1121 *value = st->variable_duration;
1122 }
1123 break;
1124 default:
1125 ret = OPUS_UNIMPLEMENTED;
1126 break;
1127 }
1128
1129 va_end(ap);
1130 return ret;
1131 bad_arg:
1132 va_end(ap);
1133 return OPUS_BAD_ARG;
1134 }
1135
1136 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1137 {
1138 opus_free(st);
1139 }
OLDNEW
« no previous file with comments | « src/opus_multistream_decoder.c ('k') | src/opus_private.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698