@@ -5803,6 +5803,7 @@ elif enabled mips; then
enabled loongson3 && check_inline_asm_flags loongson3 '"gsldxc1 $f0, 0($2, $3)"' '-march=loongson3a'
enabled loongson2 && enabled mmi && check_inline_asm mmi '"punpcklhw $f0, $f0, $f0"'
enabled loongson3 && enabled mmi && check_inline_asm mmi '"punpcklhw $f0, $f0, $f0"'
+ enabled mmi && append MMIFLAGS "-march=loongson3a"
# Enable minimum ISA based on selected options
if enabled mips64; then
@@ -7360,6 +7361,7 @@ CXXFLAGS=$CXXFLAGS
OBJCFLAGS=$OBJCFLAGS
ASFLAGS=$ASFLAGS
NVCCFLAGS=$nvccflags
+MMIFLAGS=$MMIFLAGS
AS_C=$AS_C
AS_O=$AS_O
OBJCC_C=$OBJCC_C
@@ -47,6 +47,11 @@ define COMPILE
$($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
endef
+define COMPILE_WITH_FLAG
+ $(call $(1)DEP,$(1))
+ $($(1)) $($(2)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
+endef
+
COMPILE_C = $(call COMPILE,CC)
COMPILE_CXX = $(call COMPILE,CXX)
COMPILE_S = $(call COMPILE,AS)
@@ -54,6 +59,10 @@ COMPILE_M = $(call COMPILE,OBJCC)
COMPILE_X86ASM = $(call COMPILE,X86ASM)
COMPILE_HOSTC = $(call COMPILE,HOSTCC)
COMPILE_NVCC = $(call COMPILE,NVCC)
+COMPILE_MMI = $(call COMPILE_WITH_FLAG,CC,MMIFLAGS)
+
+%_mmi.o: %_mmi.c
+ $(COMPILE_MMI)
%.o: %.c
$(COMPILE_C)
@@ -20,6 +20,7 @@
*/
#include "blockdsp_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void blockdsp_init_msa(BlockDSPContext *c)
@@ -45,8 +46,10 @@ static av_cold void blockdsp_init_mmi(BlockDSPContext *c)
void ff_blockdsp_init_mips(BlockDSPContext *c)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- blockdsp_init_mmi(c);
+ if (MIPS_MMI(cpu_flags))
+ blockdsp_init_mmi(c);
#endif /* HAVE_MMI */
#if HAVE_MSA
blockdsp_init_msa(c);
@@ -20,6 +20,7 @@
*/
#include "h264chroma_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void h264chroma_init_msa(H264ChromaContext *c, int bit_depth)
@@ -54,8 +55,10 @@ static av_cold void h264chroma_init_mmi(H264ChromaContext *c, int bit_depth)
av_cold void ff_h264chroma_init_mips(H264ChromaContext *c, int bit_depth)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- h264chroma_init_mmi(c, bit_depth);
+ if (MIPS_MMI(cpu_flags))
+ h264chroma_init_mmi(c, bit_depth);
#endif /* HAVE_MMI */
#if HAVE_MSA
h264chroma_init_msa(c, bit_depth);
@@ -20,6 +20,7 @@
*/
#include "h264dsp_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void h264dsp_init_msa(H264DSPContext *c,
@@ -138,8 +139,10 @@ static av_cold void h264dsp_init_mmi(H264DSPContext * c, const int bit_depth,
av_cold void ff_h264dsp_init_mips(H264DSPContext *c, const int bit_depth,
const int chroma_format_idc)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- h264dsp_init_mmi(c, bit_depth, chroma_format_idc);
+ if (MIPS_MMI(cpu_flags))
+ h264dsp_init_mmi(c, bit_depth, chroma_format_idc);
#endif /* HAVE_MMI */
#if HAVE_MSA
h264dsp_init_msa(c, bit_depth, chroma_format_idc);
@@ -22,6 +22,7 @@
#include "config.h"
#include "h264dsp_mips.h"
#include "h264pred_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void h264_pred_init_msa(H264PredContext *h, int codec_id,
@@ -143,8 +144,10 @@ av_cold void ff_h264_pred_init_mips(H264PredContext *h, int codec_id,
int bit_depth,
const int chroma_format_idc)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- h264_pred_init_mmi(h, codec_id, bit_depth, chroma_format_idc);
+ if (MIPS_MMI(cpu_flags))
+ h264_pred_init_mmi(h, codec_id, bit_depth, chroma_format_idc);
#endif /* HAVE_MMI */
#if HAVE_MSA
h264_pred_init_msa(h, codec_id, bit_depth, chroma_format_idc);
@@ -20,6 +20,7 @@
*/
#include "h264dsp_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void h264qpel_init_msa(H264QpelContext *c, int bit_depth)
@@ -240,8 +241,10 @@ static av_cold void h264qpel_init_mmi(H264QpelContext *c, int bit_depth)
av_cold void ff_h264qpel_init_mips(H264QpelContext *c, int bit_depth)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- h264qpel_init_mmi(c, bit_depth);
+ if (MIPS_MMI(cpu_flags))
+ h264qpel_init_mmi(c, bit_depth);
#endif /* HAVE_MMI */
#if HAVE_MSA
h264qpel_init_msa(c, bit_depth);
@@ -19,6 +19,7 @@
*/
#include "libavcodec/mips/hevcdsp_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MMI
static av_cold void hevc_dsp_init_mmi(HEVCDSPContext *c,
@@ -520,8 +521,10 @@ static av_cold void hevc_dsp_init_msa(HEVCDSPContext *c,
void ff_hevc_dsp_init_mips(HEVCDSPContext *c, const int bit_depth)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- hevc_dsp_init_mmi(c, bit_depth);
+ if (MIPS_MMI(cpu_flags))
+ hevc_dsp_init_mmi(c, bit_depth);
#endif // #if HAVE_MMI
#if HAVE_MSA
hevc_dsp_init_msa(c, bit_depth);
@@ -21,6 +21,7 @@
#include "../hpeldsp.h"
#include "libavcodec/mips/hpeldsp_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static void ff_hpeldsp_init_msa(HpelDSPContext *c, int flags)
@@ -113,8 +114,10 @@ static void ff_hpeldsp_init_mmi(HpelDSPContext *c, int flags)
void ff_hpeldsp_init_mips(HpelDSPContext *c, int flags)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- ff_hpeldsp_init_mmi(c, flags);
+ if (MIPS_MMI(cpu_flags))
+ ff_hpeldsp_init_mmi(c, flags);
#endif // #if HAVE_MMI
#if HAVE_MSA
ff_hpeldsp_init_msa(c, flags);
@@ -21,6 +21,7 @@
#include "idctdsp_mips.h"
#include "xvididct_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void idctdsp_init_msa(IDCTDSPContext *c, AVCodecContext *avctx,
@@ -65,8 +66,10 @@ static av_cold void idctdsp_init_mmi(IDCTDSPContext *c, AVCodecContext *avctx,
av_cold void ff_idctdsp_init_mips(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- idctdsp_init_mmi(c, avctx, high_bit_depth);
+ if (MIPS_MMI(cpu_flags))
+ idctdsp_init_mmi(c, avctx, high_bit_depth);
#endif /* HAVE_MMI */
#if HAVE_MSA
idctdsp_init_msa(c, avctx, high_bit_depth);
@@ -20,6 +20,7 @@
#include "h263dsp_mips.h"
#include "mpegvideo_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void dct_unquantize_init_msa(MpegEncContext *s)
@@ -49,8 +50,10 @@ static av_cold void dct_unquantize_init_mmi(MpegEncContext *s)
av_cold void ff_mpv_common_init_mips(MpegEncContext *s)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- dct_unquantize_init_mmi(s);
+ if (MIPS_MMI(cpu_flags))
+ dct_unquantize_init_mmi(s);
#endif /* HAVE_MMI */
#if HAVE_MSA
dct_unquantize_init_msa(s);
@@ -20,6 +20,7 @@
*/
#include "pixblockdsp_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void pixblockdsp_init_msa(PixblockDSPContext *c,
@@ -60,8 +61,10 @@ static av_cold void pixblockdsp_init_mmi(PixblockDSPContext *c,
void ff_pixblockdsp_init_mips(PixblockDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- pixblockdsp_init_mmi(c, avctx, high_bit_depth);
+ if (MIPS_MMI(cpu_flags))
+ pixblockdsp_init_mmi(c, avctx, high_bit_depth);
#endif /* HAVE_MMI */
#if HAVE_MSA
pixblockdsp_init_msa(c, avctx, high_bit_depth);
@@ -22,6 +22,7 @@
#include "libavcodec/vc1dsp.h"
#include "vc1dsp_mips.h"
#include "config.h"
+#include "libavutil/mips/cpu.h"
#define FN_ASSIGN(OP, X, Y, INSN) \
dsp->OP##vc1_mspel_pixels_tab[1][X+4*Y] = ff_##OP##vc1_mspel_mc##X##Y##INSN; \
@@ -121,8 +122,10 @@ static av_cold void vc1dsp_init_msa(VC1DSPContext *dsp)
av_cold void ff_vc1dsp_init_mips(VC1DSPContext *dsp)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- vc1dsp_init_mmi(dsp);
+ if (MIPS_MMI(cpu_flags))
+ vc1dsp_init_mmi(dsp);
#endif /* HAVE_MMI */
#if HAVE_MSA
vc1dsp_init_msa(dsp);
@@ -24,6 +24,7 @@
#include "libavcodec/avcodec.h"
#include "libavcodec/vp3dsp.h"
#include "vp3dsp_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void vp3dsp_init_msa(VP3DSPContext *c, int flags)
@@ -51,8 +52,10 @@ static av_cold void vp3dsp_init_mmi(VP3DSPContext *c, int flags)
av_cold void ff_vp3dsp_init_mips(VP3DSPContext *c, int flags)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- vp3dsp_init_mmi(c, flags);
+ if (MIPS_MMI(cpu_flags))
+ vp3dsp_init_mmi(c, flags);
#endif /* HAVE_MMI */
#if HAVE_MSA
vp3dsp_init_msa(c, flags);
@@ -28,6 +28,7 @@
#include "libavutil/attributes.h"
#include "libavcodec/vp8dsp.h"
#include "vp8dsp_mips.h"
+#include "libavutil/mips/cpu.h"
#define VP8_MC_MIPS_FUNC(IDX, SIZE) \
dsp->put_vp8_epel_pixels_tab[IDX][0][1] = \
@@ -193,8 +194,10 @@ static av_cold void vp8dsp_init_mmi(VP8DSPContext *dsp)
av_cold void ff_vp8dsp_init_mips(VP8DSPContext *dsp)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- vp8dsp_init_mmi(dsp);
+ if (MIPS_MMI(cpu_flags))
+ vp8dsp_init_mmi(dsp);
#endif /* HAVE_MMI */
#if HAVE_MSA
vp8dsp_init_msa(dsp);
@@ -22,6 +22,7 @@
#include "libavutil/common.h"
#include "libavcodec/vp9dsp.h"
#include "vp9dsp_mips.h"
+#include "libavutil/mips/cpu.h"
#if HAVE_MSA
static av_cold void vp9dsp_intrapred_init_msa(VP9DSPContext *dsp, int bpp)
@@ -209,8 +210,10 @@ static av_cold void vp9dsp_init_mmi(VP9DSPContext *dsp, int bpp)
av_cold void ff_vp9dsp_init_mips(VP9DSPContext *dsp, int bpp)
{
+ int cpu_flags = av_get_cpu_flags();
#if HAVE_MMI
- vp9dsp_init_mmi(dsp, bpp);
+ if (MIPS_MMI(cpu_flags))
+ vp9dsp_init_mmi(dsp, bpp);
#endif // #if HAVE_MMI
#if HAVE_MSA
vp9dsp_init_msa(dsp, bpp);
@@ -59,6 +59,8 @@ static int get_cpu_flags(void)
return ff_get_cpu_flags_ppc();
if (ARCH_X86)
return ff_get_cpu_flags_x86();
+ if (ARCH_MIPS)
+ return ff_get_cpu_flags_mips();
return 0;
}
@@ -169,6 +171,8 @@ 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
+ { "mmi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMI }, .unit = "flags" },
#endif
{ NULL },
};
@@ -250,6 +254,8 @@ 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
+ { "mmi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMI }, .unit = "flags" },
#endif
{ NULL },
};
@@ -69,6 +69,8 @@
#define AV_CPU_FLAG_NEON (1 << 5)
#define AV_CPU_FLAG_ARMV8 (1 << 6)
#define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations
+
+#define AV_CPU_FLAG_MMI (1 << 0)
#define AV_CPU_FLAG_SETEND (1 <<16)
/**
@@ -45,6 +45,7 @@ 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);
size_t ff_get_cpu_max_align_aarch64(void);
size_t ff_get_cpu_max_align_arm(void);
@@ -1 +1,2 @@
-OBJS += mips/float_dsp_mips.o
+OBJS += mips/float_dsp_mips.o \
+ mips/cpu.o
new file mode 100644
@@ -0,0 +1,70 @@
+/*
+ * CPU detection code.
+ *
+ * Copyright (c) 2019 Loongson Technology Corporation Limited
+ * Shiyou Yin <yinshiyou-hf@loongson.cn>
+ *
+ * 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 <sys/wait.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+#include "libavutil/mips/cpu.h"
+#include "libavutil/cpu.h"
+#include "libavutil/cpu_internal.h"
+
+#define MMI_MASK 0x00000010
+
+static int get_cpu_flags_from_cpuinfo(void)
+{
+ int flags = 0;
+ char buf[1024];
+
+# ifdef __linux__
+ FILE* fp = fopen("/proc/cpuinfo", "r");
+ if (!fp)
+ return flags;
+
+ memset(buf, 0, sizeof(buf));
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (!strncmp(buf, "model name", strlen("model name"))) {
+ if (strstr(buf, "Loongson-3")) {
+ flags |= AV_CPU_FLAG_MMI;
+ } else if (strstr(buf, "Loongson-2K") || strstr(buf, "2K1000")) {
+ flags |= AV_CPU_FLAG_MMI;
+ }
+ break;
+ }
+ }
+ fclose(fp);
+# endif
+ return flags;
+}
+
+/* Function to test if multimedia instructions are supported... */
+int ff_get_cpu_flags_mips(void)
+{
+ int flags = 0;
+
+ /* TODO: pending to add get_cpu_flags_from_cpucfg. */
+ flags = get_cpu_flags_from_cpuinfo();
+ return flags;
+}
new file mode 100644
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019 Loongson Technology Corporation Limited
+ * Shiyou Yin <yinshiyou-hf@loongson.cn>
+ *
+ * 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 MIPS_MMI(flags) CPUEXT(flags, MMI)
+
+#endif /* AVUTIL_MIPS_CPU_H */
@@ -74,6 +74,8 @@ static const struct {
{ AV_CPU_FLAG_BMI2, "bmi2" },
{ AV_CPU_FLAG_AESNI, "aesni" },
{ AV_CPU_FLAG_AVX512, "avx512" },
+#elif ARCH_MIPS
+ { AV_CPU_FLAG_MMI, "mmi" },
#endif
{ 0 }
};