[FFmpeg-devel] [PATCH 2/4] avcodec: Add runtime check for loongson mmi.

Yin Shiyou yinshiyou-hf at loongson.cn
Wed Dec 18 08:39:09 EET 2019


get_cpu_flags_from_cpuinfo is added for mmi support check here.
get_cpu_flags_from_cpucfg will be added in future for new processor.
---
 configure                               |  2 +
 ffbuild/common.mak                      |  9 +++++
 libavcodec/mips/blockdsp_init_mips.c    |  5 ++-
 libavcodec/mips/h264chroma_init_mips.c  |  5 ++-
 libavcodec/mips/h264dsp_init_mips.c     |  5 ++-
 libavcodec/mips/h264pred_init_mips.c    |  5 ++-
 libavcodec/mips/h264qpel_init_mips.c    |  5 ++-
 libavcodec/mips/hevcdsp_init_mips.c     |  5 ++-
 libavcodec/mips/hpeldsp_init_mips.c     |  5 ++-
 libavcodec/mips/idctdsp_init_mips.c     |  5 ++-
 libavcodec/mips/mpegvideo_init_mips.c   |  5 ++-
 libavcodec/mips/pixblockdsp_init_mips.c |  5 ++-
 libavcodec/mips/vc1dsp_init_mips.c      |  5 ++-
 libavcodec/mips/vp3dsp_init_mips.c      |  5 ++-
 libavcodec/mips/vp8dsp_init_mips.c      |  5 ++-
 libavcodec/mips/vp9dsp_init_mips.c      |  5 ++-
 libavutil/cpu.c                         |  6 +++
 libavutil/cpu.h                         |  2 +
 libavutil/cpu_internal.h                |  1 +
 libavutil/mips/Makefile                 |  3 +-
 libavutil/mips/cpu.c                    | 70 +++++++++++++++++++++++++++++++++
 libavutil/mips/cpu.h                    | 31 +++++++++++++++
 libavutil/tests/cpu.c                   |  2 +
 23 files changed, 181 insertions(+), 15 deletions(-)
 create mode 100644 libavutil/mips/cpu.c
 create mode 100644 libavutil/mips/cpu.h

