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_MMX2 (AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMX2)
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_MMX2)
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, { 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
00068 #if ARCH_PPC
00069 { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ALTIVEC }, .unit = "flags" },
00070 #elif ARCH_X86
00071 { "mmx" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_MMX }, .unit = "flags" },
00072 { "mmx2" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_MMX2 }, .unit = "flags" },
00073 { "sse" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_SSE }, .unit = "flags" },
00074 { "sse2" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_SSE2 }, .unit = "flags" },
00075 { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_SSE2SLOW }, .unit = "flags" },
00076 { "sse3" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_SSE3 }, .unit = "flags" },
00077 { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_SSE3SLOW }, .unit = "flags" },
00078 { "ssse3" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_SSSE3 }, .unit = "flags" },
00079 { "atom" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ATOM }, .unit = "flags" },
00080 { "sse4.1" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_SSE4 }, .unit = "flags" },
00081 { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_SSE42 }, .unit = "flags" },
00082 { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_AVX }, .unit = "flags" },
00083 { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_XOP }, .unit = "flags" },
00084 { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_FMA4 }, .unit = "flags" },
00085 { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_3DNOW }, .unit = "flags" },
00086 { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { CPUFLAG_3DNOWEXT }, .unit = "flags" },
00087 #elif ARCH_ARM
00088 { "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV5TE }, .unit = "flags" },
00089 { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV6 }, .unit = "flags" },
00090 { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" },
00091 { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_VFP }, .unit = "flags" },
00092 { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_VFPV3 }, .unit = "flags" },
00093 { "neon", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_NEON }, .unit = "flags" },
00094 #endif
00095 { NULL },
00096 };
00097 static const AVClass class = {
00098 .class_name = "cpuflags",
00099 .item_name = av_default_item_name,
00100 .option = cpuflags_opts,
00101 .version = LIBAVUTIL_VERSION_INT,
00102 };
00103
00104 int flags = 0, ret;
00105 const AVClass *pclass = &class;
00106
00107 if ((ret = av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, &flags)) < 0)
00108 return ret;
00109
00110 return flags & INT_MAX;
00111 }
00112
00113 int av_parse_cpu_caps(unsigned *flags, const char *s)
00114 {
00115 static const AVOption cpuflags_opts[] = {
00116 { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
00117 #if ARCH_PPC
00118 { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ALTIVEC }, .unit = "flags" },
00119 #elif ARCH_X86
00120 { "mmx" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_MMX }, .unit = "flags" },
00121 { "mmx2" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_MMX2 }, .unit = "flags" },
00122 { "sse" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE }, .unit = "flags" },
00123 { "sse2" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE2 }, .unit = "flags" },
00124 { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE2SLOW }, .unit = "flags" },
00125 { "sse3" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE3 }, .unit = "flags" },
00126 { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE3SLOW }, .unit = "flags" },
00127 { "ssse3" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSSE3 }, .unit = "flags" },
00128 { "atom" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ATOM }, .unit = "flags" },
00129 { "sse4.1" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE4 }, .unit = "flags" },
00130 { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE42 }, .unit = "flags" },
00131 { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_AVX }, .unit = "flags" },
00132 { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_XOP }, .unit = "flags" },
00133 { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_FMA4 }, .unit = "flags" },
00134 { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_3DNOW }, .unit = "flags" },
00135 { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_3DNOWEXT }, .unit = "flags" },
00136 #elif ARCH_ARM
00137 { "armv5te", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV5TE }, .unit = "flags" },
00138 { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV6 }, .unit = "flags" },
00139 { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" },
00140 { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_VFP }, .unit = "flags" },
00141 { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_VFPV3 }, .unit = "flags" },
00142 { "neon", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_NEON }, .unit = "flags" },
00143 #endif
00144 { NULL },
00145 };
00146 static const AVClass class = {
00147 .class_name = "cpuflags",
00148 .item_name = av_default_item_name,
00149 .option = cpuflags_opts,
00150 .version = LIBAVUTIL_VERSION_INT,
00151 };
00152 const AVClass *pclass = &class;
00153
00154 return av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, flags);
00155 }
00156 #ifdef TEST
00157
00158 #undef printf
00159 #include <stdio.h>
00160
00161 static const struct {
00162 int flag;
00163 const char *name;
00164 } cpu_flag_tab[] = {
00165 #if ARCH_ARM
00166 { AV_CPU_FLAG_ARMV5TE, "armv5te" },
00167 { AV_CPU_FLAG_ARMV6, "armv6" },
00168 { AV_CPU_FLAG_ARMV6T2, "armv6t2" },
00169 { AV_CPU_FLAG_VFP, "vfp" },
00170 { AV_CPU_FLAG_VFPV3, "vfpv3" },
00171 { AV_CPU_FLAG_NEON, "neon" },
00172 #elif ARCH_PPC
00173 { AV_CPU_FLAG_ALTIVEC, "altivec" },
00174 #elif ARCH_X86
00175 { AV_CPU_FLAG_MMX, "mmx" },
00176 { AV_CPU_FLAG_MMX2, "mmx2" },
00177 { AV_CPU_FLAG_SSE, "sse" },
00178 { AV_CPU_FLAG_SSE2, "sse2" },
00179 { AV_CPU_FLAG_SSE2SLOW, "sse2(slow)" },
00180 { AV_CPU_FLAG_SSE3, "sse3" },
00181 { AV_CPU_FLAG_SSE3SLOW, "sse3(slow)" },
00182 { AV_CPU_FLAG_SSSE3, "ssse3" },
00183 { AV_CPU_FLAG_ATOM, "atom" },
00184 { AV_CPU_FLAG_SSE4, "sse4.1" },
00185 { AV_CPU_FLAG_SSE42, "sse4.2" },
00186 { AV_CPU_FLAG_AVX, "avx" },
00187 { AV_CPU_FLAG_XOP, "xop" },
00188 { AV_CPU_FLAG_FMA4, "fma4" },
00189 { AV_CPU_FLAG_3DNOW, "3dnow" },
00190 { AV_CPU_FLAG_3DNOWEXT, "3dnowext" },
00191 #endif
00192 { 0 }
00193 };
00194
00195 int main(void)
00196 {
00197 int cpu_flags = av_get_cpu_flags();
00198 int i;
00199
00200 printf("cpu_flags = 0x%08X\n", cpu_flags);
00201 printf("cpu_flags =");
00202 for (i = 0; cpu_flag_tab[i].flag; i++)
00203 if (cpu_flags & cpu_flag_tab[i].flag)
00204 printf(" %s", cpu_flag_tab[i].name);
00205 printf("\n");
00206
00207 return 0;
00208 }
00209
00210 #endif