aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2013-02-07 10:54:20 +0200
committerMartin Storsjö <martin@martin.st>2013-02-14 10:39:23 +0200
commit5310da7e83ec9f149dac4c2c5a64e1a24951259e (patch)
tree3298ebac261856fa835edb7448378e6548afa756
parent4eede1fca24a24e10befab1716e042beccee8df9 (diff)
downloadffmpeg-5310da7e83ec9f149dac4c2c5a64e1a24951259e.tar.gz
arm: Fall back to runtime cpu feature detection via /proc/cpuinfo
On recent android versions, /proc/self/auxw is unreadable (unless the process is running running under the shell uid or in debuggable mode, which makes it hard to notice). See http://b.android.com/43055 and https://android-review.googlesource.com/51271 for more information about the issue. This makes sure e.g. neon optimizations are enabled at runtime in android apps even when built in release mode, if configured to use the runtime detection. CC: libav-stable@libav.org Signed-off-by: Martin Storsjö <martin@martin.st> (cherry picked from commit ab8f1a698990c33afb4c1c6ae5af3d6de4f696cb) Signed-off-by: Martin Storsjö <martin@martin.st>
-rw-r--r--libavutil/arm/cpu.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/libavutil/arm/cpu.c b/libavutil/arm/cpu.c
index 041afc985a..b4aabc375e 100644
--- a/libavutil/arm/cpu.c
+++ b/libavutil/arm/cpu.c
@@ -34,6 +34,8 @@
#include <stdint.h>
#include <stdio.h>
+#include <string.h>
+#include "libavutil/avstring.h"
#define AT_HWCAP 16
@@ -66,13 +68,44 @@ static int get_hwcap(uint32_t *hwcap)
return err;
}
+static int get_cpuinfo(uint32_t *hwcap)
+{
+ FILE *f = fopen("/proc/cpuinfo", "r");
+ char buf[200];
+
+ if (!f)
+ return -1;
+
+ *hwcap = 0;
+ while (fgets(buf, sizeof(buf), f)) {
+ if (av_strstart(buf, "Features", NULL)) {
+ if (strstr(buf, " edsp "))
+ *hwcap |= HWCAP_EDSP;
+ if (strstr(buf, " tls "))
+ *hwcap |= HWCAP_TLS;
+ if (strstr(buf, " thumbee "))
+ *hwcap |= HWCAP_THUMBEE;
+ if (strstr(buf, " vfp "))
+ *hwcap |= HWCAP_VFP;
+ if (strstr(buf, " vfpv3 "))
+ *hwcap |= HWCAP_VFPv3;
+ if (strstr(buf, " neon "))
+ *hwcap |= HWCAP_NEON;
+ break;
+ }
+ }
+ fclose(f);
+ return 0;
+}
+
int ff_get_cpu_flags_arm(void)
{
int flags = CORE_CPU_FLAGS;
uint32_t hwcap;
if (get_hwcap(&hwcap) < 0)
- return flags;
+ if (get_cpuinfo(&hwcap) < 0)
+ return flags;
#define check_cap(cap, flag) do { \
if (hwcap & HWCAP_ ## cap) \