[FFmpeg-devel] [PATCH] codec/hevc:add transform_luma_neon and checkasm
xufuji456
839789740 at qq.com
Sat Apr 8 11:59:18 EEST 2023
got 56% speed up (run_count=1000, CPU=Cortex A53)
transform_4x4_luma_neon: 45 transform_4x4_luma_c: 103
---
libavcodec/aarch64/hevcdsp_idct_neon.S | 51 ++++++++++++++++++++++-
libavcodec/aarch64/hevcdsp_init_aarch64.c | 2 +
tests/checkasm/hevc_idct.c | 28 +++++++++++++
3 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/libavcodec/aarch64/hevcdsp_idct_neon.S b/libavcodec/aarch64/hevcdsp_idct_neon.S
index 74a96957bf..f302ed9773 100644
--- a/libavcodec/aarch64/hevcdsp_idct_neon.S
+++ b/libavcodec/aarch64/hevcdsp_idct_neon.S
@@ -6,6 +6,7 @@
* Ported from arm/hevcdsp_idct_neon.S by
* Copyright (c) 2020 Reimar Döffinger
* Copyright (c) 2023 J. Dekker <jdek at itanimul.li>
+ * Copyright (c) 2023 xu fulong <839789740 at qq.com>
*
* This file is part of FFmpeg.
*
@@ -656,4 +657,52 @@ idct_dc 16, 8
idct_dc 16, 10
idct_dc 32, 8
-idct_dc 32, 10
\ No newline at end of file
+idct_dc 32, 10
+
+.macro tr4_luma_shift r0, r1, r2, r3, shift
+ saddl v0.4s, \r0, \r2 // c0 = src0 + src2
+ saddl v1.4s, \r2, \r3 // c1 = src2 + src3
+ ssubl v2.4s, \r0, \r3 // c2 = src0 - src3
+ smull v3.4s, \r1, v21.4h // c3 = 74 * src1
+
+ saddl v7.4s, \r0, \r3 // src0 + src3
+ ssubw v7.4s, v7.4s, \r2 // src0 - src2 + src3
+ mul v7.4s, v7.4s, v18.4s // dst2 = 74 * (src0 - src2 + src3)
+
+ mul v5.4s, v0.4s, v19.4s // 29 * c0
+ mul v6.4s, v1.4s, v20.4s // 55 * c1
+ add v5.4s, v5.4s, v6.4s // 29 * c0 + 55 * c1
+ add v5.4s, v5.4s, v3.4s // dst0 = 29 * c0 + 55 * c1 + c3
+
+ mul v1.4s, v1.4s, v19.4s // 29 * c1
+ mul v6.4s, v2.4s, v20.4s // 55 * c2
+ sub v6.4s, v6.4s, v1.4s // 55 * c2 - 29 * c1
+ add v6.4s, v6.4s, v3.4s // dst1 = 55 * c2 - 29 * c1 + c3
+
+ mul v0.4s, v0.4s, v20.4s // 55 * c0
+ mul v2.4s, v2.4s, v19.4s // 29 * c2
+ add v0.4s, v0.4s, v2.4s // 55 * c0 + 29 * c2
+ sub v0.4s, v0.4s, v3.4s // dst3 = 55 * c0 + 29 * c2 - c3
+
+ sqrshrn \r0, v5.4s, \shift
+ sqrshrn \r1, v6.4s, \shift
+ sqrshrn \r2, v7.4s, \shift
+ sqrshrn \r3, v0.4s, \shift
+.endm
+
+function ff_hevc_transform_luma_4x4_neon_8, export=1
+ ld1 {v28.4h-v31.4h}, [x0]
+ movi v18.4s, #74
+ movi v19.4s, #29
+ movi v20.4s, #55
+ movi v21.4h, #74
+
+ tr4_luma_shift v28.4h, v29.4h, v30.4h, v31.4h, #7
+ transpose_4x4H v28, v29, v30, v31, v22, v23, v24, v25
+
+ tr4_luma_shift v28.4h, v29.4h, v30.4h, v31.4h, #12
+ transpose_4x4H v28, v29, v30, v31, v22, v23, v24, v25
+
+ st1 {v28.4h-v31.4h}, [x0]
+ ret
+endfunc
\ No newline at end of file
diff --git a/libavcodec/aarch64/hevcdsp_init_aarch64.c b/libavcodec/aarch64/hevcdsp_init_aarch64.c
index 1deefca0a2..10e7f2318e 100644
--- a/libavcodec/aarch64/hevcdsp_init_aarch64.c
+++ b/libavcodec/aarch64/hevcdsp_init_aarch64.c
@@ -63,6 +63,7 @@ void ff_hevc_idct_4x4_dc_10_neon(int16_t *coeffs);
void ff_hevc_idct_8x8_dc_10_neon(int16_t *coeffs);
void ff_hevc_idct_16x16_dc_10_neon(int16_t *coeffs);
void ff_hevc_idct_32x32_dc_10_neon(int16_t *coeffs);
+void ff_hevc_transform_luma_4x4_neon_8(int16_t *coeffs);
void ff_hevc_sao_band_filter_8x8_8_neon(uint8_t *_dst, const uint8_t *_src,
ptrdiff_t stride_dst, ptrdiff_t stride_src,
const int16_t *sao_offset_val, int sao_left_class,
@@ -128,6 +129,7 @@ av_cold void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth)
c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_neon;
c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_neon;
c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_neon;
+ c->transform_4x4_luma = ff_hevc_transform_luma_4x4_neon_8;
c->sao_band_filter[0] =
c->sao_band_filter[1] =
c->sao_band_filter[2] =
diff --git a/tests/checkasm/hevc_idct.c b/tests/checkasm/hevc_idct.c
index 338b8a23e4..1d246364ca 100644
--- a/tests/checkasm/hevc_idct.c
+++ b/tests/checkasm/hevc_idct.c
@@ -84,6 +84,27 @@ static void check_idct_dc(HEVCDSPContext h, int bit_depth)
}
}
+static void check_transform_luma(HEVCDSPContext h)
+{
+ LOCAL_ALIGNED(32, int16_t, coeffs0, [32 * 32]);
+ LOCAL_ALIGNED(32, int16_t, coeffs1, [32 * 32]);
+
+ int block_size = 4;
+ int size = block_size * block_size;
+ declare_func_emms(AV_CPU_FLAG_MMXEXT, void, int16_t *coeffs);
+
+ randomize_buffers(coeffs0, size);
+ memcpy(coeffs1, coeffs0, sizeof(*coeffs0) * size);
+
+ if (check_func(h.transform_4x4_luma, "transform_luma_%dx%d", block_size, block_size)) {
+ call_ref(coeffs0);
+ call_new(coeffs1);
+ if (memcmp(coeffs0, coeffs1, sizeof(*coeffs0) * size))
+ fail();
+ bench_new(coeffs1);
+ }
+}
+
void checkasm_check_hevc_idct(void)
{
int bit_depth;
@@ -103,4 +124,11 @@ void checkasm_check_hevc_idct(void)
check_idct(h, bit_depth);
}
report("idct");
+
+ bit_depth = 8;
+ HEVCDSPContext h;
+
+ ff_hevc_dsp_init(&h, bit_depth);
+ check_transform_luma(h);
+ report("transform_luma");
}
--
2.32.0 (Apple Git-132)
More information about the ffmpeg-devel
mailing list