diff --git a/libavcodec/aacenc_utils.h b/libavcodec/aacenc_utils.h index 41a62961e1..07f733746b 100644 --- a/libavcodec/aacenc_utils.h +++ b/libavcodec/aacenc_utils.h @@ -28,6 +28,7 @@ #ifndef AVCODEC_AACENC_UTILS_H #define AVCODEC_AACENC_UTILS_H +#include "libavutil/internal.h" #include "aac.h" #include "aacenctab.h" #include "aactab.h" @@ -122,7 +123,10 @@ static inline float find_form_factor(int group_len, int swb_size, float thresh, if (s >= ethresh) { nzl += 1.0f; } else { - nzl += powf(s / ethresh, nzslope); + if (nzslope == 2.f) + nzl += (s / ethresh) * (s / ethresh); + else + nzl += ff_fast_powf(s / ethresh, nzslope); } } if (e2 > thresh) { diff --git a/libavutil/internal.h b/libavutil/internal.h index da76ca26d3..340e18bc5d 100644 --- a/libavutil/internal.h +++ b/libavutil/internal.h @@ -314,6 +314,22 @@ static av_always_inline float ff_exp10f(float x) return exp2f(M_LOG2_10 * x); } +/** + * Compute x^y for floating point x, y. Note: this function is faster than the + * libm variant due to mainly 2 reasons: + * 1. It does not handle any edge cases. In particular, this is only guaranteed + * to work correctly for x > 0. + * 2. It is not as accurate as a standard nearly "correctly rounded" libm variant. + * @param x base + * @param y exponent + * @return x^y + */ +static av_always_inline float ff_fast_powf(float x, float y) +{ + return expf(logf(x) * y); +} + + /** * A wrapper for open() setting O_CLOEXEC. */