Commit aab6cec3e8 for ffmpeg

commit aab6cec3e8415154b3f0570f8d131db07a9901de
Author: Zuxy Meng <zuxy.meng@gmail.com>
Date:   Sat Oct 31 14:29:19 2026 -0700

    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. 18% faster on full
    4-edge bidir blocks when benchmarked on a Zen 4 (smaller unidir
    blocks gain less).

diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm
index 717349b931..ff94a5eabc 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
+    psubw            m1, m2
+    movu             m2, [mvq+b_idxq*4+52*4]
+    psubw            m3, m2
+    packsswb         m1, m3
     paddb            m1, m6
-    paddb            m3, m6
     psubusb          m1, m5 ; abs(mv[b] - mv[bn]) >= limit
-    psubusb          m3, m5
-    packsswb         m1, m3
+    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
+    psubw            m1, m2
+    movu             m2, [mvq+b_idxq*4+52*4]
+    psubw            m3, m2
+    packsswb         m1, m3
     paddb            m1, m6
-    paddb            m3, m6
     psubusb          m1, m5 ; abs(mv[b] - mv[bn]) >= limit
-    psubusb          m3, m5
-    packsswb         m1, m3
+    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, m4
+    pminub           m0, m4
     psllw            m1, 1
     pxor             m2, m2
     pmaxub           m1, m0
@@ -1087,13 +1081,28 @@ 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, \
+%macro TRANSPOSE_BS 0
+    ; store-forwarding from loop_filter_strength_iteration needs 8-byte load
+    movq             m0, [bsq]
+    movq             m1, [bsq+8]
+    movq             m2, [bsq+16]
+    movq             m3, [bsq+24]
+    punpcklwd        m0, m1
+    punpcklwd        m2, m3
+    mova             m1, m0
+    punpckldq        m0, m2
+    punpckhdq        m1, m2
+    movu          [bsq], m0
+    movu       [bsq+16], m1
+%endmacro
+
+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             m4, [pb_1]
     mova             m5, [pb_3]
     je .nofield
     mova             m5, [pb_3_1]
@@ -1115,28 +1124,12 @@ 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
+    TRANSPOSE_BS
     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
+    TRANSPOSE_BS
     RET
diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c
index d103fe041f..3b9cb794a7 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)) {