00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "libavutil/cpu.h"
00020 #include "config.h"
00021
00022 #define CORE_FLAG(f) \
00023 (AV_CPU_FLAG_ ## f * (HAVE_ ## f ## _EXTERNAL || HAVE_ ## f ## _INLINE))
00024
00025 #define CORE_CPU_FLAGS \
00026 (CORE_FLAG(ARMV5TE) | \
00027 CORE_FLAG(ARMV6) | \
00028 CORE_FLAG(ARMV6T2) | \
00029 CORE_FLAG(VFP) | \
00030 CORE_FLAG(VFPV3) | \
00031 CORE_FLAG(NEON))
00032
00033 #if defined __linux__ || defined __ANDROID__
00034
00035 #include <stdint.h>
00036 #include <stdio.h>
00037
00038 #define AT_HWCAP 16
00039
00040
00041 #define HWCAP_VFP (1 << 6)
00042 #define HWCAP_EDSP (1 << 7)
00043 #define HWCAP_THUMBEE (1 << 11)
00044 #define HWCAP_NEON (1 << 12)
00045 #define HWCAP_VFPv3 (1 << 13)
00046 #define HWCAP_TLS (1 << 15)
00047
00048 static int get_hwcap(uint32_t *hwcap)
00049 {
00050 struct { uint32_t a_type; uint32_t a_val; } auxv;
00051 FILE *f = fopen("/proc/self/auxv", "r");
00052 int err = -1;
00053
00054 if (!f)
00055 return -1;
00056
00057 while (fread(&auxv, sizeof(auxv), 1, f) > 0) {
00058 if (auxv.a_type == AT_HWCAP) {
00059 *hwcap = auxv.a_val;
00060 err = 0;
00061 break;
00062 }
00063 }
00064
00065 fclose(f);
00066 return err;
00067 }
00068
00069 int ff_get_cpu_flags_arm(void)
00070 {
00071 int flags = CORE_CPU_FLAGS;
00072 uint32_t hwcap;
00073
00074 if (get_hwcap(&hwcap) < 0)
00075 return flags;
00076
00077 #define check_cap(cap, flag) do { \
00078 if (hwcap & HWCAP_ ## cap) \
00079 flags |= AV_CPU_FLAG_ ## flag; \
00080 } while (0)
00081
00082
00083
00084 check_cap(EDSP, ARMV5TE);
00085 check_cap(TLS, ARMV6);
00086 check_cap(THUMBEE, ARMV6T2);
00087 check_cap(VFP, VFP);
00088 check_cap(VFPv3, VFPV3);
00089 check_cap(NEON, NEON);
00090
00091
00092
00093 if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON))
00094 flags |= AV_CPU_FLAG_ARMV6T2;
00095 if (flags & AV_CPU_FLAG_ARMV6T2)
00096 flags |= AV_CPU_FLAG_ARMV6;
00097
00098 return flags;
00099 }
00100
00101 #else
00102
00103 int ff_get_cpu_flags_arm(void)
00104 {
00105 return AV_CPU_FLAG_ARMV5TE * HAVE_ARMV5TE |
00106 AV_CPU_FLAG_ARMV6 * HAVE_ARMV6 |
00107 AV_CPU_FLAG_ARMV6T2 * HAVE_ARMV6T2 |
00108 AV_CPU_FLAG_VFP * HAVE_VFP |
00109 AV_CPU_FLAG_VFPV3 * HAVE_VFPV3 |
00110 AV_CPU_FLAG_NEON * HAVE_NEON;
00111 }
00112
00113 #endif