diff --git a/configure b/configure
index 4ff778a..cc7a0da 100755
--- a/configure
+++ b/configure
@@ -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
diff --git a/ffbuild/common.mak b/ffbuild/common.mak
index 7355508..d3cce1a 100644
--- a/ffbuild/common.mak
+++ b/ffbuild/common.mak
@@ -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)
diff --git a/libavcodec/mips/blockdsp_init_mips.c b/libavcodec/mips/blockdsp_init_mips.c
index 55ac1c3..85e928c 100644
--- a/libavcodec/mips/blockdsp_init_mips.c
+++ b/libavcodec/mips/blockdsp_init_mips.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);
diff --git a/libavcodec/mips/h264chroma_init_mips.c b/libavcodec/mips/h264chroma_init_mips.c
index ae817e4..7c75766 100644
--- a/libavcodec/mips/h264chroma_init_mips.c
+++ b/libavcodec/mips/h264chroma_init_mips.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);
diff --git a/libavcodec/mips/h264dsp_init_mips.c b/libavcodec/mips/h264dsp_init_mips.c
index dc08a25..3ed4d76 100644
--- a/libavcodec/mips/h264dsp_init_mips.c
+++ b/libavcodec/mips/h264dsp_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/h264pred_init_mips.c b/libavcodec/mips/h264pred_init_mips.c
index e537ad8..30aefe5 100644
--- a/libavcodec/mips/h264pred_init_mips.c
+++ b/libavcodec/mips/h264pred_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/h264qpel_init_mips.c b/libavcodec/mips/h264qpel_init_mips.c
index 33bae30..4f62766 100644
--- a/libavcodec/mips/h264qpel_init_mips.c
+++ b/libavcodec/mips/h264qpel_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/hevcdsp_init_mips.c b/libavcodec/mips/hevcdsp_init_mips.c
index 88337f4..7f7c699 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_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);
diff --git a/libavcodec/mips/hpeldsp_init_mips.c b/libavcodec/mips/hpeldsp_init_mips.c
index d6f7a97..3614d5c 100644
--- a/libavcodec/mips/hpeldsp_init_mips.c
+++ b/libavcodec/mips/hpeldsp_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/idctdsp_init_mips.c b/libavcodec/mips/idctdsp_init_mips.c
index 85b76ca..7aa4c52 100644
--- a/libavcodec/mips/idctdsp_init_mips.c
+++ b/libavcodec/mips/idctdsp_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/mpegvideo_init_mips.c b/libavcodec/mips/mpegvideo_init_mips.c
index be77308..271e26c 100644
--- a/libavcodec/mips/mpegvideo_init_mips.c
+++ b/libavcodec/mips/mpegvideo_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/pixblockdsp_init_mips.c b/libavcodec/mips/pixblockdsp_init_mips.c
index fd0238d..dfe094b 100644
--- a/libavcodec/mips/pixblockdsp_init_mips.c
+++ b/libavcodec/mips/pixblockdsp_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/vc1dsp_init_mips.c b/libavcodec/mips/vc1dsp_init_mips.c
index c0007ff..2fa7e2c 100644
--- a/libavcodec/mips/vc1dsp_init_mips.c
+++ b/libavcodec/mips/vc1dsp_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/vp3dsp_init_mips.c b/libavcodec/mips/vp3dsp_init_mips.c
index e183db3..8f15a32 100644
--- a/libavcodec/mips/vp3dsp_init_mips.c
+++ b/libavcodec/mips/vp3dsp_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/vp8dsp_init_mips.c b/libavcodec/mips/vp8dsp_init_mips.c
index 7fd8fb0..ef1d4d7 100644
--- a/libavcodec/mips/vp8dsp_init_mips.c
+++ b/libavcodec/mips/vp8dsp_init_mips.c
@@ -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);
diff --git a/libavcodec/mips/vp9dsp_init_mips.c b/libavcodec/mips/vp9dsp_init_mips.c
index 5990fa6..86d2c30 100644
--- a/libavcodec/mips/vp9dsp_init_mips.c
+++ b/libavcodec/mips/vp9dsp_init_mips.c
@@ -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);
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 6548cc3..1ce893b 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -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 },
     };
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 8bb9eb6..ce80b17 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -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)
 
 /**
diff --git a/libavutil/cpu_internal.h b/libavutil/cpu_internal.h
index 37122d1..66f1023 100644
--- a/libavutil/cpu_internal.h
+++ b/libavutil/cpu_internal.h
@@ -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);
diff --git a/libavutil/mips/Makefile b/libavutil/mips/Makefile
index dbfa5aa..e8d15c6 100644
--- a/libavutil/mips/Makefile
+++ b/libavutil/mips/Makefile
@@ -1 +1,2 @@
-OBJS += mips/float_dsp_mips.o
+OBJS += mips/float_dsp_mips.o                   \
+        mips/cpu.o
diff --git a/libavutil/mips/cpu.c b/libavutil/mips/cpu.c
new file mode 100644
index 0000000..4c2fa24
--- /dev/null
+++ b/libavutil/mips/cpu.c
@@ -0,0 +1,70 @@
+/*
+ * CPU detection code.
+ *
+ * Copyright (c) 2019 Loongson Technology Corporation Limited
+ *                    Shiyou Yin <yinshiyou-hf at 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;
+}
diff --git a/libavutil/mips/cpu.h b/libavutil/mips/cpu.h
new file mode 100644
index 0000000..e62416a
--- /dev/null
+++ b/libavutil/mips/cpu.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019 Loongson Technology Corporation Limited
+ *                    Shiyou Yin <yinshiyou-hf at 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 */
diff --git a/libavutil/tests/cpu.c b/libavutil/tests/cpu.c
index ce45b71..0a4240a 100644
--- a/libavutil/tests/cpu.c
+++ b/libavutil/tests/cpu.c
@@ -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 }
 };
-- 
2.1.0



More information about the ffmpeg-devel mailing list