[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