1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-21 10:55:51 +02:00

lavu/libm: add exp10 support

exp10 is a function available in GNU libm. Looks like no other common
libm has it. This adds support for it to FFmpeg.

There are essentially 2 ways of handling the fallback:
1. Using pow(10, x)
2. Using exp2(M_LOG2_10 * x).

First one represents a Pareto improvement, with no speed or accuracy
regression anywhere, but speed improvement limited to GNU libm.

Second one represents a slight accuracy loss (relative error ~ 1e-13)
for non GNU libm. Speedup of > 2x is obtained on non GNU libm platforms,
~30% on GNU libm. These are "average case numbers", another benefit is
the lack of triggering of the well-known terrible worst case paths
through pow.

Based on reviews, second one chosen. Comment added accordingly.

Reviewed-by: Hendrik Leppkes <h.leppkes@gmail.com>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Reviewed-by: Ronald S. Bultje <rsbultje@gmail.com>
Signed-off-by: Ganesh Ajjanagadde <gajjanagadde@gmail.com>
This commit is contained in:
Ganesh Ajjanagadde 2015-12-21 19:05:00 -08:00
parent 520a5d33f0
commit e29db08cf7
2 changed files with 21 additions and 0 deletions

2
configure vendored
View File

@ -1815,6 +1815,8 @@ MATH_FUNCS="
copysign
cosf
erf
exp10
exp10f
exp2
exp2f
expf

View File

@ -29,6 +29,7 @@
#include "config.h"
#include "attributes.h"
#include "intfloat.h"
#include "mathematics.h"
#if HAVE_MIPSFPU && HAVE_INLINE_ASM
#include "libavutil/mips/libm_mips.h"
@ -292,6 +293,24 @@ static inline double erf(double z)
#define exp2f(x) ((float)exp2(x))
#endif /* HAVE_EXP2F */
/* Somewhat inaccurate fallbacks, relative error ~ 1e-13 concentrated on very
small and very large values. For perfection accuracy-wise, should use pow.
Speed benefits (>2x average, with no super slow paths) deemed to be worth the
accuracy tradeoff */
#if !HAVE_EXP10
static av_always_inline double exp10(double x)
{
return exp2(M_LOG2_10 * x);
}
#endif /* HAVE_EXP10 */
#if !HAVE_EXP10F
static av_always_inline float exp10f(float x)
{
return exp2f(M_LOG2_10 * x);
}
#endif /* HAVE_EXP10F */
#if !HAVE_ISINF
#undef isinf
/* Note: these do not follow the BSD/Apple/GNU convention of returning -1 for