Commit 270e18c364 for ffmpeg
commit 270e18c36463655579b55005b7a7f0eea91fd2e4
Author: Zuxy Meng <zuxy.meng@gmail.com>
Date: Sat Oct 10 21:52:31 2026 -0700
avcodec/x86/h264: convert chroma MC MMX to SSE2
Convert the last MMX (mmxext) chroma MC functions, 8-bit mc2
put/avg and 10-bit mc4/mc2 put/avg, to SSE2. pshufw becomes
pshuflw (identical low half); the 10-bit MC4 macro needs no code
change (SPLATW is dual-ISA). Dispatch moves from EXTERNAL_MMXEXT
to EXTERNAL_SSE2.
checkasm h264chroma passes. No difference in performance.
diff --git a/libavcodec/x86/h264_chromamc.asm b/libavcodec/x86/h264_chromamc.asm
index 705da95feb..9fc88029d9 100644
--- a/libavcodec/x86/h264_chromamc.asm
+++ b/libavcodec/x86/h264_chromamc.asm
@@ -1,5 +1,5 @@
;******************************************************************************
-;* MMX/SSSE3-optimized functions for H.264 chroma MC
+;* SSE2/SSSE3-optimized functions for H.264 chroma MC
;* Copyright (c) 2005 Zoltan Hidvegi <hzoli -a- hzoli -d- com>,
;* 2005-2008 Loren Merritt
;*
@@ -67,8 +67,8 @@ SECTION .text
jne .next4rows
%endmacro
-%macro chroma_mc2_mmx_func 2
-cglobal %1_%2_chroma_mc2, 6, 7, 0
+%macro chroma_mc2_sse2_func 2
+cglobal %1_%2_chroma_mc2, 6, 7, 6
mov r6d, r4d
shl r4d, 16
sub r4d, r6d
@@ -78,29 +78,29 @@ cglobal %1_%2_chroma_mc2, 6, 7, 0
sub r4d, r5d ; x*(8-y)<<16 | (8-x)*(8-y)
movd m5, r4d
- movd m6, r5d
+ movd m4, r5d
punpckldq m5, m5 ; mm5 = {A,B,A,B}
- punpckldq m6, m6 ; mm6 = {C,D,C,D}
- pxor m7, m7
+ punpckldq m4, m4 ; mm4 = {C,D,C,D}
+ pxor m3, m3
movd m2, [r1]
- punpcklbw m2, m7
- pshufw m2, m2, 0x94 ; mm0 = src[0,1,1,2]
+ punpcklbw m2, m3
+ pshuflw m2, m2, 0x94 ; mm0 = src[0,1,1,2]
.nextrow:
add r1, r2
movq m1, m2
pmaddwd m1, m5 ; mm1 = A * src[0,1] + B * src[1,2]
movd m0, [r1]
- punpcklbw m0, m7
- pshufw m0, m0, 0x94 ; mm0 = src[0,1,1,2]
+ punpcklbw m0, m3
+ pshuflw m0, m0, 0x94 ; mm0 = src[0,1,1,2]
movq m2, m0
- pmaddwd m0, m6
+ pmaddwd m0, m4
paddw m1, [rnd_2d_%2]
paddw m1, m0 ; mm1 += C * src[0,1] + D * src[1,2]
psrlw m1, 6
- packssdw m1, m7
- packuswb m1, m7
- CHROMAMC_AVG4 m1, m3, [r0]
+ packssdw m1, m3
+ packuswb m1, m3
+ CHROMAMC_AVG4 m1, m0, [r0]
movd r5d, m1
mov [r0], r5w
add r0, r2
@@ -125,14 +125,14 @@ cglobal %1_%2_chroma_mc2, 6, 7, 0
%endmacro
-INIT_MMX mmxext
+INIT_XMM sse2
%define CHROMAMC_AVG NOTHING
%define CHROMAMC_AVG4 NOTHING
-chroma_mc2_mmx_func put, h264
+chroma_mc2_sse2_func put, h264
%define CHROMAMC_AVG DIRECT_AVG
%define CHROMAMC_AVG4 COPY_AVG
-chroma_mc2_mmx_func avg, h264
+chroma_mc2_sse2_func avg, h264
%macro chroma_mc8_ssse3_func 2-3
cglobal %1_%2_chroma_mc8%3, 6, 7+UNIX64, 8
diff --git a/libavcodec/x86/h264_chromamc_10bit.asm b/libavcodec/x86/h264_chromamc_10bit.asm
index d4f92c90c7..d13d06d6a3 100644
--- a/libavcodec/x86/h264_chromamc_10bit.asm
+++ b/libavcodec/x86/h264_chromamc_10bit.asm
@@ -202,7 +202,7 @@ cglobal %1_h264_chroma_mc4_10, 6,6,7
; int h, int mx, int my)
;-----------------------------------------------------------------------------
%macro CHROMA_MC2 1
-cglobal %1_h264_chroma_mc2_10, 6,7
+cglobal %1_h264_chroma_mc2_10, 6,7,6
mov r6d, r4d
shl r4d, 16
sub r4d, r6d
@@ -212,24 +212,26 @@ cglobal %1_h264_chroma_mc2_10, 6,7
sub r4d, r5d ; x*(8-y)<<16 | (8-x)*(8-y)
movd m5, r4d
- movd m6, r5d
+ movd m4, r5d
punpckldq m5, m5 ; mm5 = {A,B,A,B}
- punpckldq m6, m6 ; mm6 = {C,D,C,D}
- pxor m7, m7
- pshufw m2, [r1], 0x94 ; mm0 = src[0,1,1,2]
+ punpckldq m4, m4 ; mm4 = {C,D,C,D}
+ pxor m3, m3
+ movq m2, [r1]
+ pshuflw m2, m2, 0x94 ; mm0 = src[0,1,1,2]
.nextrow:
add r1, r2
movq m1, m2
pmaddwd m1, m5 ; mm1 = A * src[0,1] + B * src[1,2]
- pshufw m0, [r1], 0x94 ; mm0 = src[0,1,1,2]
+ movq m0, [r1]
+ pshuflw m0, m0, 0x94 ; mm0 = src[0,1,1,2]
movq m2, m0
- pmaddwd m0, m6
+ pmaddwd m0, m4
paddw m1, [pw_32]
paddw m1, m0 ; mm1 += C * src[0,1] + D * src[1,2]
psrlw m1, 6
- packssdw m1, m7
- CHROMAMC_AVG m1, m3, [r0]
+ packssdw m1, m3
+ CHROMAMC_AVG m1, m0, [r0]
movd [r0], m1
add r0, r2
dec r3d
@@ -247,23 +249,21 @@ cglobal %1_h264_chroma_mc2_10, 6,7
%endmacro
%define CHROMAMC_AVG NOTHING
-INIT_XMM sse2
-CHROMA_MC8 put
%if HAVE_AVX_EXTERNAL
INIT_XMM avx
CHROMA_MC8 put
%endif
-INIT_MMX mmxext
+INIT_XMM sse2
+CHROMA_MC8 put
CHROMA_MC4 put
CHROMA_MC2 put
%define CHROMAMC_AVG AVG
-INIT_XMM sse2
-CHROMA_MC8 avg
%if HAVE_AVX_EXTERNAL
INIT_XMM avx
CHROMA_MC8 avg
%endif
-INIT_MMX mmxext
+INIT_XMM sse2
+CHROMA_MC8 avg
CHROMA_MC4 avg
CHROMA_MC2 avg
diff --git a/libavcodec/x86/h264chroma_init.c b/libavcodec/x86/h264chroma_init.c
index 6eb52746ad..6a5d24614d 100644
--- a/libavcodec/x86/h264chroma_init.c
+++ b/libavcodec/x86/h264chroma_init.c
@@ -24,9 +24,9 @@
#include "libavutil/x86/cpu.h"
#include "libavcodec/h264chroma.h"
-void ff_put_h264_chroma_mc2_mmxext (uint8_t *dst, const uint8_t *src,
+void ff_put_h264_chroma_mc2_sse2 (uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc2_mmxext (uint8_t *dst, const uint8_t *src,
+void ff_avg_h264_chroma_mc2_sse2 (uint8_t *dst, const uint8_t *src,
ptrdiff_t stride, int h, int x, int y);
void ff_put_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, const uint8_t *src,
@@ -44,10 +44,10 @@ void ff_ ## OP ## _h264_chroma_mc ## NUM ## _ ## DEPTH ## _ ## OPT \
(uint8_t *dst, const uint8_t *src, \
ptrdiff_t stride, int h, int x, int y);
-CHROMA_MC(put, 2, 10, mmxext)
-CHROMA_MC(avg, 2, 10, mmxext)
-CHROMA_MC(put, 4, 10, mmxext)
-CHROMA_MC(avg, 4, 10, mmxext)
+CHROMA_MC(put, 2, 10, sse2)
+CHROMA_MC(avg, 2, 10, sse2)
+CHROMA_MC(put, 4, 10, sse2)
+CHROMA_MC(avg, 4, 10, sse2)
CHROMA_MC(put, 8, 10, sse2)
CHROMA_MC(avg, 8, 10, sse2)
CHROMA_MC(put, 8, 10, avx)
@@ -58,19 +58,16 @@ av_cold void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth)
int high_bit_depth = bit_depth > 8;
int cpu_flags = av_get_cpu_flags();
- if (EXTERNAL_MMXEXT(cpu_flags) && !high_bit_depth) {
- c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_mmxext;
- c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_mmxext;
- }
-
- if (EXTERNAL_MMXEXT(cpu_flags) && bit_depth > 8 && bit_depth <= 10) {
- c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_10_mmxext;
- c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_10_mmxext;
- c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_10_mmxext;
- c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_10_mmxext;
+ if (EXTERNAL_SSE2(cpu_flags) && !high_bit_depth) {
+ c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_sse2;
+ c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_sse2;
}
if (EXTERNAL_SSE2(cpu_flags) && bit_depth > 8 && bit_depth <= 10) {
+ c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_10_sse2;
+ c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_10_sse2;
+ c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_10_sse2;
+ c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_10_sse2;
c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_sse2;
c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_sse2;
}
diff --git a/tests/checkasm/h264chroma.c b/tests/checkasm/h264chroma.c
index 5115b8b3f1..5697b2b2d8 100644
--- a/tests/checkasm/h264chroma.c
+++ b/tests/checkasm/h264chroma.c
@@ -46,8 +46,8 @@ static void check_chroma_mc(void)
DECLARE_ALIGNED_16(uint8_t, dst0)[16 * 18 * 2];
DECLARE_ALIGNED_16(uint8_t, dst1)[16 * 18 * 2];
- declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, const uint8_t *src,
- ptrdiff_t stride, int h, int x, int y);
+ declare_func(void, uint8_t *dst, const uint8_t *src,
+ ptrdiff_t stride, int h, int x, int y);
for (int bit_depth = 8; bit_depth <= 10; bit_depth++) {
ff_h264chroma_init(&h, bit_depth);