PR #25636 opened by zuxy URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25636 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25636.patch
Convert ff_h264_loop_filter_strength from MMX to SSE2, following the pattern of the qpel/IDCT/chroma conversions. 17% faster when benchmarked on a Zen 4. >From 2cf9758617f8e81dcadfbe8b960f25b065dfa95b Mon Sep 17 00:00:00 2001 From: Zuxy Meng <[email protected]> Date: Fri, 30 Oct 2026 23:51:59 -0700 Subject: [PATCH] avcodec/x86/h264: convert deblock MMX to SSE2 Convert ff_h264_loop_filter_strength from MMX to SSE2, following the pattern of the qpel/IDCT/chroma conversions. 17% faster when benchmarked on a Zen 4. --- libavcodec/x86/h264_deblock.asm | 141 +++++++++++++++++--------------- libavcodec/x86/h264dsp_init.c | 14 ++-- 2 files changed, 84 insertions(+), 71 deletions(-) diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm index 717349b9313..fa3ada865de 100644 --- a/libavcodec/x86/h264_deblock.asm +++ b/libavcodec/x86/h264_deblock.asm @@ -1,5 +1,5 @@ ;***************************************************************************** -;* MMX/SSE2/AVX-optimized H.264 deblocking code +;* SSE2/AVX-optimized H.264 deblocking code ;***************************************************************************** ;* Copyright (C) 2005-2011 x264 project ;* @@ -29,7 +29,7 @@ SECTION_RODATA pb_A1: times 16 db 0xA1 -pb_3_1: times 4 db 3, 1 +pb_3_1: times 8 db 3, 1 SECTION .text @@ -1008,62 +1008,55 @@ DEBLOCK_CHROMA_XMM avx jnz %%.skip_loop_iter ; if (!(b_idx & mask_mv)) %if bidir == 1 movd m2, [refq+b_idxq+d_idx+12] ; { ref0[bn] } - punpckldq m2, [refq+b_idxq+d_idx+52] ; { ref0[bn], ref1[bn] } - pshufw m0, [refq+b_idxq+12], 0x44 ; { ref0[b], ref0[b] } - pshufw m1, [refq+b_idxq+52], 0x44 ; { ref1[b], ref1[b] } - pshufw m3, m2, 0x4E ; { ref1[bn], ref0[bn] } + movd m3, [refq+b_idxq+d_idx+52] ; { ref1[bn] } + punpckldq m2, m3 ; { ref0[bn], ref1[bn] } + movd m0, [refq+b_idxq+12] + pshuflw m0, m0, q1010 ; { ref0[b], ref0[b] } + movd m1, [refq+b_idxq+52] + pshuflw m1, m1, q1010 ; { ref1[b], ref1[b] } + pshuflw m3, m2, q1032 ; { ref1[bn], ref0[bn] } psubb m0, m2 ; { ref0[b] != ref0[bn], ; ref0[b] != ref1[bn] } psubb m1, m3 ; { ref1[b] != ref1[bn], ; ref1[b] != ref0[bn] } por m0, m1 - mova m1, [mvq+b_idxq*4+(d_idx+12)*4] - mova m2, [mvq+b_idxq*4+(d_idx+12)*4+mmsize] + movu m1, [mvq+b_idxq*4+(d_idx+12)*4] + movu m2, [mvq+b_idxq*4+12*4] mova m3, m1 - mova m4, m2 - psubw m1, [mvq+b_idxq*4+12*4] - psubw m2, [mvq+b_idxq*4+12*4+mmsize] - psubw m3, [mvq+b_idxq*4+52*4] - psubw m4, [mvq+b_idxq*4+52*4+mmsize] - packsswb m1, m2 - packsswb m3, m4 - paddb m1, m6 - paddb m3, m6 - psubusb m1, m5 ; abs(mv[b] - mv[bn]) >= limit - psubusb m3, m5 + psubw m1, m2 + movu m2, [mvq+b_idxq*4+52*4] + psubw m3, m2 packsswb m1, m3 + paddb m1, m6 + psubusb m1, m5 ; abs(mv[b] - mv[bn]) >= limit + packsswb m1, m1 por m0, m1 - mova m1, [mvq+b_idxq*4+(d_idx+52)*4] - mova m2, [mvq+b_idxq*4+(d_idx+52)*4+mmsize] + movu m1, [mvq+b_idxq*4+(d_idx+52)*4] + movu m2, [mvq+b_idxq*4+12*4] mova m3, m1 - mova m4, m2 - psubw m1, [mvq+b_idxq*4+12*4] - psubw m2, [mvq+b_idxq*4+12*4+mmsize] - psubw m3, [mvq+b_idxq*4+52*4] - psubw m4, [mvq+b_idxq*4+52*4+mmsize] - packsswb m1, m2 - packsswb m3, m4 - paddb m1, m6 - paddb m3, m6 - psubusb m1, m5 ; abs(mv[b] - mv[bn]) >= limit - psubusb m3, m5 + psubw m1, m2 + movu m2, [mvq+b_idxq*4+52*4] + psubw m3, m2 packsswb m1, m3 + paddb m1, m6 + psubusb m1, m5 ; abs(mv[b] - mv[bn]) >= limit + packsswb m1, m1 - pshufw m1, m1, 0x4E + pshuflw m1, m1, q1032 por m0, m1 - pshufw m1, m0, 0x4E + pshuflw m1, m0, q1032 pminub m0, m1 %else ; bidir == 0 movd m0, [refq+b_idxq+12] - psubb m0, [refq+b_idxq+d_idx+12] ; ref[b] != ref[bn] + movq m2, [refq+b_idxq+d_idx+12] ; ref[bn] + psubb m0, m2 ; ref[b] != ref[bn] - mova m1, [mvq+b_idxq*4+12*4] - mova m2, [mvq+b_idxq*4+12*4+mmsize] - psubw m1, [mvq+b_idxq*4+(d_idx+12)*4] - psubw m2, [mvq+b_idxq*4+(d_idx+12)*4+mmsize] - packsswb m1, m2 + movu m1, [mvq+b_idxq*4+12*4] + movu m2, [mvq+b_idxq*4+(d_idx+12)*4] + psubw m1, m2 + packsswb m1, m1 paddb m1, m6 psubusb m1, m5 ; abs(mv[b] - mv[bn]) >= limit packsswb m1, m1 @@ -1072,10 +1065,11 @@ DEBLOCK_CHROMA_XMM avx %%.skip_loop_iter: movd m1, [nnzq+b_idxq+12] - por m1, [nnzq+b_idxq+d_idx+12] ; nnz[b] || nnz[bn] + movq m2, [nnzq+b_idxq+d_idx+12] ; nnz[bn] + por m1, m2 ; nnz[b] || nnz[bn] - pminub m1, m7 - pminub m0, m7 + pminub m1, [pb_1] + pminub m0, [pb_1] psllw m1, 1 pxor m2, m2 pmaxub m1, m0 @@ -1087,13 +1081,12 @@ DEBLOCK_CHROMA_XMM avx jl %%.b_idx_loop %endmacro -INIT_MMX mmxext -cglobal h264_loop_filter_strength, 9, 9, 0, bs, nnz, ref, mv, bidir, edges, \ +INIT_XMM sse2 +cglobal h264_loop_filter_strength, 9, 9, 7, bs, nnz, ref, mv, bidir, edges, \ step, mask_mv0, mask_mv1, field %define b_idxq bidirq %define b_idxd bidird cmp dword fieldm, 0 - mova m7, [pb_1] mova m5, [pb_3] je .nofield mova m5, [pb_3_1] @@ -1115,28 +1108,48 @@ cglobal h264_loop_filter_strength, 9, 9, 0, bs, nnz, ref, mv, bidir, edges, \ loop_filter_strength_iteration edgesd, stepd, mask_mv1d, 1, -8, 0, 0 loop_filter_strength_iteration 32, 8, mask_mv0d, 0, -1, -1, 0 - mova m0, [bsq+mmsize*0] - mova m1, [bsq+mmsize*1] - mova m2, [bsq+mmsize*2] - mova m3, [bsq+mmsize*3] - TRANSPOSE4x4W 0, 1, 2, 3, 4 - mova [bsq+mmsize*0], m0 - mova [bsq+mmsize*1], m1 - mova [bsq+mmsize*2], m2 - mova [bsq+mmsize*3], m3 + movu m0, [bsq+8*0] ; [A|B] + movu m1, [bsq+8*2] ; [C|D] + mova m2, m0 + movlhps m2, m1 ; u0 = [A|C] + mova m3, m1 + movhlps m3, m0 ; u1 = [B|D] + mova m4, m2 + punpcklwd m4, m3 ; t01, low = [a0,b0,a1,b1] + mova m0, m2 + punpckhwd m0, m3 ; s01, low = [c0,d0,c1,d1] + punpckldq m4, m0 ; [out0|out1] + movu [bsq+8*0], m4 + pshufd m2, m2, q3311 ; [(a2,a3)x2,(c2,c3)x2] + pshufd m3, m3, q3311 + mova m4, m2 + punpcklwd m4, m3 ; low = [a2,b2,a3,b3] + punpckhwd m2, m3 ; low = [c2,d2,c3,d3] + punpckldq m4, m2 ; [out2|out3] + movu [bsq+8*2], m4 RET .bidir: loop_filter_strength_iteration edgesd, stepd, mask_mv1d, 1, -8, 0, 1 loop_filter_strength_iteration 32, 8, mask_mv0d, 0, -1, -1, 1 - mova m0, [bsq+mmsize*0] - mova m1, [bsq+mmsize*1] - mova m2, [bsq+mmsize*2] - mova m3, [bsq+mmsize*3] - TRANSPOSE4x4W 0, 1, 2, 3, 4 - mova [bsq+mmsize*0], m0 - mova [bsq+mmsize*1], m1 - mova [bsq+mmsize*2], m2 - mova [bsq+mmsize*3], m3 + movu m0, [bsq+8*0] ; [A|B] + movu m1, [bsq+8*2] ; [C|D] + mova m2, m0 + movlhps m2, m1 ; u0 = [A|C] + mova m3, m1 + movhlps m3, m0 ; u1 = [B|D] + mova m4, m2 + punpcklwd m4, m3 ; t01, low = [a0,b0,a1,b1] + mova m0, m2 + punpckhwd m0, m3 ; s01, low = [c0,d0,c1,d1] + punpckldq m4, m0 ; [out0|out1] + movu [bsq+8*0], m4 + pshufd m2, m2, q3311 ; [(a2,a3)x2,(c2,c3)x2] + pshufd m3, m3, q3311 + mova m4, m2 + punpcklwd m4, m3 ; low = [a2,b2,a3,b3] + punpckhwd m2, m3 ; low = [c2,d2,c3,d3] + punpckldq m4, m2 ; [out2|out3] + movu [bsq+8*2], m4 RET diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c index d103fe041fb..3b9cb794a75 100644 --- a/libavcodec/x86/h264dsp_init.c +++ b/libavcodec/x86/h264dsp_init.c @@ -80,11 +80,11 @@ void ff_h264_luma_dc_dequant_idct_sse2(int16_t *output, int16_t *input, int qmul /***********************************/ /* deblocking */ -void ff_h264_loop_filter_strength_mmxext(int16_t bS[2][4][4], uint8_t nnz[40], - int8_t ref[2][40], - int16_t mv[2][40][2], - int bidir, int edges, int step, - int mask_mv0, int mask_mv1, int field); +void ff_h264_loop_filter_strength_sse2(int16_t bS[2][4][4], uint8_t nnz[40], + int8_t ref[2][40], + int16_t mv[2][40][2], + int bidir, int edges, int step, + int mask_mv0, int mask_mv1, int field); #define LF_FUNC(DIR, TYPE, DEPTH, OPT) \ void ff_deblock_ ## DIR ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT(uint8_t *pix, \ @@ -182,8 +182,8 @@ av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, { int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_MMXEXT(cpu_flags) && chroma_format_idc <= 1) - c->loop_filter_strength = ff_h264_loop_filter_strength_mmxext; + if (EXTERNAL_SSE2(cpu_flags) && chroma_format_idc <= 1) + c->loop_filter_strength = ff_h264_loop_filter_strength_sse2; if (bit_depth == 8) { if (EXTERNAL_SSE2(cpu_flags)) { -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
