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.

---
I'm doing the string matching using strstr() with an extra space
before and after the words for simplicity, so that we don't match
substrings of features (e.g. vfpv3 vs vfpv3d16). Alternatively
this could be split off to a function checking with strstr() and
making sure the first char before and after the matched string is
either whitespace or the end of the string.

Also, I take it that vfpv3d16 shouldn't imply vfpv3 in general,
or should it?

I don't find any cpuinfo feature name that would correspond to thumbee,
so armv6t2 only gets enabled if we have vfpv3 or neon.
---
 libavutil/arm/cpu.c |   34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/libavutil/arm/cpu.c b/libavutil/arm/cpu.c
index 041afc9..888b7b5 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,43 @@ 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)) {
+            /* No way of detecting thumbee/armv6t2 */
+            if (strstr(buf, " edsp "))
+                *hwcap |= HWCAP_EDSP;
+            if (strstr(buf, " tls "))
+                *hwcap |= HWCAP_TLS;
+            if (strstr(buf, " vfp "))
+                *hwcap |= HWCAP_VFP;
+            if (strstr(buf, " vfpv3 ")) /* Not matching vfpv3d16 */
+                *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)              \
-- 
1.7.9.5

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to