[FFmpeg-soc] [soc]: r2689 - aacenc/aacpsy.c
kostya
subversion at mplayerhq.hu
Sat Jul 5 12:13:37 CEST 2008
Author: kostya
Date: Sat Jul 5 12:13:36 2008
New Revision: 2689
Log:
Make null psy model produce better scales
Modified:
aacenc/aacpsy.c
Modified: aacenc/aacpsy.c
==============================================================================
--- aacenc/aacpsy.c (original)
+++ aacenc/aacpsy.c Sat Jul 5 12:13:36 2008
@@ -55,6 +55,24 @@ static inline int convert_coeffs(float *
return sum;
}
+static inline float unquant(int q, int scale_idx){
+ return (FFABS(q) * cbrt(q*1.0)) * pow2sf_tab[200 + scale_idx - SCALE_ONE_POS];
+}
+static inline float calc_distortion(float *c, int size, int scale_idx)
+{
+ int i;
+ int q;
+ float coef, unquant, sum = 0.0f;
+ for(i = 0; i < size; i++){
+ coef = FFABS(c[i]);
+ q = (int)(pow(FFABS(coef) * pow2sf_tab[200 - scale_idx + SCALE_ONE_POS], 0.75) + 0.4054);
+ q = av_clip(q, 0, 8191);
+ unquant = (q * cbrt(q)) * pow2sf_tab[200 + scale_idx - SCALE_ONE_POS];
+ sum += (coef - unquant) * (coef - unquant);
+ }
+ return sum;
+}
+
/**
* Produce integer coefficients from scalefactors provided by model.
*/
@@ -165,24 +183,39 @@ static void psy_null_process(AACPsyConte
{
int start;
int ch, g, i;
+ int minscale;
- //detect M/S
- if(apc->avctx->channels > 1 && cpe->common_window){
+ for(ch = 0; ch < apc->avctx->channels; ch++){
start = 0;
for(g = 0; g < apc->num_bands1024; g++){
- float diff = 0.0f;
+ float energy = 0.0f, ffac = 0.0f, thr, dist;
- for(i = 0; i < apc->bands1024[g]; i++)
- diff += fabs(cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i]);
- cpe->ms.mask[0][g] = diff == 0.0;
+ for(i = 0; i < apc->bands1024[g]; i++){
+ energy += cpe->ch[ch].coeffs[start+i]*cpe->ch[ch].coeffs[start+i];
+ ffac += sqrt(FFABS(cpe->ch[ch].coeffs[start+i]));
+ }
+ thr = energy * 0.001258925f;
+ cpe->ch[ch].sf_idx[ch][g] = 136;
+ cpe->ch[ch].zeroes[ch][g] = (energy == 0.0);
+ if(cpe->ch[ch].zeroes[ch][g]) continue;
+ minscale = (int)(2.66667 * (log2(6.75*thr) - log2(ffac)));
+ cpe->ch[ch].sf_idx[ch][g] = SCALE_ONE_POS - minscale;
+ while(cpe->ch[ch].sf_idx[ch][g] > 3){
+ dist = calc_distortion(cpe->ch[ch].coeffs + start, apc->bands1024[g], cpe->ch[ch].sf_idx[ch][g]);
+ if(dist < thr) break;
+ cpe->ch[ch].sf_idx[ch][g] -= 3;
+ }
}
}
for(ch = 0; ch < apc->avctx->channels; ch++){
- cpe->ch[ch].gain = SCALE_ONE_POS;
- for(g = 0; g < apc->num_bands1024; g++){
- cpe->ch[ch].sf_idx[0][g] = SCALE_ONE_POS;
- cpe->ch[ch].zeroes[0][g] = 0;
- }
+ minscale = 255;
+ for(g = 0; g < apc->num_bands1024; g++)
+ if(!cpe->ch[ch].zeroes[0][g])
+ minscale = FFMIN(minscale, cpe->ch[ch].sf_idx[0][g]);
+ cpe->ch[ch].gain = minscale;
+ for(g = 0; g < apc->num_bands1024; g++)
+ if(!cpe->ch[ch].zeroes[0][g])
+ cpe->ch[ch].sf_idx[0][g] = FFMIN(minscale + SCALE_MAX_DIFF, cpe->ch[ch].sf_idx[0][g]);
}
psy_create_output(apc, cpe, 1);
}
More information about the FFmpeg-soc
mailing list