[FFmpeg-devel] [PATCH 1/2] libavcodec: changed mathematical functions in aacpsy.c

Zivkovic, Bojan (c) bojan at mips.com
Wed Jan 23 13:46:29 CET 2013


Hello!

> > diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
> > index d77b3de..cd70247 100644
> > --- a/libavcodec/aacpsy.c
> > +++ b/libavcodec/aacpsy.c
> > @@ -78,6 +78,9 @@
> >  
> >  #define PSY_3GPP_AH_THR_LONG    0.5f
> >  #define PSY_3GPP_AH_THR_SHORT   0.63f
> > +#define PSY_LN_10               log(10)
> > +#define PSY_3GPP_REDUCTION      0.1732868f    /* 0.25f * ln(0.5f) */
> > +#define PSY_3GPP_LN_2           log(2.0f)
> >  
> >  enum {
> >      PSY_3GPP_AH_NONE,
> 
> > @@ -330,12 +333,12 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) {
> >          for (g = 0; g < ctx->num_bands[j] - 1; g++) {
> >              AacPsyCoeffs *coeff = &coeffs[g];
> >              float bark_width = coeffs[g+1].barks - coeffs->barks;
> > -            coeff->spread_low[0] = pow(10.0, -bark_width * PSY_3GPP_THR_SPREAD_LOW);
> > -            coeff->spread_hi [0] = pow(10.0, -bark_width * PSY_3GPP_THR_SPREAD_HI);
> > -            coeff->spread_low[1] = pow(10.0, -bark_width * en_spread_low);
> > -            coeff->spread_hi [1] = pow(10.0, -bark_width * en_spread_hi);
> > +            coeff->spread_low[0] = exp(-bark_width * PSY_3GPP_THR_SPREAD_HI * PSY_LN_10);
> > +            coeff->spread_hi [0] = exp(-bark_width * PSY_3GPP_THR_SPREAD_HI * PSY_LN_10);
> > +            coeff->spread_low[1] = exp(-bark_width * en_spread_low * PSY_LN_10);
> > +            coeff->spread_hi [1] = exp(-bark_width * en_spread_hi  * PSY_LN_10);
> >              pe_min = bark_pe * bark_width;
> > -            minsnr = exp2(pe_min / band_sizes[g]) - 1.5f;
> > +            minsnr = expf(PSY_3GPP_LN_2 * pe_min / band_sizes[g]) - 1.5f;
> >              coeff->min_snr = av_clipf(1.0f / minsnr, PSY_SNR_25DB, PSY_SNR_1DB);
> >          }
> >          start = 0;
> 
> This function is only executed once, so i suspect it has little if any
> effect on speed

You are right, I will remove the changes.

> > @@ -529,8 +532,8 @@ static float calc_reduction_3gpp(float a, float desired_pe, float pe,
> >      if(active_lines == 0.0)
> >          return 0;
> >  
> > -    thr_avg   = exp2f((a - pe) / (4.0f * active_lines));
> > -    reduction = exp2f((a - desired_pe) / (4.0f * active_lines)) - thr_avg;
> > +    thr_avg   = exp(PSY_3GPP_REDUCTION * (a - pe) / active_lines);
> > +    reduction = exp(PSY_3GPP_REDUCTION * (a - desired_pe) / active_lines) - thr_avg;
> >  
> >      return FFMAX(reduction, 0.0f);
> >  }
> > @@ -541,8 +544,10 @@ static float calc_reduced_thr_3gpp(AacPsyBand *band, float min_snr,
> >      float thr = band->thr;
> >  
> >      if (band->energy > thr) {
> > -        thr = powf(thr, 0.25f) + reduction;
> > -        thr = powf(thr, 4.0f);
> > +        thr = sqrtf(thr);
> > +        thr = sqrtf(thr) + reduction;
> > +        thr *= thr;
> > +        thr *= thr;
> >  
> >          /* This deviates from the 3GPP spec to match the reference encoder.
> >           * It performs min(thr_reduced, max(thr, energy/min_snr)) only for bands
> > @@ -582,13 +587,15 @@ static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel,
> >              AacPsyBand *band = &pch->band[w+g];
> >  
> >              float form_factor = 0.0f;
> > +            float Temp;
> >              band->energy = 0.0f;
> >              for (i = 0; i < band_sizes[g]; i++) {
> >                  band->energy += coefs[start+i] * coefs[start+i];
> >                  form_factor  += sqrtf(fabs(coefs[start+i]));
> >              }
> > +            Temp = sqrtf((float)band_sizes[g] / band->energy);
> 
> division by 0 may be possible here

Will be fixed.

> >              band->thr      = band->energy * 0.001258925f;
> > -            band->nz_lines = band->energy>0 ? form_factor / powf(band->energy / band_sizes[g], 0.25f) : 0;
> > +            band->nz_lines = form_factor * sqrtf(Temp);
> >  
> >              start += band_sizes[g];
> >          }
> > @@ -708,7 +715,7 @@ static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel,
>                                                            
> >                          float delta_sfb_pe = band->norm_fac * norm_fac * delta_pe;
> >                          float thr = band->thr;
> >  
> > -                        thr *= exp2f(delta_sfb_pe / band->active_lines);
> > +                        thr *= exp(PSY_3GPP_LN_2 * delta_sfb_pe / band->active_lines);
> 
> If exp(C*x) is faster then exp2f(x) with some compiler then you could
> just replace exp2f through some #define from a header everywhere

Should I check if the compiler is GCC,and if the case is true define this function in one way,
otherwise in other? Can you give me an advice how to check which compiler was used?
This was compiled using GCC compiler.

-Bojan


More information about the ffmpeg-devel mailing list