X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fac3.c;h=99e5b50acbda8193e9f0dbc71a4ba0d9ea5f0884;hb=0a60780c7fe72e2f9cc41efc152b3807954b7820;hp=6b18930ca14ca528fe57155f98443bb4ef7c1a89;hpb=687671f03b3df1376479c7a2f880b5fc5634772e;p=ffmpeg diff --git a/libavcodec/ac3.c b/libavcodec/ac3.c index 6b18930ca14..99e5b50acbd 100644 --- a/libavcodec/ac3.c +++ b/libavcodec/ac3.c @@ -1,35 +1,77 @@ /* - * Common code between AC3 encoder and decoder - * Copyright (c) 2000 Fabrice Bellard. + * Common code between the AC-3 encoder and decoder + * Copyright (c) 2000 Fabrice Bellard * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file ac3.c - * Common code between AC3 encoder and decoder. + * @file + * Common code between the AC-3 encoder and decoder. */ #include "avcodec.h" #include "ac3.h" -#include "bitstream.h" +#include "get_bits.h" -static uint8_t band_start_tab[51]; -static uint8_t bin_to_band_tab[253]; +/** + * Starting frequency coefficient bin for each critical band. + */ +const uint8_t ff_ac3_band_start_tab[AC3_CRITICAL_BANDS+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, + 34, 37, 40, 43, 46, 49, 55, 61, 67, 73, + 79, 85, 97, 109, 121, 133, 157, 181, 205, 229, 253 +}; + +#if CONFIG_HARDCODED_TABLES + +/** + * Map each frequency coefficient bin to the critical band that contains it. + */ +const uint8_t ff_ac3_bin_to_band_tab[253] = { + 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, + 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, + 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, + 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, + 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49 +}; + +#else /* CONFIG_HARDCODED_TABLES */ +uint8_t ff_ac3_bin_to_band_tab[253]; +#endif static inline int calc_lowcomp1(int a, int b0, int b1, int c) { @@ -55,187 +97,135 @@ static inline int calc_lowcomp(int a, int b0, int b1, int bin) void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd, int16_t *band_psd) { - int bin, i, j, k, end1, v; + int bin, band; /* exponent mapping to PSD */ - for(bin=start;bin> 1, 255); - v = FFMAX(v, psd[j]) + ff_ac3_log_add_tab[adr]; - j++; + int adr = FFMIN(max - ((v + psd[bin] + 1) >> 1), 255); + v = max + ff_ac3_log_add_tab[adr]; } - band_psd[k]=v; - k++; - } while (end > band_start_tab[k]); + band_psd[band++] = v; + } while (end > ff_ac3_band_start_tab[band]); } -void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd, - int start, int end, int fast_gain, int is_lfe, - int dba_mode, int dba_nsegs, uint8_t *dba_offsets, - uint8_t *dba_lengths, uint8_t *dba_values, - int16_t *mask) +int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd, + int start, int end, int fast_gain, int is_lfe, + int dba_mode, int dba_nsegs, uint8_t *dba_offsets, + uint8_t *dba_lengths, uint8_t *dba_values, + int16_t *mask) { - int16_t excite[50]; /* excitation */ - int bin, k; - int bndstrt, bndend, begin, end1, tmp; + int16_t excite[AC3_CRITICAL_BANDS]; /* excitation */ + int band; + int band_start, band_end, begin, end1; int lowcomp, fastleak, slowleak; /* excitation function */ - bndstrt = bin_to_band_tab[start]; - bndend = bin_to_band_tab[end-1] + 1; + band_start = ff_ac3_bin_to_band_tab[start]; + band_end = ff_ac3_bin_to_band_tab[end-1] + 1; - if (bndstrt == 0) { + if (band_start == 0) { lowcomp = 0; lowcomp = calc_lowcomp1(lowcomp, band_psd[0], band_psd[1], 384); excite[0] = band_psd[0] - fast_gain - lowcomp; lowcomp = calc_lowcomp1(lowcomp, band_psd[1], band_psd[2], 384); excite[1] = band_psd[1] - fast_gain - lowcomp; begin = 7; - for (bin = 2; bin < 7; bin++) { - if (!(is_lfe && bin == 6)) - lowcomp = calc_lowcomp1(lowcomp, band_psd[bin], band_psd[bin+1], 384); - fastleak = band_psd[bin] - fast_gain; - slowleak = band_psd[bin] - s->slow_gain; - excite[bin] = fastleak - lowcomp; - if (!(is_lfe && bin == 6)) { - if (band_psd[bin] <= band_psd[bin+1]) { - begin = bin + 1; + for (band = 2; band < 7; band++) { + if (!(is_lfe && band == 6)) + lowcomp = calc_lowcomp1(lowcomp, band_psd[band], band_psd[band+1], 384); + fastleak = band_psd[band] - fast_gain; + slowleak = band_psd[band] - s->slow_gain; + excite[band] = fastleak - lowcomp; + if (!(is_lfe && band == 6)) { + if (band_psd[band] <= band_psd[band+1]) { + begin = band + 1; break; } } } - end1=bndend; - if (end1 > 22) end1=22; - - for (bin = begin; bin < end1; bin++) { - if (!(is_lfe && bin == 6)) - lowcomp = calc_lowcomp(lowcomp, band_psd[bin], band_psd[bin+1], bin); - - fastleak = FFMAX(fastleak - s->fast_decay, band_psd[bin] - fast_gain); - slowleak = FFMAX(slowleak - s->slow_decay, band_psd[bin] - s->slow_gain); - excite[bin] = FFMAX(fastleak - lowcomp, slowleak); + end1 = FFMIN(band_end, 22); + for (band = begin; band < end1; band++) { + if (!(is_lfe && band == 6)) + lowcomp = calc_lowcomp(lowcomp, band_psd[band], band_psd[band+1], band); + fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain); + slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain); + excite[band] = FFMAX(fastleak - lowcomp, slowleak); } begin = 22; } else { /* coupling channel */ - begin = bndstrt; - + begin = band_start; fastleak = (s->cpl_fast_leak << 8) + 768; slowleak = (s->cpl_slow_leak << 8) + 768; } - for (bin = begin; bin < bndend; bin++) { - fastleak = FFMAX(fastleak - s->fast_decay, band_psd[bin] - fast_gain); - slowleak = FFMAX(slowleak - s->slow_decay, band_psd[bin] - s->slow_gain); - excite[bin] = FFMAX(fastleak, slowleak); + for (band = begin; band < band_end; band++) { + fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain); + slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain); + excite[band] = FFMAX(fastleak, slowleak); } /* compute masking curve */ - for (bin = bndstrt; bin < bndend; bin++) { - tmp = s->db_per_bit - band_psd[bin]; + for (band = band_start; band < band_end; band++) { + int tmp = s->db_per_bit - band_psd[band]; if (tmp > 0) { - excite[bin] += tmp >> 2; + excite[band] += tmp >> 2; } - mask[bin] = FFMAX(ff_ac3_hearing_threshold_tab[bin >> s->sr_shift][s->sr_code], excite[bin]); + mask[band] = FFMAX(ff_ac3_hearing_threshold_tab[band >> s->sr_shift][s->sr_code], excite[band]); } /* delta bit allocation */ if (dba_mode == DBA_REUSE || dba_mode == DBA_NEW) { - int band, seg, delta; - band = 0; - for (seg = 0; seg < FFMIN(8, dba_nsegs); seg++) { - band = FFMIN(49, band + dba_offsets[seg]); + int i, seg, delta; + if (dba_nsegs > 8) + return -1; + band = band_start; + for (seg = 0; seg < dba_nsegs; seg++) { + band += dba_offsets[seg]; + if (band >= AC3_CRITICAL_BANDS || dba_lengths[seg] > AC3_CRITICAL_BANDS-band) + return -1; if (dba_values[seg] >= 4) { delta = (dba_values[seg] - 3) << 7; } else { delta = (dba_values[seg] - 4) << 7; } - for (k = 0; k < dba_lengths[seg]; k++) { - mask[band] += delta; - band++; + for (i = 0; i < dba_lengths[seg]; i++) { + mask[band++] += delta; } } } -} - -void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end, - int snr_offset, int floor, - const uint8_t *bap_tab, uint8_t *bap) -{ - int i, j, k, end1, v, address; - - /* special case, if snr offset is -960, set all bap's to zero */ - if(snr_offset == -960) { - memset(bap, 0, 256); - return; - } - - i = start; - j = bin_to_band_tab[start]; - do { - v = (FFMAX(mask[j] - snr_offset - floor, 0) & 0x1FE0) + floor; - end1 = FFMIN(band_start_tab[j] + ff_ac3_critical_band_size_tab[j], end); - for (k = i; k < end1; k++) { - address = av_clip((psd[i] - v) >> 5, 0, 63); - bap[i] = bap_tab[address]; - i++; - } - } while (end > band_start_tab[j++]); -} - -/* AC3 bit allocation. The algorithm is the one described in the AC3 - spec. */ -void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap, - int8_t *exp, int start, int end, - int snr_offset, int fast_gain, int is_lfe, - int dba_mode, int dba_nsegs, - uint8_t *dba_offsets, uint8_t *dba_lengths, - uint8_t *dba_values) -{ - int16_t psd[256]; /* scaled exponents */ - int16_t band_psd[50]; /* interpolated exponents */ - int16_t mask[50]; /* masking value */ - - ff_ac3_bit_alloc_calc_psd(exp, start, end, psd, band_psd); - - ff_ac3_bit_alloc_calc_mask(s, band_psd, start, end, fast_gain, is_lfe, - dba_mode, dba_nsegs, dba_offsets, dba_lengths, dba_values, - mask); - - ff_ac3_bit_alloc_calc_bap(mask, psd, start, end, snr_offset, s->floor, - ff_ac3_bap_tab, bap); + return 0; } /** - * Initializes some tables. + * Initialize some tables. * note: This function must remain thread safe because it is called by the * AVParser init code. */ -av_cold void ac3_common_init(void) +av_cold void ff_ac3_common_init(void) { - int i, j, k, l, v; - /* compute bndtab and masktab from bandsz */ - k = 0; - l = 0; - for(i=0;i<50;i++) { - band_start_tab[i] = l; - v = ff_ac3_critical_band_size_tab[i]; - for(j=0;j