[FFmpeg-devel] [PATCH] Add detection for sincos usage without sincos implementation.

Raymond Toy rtoy at google.com
Wed Sep 5 19:50:42 CEST 2012


When building ffmpeg on Android, I ran into a problem where the compiler
(gcc) would convert successive calls to sin() and cos() to a single call to
sincos().  However on Android, sincos() isn't implemented so ffmpeg won't
run.

The following patch adds a configure check for the existence of sincos and
sincosf.  If they don't exist, simple versions are used (in
libavutil/mathematics.c).

Ray

 configure               |   49 ++++++++++++++++++++++++++++++++++++++++++
 libavutil/mathematics.c |   54
+++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+), 0 deletions(-)
diff --git a/configure b/configure
index 7363f9a..2ce1cf0 100755
--- a/configure
+++ b/configure
@@ -816,6 +816,49 @@ int main(void){ return (int) foo; }
 EOF
 }

+check_sincos(){
+    log check_sincos "sincos"
+    func=$1
+    ftype=$2
+    shift 2
+    if [ "$ftype" = "f" ]; then
+        vtype=float
+    else
+        vtype=double
+        ftype=
+    fi
+    disable $func
+
+    # -O is important because that enables the sincos optimization, if
+    # available.
+
+    # If this compiles and links, then one of two things are assumed
+    # to happen.  1. The compiler doesn't generate calls to sincos.
+    # 2. sincos was generated and the system includes an
+    # implementation of sincos. In either case, HAVE_SINCOS is defined
+    # so that we don't use our own version.
+
+    # If this fails, we assume sincos was generated but not
+    # implemented in any library so we use our own.
+
+    check_ld "cc" "-O $@" <<EOF && enable $func
+#include <math.h>
+void doit($vtype z, $vtype* s, $vtype* c)
+{
+  *s = sin$ftype(z);
+  *c = cos$ftype(z);
+}
+
+int main(void)
+{
+  $vtype x, y;
+
+  doit(42.0, &x, &y);
+  return 0;
+}
+EOF
+}
+
 check_func_headers(){
     log check_func_headers "$@"
     headers=$1
@@ -1290,6 +1333,8 @@ HAVE_LIST="
     setmode
     setrlimit
     Sleep
+    sincos
+    sincosf
     sndio_h
     socklen_t
     soundcard_h
@@ -3325,6 +3370,10 @@ check_mathfunc roundf
 check_mathfunc trunc
 check_mathfunc truncf

+# Check if sincos exists.
+check_sincos sincos d
+check_sincos sincosf f
+
 # these are off by default, so fail if requested and not available
 enabled avisynth   && require2 vfw32 "windows.h vfw.h" AVIFileInit
-lavifil32
 enabled fontconfig && require_pkg_config fontconfig
"fontconfig/fontconfig.h" FcInit
diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c
index 2e6a5fa..df755ad 100644
--- a/libavutil/mathematics.c
+++ b/libavutil/mathematics.c
@@ -160,3 +160,57 @@ int64_t av_compare_mod(uint64_t a, uint64_t b,
uint64_t mod){
         c-= mod;
     return c;
 }
+
+
+/*
+ * Some versions of gcc compile consecutive calls to sin/cos to a
+ * single call to sincos.  Unfortunately on some of these same systems,
+ * sincos does not exist anywhere.  So this hack implements our own
+ * version of sincos.  But we can't just do the obvious implementation
+ * of sincos because the calls to sin/cos will be converted to a
+ * single call to sincos.  Hence, sincos calls my_sin and my_cos
+ * functions.
+ */
+#if !HAVE_SINCOS
+void sincos(double x, double* s, double* c);
+double my_sin(double x);
+double my_cos(double x);
+
+void sincos(double x, double* s, double* c)
+{
+    *s = my_sin(x);
+    *c = my_cos(x);
+}
+
+double my_sin(double x)
+{
+    return sin(x);
+}
+
+double my_cos(double x)
+{
+    return cos(x);
+}
+#endif
+
+#if !HAVE_SINCOSF
+void sincosf(float x, float* s, float* c);
+double my_sinf(double x);
+double my_cosf(double x);
+
+void sincosf(float x, float* s, float* c)
+{
+    *s = my_sinf(x);
+    *c = my_cosf(x);
+}
+
+double my_sinf(double x)
+{
+    return sinf(x);
+}
+
+double my_cosf(double x)
+{
+    return cosf(x);
+}
+#endif


More information about the ffmpeg-devel mailing list