comparison ac3dec.c @ 7554:96d57e3b78e5 libavcodec

optimize ac3_downmix. 1.3x faster 5.1->stereo, 1.9x faster 5.1->mono.
author lorenm
date Tue, 12 Aug 2008 23:45:46 +0000
parents f9e4afa46993
children be6d31643128
comparison
equal deleted inserted replaced
7553:b5f8d814a206 7554:96d57e3b78e5
319 static void set_downmix_coeffs(AC3DecodeContext *s) 319 static void set_downmix_coeffs(AC3DecodeContext *s)
320 { 320 {
321 int i; 321 int i;
322 float cmix = gain_levels[center_levels[s->center_mix_level]]; 322 float cmix = gain_levels[center_levels[s->center_mix_level]];
323 float smix = gain_levels[surround_levels[s->surround_mix_level]]; 323 float smix = gain_levels[surround_levels[s->surround_mix_level]];
324 float norm0, norm1;
324 325
325 for(i=0; i<s->fbw_channels; i++) { 326 for(i=0; i<s->fbw_channels; i++) {
326 s->downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; 327 s->downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
327 s->downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; 328 s->downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
328 } 329 }
336 if(s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) { 337 if(s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) {
337 int nf = s->channel_mode - 4; 338 int nf = s->channel_mode - 4;
338 s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = smix; 339 s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = smix;
339 } 340 }
340 341
341 /* calculate adjustment needed for each channel to avoid clipping */ 342 /* renormalize */
342 s->downmix_coeff_adjust[0] = s->downmix_coeff_adjust[1] = 0.0f; 343 norm0 = norm1 = 0.0;
343 for(i=0; i<s->fbw_channels; i++) { 344 for(i=0; i<s->fbw_channels; i++) {
344 s->downmix_coeff_adjust[0] += s->downmix_coeffs[i][0]; 345 norm0 += s->downmix_coeffs[i][0];
345 s->downmix_coeff_adjust[1] += s->downmix_coeffs[i][1]; 346 norm1 += s->downmix_coeffs[i][1];
346 } 347 }
347 s->downmix_coeff_adjust[0] = 1.0f / s->downmix_coeff_adjust[0]; 348 norm0 = 1.0f / norm0;
348 s->downmix_coeff_adjust[1] = 1.0f / s->downmix_coeff_adjust[1]; 349 norm1 = 1.0f / norm1;
350 for(i=0; i<s->fbw_channels; i++) {
351 s->downmix_coeffs[i][0] *= norm0;
352 s->downmix_coeffs[i][1] *= norm1;
353 }
354
355 if(s->output_mode == AC3_CHMODE_MONO) {
356 for(i=0; i<s->fbw_channels; i++)
357 s->downmix_coeffs[i][0] = (s->downmix_coeffs[i][0] + s->downmix_coeffs[i][1]) * LEVEL_MINUS_3DB;
358 }
349 } 359 }
350 360
351 /** 361 /**
352 * Decode the grouped exponents according to exponent strategy. 362 * Decode the grouped exponents according to exponent strategy.
353 * reference: Section 7.1.3 Exponent Decoding 363 * reference: Section 7.1.3 Exponent Decoding
617 } 627 }
618 628
619 /** 629 /**
620 * Downmix the output to mono or stereo. 630 * Downmix the output to mono or stereo.
621 */ 631 */
622 static void ac3_downmix(AC3DecodeContext *s, 632 static av_noinline void ac3_downmix(AC3DecodeContext *s,
623 float samples[AC3_MAX_CHANNELS][256], int ch_offset) 633 float samples[AC3_MAX_CHANNELS][256])
624 { 634 {
625 int i, j; 635 int i, j;
626 float v0, v1; 636 float v0, v1;
627 637
628 for(i=0; i<256; i++) { 638 if(s->output_mode == AC3_CHMODE_STEREO) {
629 v0 = v1 = 0.0f; 639 for(i=0; i<256; i++) {
630 for(j=0; j<s->fbw_channels; j++) { 640 v0 = v1 = 0.0f;
631 v0 += samples[j+ch_offset][i] * s->downmix_coeffs[j][0]; 641 for(j=0; j<s->fbw_channels; j++) {
632 v1 += samples[j+ch_offset][i] * s->downmix_coeffs[j][1]; 642 v0 += samples[j][i] * s->downmix_coeffs[j][0];
633 } 643 v1 += samples[j][i] * s->downmix_coeffs[j][1];
634 v0 *= s->downmix_coeff_adjust[0]; 644 }
635 v1 *= s->downmix_coeff_adjust[1]; 645 samples[0][i] = v0;
636 if(s->output_mode == AC3_CHMODE_MONO) { 646 samples[1][i] = v1;
637 samples[ch_offset][i] = (v0 + v1) * LEVEL_MINUS_3DB; 647 }
638 } else if(s->output_mode == AC3_CHMODE_STEREO) { 648 } else if(s->output_mode == AC3_CHMODE_MONO) {
639 samples[ ch_offset][i] = v0; 649 for(i=0; i<256; i++) {
640 samples[1+ch_offset][i] = v1; 650 v0 = 0.0f;
651 for(j=0; j<s->fbw_channels; j++)
652 v0 += samples[j][i] * s->downmix_coeffs[j][0];
653 samples[0][i] = v0;
641 } 654 }
642 } 655 }
643 } 656 }
644 657
645 /** 658 /**
1000 } 1013 }
1001 1014
1002 do_imdct(s, s->channels); 1015 do_imdct(s, s->channels);
1003 1016
1004 if(downmix_output) { 1017 if(downmix_output) {
1005 ac3_downmix(s, s->output, 0); 1018 ac3_downmix(s, s->output);
1006 } 1019 }
1007 } else { 1020 } else {
1008 if(downmix_output) { 1021 if(downmix_output) {
1009 ac3_downmix(s, s->transform_coeffs, 1); 1022 ac3_downmix(s, s->transform_coeffs+1);
1010 } 1023 }
1011 1024
1012 if(!s->downmixed) { 1025 if(!s->downmixed) {
1013 s->downmixed = 1; 1026 s->downmixed = 1;
1014 // FIXME delay[] is half the size of the other downmixes 1027 // FIXME delay[] is half the size of the other downmixes
1015 ac3_downmix(s, s->delay, 0); 1028 ac3_downmix(s, s->delay);
1016 } 1029 }
1017 1030
1018 do_imdct(s, s->out_channels); 1031 do_imdct(s, s->out_channels);
1019 } 1032 }
1020 1033