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

Michael Niedermayer michaelni at gmx.at
Fri Jan 18 03:14:16 CET 2013


On Mon, Dec 24, 2012 at 05:13:15PM +0100, Bojan Zivkovic wrote:
> This patch changes existing mathematical functions with faster
> ones. Speeds up encoding more than 10%. Tested on x86 and
> MIPS platforms.
> 
> Signed-off-by: Bojan Zivkovic <bojan at mips.com>
> ---
>  libavcodec/aacpsy.c |   29 ++++++++++++++++++-----------
>  1 files changed, 18 insertions(+), 11 deletions(-)
> 
> 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



> @@ -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


>              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

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Those who are too smart to engage in politics are punished by being
governed by those who are dumber. -- Plato 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130118/98d3af20/attachment.asc>


More information about the ffmpeg-devel mailing list