[FFmpeg-devel] [PATCH] avutil: runtime cpu detection for mips
shivraj.patil at imgtec.com
shivraj.patil at imgtec.com
Wed Sep 30 15:33:46 CEST 2015
From: Shivraj Patil <shivraj.patil at imgtec.com>
Signed-off-by: Shivraj Patil <shivraj.patil at imgtec.com>
---
libavcodec/mips/hevcdsp_init_mips.c | 6 +-
libavutil/cpu.c | 35 ++++++++++
libavutil/cpu.h | 8 +++
libavutil/cpu_internal.h | 1 +
libavutil/mips/Makefile | 1 +
libavutil/mips/cpu.c | 124 +++++++++++++++++++++++++++++++++++
libavutil/mips/cpu.h | 36 ++++++++++
7 files changed, 210 insertions(+), 1 deletion(-)
create mode 100644 libavutil/mips/cpu.c
create mode 100644 libavutil/mips/cpu.h
diff --git a/libavcodec/mips/hevcdsp_init_mips.c b/libavcodec/mips/hevcdsp_init_mips.c
index 3675b93..499d2e8 100644
--- a/libavcodec/mips/hevcdsp_init_mips.c
+++ b/libavcodec/mips/hevcdsp_init_mips.c
@@ -19,6 +19,7 @@
*/
#include "libavcodec/mips/hevcdsp_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void hevc_dsp_init_msa(HEVCDSPContext *c,
@@ -449,6 +450,9 @@ static av_cold void hevc_dsp_init_msa(HEVCDSPContext *c,
void ff_hevc_dsp_init_mips(HEVCDSPContext *c, const int bit_depth)
{
#if HAVE_MSA
- hevc_dsp_init_msa(c, bit_depth);
+ int cpu_flags = av_get_cpu_flags();
+
+ if (have_msa(cpu_flags))
+ hevc_dsp_init_msa(c, bit_depth);
#endif // #if HAVE_MSA
}
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 780368d..1e716c6 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -86,6 +86,8 @@ int av_get_cpu_flags(void)
flags = ff_get_cpu_flags_ppc();
if (ARCH_X86)
flags = ff_get_cpu_flags_x86();
+ if (ARCH_MIPS)
+ flags = ff_get_cpu_flags_mips();
checked = 1;
return flags;
@@ -156,6 +158,17 @@ int av_parse_cpu_flags(const char *s)
{ "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" },
{ "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" },
{ "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" },
+#elif ARCH_MIPS
+ { "mipsfpu", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPSFPU }, .unit = "flags" },
+ { "mips32r2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPS32R2 }, .unit = "flags" },
+ { "mips32r5", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPS32R5 }, .unit = "flags" },
+ { "dspr1", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPSDSPR1 }, .unit = "flags" },
+ { "dspr2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPSDSPR2 }, .unit = "flags" },
+ { "msa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MSA }, .unit = "flags" },
+#elif ARCH_MIPS64
+ { "mipsfpu", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPSFPU }, .unit = "flags" },
+ { "mips64r6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPS64R6 }, .unit = "flags" },
+ { "msa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MSA }, .unit = "flags" },
#endif
{ NULL },
};
@@ -234,6 +247,17 @@ int av_parse_cpu_caps(unsigned *flags, const char *s)
{ "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" },
{ "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" },
{ "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" },
+#elif ARCH_MIPS
+ { "mipsfpu", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPSFPU }, .unit = "flags" },
+ { "mips32r2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPS32R2 }, .unit = "flags" },
+ { "mips32r5", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPS32R5 }, .unit = "flags" },
+ { "dspr1", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPSDSPR1 }, .unit = "flags" },
+ { "dspr2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPSDSPR2 }, .unit = "flags" },
+ { "msa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MSA }, .unit = "flags" },
+#elif ARCH_MIPS64
+ { "mipsfpu", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPSFPU }, .unit = "flags" },
+ { "mips64r6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MIPS64R6 }, .unit = "flags" },
+ { "msa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MSA }, .unit = "flags" },
#endif
{ NULL },
};
@@ -334,6 +358,17 @@ static const struct {
{ AV_CPU_FLAG_AVX2, "avx2" },
{ AV_CPU_FLAG_BMI1, "bmi1" },
{ AV_CPU_FLAG_BMI2, "bmi2" },
+#elif ARCH_MIPS
+ { AV_CPU_FLAG_MIPSFPU, "mipsfpu" },
+ { AV_CPU_FLAG_MIPS32R2, "mips32r2" },
+ { AV_CPU_FLAG_MIPS32R5, "mips32r5" },
+ { AV_CPU_FLAG_MIPSDSPR1, "dspr1" },
+ { AV_CPU_FLAG_MIPSDSPR2, "dspr2" },
+ { AV_CPU_FLAG_MSA, "msa" },
+#elif ARCH_MIPS64
+ { AV_CPU_FLAG_MIPSFPU "mipsfpu" },
+ { AV_CPU_FLAG_MIPS64R6 "mips64r6" },
+ { AV_CPU_FLAG_MSA "msa" },
#endif
{ 0 }
};
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 9403eca..a636d99 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -65,6 +65,14 @@
#define AV_CPU_FLAG_ARMV8 (1 << 6)
#define AV_CPU_FLAG_SETEND (1 <<16)
+#define AV_CPU_FLAG_MIPSFPU (1 << 0)
+#define AV_CPU_FLAG_MIPS32R2 (1 << 1)
+#define AV_CPU_FLAG_MIPS32R5 (1 << 2)
+#define AV_CPU_FLAG_MIPS64R6 (1 << 3)
+#define AV_CPU_FLAG_MIPSDSPR1 (1 << 4)
+#define AV_CPU_FLAG_MIPSDSPR2 (1 << 5)
+#define AV_CPU_FLAG_MSA (1 << 6)
+
/**
* Return the flags which specify extensions supported by the CPU.
* The returned value is affected by av_force_cpu_flags() if that was used
diff --git a/libavutil/cpu_internal.h b/libavutil/cpu_internal.h
index 2105298..bedbcfb 100644
--- a/libavutil/cpu_internal.h
+++ b/libavutil/cpu_internal.h
@@ -40,5 +40,6 @@ int ff_get_cpu_flags_aarch64(void);
int ff_get_cpu_flags_arm(void);
int ff_get_cpu_flags_ppc(void);
int ff_get_cpu_flags_x86(void);
+int ff_get_cpu_flags_mips(void);
#endif /* AVUTIL_CPU_INTERNAL_H */
diff --git a/libavutil/mips/Makefile b/libavutil/mips/Makefile
index dbfa5aa..c83c6de 100644
--- a/libavutil/mips/Makefile
+++ b/libavutil/mips/Makefile
@@ -1 +1,2 @@
OBJS += mips/float_dsp_mips.o
+OBJS += mips/cpu.o
diff --git a/libavutil/mips/cpu.c b/libavutil/mips/cpu.c
new file mode 100644
index 0000000..45ebfe1
--- /dev/null
+++ b/libavutil/mips/cpu.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale at imgtec.com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libavutil/cpu.h"
+#include "libavutil/cpu_internal.h"
+#include "libavutil/avstring.h"
+#include "config.h"
+
+#define CORE_FLAG(f) \
+ (AV_CPU_FLAG_ ## f * (HAVE_ ## f || HAVE_ ## f ## _EXTERNAL || HAVE_ ## f ## _INLINE))
+
+#define CORE_CPU_FLAGS \
+ (CORE_FLAG(MIPSFPU) | \
+ CORE_FLAG(MIPS32R2) | \
+ CORE_FLAG(MIPS32R5) | \
+ CORE_FLAG(MIPS64R6) | \
+ CORE_FLAG(MIPSDSPR1) | \
+ CORE_FLAG(MIPSDSPR2) | \
+ CORE_FLAG(MSA))
+
+#define HWCAP_VZ (1 << 0)
+#define HWCAP_EVA (1 << 1)
+#define HWCAP_HTW (1 << 2)
+#define HWCAP_FPU (1 << 3)
+#define HWCAP_MIPS32R2 (1 << 4)
+#define HWCAP_MIPS32R5 (1 << 5)
+#define HWCAP_MIPS64R6 (1 << 6)
+#define HWCAP_DSPR1 (1 << 7)
+#define HWCAP_DSPR2 (1 << 8)
+#define HWCAP_MSA (1 << 9)
+
+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, "isa", NULL)) {
+ if (strstr(buf, "mips32r2"))
+ *hwcap |= HWCAP_MIPS32R2;
+ if (strstr(buf, "mips32r5"))
+ *hwcap |= HWCAP_MIPS32R5;
+ if (strstr(buf, "mips64r6"))
+ *hwcap |= HWCAP_MIPS64R6;
+ }
+
+ if (av_strstart(buf, "ASEs implemented", NULL)) {
+ if (strstr(buf, "vz"))
+ *hwcap |= HWCAP_VZ;
+ if (strstr(buf, "eva"))
+ *hwcap |= HWCAP_EVA;
+ if (strstr(buf, "htw"))
+ *hwcap |= HWCAP_HTW;
+ if (strstr(buf, "msa"))
+ {
+ *hwcap |= HWCAP_MSA;
+ *hwcap |= HWCAP_FPU;
+ }
+ if (strstr(buf, "dsp"))
+ *hwcap |= HWCAP_DSPR1;
+ if (strstr(buf, "dsp2"))
+ *hwcap |= HWCAP_DSPR2;
+ break;
+ }
+ }
+
+ fclose(f);
+ return 0;
+}
+
+int ff_get_cpu_flags_mips(void)
+{
+ int cpuflags = CORE_CPU_FLAGS;
+ int hwcpuflags = 0;
+ uint32_t hwcap;
+
+#if !CONFIG_RUNTIME_CPUDETECT
+ return cpuflags;
+#endif
+
+ if (get_cpuinfo(&hwcap) < 0)
+ return cpuflags;
+
+#define set_cpucap(cap, flag) do { \
+ if ((hwcap & HWCAP_ ## cap) && (cpuflags & CORE_FLAG(flag))) \
+ hwcpuflags |= AV_CPU_FLAG_ ## flag; \
+ } while (0)
+
+ /* add ISA and ASE capabilities in cpuflags */
+ set_cpucap(FPU, MIPSFPU);
+ set_cpucap(MIPS32R2, MIPS32R2);
+ set_cpucap(MIPS32R5, MIPS32R5);
+ set_cpucap(MIPS64R6, MIPS64R6);
+ set_cpucap(DSPR1, MIPSDSPR1);
+ set_cpucap(DSPR2, MIPSDSPR2);
+ set_cpucap(MSA, MSA);
+
+ return hwcpuflags;
+}
diff --git a/libavutil/mips/cpu.h b/libavutil/mips/cpu.h
new file mode 100644
index 0000000..24813f6
--- /dev/null
+++ b/libavutil/mips/cpu.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale at imgtec.com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_MIPS_CPU_H
+#define AVUTIL_MIPS_CPU_H
+
+#include "config.h"
+#include "libavutil/cpu.h"
+#include "libavutil/cpu_internal.h"
+
+#define have_mipsfpu(flags) CPUEXT(flags, MIPSFPU)
+#define have_mips32r2(flags) CPUEXT(flags, MIPS32R2)
+#define have_mips32r5(flags) CPUEXT(flags, MIPS32R5)
+#define have_mips64r6(flags) CPUEXT(flags, MIPS64R6)
+#define have_mipsdspr1(flags) CPUEXT(flags, MIPSDSPR1)
+#define have_mipsdspr2(flags) CPUEXT(flags, MIPSDSPR2)
+#define have_msa(flags) CPUEXT(flags, MSA)
+
+#endif /* #ifndef AVUTIL_MIPS_CPU_H */
--
1.7.9.5
More information about the ffmpeg-devel
mailing list