[FFmpeg-soc] [soc]: r3764 - aacenc/aacenc.c
kostya
subversion at mplayerhq.hu
Thu Oct 16 07:41:36 CEST 2008
Author: kostya
Date: Thu Oct 16 07:41:35 2008
New Revision: 3764
Log:
Here's a bunch of my experimental stuff for different quantiser search
and quantisation.
Modified:
aacenc/aacenc.c
Modified: aacenc/aacenc.c
==============================================================================
--- aacenc/aacenc.c (original)
+++ aacenc/aacenc.c Thu Oct 16 07:41:35 2008
@@ -341,18 +341,254 @@ static av_always_inline int quant(float
return av_clip((int)(pow(fabsf(coef) * Q, 0.75) + 0.4054), 0, 8191);
}
+#if 1
+
+static av_always_inline int quant2(float coef, const float Q)
+{
+ return av_clip((int)(pow(fabsf(coef) * Q, 0.75)), 0, 8191);
+}
+
+static const float aac_cb_range[12] = { 0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};
+static const float aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16};
+
/**
* Calculate rate distortion cost for quantizing with given codebook
*
* @return quantization distortion
*/
static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
- const float lambda, const float uplim)
+ const float lambda, const float uplim, int *bits)
+{
+ const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
+ const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
+ int i, j, k;
+ float cost = 0;
+ const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
+ int resbits = 0;
+ const int range = aac_cb_range[cb];
+ const int maxval = aac_cb_maxval[cb];
+ int offs[4];
+
+ if(!cb){
+ for(i = 0; i < size; i++)
+ cost += in[i]*in[i]*lambda;
+ return cost;
+ }
+ offs[0] = 1;
+ for(i = 1; i < dim; i++)
+ offs[i] = offs[i-1]*range;
+ for(i = 0; i < size; i += dim){
+ float mincost;
+ int minidx = 0;
+ int minbits = 0;
+ int quants[4][2], realquants[4][2];
+ mincost = 0.0f;
+ for(j = 0; j < dim; j++){
+ realquants[j][0] = quant2(in[i+j], Q);
+ realquants[j][1] = quant (in[i+j], Q);
+ for(k = 0; k < 2; k++){
+ quants[j][k] = FFMIN(realquants[j][k], maxval);
+ if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
+ quants[j][k] = -quants[j][k];
+ }
+ mincost += in[i+j]*in[i+j]*lambda;
+ }
+ minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
+ minbits = ff_aac_spectral_bits[cb-1][minidx];
+ mincost += minbits;
+ for(j = 0; j < (1<<dim); j++){
+ float rd = 0.0f;
+ int curbits;
+ int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
+ const float *vec;
+ int same = 0;
+ for(k = 0; k < dim; k++){
+ if((j & (1 << k)) && quants[k][0] == quants[k][1]){
+ same = 1;
+ break;
+ }
+ }
+ if(same)
+ continue;
+ for(k = 0; k < dim; k++)
+ curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k];
+ curbits = ff_aac_spectral_bits[cb-1][curidx];
+ vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
+ if(IS_CODEBOOK_UNSIGNED(cb)){
+ for(k = 0; k < dim; k++){
+ float t = fabsf(in[i+k]);
+ float di;
+ //do not code with escape sequence small values
+ if(vec[k] == 64.0f && t < 39.0f*IQ){
+ rd = INFINITY;
+ break;
+ }
+ if(vec[k] == 64.0f){//FIXME: slow
+ if(t >= 165140.0f*IQ){ // clipped value
+ di = t - 165140.0f;
+ curbits += 21;
+ }else{
+ int c = realquants[k];
+ di = t - c*cbrt(c)*IQ;
+ curbits += av_log2(c)*2 - 4 + 1;
+ }
+ }else{
+ di = t - vec[k]*IQ;
+ }
+ if(vec[k] != 0.0f)
+ curbits++;
+ rd += di*di*lambda;
+ }
+ }else{
+ for(k = 0; k < dim; k++){
+ float di = in[i+k] - vec[k]*IQ;
+ rd += di*di*lambda;
+ }
+ }
+ rd += curbits;
+ if(rd < mincost){
+ mincost = rd;
+ minidx = j;
+ minbits = curbits;
+ }
+ }
+ cost += mincost;
+ resbits += minbits;
+ if(cost >= uplim)
+ return uplim;
+ }
+
+ if(bits)
+ *bits = resbits;
+ return cost;
+}
+
+static void quantize_and_encode_band(PutBitContext *pb, const float *in, int size,
+ int scale_idx, int cb, const float lambda)
+{
+ const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
+ const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
+ const int range = aac_cb_range[cb];
+ const int maxval = aac_cb_maxval[cb];
+ const int dim = (cb < FIRST_PAIR_BT) ? 4 : 2;
+ int i, j, k;
+ int offs[4];
+
+ if(!cb)
+ return;
+
+ offs[0] = 1;
+ for(i = 1; i < dim; i++)
+ offs[i] = offs[i-1]*range;
+ for(i = 0; i < size; i += dim){
+ float mincost;
+ int minidx = 0;
+ int minbits = 0;
+ int quants[4][2];
+ mincost = 0.0f;
+ for(j = 0; j < dim; j++){
+ quants[j][0] = av_clip(quant2(in[i+j], Q), -maxval, maxval);
+ quants[j][1] = av_clip(quant (in[i+j], Q), -maxval, maxval);
+ for(k = 0; k < 2; k++){
+ quants[j][k] = FFMIN(quants[j][k], maxval);
+ if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
+ quants[j][k] = -quants[j][k];
+ }
+ mincost += in[i+j]*in[i+j]*lambda;
+ }
+ minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
+ minbits = ff_aac_spectral_bits[cb-1][minidx];
+ mincost += minbits;
+ for(j = 0; j < (1<<dim); j++){
+ float rd = 0.0f;
+ int curbits;
+ int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
+ const float *vec;
+ int same = 0;
+ for(k = 0; k < dim; k++){
+ if((j & (1 << k)) && quants[k][0] == quants[k][1]){
+ same = 1;
+ break;
+ }
+ }
+ if(same)
+ continue;
+ for(k = 0; k < dim; k++)
+ curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k];
+ curbits = ff_aac_spectral_bits[cb-1][curidx];
+ vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
+ if(IS_CODEBOOK_UNSIGNED(cb)){
+ for(k = 0; k < dim; k++){
+ float t = fabsf(in[i+k]);
+ float di;
+ //do not code with escape sequence small values
+ if(vec[k] == 64.0f && t < 39.0f*IQ){
+ rd = INFINITY;
+ break;
+ }
+ if(vec[k] == 64.0f){//FIXME: slow
+ if(t >= 165140.0f*IQ){ // clipped value
+ di = t - 165140.0f;
+ curbits += 21;
+ }else{
+ int c = quant(t, Q);
+ di = t - c*cbrt(c)*IQ;
+ curbits += av_log2(c)*2 - 4 + 1;
+ }
+ }else{
+ di = t - vec[k]*IQ;
+ }
+ if(vec[k] != 0.0f)
+ curbits++;
+ rd += di*di*lambda;
+ }
+ }else{
+ for(k = 0; k < dim; k++){
+ float di = in[i+k] - vec[k]*IQ;
+ rd += di*di*lambda;
+ }
+ }
+ rd += curbits;
+ if(rd < mincost){
+ mincost = rd;
+ minidx = curidx;
+ minbits = curbits;
+ }
+ }
+ put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
+ if(IS_CODEBOOK_UNSIGNED(cb))
+ for(j = 0; j < dim; j++)
+ if(ff_aac_codebook_vectors[cb-1][minidx*dim+j] != 0.0f)
+ put_bits(pb, 1, in[i+j] < 0.0f);
+ if(cb == ESC_BT){
+ for(j = 0; j < 2; j++){
+ if(ff_aac_codebook_vectors[cb-1][minidx*2+j] == 64.0f){
+ int coef = quant(in[i+j], Q);
+ int len = av_log2(coef);
+
+ put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
+ put_bits(pb, len, coef & ((1 << len) - 1));
+ }
+ }
+ }
+ }
+}
+
+#else
+
+/**
+ * Calculate rate distortion cost for quantizing with given codebook
+ *
+ * @return quantization distortion
+ */
+static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
+ const float lambda, const float uplim, int *bits)
{
const float Q = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
int i, j, k;
float cost = 0;
const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
+ int resbits = 0;
if(!cb){
for(i = 0; i < size; i++)
@@ -406,10 +642,13 @@ static float quantize_band_cost(const fl
}
}
cost += mincost;
+ resbits += minbits;
if(cost >= uplim)
return uplim;
}
+ if(bits)
+ *bits = resbits;
return cost;
}
@@ -425,6 +664,7 @@ static void quantize_and_encode_band(Put
const float IQ = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
int i, j, k;
const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
+
if(!cb)
return;
@@ -440,15 +680,13 @@ static void quantize_and_encode_band(Put
for(k = 0; k < dim; k++){
float t = fabsf(in[i+k]);
float di;
- if(vec[k] != 0.0f)
- curbits++;
//do not code with escape sequence small values
if(vec[k] == 64.0f && t < 39.0f*Q){
rd = INFINITY;
break;
}
if(vec[k] == 64.0f){//FIXME: slow
- if(t*IQ >= 165140.0f){ // clipped value
+ if(t >= 165140.0f*Q){ // clipped value
di = t - 165140.0f;
curbits += 21;
}else{
@@ -459,6 +697,8 @@ static void quantize_and_encode_band(Put
}else{
di = t - vec[k]*Q;
}
+ if(vec[k] != 0.0f)
+ curbits++;
rd += di*di*lambda;
}
}else{
@@ -493,6 +733,8 @@ static void quantize_and_encode_band(Put
}
}
+#endif
+
/**
* structure used in optimal codebook search
*/
@@ -542,7 +784,7 @@ static void encode_window_bands_info(AAC
FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(win+w)*16+swb];
rd += quantize_band_cost(sce->coeffs + start + w*128, size,
sce->sf_idx[(win+w)*16+swb], cb,
- s->lambda / band->threshold, INFINITY);
+ s->lambda / band->threshold, INFINITY, NULL);
}
if( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]
!= run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])
@@ -730,7 +972,7 @@ static void search_for_quantizers_anmr(A
int cb;
for(cb = 0; cb <= ESC_BT; cb++){
dists[cb] += quantize_band_cost(coefs + w2*128, sce->ics.swb_sizes[g],
- q, cb, s->lambda / band->threshold, INFINITY);
+ q, cb, s->lambda / band->threshold, INFINITY, NULL);
}
}
dist = dists[0];
@@ -806,6 +1048,350 @@ static void search_for_quantizers_anmr(A
sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
}
+/**
+ * two-loop quantizers search taken from ISO 13818-7 Appendix C
+ */
+static void search_for_quantizers_twoloop(AVCodecContext *avctx, AACEncContext *s,
+ SingleChannelElement *sce, const float lambda)
+{
+ int start = 0, i, w, w2, g;
+ int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels;
+ float dists[128], uplims[128];
+ int fflag, minscaler;
+ int its = 0;
+ int allz = 0;
+ float minthr = INFINITY;
+
+ //XXX: some heuristic to determine initial quantizers will reduce search time
+ memset(dists, 0, sizeof(dists));
+ //determine zero bands and upper limits
+ for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
+ for(g = 0; g < sce->ics.num_swb; g++){
+ int nz = 0;
+ float uplim = 0.0f;
+ for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
+ FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
+ uplim += band->threshold;
+ if(band->energy <= band->threshold || band->threshold == 0.0f){
+ sce->zeroes[(w+w2)*16+g] = 1;
+ continue;
+ }
+ nz = 1;
+ }
+ uplims[w*16+g] = uplim *512;
+ sce->zeroes[w*16+g] = !nz;
+ if(nz)
+ minthr = fminf(minthr, uplim);
+ allz = FFMAX(allz, nz);
+ }
+ }
+ for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
+ for(g = 0; g < sce->ics.num_swb; g++){
+ if(sce->zeroes[w*16+g]){
+ sce->sf_idx[w*16+g] = SCALE_ONE_POS;
+ continue;
+ }
+ sce->sf_idx[w*16+g] = SCALE_ONE_POS + fminf(log2(uplims[w*16+g]/minthr)*4,59);
+ }
+ }
+
+ if(!allz)
+ return;
+ //perform two-loop search
+ //outer loop - improve quality
+ do{
+ int tbits, qstep;
+ minscaler = sce->sf_idx[0];
+ //inner loop - quantize spectrum to fit into given number of bits
+ qstep = its ? 1 : 32;
+ do{
+ int prev = -1;
+ tbits = 0;
+ fflag = 0;
+ for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
+ start = w*128;
+ for(g = 0; g < sce->ics.num_swb; g++){
+ const float *coefs = sce->coeffs + start;
+ int bits = 0;
+ int cb;
+ float mindist = INFINITY;
+ int minbits = 0;
+
+ if(sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218)
+ continue;
+ minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]);
+ for(cb = 0; cb <= ESC_BT; cb++){
+ float dist = 0.0f;
+ int bb = 0;
+ for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
+ int b;
+ dist += quantize_band_cost(coefs + w2*128,
+ sce->ics.swb_sizes[g],
+ sce->sf_idx[w*16+g],
+ ESC_BT,
+ 1.0,
+ INFINITY,
+ &b);
+ bb += b;
+ }
+ if(dist < mindist){
+ mindist = dist;
+ minbits = bb;
+ }
+ }
+ dists[w*16+g] = mindist - minbits;
+ bits = minbits;
+ if(prev != -1){
+ bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO];
+ }
+ tbits += bits;
+ start += sce->ics.swb_sizes[g];
+ prev = sce->sf_idx[w*16+g];
+ }
+ }
+ if(tbits > destbits){
+ for(i = 0; i < 128; i++){
+ if(sce->sf_idx[i] < 218 - qstep){
+ sce->sf_idx[i] += qstep;
+ }
+ }
+ }else{
+ for(i = 0; i < 128; i++){
+ if(sce->sf_idx[i] > 60 - qstep){
+ sce->sf_idx[i] -= qstep;
+ }
+ }
+ }
+ qstep >>= 1;
+ if(!qstep && tbits > destbits*1.02)
+ qstep = 1;
+ if(sce->sf_idx[0] >= 217)break;
+ }while(qstep);
+
+ fflag = 0;
+ minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF);
+ for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
+ start = w*128;
+ for(g = 0; g < sce->ics.num_swb; g++){
+ int prevsc = sce->sf_idx[w*16+g];
+ if(dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60)
+ sce->sf_idx[w*16+g]--;
+ sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF);
+ sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219);
+ if(sce->sf_idx[w*16+g] != prevsc)
+ fflag = 1;
+ }
+ }
+ its++;
+ }while(fflag && its < 10);
+}
+
+static void search_for_quantizers_faac(AACEncContext *s, SingleChannelElement *sce, const float lambda)
+{
+ int start = 0, i, w, w2, g;
+ float uplim[128], maxq[128];
+ int minq;
+#if 0
+ float distfact = ((sce->ics.num_windows > 1) ? 85.80 : 147.84) / lambda;
+ int last = 0, lastband = 0, curband = 0;
+ float avg_energy = 0.0;
+ if(sce->ics.num_windows == 1){
+ start = 0;
+ for(i = 0; i < 1024; i++){
+ if(i - start >= sce->ics.swb_sizes[curband]){
+ start += sce->ics.swb_sizes[curband];
+ curband++;
+ }
+ if(sce->coeffs[i]){
+ avg_energy += sce->coeffs[i] * sce->coeffs[i];
+ last = i;
+ lastband = curband;
+ }
+ }
+ }else{
+ for(w = 0; w < 8; w++){
+ const float *coeffs = sce->coeffs + w*128;
+ start = 0;
+ for(i = 0; i < 128; i++){
+ if(i - start >= sce->ics.swb_sizes[curband]){
+ start += sce->ics.swb_sizes[curband];
+ curband++;
+ }
+ if(coeffs[i]){
+ avg_energy += coeffs[i] * coeffs[i];
+ last = FFMAX(last, i);
+ lastband = FFMAX(lastband, curband);
+ }
+ }
+ }
+ }
+ last++;
+ avg_energy /= last;
+ for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
+ start = w*128;
+ for(g = 0; g < sce->ics.num_swb; g++){
+ float *coefs = sce->coeffs + start;
+ const int size = sce->ics.swb_sizes[g];
+ int start2 = start, end2 = start + size, peakpos = start;
+ float maxval = -1, thr = 0.0f, t;
+ maxq[w*16+g] = 0.0f;
+ if(g > lastband){
+ maxq[w*16+g] = 0.0f;
+ start += size;
+ for(w2 = 0; w2 < sce->ics.group_len[w]; w2++)
+ memset(coefs + w2*128, 0, sizeof(coefs[0])*size);
+ continue;
+ }
+ for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
+ for(i = 0; i < size; i++){
+ float t = coefs[w2*128+i]*coefs[w2*128+i];
+ maxq[w*16+g] = fmaxf(maxq[w*16+g], coefs[w2*128 + i]);
+ thr += t;
+ if(sce->ics.num_windows == 1 && maxval < t){
+ maxval = t;
+ peakpos = start+i;
+ }
+ }
+ }
+ if(sce->ics.num_windows == 1){
+ start2 = FFMAX(peakpos - 2, start2);
+ end2 = FFMIN(peakpos + 3, end2);
+ }
+ start += size;
+ thr = pow(thr / (avg_energy * (end2 - start2)), 0.3 + 0.1*(lastband - g) / lastband);
+ t = 1.0 - (1.0 * start2 / last);
+ uplim[w*16+g] = distfact / (1.4 * thr + t*t*t + 0.075);
+ }
+ }
+#else
+ memset(maxq, 0, sizeof(maxq));
+ for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
+ start = w*128;
+ for(g = 0; g < sce->ics.num_swb; g++){
+ float *coefs = sce->coeffs + start;
+ const int size = sce->ics.swb_sizes[g];
+ float thr = 0.0f;
+ for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
+ FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
+ thr += band->threshold;
+ for(i = 0; i < size; i++){
+ maxq[w*16+g] = fmaxf(maxq[w*16+g], fabsf(coefs[w2*128 + i]));
+ }
+ }
+ uplim[w*16+g] = thr / lambda;
+ start += size;
+ }
+ }
+#endif
+ memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
+ for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
+ start = w*128;
+ for(g = 0; g < sce->ics.num_swb; g++){
+ const float *coefs = sce->coeffs + start;
+ const int size = sce->ics.swb_sizes[g];
+ int scf, prev_scf, step;
+ if(maxq[w*16+g] < 21.544){
+ sce->zeroes[w*16+g] = 1;
+ continue;
+ }
+ sce->zeroes[w*16+g] = 0;
+ scf = prev_scf = av_clip(SCALE_ONE_POS + log2(1/maxq[w*16+g])*16/3, 60, 218);
+ step = 16;
+ for(;;){
+ float dist = 0.0f, t;
+ int quant_max;
+
+ for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
+ int b;
+ dist += quantize_band_cost(coefs + w2*128,
+ sce->ics.swb_sizes[g],
+ scf,
+ ESC_BT,
+ 1.0,
+ INFINITY,
+ &b);
+ dist -= b;
+ }
+ quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[200 - scf + SCALE_ONE_POS]);
+ if(quant_max >= 8191){ // too much, return to the previous quantizer
+ sce->sf_idx[w*16+g] = prev_scf;
+ break;
+ }
+ prev_scf = scf;
+ t = pow(dist / size, -2.0/3.0);
+ if(FFABS(step) > 4){
+ int newstep = 4*log(t / maxq[w*16+g])/log(2) - 2;
+ step = av_clip(-newstep, -4, 4);
+ }
+ if(FFABS(step) >= 4){
+ step = 1 - step;
+ scf += step;
+ }else if(t >= uplim[w*16+g]){
+ scf -= FFABS(step);
+ }else{
+ sce->sf_idx[w*16+g] = scf;
+ break;
+ }
+ }
+ start += size;
+ }
+ }
+ minq = sce->sf_idx[0] ? sce->sf_idx[0] : INT_MAX;
+ for(i = 1; i < 128; i++){
+ if(!sce->sf_idx[i])
+ sce->sf_idx[i] = sce->sf_idx[i-1];
+ else
+ minq = FFMIN(minq, sce->sf_idx[i]);
+ }
+ if(minq == INT_MAX) minq = 0;
+ for(i = 126; i >= 0; i--){
+ if(!sce->sf_idx[i])
+ sce->sf_idx[i] = sce->sf_idx[i+1];
+ sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF);
+ }
+}
+
+static void search_for_quantizers_fast(AACEncContext *s, SingleChannelElement *sce)
+{
+ int start = 0, i, w, w2, g;
+ int minq = 255;
+
+ memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
+ for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
+ start = w*128;
+ for(g = 0; g < sce->ics.num_swb; g++){
+ for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
+ FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
+ if(band->energy <= band->threshold){
+ sce->sf_idx[(w+w2)*16+g] = 218;
+ sce->zeroes[(w+w2)*16+g] = 1;
+ }else{
+ sce->sf_idx[(w+w2)*16+g] = av_clip(SCALE_ONE_POS - SCALE_DIV_512 + log2(band->threshold), 80, 218);
+ sce->zeroes[(w+w2)*16+g] = 0;
+ }
+ minq = FFMIN(minq, sce->sf_idx[(w+w2)*16+g]);
+ }
+ }
+ }
+ for(i = 0; i < 128; i++){
+ sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
+ }
+ //set the same quantizers inside window groups
+ for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
+ for(g = 0; g < sce->ics.num_swb; g++)
+ for(w2 = 1; w2 < sce->ics.group_len[w]; w2++)
+ sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
+}
+
+static void search_for_quantizers(AVCodecContext *avctx, AACEncContext *s,
+ SingleChannelElement *sce)
+{
+ search_for_quantizers_anmr(s, sce, s->lambda);
+// search_for_quantizers_twoloop(avctx, s, sce, s->lambda);
+// search_for_quantizers_faac(s, sce, av_clipf(s->lambda * 2e8, 50.0f, 300.0f));
+// search_for_quantizers_fast(s, sce);
+}
+
static void search_for_ms(AACEncContext *s, ChannelElement *cpe, const float lambda)
{
int start = 0, i, w, w2, g;
@@ -833,22 +1419,22 @@ static void search_for_ms(AACEncContext
sce0->ics.swb_sizes[g],
sce0->sf_idx[(w+w2)*16+g],
sce0->band_type[(w+w2)*16+g],
- lambda / band0->threshold, INFINITY);
+ lambda / band0->threshold, INFINITY, NULL);
dist1 += quantize_band_cost(sce1->coeffs + start + w2*128,
sce1->ics.swb_sizes[g],
sce1->sf_idx[(w+w2)*16+g],
sce1->band_type[(w+w2)*16+g],
- lambda / band1->threshold, INFINITY);
+ lambda / band1->threshold, INFINITY, NULL);
dist2 += quantize_band_cost(M,
sce0->ics.swb_sizes[g],
sce0->sf_idx[(w+w2)*16+g],
sce0->band_type[(w+w2)*16+g],
- lambda / maxthr, INFINITY);
+ lambda / maxthr, INFINITY, NULL);
dist2 += quantize_band_cost(S,
sce1->ics.swb_sizes[g],
sce1->sf_idx[(w+w2)*16+g],
sce1->band_type[(w+w2)*16+g],
- lambda / minthr, INFINITY);
+ lambda / minthr, INFINITY, NULL);
}
cpe->ms_mask[w*16+g] = dist2 < dist1;
}
@@ -1031,7 +1617,7 @@ static int aac_encode_frame(AVCodecConte
s->cur_channel = start_ch + j;
apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j);
- search_for_quantizers_anmr(s, &cpe->ch[j], s->lambda);
+ search_for_quantizers(avctx, s, &cpe->ch[j]);
}
cpe->common_window = 0;
if(chans > 1
More information about the FFmpeg-soc
mailing list