00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avcodec.h"
00028 #include "ac3.h"
00029 #include "bitstream.h"
00030
00031 static uint8_t band_start_tab[51];
00032 static uint8_t bin_to_band_tab[253];
00033
00034 static inline int calc_lowcomp1(int a, int b0, int b1, int c)
00035 {
00036 if ((b0 + 256) == b1) {
00037 a = c;
00038 } else if (b0 > b1) {
00039 a = FFMAX(a - 64, 0);
00040 }
00041 return a;
00042 }
00043
00044 static inline int calc_lowcomp(int a, int b0, int b1, int bin)
00045 {
00046 if (bin < 7) {
00047 return calc_lowcomp1(a, b0, b1, 384);
00048 } else if (bin < 20) {
00049 return calc_lowcomp1(a, b0, b1, 320);
00050 } else {
00051 return FFMAX(a - 128, 0);
00052 }
00053 }
00054
00055 void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd,
00056 int16_t *band_psd)
00057 {
00058 int bin, i, j, k, end1, v;
00059
00060
00061 for(bin=start;bin<end;bin++) {
00062 psd[bin]=(3072 - (exp[bin] << 7));
00063 }
00064
00065
00066 j=start;
00067 k=bin_to_band_tab[start];
00068 do {
00069 v=psd[j];
00070 j++;
00071 end1 = FFMIN(band_start_tab[k+1], end);
00072 for(i=j;i<end1;i++) {
00073
00074 int adr = FFMIN(FFABS(v - psd[j]) >> 1, 255);
00075 v = FFMAX(v, psd[j]) + ff_ac3_log_add_tab[adr];
00076 j++;
00077 }
00078 band_psd[k]=v;
00079 k++;
00080 } while (end > band_start_tab[k]);
00081 }
00082
00083 int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd,
00084 int start, int end, int fast_gain, int is_lfe,
00085 int dba_mode, int dba_nsegs, uint8_t *dba_offsets,
00086 uint8_t *dba_lengths, uint8_t *dba_values,
00087 int16_t *mask)
00088 {
00089 int16_t excite[50];
00090 int bin, k;
00091 int bndstrt, bndend, begin, end1, tmp;
00092 int lowcomp, fastleak, slowleak;
00093
00094
00095 bndstrt = bin_to_band_tab[start];
00096 bndend = bin_to_band_tab[end-1] + 1;
00097
00098 if (bndstrt == 0) {
00099 lowcomp = 0;
00100 lowcomp = calc_lowcomp1(lowcomp, band_psd[0], band_psd[1], 384);
00101 excite[0] = band_psd[0] - fast_gain - lowcomp;
00102 lowcomp = calc_lowcomp1(lowcomp, band_psd[1], band_psd[2], 384);
00103 excite[1] = band_psd[1] - fast_gain - lowcomp;
00104 begin = 7;
00105 for (bin = 2; bin < 7; bin++) {
00106 if (!(is_lfe && bin == 6))
00107 lowcomp = calc_lowcomp1(lowcomp, band_psd[bin], band_psd[bin+1], 384);
00108 fastleak = band_psd[bin] - fast_gain;
00109 slowleak = band_psd[bin] - s->slow_gain;
00110 excite[bin] = fastleak - lowcomp;
00111 if (!(is_lfe && bin == 6)) {
00112 if (band_psd[bin] <= band_psd[bin+1]) {
00113 begin = bin + 1;
00114 break;
00115 }
00116 }
00117 }
00118
00119 end1=bndend;
00120 if (end1 > 22) end1=22;
00121
00122 for (bin = begin; bin < end1; bin++) {
00123 if (!(is_lfe && bin == 6))
00124 lowcomp = calc_lowcomp(lowcomp, band_psd[bin], band_psd[bin+1], bin);
00125
00126 fastleak = FFMAX(fastleak - s->fast_decay, band_psd[bin] - fast_gain);
00127 slowleak = FFMAX(slowleak - s->slow_decay, band_psd[bin] - s->slow_gain);
00128 excite[bin] = FFMAX(fastleak - lowcomp, slowleak);
00129 }
00130 begin = 22;
00131 } else {
00132
00133 begin = bndstrt;
00134
00135 fastleak = (s->cpl_fast_leak << 8) + 768;
00136 slowleak = (s->cpl_slow_leak << 8) + 768;
00137 }
00138
00139 for (bin = begin; bin < bndend; bin++) {
00140 fastleak = FFMAX(fastleak - s->fast_decay, band_psd[bin] - fast_gain);
00141 slowleak = FFMAX(slowleak - s->slow_decay, band_psd[bin] - s->slow_gain);
00142 excite[bin] = FFMAX(fastleak, slowleak);
00143 }
00144
00145
00146
00147 for (bin = bndstrt; bin < bndend; bin++) {
00148 tmp = s->db_per_bit - band_psd[bin];
00149 if (tmp > 0) {
00150 excite[bin] += tmp >> 2;
00151 }
00152 mask[bin] = FFMAX(ff_ac3_hearing_threshold_tab[bin >> s->sr_shift][s->sr_code], excite[bin]);
00153 }
00154
00155
00156
00157 if (dba_mode == DBA_REUSE || dba_mode == DBA_NEW) {
00158 int band, seg, delta;
00159 if (dba_nsegs >= 8)
00160 return -1;
00161 band = 0;
00162 for (seg = 0; seg < dba_nsegs; seg++) {
00163 band += dba_offsets[seg];
00164 if (band >= 50 || dba_lengths[seg] > 50-band)
00165 return -1;
00166 if (dba_values[seg] >= 4) {
00167 delta = (dba_values[seg] - 3) << 7;
00168 } else {
00169 delta = (dba_values[seg] - 4) << 7;
00170 }
00171 for (k = 0; k < dba_lengths[seg]; k++) {
00172 mask[band] += delta;
00173 band++;
00174 }
00175 }
00176 }
00177 return 0;
00178 }
00179
00180 void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end,
00181 int snr_offset, int floor,
00182 const uint8_t *bap_tab, uint8_t *bap)
00183 {
00184 int i, j, k, end1, v, address;
00185
00186
00187 if(snr_offset == -960) {
00188 memset(bap, 0, 256);
00189 return;
00190 }
00191
00192 i = start;
00193 j = bin_to_band_tab[start];
00194 do {
00195 v = (FFMAX(mask[j] - snr_offset - floor, 0) & 0x1FE0) + floor;
00196 end1 = FFMIN(band_start_tab[j] + ff_ac3_critical_band_size_tab[j], end);
00197 for (k = i; k < end1; k++) {
00198 address = av_clip((psd[i] - v) >> 5, 0, 63);
00199 bap[i] = bap_tab[address];
00200 i++;
00201 }
00202 } while (end > band_start_tab[j++]);
00203 }
00204
00205
00206
00207 void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap,
00208 int8_t *exp, int start, int end,
00209 int snr_offset, int fast_gain, int is_lfe,
00210 int dba_mode, int dba_nsegs,
00211 uint8_t *dba_offsets, uint8_t *dba_lengths,
00212 uint8_t *dba_values)
00213 {
00214 int16_t psd[256];
00215 int16_t band_psd[50];
00216 int16_t mask[50];
00217
00218 ff_ac3_bit_alloc_calc_psd(exp, start, end, psd, band_psd);
00219
00220 ff_ac3_bit_alloc_calc_mask(s, band_psd, start, end, fast_gain, is_lfe,
00221 dba_mode, dba_nsegs, dba_offsets, dba_lengths, dba_values,
00222 mask);
00223
00224 ff_ac3_bit_alloc_calc_bap(mask, psd, start, end, snr_offset, s->floor,
00225 ff_ac3_bap_tab, bap);
00226 }
00227
00233 av_cold void ac3_common_init(void)
00234 {
00235 int i, j, k, l, v;
00236
00237 k = 0;
00238 l = 0;
00239 for(i=0;i<50;i++) {
00240 band_start_tab[i] = l;
00241 v = ff_ac3_critical_band_size_tab[i];
00242 for(j=0;j<v;j++) bin_to_band_tab[k++]=i;
00243 l += v;
00244 }
00245 band_start_tab[50] = l;
00246 }