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

Reimar Döffinger Reimar.Doeffinger at gmx.de
Thu Nov 22 19:43:10 CET 2012


On Thu, Nov 22, 2012 at 02:11:53PM +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, 15 insertions(+), 14 deletions(-)
> 
> diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
> index fa562b3..8a57d86 100644
> --- a/libavcodec/aacpsy.c
> +++ b/libavcodec/aacpsy.c
> @@ -330,12 +330,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 * 6.9077553f);
> +            coeff->spread_hi [0] = exp(-bark_width * 3.4538776f);
> +            coeff->spread_low[1] = exp(-bark_width * en_spread_low * 2.302585f);
> +            coeff->spread_hi [1] = exp(-bark_width * en_spread_hi  * 2.302585f);

You should avoid that kind of magic constants, they should be a define,
and you should leave it to the compiler to calculate
PSY_3GPP_THR_SPREAD_LOW * 2.302585f.

> -            minsnr = exp2(pe_min / band_sizes[g]) - 1.5f;
> +            minsnr = exp(0.693147f * pe_min / band_sizes[g]) - 1.5f;

In all cases, a question is why the compiler doesn't do that
optimization and if that reason is an issue for us.
In addition, doing the multiplication with single precision
while doing the exponentiation with double precision seems just wrong to
me.

> @@ -582,13 +581,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);
>              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);

I expect this to significantly change the precision of the calculation.
I don't know whether this might not be an issue though.


More information about the ffmpeg-devel mailing list