[FFmpeg-devel] [PATCH] libavcodec/mips: Optimize avc idct 4x4 for msa
kaustubh.raste at imgtec.com
kaustubh.raste at imgtec.com
Mon Jul 24 15:41:53 EEST 2017
From: Kaustubh Raste <kaustubh.raste at imgtec.com>
Removed memset call and improved performance.
Signed-off-by: Kaustubh Raste <kaustubh.raste at imgtec.com>
---
libavcodec/mips/h264idct_msa.c | 104 +++++++++++++++++++----------------
libavutil/mips/generic_macros_msa.h | 18 ++++++
2 files changed, 74 insertions(+), 48 deletions(-)
diff --git a/libavcodec/mips/h264idct_msa.c b/libavcodec/mips/h264idct_msa.c
index fac1e7a..81e09e9 100644
--- a/libavcodec/mips/h264idct_msa.c
+++ b/libavcodec/mips/h264idct_msa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale at imgtec.com)
+ * Copyright (c) 2015 - 2017 Manojkumar Bhosale (Manojkumar.Bhosale at imgtec.com)
*
* This file is part of FFmpeg.
*
@@ -36,48 +36,6 @@
BUTTERFLY_4(tmp0_m, tmp1_m, tmp2_m, tmp3_m, out0, out1, out2, out3); \
}
-static void avc_idct4x4_addblk_msa(uint8_t *dst, int16_t *src,
- int32_t dst_stride)
-{
- v8i16 src0, src1, src2, src3;
- v8i16 hres0, hres1, hres2, hres3;
- v8i16 vres0, vres1, vres2, vres3;
- v8i16 zeros = { 0 };
-
- LD4x4_SH(src, src0, src1, src2, src3);
- AVC_ITRANS_H(src0, src1, src2, src3, hres0, hres1, hres2, hres3);
- TRANSPOSE4x4_SH_SH(hres0, hres1, hres2, hres3, hres0, hres1, hres2, hres3);
- AVC_ITRANS_H(hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3);
- SRARI_H4_SH(vres0, vres1, vres2, vres3, 6);
- ADDBLK_ST4x4_UB(vres0, vres1, vres2, vres3, dst, dst_stride);
- ST_SH2(zeros, zeros, src, 8);
-}
-
-static void avc_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src,
- int32_t dst_stride)
-{
- int16_t dc;
- uint32_t src0, src1, src2, src3;
- v16u8 pred = { 0 };
- v16i8 out;
- v8i16 input_dc, pred_r, pred_l;
-
- dc = (src[0] + 32) >> 6;
- input_dc = __msa_fill_h(dc);
- src[0] = 0;
-
- LW4(dst, dst_stride, src0, src1, src2, src3);
- INSERT_W4_UB(src0, src1, src2, src3, pred);
- UNPCK_UB_SH(pred, pred_r, pred_l);
-
- pred_r += input_dc;
- pred_l += input_dc;
-
- CLIP_SH2_0_255(pred_r, pred_l);
- out = __msa_pckev_b((v16i8) pred_l, (v16i8) pred_r);
- ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride);
-}
-
static void avc_deq_idct_luma_dc_msa(int16_t *dst, int16_t *src,
int32_t de_q_val)
{
@@ -317,11 +275,45 @@ static void avc_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src,
ST8x4_UB(dst2, dst3, dst, dst_stride);
}
-void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src,
- int32_t dst_stride)
+void ff_h264_idct_add_msa(uint8_t *dst, int16_t *src, int32_t dst_stride)
{
- avc_idct4x4_addblk_msa(dst, src, dst_stride);
- memset(src, 0, 16 * sizeof(dctcoef));
+ uint32_t src0_m, src1_m, src2_m, src3_m, out0_m, out1_m, out2_m, out3_m;
+ v16i8 dst0_m = { 0 };
+ v16i8 dst1_m = { 0 };
+ v8i16 hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3;
+ v8i16 inp0_m, inp1_m, res0_m, res1_m, src1, src3;
+ const v8i16 src0 = LD_SH(src);
+ const v8i16 src2 = LD_SH(src + 8);
+ const v8i16 zero = { 0 };
+ const uint8_t *dst1 = dst + dst_stride;
+ const uint8_t *dst2 = dst + 2 * dst_stride;
+ const uint8_t *dst3 = dst + 3 * dst_stride;
+
+ ILVL_D2_SH(src0, src0, src2, src2, src1, src3);
+ ST_SH2(zero, zero, src, 8);
+ AVC_ITRANS_H(src0, src1, src2, src3, hres0, hres1, hres2, hres3);
+ TRANSPOSE4x4_SH_SH(hres0, hres1, hres2, hres3, hres0, hres1, hres2, hres3);
+ AVC_ITRANS_H(hres0, hres1, hres2, hres3, vres0, vres1, vres2, vres3);
+ src0_m = LW(dst);
+ src1_m = LW(dst1);
+ SRARI_H4_SH(vres0, vres1, vres2, vres3, 6);
+ src2_m = LW(dst2);
+ src3_m = LW(dst3);
+ ILVR_D2_SH(vres1, vres0, vres3, vres2, inp0_m, inp1_m);
+ INSERT_W2_SB(src0_m, src1_m, dst0_m);
+ INSERT_W2_SB(src2_m, src3_m, dst1_m);
+ ILVR_B2_SH(zero, dst0_m, zero, dst1_m, res0_m, res1_m);
+ ADD2(res0_m, inp0_m, res1_m, inp1_m, res0_m, res1_m);
+ CLIP_SH2_0_255(res0_m, res1_m);
+ PCKEV_B2_SB(res0_m, res0_m, res1_m, res1_m, dst0_m, dst1_m);
+ out0_m = __msa_copy_u_w((v4i32) dst0_m, 0);
+ out1_m = __msa_copy_u_w((v4i32) dst0_m, 1);
+ out2_m = __msa_copy_u_w((v4i32) dst1_m, 0);
+ out3_m = __msa_copy_u_w((v4i32) dst1_m, 1);
+ SW(out0_m, dst);
+ SW(out1_m, dst1);
+ SW(out2_m, dst2);
+ SW(out3_m, dst3);
}
void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src,
@@ -334,7 +326,23 @@ void ff_h264_idct8_addblk_msa(uint8_t *dst, int16_t *src,
void ff_h264_idct4x4_addblk_dc_msa(uint8_t *dst, int16_t *src,
int32_t dst_stride)
{
- avc_idct4x4_addblk_dc_msa(dst, src, dst_stride);
+ v16u8 pred = { 0 };
+ v16i8 out;
+ v8i16 pred_r, pred_l;
+ const uint32_t src0 = LW(dst);
+ const uint32_t src1 = LW(dst + dst_stride);
+ const uint32_t src2 = LW(dst + 2 * dst_stride);
+ const uint32_t src3 = LW(dst + 3 * dst_stride);
+ const int16_t dc = (src[0] + 32) >> 6;
+ const v8i16 input_dc = __msa_fill_h(dc);
+
+ src[0] = 0;
+ INSERT_W4_UB(src0, src1, src2, src3, pred);
+ UNPCK_UB_SH(pred, pred_r, pred_l);
+ ADD2(pred_r, input_dc, pred_l, input_dc, pred_r, pred_l);
+ CLIP_SH2_0_255(pred_r, pred_l);
+ out = __msa_pckev_b((v16i8) pred_l, (v16i8) pred_r);
+ ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride);
}
void ff_h264_idct8_dc_addblk_msa(uint8_t *dst, int16_t *src,
diff --git a/libavutil/mips/generic_macros_msa.h b/libavutil/mips/generic_macros_msa.h
index 61a8ee0..407d46e 100644
--- a/libavutil/mips/generic_macros_msa.h
+++ b/libavutil/mips/generic_macros_msa.h
@@ -1531,6 +1531,24 @@
#define ILVR_D4_SB(...) ILVR_D4(v16i8, __VA_ARGS__)
#define ILVR_D4_UB(...) ILVR_D4(v16u8, __VA_ARGS__)
+/* Description : Interleave left half of double word elements from vectors
+ Arguments : Inputs - in0, in1, in2, in3
+ Outputs - out0, out1
+ Return Type - as per RTYPE
+ Details : Left half of double word elements of in0 and left half of
+ double word elements of in1 are interleaved and copied to out0.
+ Left half of double word elements of in2 and left half of
+ double word elements of in3 are interleaved and copied to out1.
+*/
+#define ILVL_D2(RTYPE, in0, in1, in2, in3, out0, out1) \
+{ \
+ out0 = (RTYPE) __msa_ilvl_d((v2i64) in0, (v2i64) in1); \
+ out1 = (RTYPE) __msa_ilvl_d((v2i64) in2, (v2i64) in3); \
+}
+#define ILVL_D2_UB(...) ILVL_D2(v16u8, __VA_ARGS__)
+#define ILVL_D2_SB(...) ILVL_D2(v16i8, __VA_ARGS__)
+#define ILVL_D2_SH(...) ILVL_D2(v8i16, __VA_ARGS__)
+
/* Description : Interleave both left and right half of input vectors
Arguments : Inputs - in0, in1
Outputs - out0, out1
--
1.7.9.5
More information about the ffmpeg-devel
mailing list