00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "cpu.h"
00020 #include "config.h"
00021 #include "opt.h"
00022
00023 static int flags, checked;
00024
00025 void av_force_cpu_flags(int arg){
00026 flags = arg;
00027 checked = arg != -1;
00028 }
00029
00030 int av_get_cpu_flags(void)
00031 {
00032 if (checked)
00033 return flags;
00034
00035 if (ARCH_ARM) flags = ff_get_cpu_flags_arm();
00036 if (ARCH_PPC) flags = ff_get_cpu_flags_ppc();
00037 if (ARCH_X86) flags = ff_get_cpu_flags_x86();
00038
00039 checked = 1;
00040 return flags;
00041 }
00042
00043 void av_set_cpu_flags_mask(int mask)
00044 {
00045 checked = 0;
00046 flags = av_get_cpu_flags() & mask;
00047 checked = 1;
00048 }
00049
00050 int av_parse_cpu_flags(const char *s)
00051 {
00052 #define CPUFLAG_MMXEXT (AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT | AV_CPU_FLAG_CMOV)
00053 #define CPUFLAG_3DNOW (AV_CPU_FLAG_3DNOW | AV_CPU_FLAG_MMX)
00054 #define CPUFLAG_3DNOWEXT (AV_CPU_FLAG_3DNOWEXT | CPUFLAG_3DNOW)
00055 #define CPUFLAG_SSE (AV_CPU_FLAG_SSE | CPUFLAG_MMXEXT)
00056 #define CPUFLAG_SSE2 (AV_CPU_FLAG_SSE2 | CPUFLAG_SSE)
00057 #define CPUFLAG_SSE2SLOW (AV_CPU_FLAG_SSE2SLOW | CPUFLAG_SSE2)
00058 #define CPUFLAG_SSE3 (AV_CPU_FLAG_SSE3 | CPUFLAG_SSE2)
00059 #define CPUFLAG_SSE3SLOW (AV_CPU_FLAG_SSE3SLOW | CPUFLAG_SSE3)
00060 #define CPUFLAG_SSSE3 (AV_CPU_FLAG_SSSE3 | CPUFLAG_SSE3)
00061 #define CPUFLAG_SSE4 (AV_CPU_FLAG_SSE4 | CPUFLAG_SSSE3)
00062 #define CPUFLAG_SSE42 (AV_CPU_FLAG_SSE42 | CPUFLAG_SSE4)
00063 #define CPUFLAG_AVX (AV_CPU_FLAG_AVX | CPUFLAG_SSE42)
00064 #define CPUFLAG_XOP (AV_CPU_FLAG_XOP | CPUFLAG_AVX)
00065 #define CPUFLAG_FMA4 (AV_CPU_FLAG_FMA4 | CPUFLAG_AVX)
00066 static const AVOption cpuflags_opts[] = {
00067 { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
00068 #if ARCH_PPC
00069 { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ALTIVEC }, .unit = "flags" },
00070 #elif ARCH_X86
00071 { "mmx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX }, .unit = "flags" },
00072 { "mmxext" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_MMXEXT }, .unit = "flags" },
00073 { "sse" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE }, .unit = "flags" },
00074 { "sse2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE2 }, .unit = "flags" },
00075 { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE2SLOW }, .unit = "flags" },
00076 { "sse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE3 }, .unit = "flags" },
00077 { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE3SLOW }, .unit = "flags" },
00078 { "ssse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSSE3 }, .unit = "flags" },
00079 { "atom" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ATOM }, .unit = "flags" },
00080 { "sse4.1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE4 }, .unit = "flags" },
00081 { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE42 }, .unit = "flags" },
00082 { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX }, .unit = "flags" },
00083 { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_XOP }, .unit = "flags" },
00084 { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_FMA4 }, .unit = "flags" },
00085 { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOW }, .unit = "flags" },
00086 { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOWEXT }, .unit = "flags" },
00087 { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" },
00088 #elif ARCH_ARM
00089 { "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV5TE }, .unit = "flags" },
00090 { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6 }, .unit = "flags" },
00091 { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" },
00092 { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" },
00093 { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" },
00094 { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" },
00095 #endif
00096 { NULL },
00097 };
00098 static const AVClass class = {
00099 .class_name = "cpuflags",
00100 .item_name = av_default_item_name,
00101 .option = cpuflags_opts,
00102 .version = LIBAVUTIL_VERSION_INT,
00103 };
00104
00105 int flags = 0, ret;
00106 const AVClass *pclass = &class;
00107
00108 if ((ret = av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, &flags)) < 0)
00109 return ret;
00110
00111 return flags & INT_MAX;
00112 }
00113
00114 int av_parse_cpu_caps(unsigned *flags, const char *s)
00115 {
00116 static const AVOption cpuflags_opts[] = {
00117 { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
00118 #if ARCH_PPC
00119 { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ALTIVEC }, .unit = "flags" },
00120 #elif ARCH_X86
00121 { "mmx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX }, .unit = "flags" },
00122 { "mmx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX2 }, .unit = "flags" },
00123 { "mmxext" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX2 }, .unit = "flags" },
00124 { "sse" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE }, .unit = "flags" },
00125 { "sse2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE2 }, .unit = "flags" },
00126 { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE2SLOW }, .unit = "flags" },
00127 { "sse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE3 }, .unit = "flags" },
00128 { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE3SLOW }, .unit = "flags" },
00129 { "ssse3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSSE3 }, .unit = "flags" },
00130 { "atom" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ATOM }, .unit = "flags" },
00131 { "sse4.1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE4 }, .unit = "flags" },
00132 { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE42 }, .unit = "flags" },
00133 { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX }, .unit = "flags" },
00134 { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_XOP }, .unit = "flags" },
00135 { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_FMA4 }, .unit = "flags" },
00136 { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOW }, .unit = "flags" },
00137 { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOWEXT }, .unit = "flags" },
00138 #elif ARCH_ARM
00139 { "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV5TE }, .unit = "flags" },
00140 { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6 }, .unit = "flags" },
00141 { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" },
00142 { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" },
00143 { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" },
00144 { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" },
00145 #endif
00146 { NULL },
00147 };
00148 static const AVClass class = {
00149 .class_name = "cpuflags",
00150 .item_name = av_default_item_name,
00151 .option = cpuflags_opts,
00152 .version = LIBAVUTIL_VERSION_INT,
00153 };
00154 const AVClass *pclass = &class;
00155
00156 return av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, flags);
00157 }
00158 #ifdef TEST
00159
00160 #undef printf
00161 #include <stdio.h>
00162
00163 static const struct {
00164 int flag;
00165 const char *name;
00166 } cpu_flag_tab[] = {
00167 #if ARCH_ARM
00168 { AV_CPU_FLAG_ARMV5TE, "armv5te" },
00169 { AV_CPU_FLAG_ARMV6, "armv6" },
00170 { AV_CPU_FLAG_ARMV6T2, "armv6t2" },
00171 { AV_CPU_FLAG_VFP, "vfp" },
00172 { AV_CPU_FLAG_VFPV3, "vfpv3" },
00173 { AV_CPU_FLAG_NEON, "neon" },
00174 #elif ARCH_PPC
00175 { AV_CPU_FLAG_ALTIVEC, "altivec" },
00176 #elif ARCH_X86
00177 { AV_CPU_FLAG_MMX, "mmx" },
00178 { AV_CPU_FLAG_MMXEXT, "mmxext" },
00179 { AV_CPU_FLAG_SSE, "sse" },
00180 { AV_CPU_FLAG_SSE2, "sse2" },
00181 { AV_CPU_FLAG_SSE2SLOW, "sse2(slow)" },
00182 { AV_CPU_FLAG_SSE3, "sse3" },
00183 { AV_CPU_FLAG_SSE3SLOW, "sse3(slow)" },
00184 { AV_CPU_FLAG_SSSE3, "ssse3" },
00185 { AV_CPU_FLAG_ATOM, "atom" },
00186 { AV_CPU_FLAG_SSE4, "sse4.1" },
00187 { AV_CPU_FLAG_SSE42, "sse4.2" },
00188 { AV_CPU_FLAG_AVX, "avx" },
00189 { AV_CPU_FLAG_XOP, "xop" },
00190 { AV_CPU_FLAG_FMA4, "fma4" },
00191 { AV_CPU_FLAG_3DNOW, "3dnow" },
00192 { AV_CPU_FLAG_3DNOWEXT, "3dnowext" },
00193 { AV_CPU_FLAG_CMOV, "cmov" },
00194 #endif
00195 { 0 }
00196 };
00197
00198 int main(void)
00199 {
00200 int cpu_flags = av_get_cpu_flags();
00201 int i;
00202
00203 printf("cpu_flags = 0x%08X\n", cpu_flags);
00204 printf("cpu_flags =");
00205 for (i = 0; cpu_flag_tab[i].flag; i++)
00206 if (cpu_flags & cpu_flag_tab[i].flag)
00207 printf(" %s", cpu_flag_tab[i].name);
00208 printf("\n");
00209
00210 return 0;
00211 }
00212
00213 #endif