PR #23776 opened by Marcos Ashton (MarcosAsh) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23776 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23776.patch
Adds an x86 SIMD implementation of the 4x4 luma DST-VII inverse transform (previously C-only), for 8 and 10 bit, as part of #23022. The kernel accumulates with pmaddwd on (src0,src2)/(src1,src3) coefficient pairs, mirroring the structure of the existing 4x4 IDCT in idct.asm. SSE2 suffices as a baseline since the kernel is pure pmaddwd/paddd/packssdw; an AVX variant is instantiated via the existing macro framework. checkasm -t hevc_idct passes bit-exact. Benchmarks (Core Ultra 7 155H): ``` hevc_transform_4x4_luma_8_c: 220.8 hevc_transform_4x4_luma_8_sse2: 54.1 hevc_transform_4x4_luma_10_c: 220.7 hevc_transform_4x4_luma_10_sse2: 54.9 ``` >From 5306df2f92be9ec25ecb144628403c2eada97010 Mon Sep 17 00:00:00 2001 From: Marcos Ashton Iglesias <[email protected]> Date: Sat, 11 Jul 2026 17:07:55 +0100 Subject: [PATCH] avcodec/x86/hevc: add SSE2 transform_4x4_luma Implements the 4x4 luma DST-VII inverse transform for 8 and 10 bit, using pmaddwd on (src0,src2)/(src1,src3) pairs, mirroring the existing 4x4 IDCT structure. checkasm --bench on a Core Ultra 7 155H: hevc_transform_4x4_luma_8_c: 220.8 hevc_transform_4x4_luma_8_sse2: 54.1 hevc_transform_4x4_luma_10_c: 220.7 hevc_transform_4x4_luma_10_sse2: 54.9 Part of #23022. --- libavcodec/x86/hevc/dsp_init.c | 10 +++++ libavcodec/x86/hevc/idct.asm | 76 ++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/libavcodec/x86/hevc/dsp_init.c b/libavcodec/x86/hevc/dsp_init.c index bd967eac67..cee67fb2a6 100644 --- a/libavcodec/x86/hevc/dsp_init.c +++ b/libavcodec/x86/hevc/dsp_init.c @@ -87,6 +87,12 @@ void ff_hevc_idct_32x32_10_ ## opt(int16_t *coeffs, int col_limit); IDCT_FUNCS(sse2) IDCT_FUNCS(avx) +#define TRANSFORM_LUMA_FUNCS(opt) \ +void ff_hevc_transform_4x4_luma_8_ ## opt(int16_t *coeffs); \ +void ff_hevc_transform_4x4_luma_10_ ## opt(int16_t *coeffs) + +TRANSFORM_LUMA_FUNCS(sse2); +TRANSFORM_LUMA_FUNCS(avx); #define ff_hevc_pel_filters ff_hevc_qpel_filters #define DECL_HV_FILTER(f) \ @@ -839,6 +845,7 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) c->idct[0] = ff_hevc_idct_4x4_8_sse2; c->idct[1] = ff_hevc_idct_8x8_8_sse2; + c->transform_4x4_luma = ff_hevc_transform_4x4_luma_8_sse2; c->add_residual[1] = ff_hevc_add_residual_8_8_sse2; c->add_residual[2] = ff_hevc_add_residual_16_8_sse2; @@ -880,6 +887,7 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) c->idct[0] = ff_hevc_idct_4x4_8_avx; c->idct[1] = ff_hevc_idct_8x8_8_avx; + c->transform_4x4_luma = ff_hevc_transform_4x4_luma_8_avx; } if (EXTERNAL_AVX2(cpu_flags)) { c->sao_band_filter[0] = ff_hevc_sao_band_filter_8_8_avx2; @@ -1019,6 +1027,7 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) c->idct[0] = ff_hevc_idct_4x4_10_sse2; c->idct[1] = ff_hevc_idct_8x8_10_sse2; + c->transform_4x4_luma = ff_hevc_transform_4x4_luma_10_sse2; c->add_residual[1] = ff_hevc_add_residual_8_10_sse2; c->add_residual[2] = ff_hevc_add_residual_16_10_sse2; @@ -1056,6 +1065,7 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) c->idct[0] = ff_hevc_idct_4x4_10_avx; c->idct[1] = ff_hevc_idct_8x8_10_avx; + c->transform_4x4_luma = ff_hevc_transform_4x4_luma_10_avx; SAO_BAND_INIT(10, avx); } diff --git a/libavcodec/x86/hevc/idct.asm b/libavcodec/x86/hevc/idct.asm index 088144171d..cfa156c705 100644 --- a/libavcodec/x86/hevc/idct.asm +++ b/libavcodec/x86/hevc/idct.asm @@ -35,6 +35,16 @@ pw_64_m64: times 4 dw 64, -64 pw_83_36: times 4 dw 83, 36 pw_36_m83: times 4 dw 36, -83 +; 4x4 luma (DST-VII) transform coeffs, paired as (src0, src2) and (src1, src3) +pw_29_84: times 4 dw 29, 84 +pw_74_55: times 4 dw 74, 55 +pw_55_m29: times 4 dw 55, -29 +pw_74_m84: times 4 dw 74, -84 +pw_74_m74: times 4 dw 74, -74 +pw_0_74: times 4 dw 0, 74 +pw_84_55: times 4 dw 84, 55 +pw_m74_m29: times 4 dw -74, -29 + ; 8x8 transform coeffs pw_89_75: times 4 dw 89, 75 pw_50_18: times 4 dw 50, 18 @@ -366,6 +376,71 @@ cglobal hevc_idct_4x4_%1, 1, 1, 5, coeffs RET %endmacro +; 4x4 luma inverse transform (DST-VII), one pass over 4 columns at once. +; Unlike the DCT, DST-VII has no even/odd symmetry, so every output is a full +; dot product of the 4 inputs; we pair them as (src0, src2) and (src1, src3) +; and accumulate with pmaddwd, then scale, clip16 and transpose for the next pass. +; expects input rows in m0 (rows 0, 1) and m1 (rows 2, 3) +; %1 - shift +; %2 - rounding constant (label of a pd_* array) +%macro TR_4x4_LUMA 2 + ; m0: (s0, s2) per column m1: (s1, s3) per column + SBUTTERFLY wd, 0, 1, 2 + + pmaddwd m2, m0, [pw_29_84] ; dst0 + pmaddwd m3, m1, [pw_74_55] + paddd m2, m3 + pmaddwd m3, m0, [pw_55_m29] ; dst1 + pmaddwd m4, m1, [pw_74_m84] + paddd m3, m4 + pmaddwd m4, m0, [pw_74_m74] ; dst2 + pmaddwd m5, m1, [pw_0_74] + paddd m4, m5 + pmaddwd m5, m0, [pw_84_55] ; dst3 + pmaddwd m0, m1, [pw_m74_m29] + paddd m5, m0 + + mova m0, [%2] + paddd m2, m0 + paddd m3, m0 + paddd m4, m0 + paddd m5, m0 + + psrad m2, %1 + psrad m3, %1 + psrad m4, %1 + psrad m5, %1 + + ; clip16 + packssdw m2, m3 ; dst0 | dst1 + packssdw m4, m5 ; dst2 | dst3 + + ; transpose the 4x4 block for the next pass + SBUTTERFLY wd, 2, 4, 0 + SBUTTERFLY wd, 2, 4, 0 + SWAP 0, 2 + SWAP 1, 4 +%endmacro + +; void ff_hevc_transform_4x4_luma_{8,10}_<opt>(int16_t *coeffs) +; %1 = bitdepth +%macro TRANSFORM_4x4_LUMA 1 +cglobal hevc_transform_4x4_luma_%1, 1, 1, 6, coeffs + mova m0, [coeffsq] + mova m1, [coeffsq + 16] + + TR_4x4_LUMA 7, pd_64 +%if %1 == 8 + TR_4x4_LUMA 12, pd_2048 +%elif %1 == 10 + TR_4x4_LUMA 10, pd_512 +%endif + + mova [coeffsq], m0 + mova [coeffsq + 16], m1 + RET +%endmacro + ; scale, pack (clip16) and store the residuals 0 e8[0] + o8[0] --> + %1 ; 4 at one time (4 columns) 1 e8[1] + o8[1] ; from %5: e8/16 + o8/16, with %1 offset ... @@ -832,6 +907,7 @@ INIT_XMM %2 %endif IDCT_8x8 %1 IDCT_4x4 %1 +TRANSFORM_4x4_LUMA %1 %endmacro INIT_IDCT_DC 8 -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
