[FFmpeg-cvslog] configure+libm.h: add hypot emulation

Ganesh Ajjanagadde git at videolan.org
Sat Nov 21 14:52:59 CET 2015


ffmpeg | branch: master | Ganesh Ajjanagadde <gajjanagadde at gmail.com> | Sat Nov 14 11:57:28 2015 -0500| [275aca8fba50e77af16627d8d5db4b3d4987d889] | committer: Ganesh Ajjanagadde

configure+libm.h: add hypot emulation

It is known that the naive sqrt(x*x + y*y) approach for computing the
hypotenuse suffers from overflow and accuracy issues, see e.g
http://www.johndcook.com/blog/2010/06/02/whats-so-hard-about-finding-a-hypotenuse/.
This adds hypot support to FFmpeg, a C99 function.

On platforms without hypot, this patch does a reaonable workaround, that
although not as accurate as GNU libm, is readable and does not suffer
from the overflow issue. Improvements can be made separately.

Reviewed-by: Michael Niedermayer <michael at niedermayer.cc>
Signed-off-by: Ganesh Ajjanagadde <gajjanagadde at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=275aca8fba50e77af16627d8d5db4b3d4987d889
---

 configure        |    2 ++
 libavutil/libm.h |   23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/configure b/configure
index 9a736ce..4a28836 100755
--- a/configure
+++ b/configure
@@ -1773,6 +1773,7 @@ MATH_FUNCS="
     exp2
     exp2f
     expf
+    hypot
     isinf
     isnan
     ldexpf
@@ -5308,6 +5309,7 @@ disabled crystalhd || check_lib libcrystalhd/libcrystalhd_if.h DtsCrystalHDVersi
 
 atan2f_args=2
 copysign_args=2
+hypot_args=2
 ldexpf_args=2
 powf_args=2
 
diff --git a/libavutil/libm.h b/libavutil/libm.h
index 221c286..9e5ec5d 100644
--- a/libavutil/libm.h
+++ b/libavutil/libm.h
@@ -132,6 +132,29 @@ static av_always_inline av_const int avpriv_isnan(double x)
         : avpriv_isnan(x))
 #endif /* HAVE_ISNAN */
 
+#if !HAVE_HYPOT
+#undef hypot
+static inline av_const double hypot(double x, double y)
+{
+    double ret, temp;
+    x = fabs(x);
+    y = fabs(y);
+
+    if (isinf(x) || isinf(y))
+        return av_int2double(0x7ff0000000000000);
+    if (x == 0 || y == 0)
+        return x + y;
+    if (x < y) {
+        temp = x;
+        x = y;
+        y = temp;
+    }
+
+    y = y/x;
+    return x*sqrt(1 + y*y);
+}
+#endif /* HAVE_HYPOT */
+
 #if !HAVE_LDEXPF
 #undef ldexpf
 #define ldexpf(x, exp) ((float)ldexp(x, exp))



More information about the ffmpeg-cvslog mailing list