This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 57f9d96cacd2dd62fe8c126b840ff2d0676f383b Author: dgavriloff <[email protected]> AuthorDate: Fri Apr 10 13:21:29 2026 -0700 Commit: michaelni <[email protected]> CommitDate: Sun Sep 20 12:29:38 2026 +0000 avcodec/x86/me_cmp: Port 8-wide SAD/VSAD functions from MMXEXT to SSE2 Continues the work from d91b1559e0 and 8157aa1a3f which ported the 16-wide and (n)sse functions. The remaining 8-wide MMXEXT functions (sad8, sad8_x2, sad8_y2, sad8_approx_xy2, vsad_intra8, vsad8_approx) are always overridden on x86-64 where SSE2 is baseline. For SAD, SAD_X2, SAD_Y2 and SAD_APPROX_XY2 two consecutive 8-byte rows are packed into one xmm register (movh + movhps, or movh + punpcklqdq when a row is carried across iterations); a single psadbw then produces both row SADs in the low and high qwords, combined by movhlps + paddw at the end. VSAD_INTRA and VSAD_APPROX consume each row in two consecutive pairs (N-1, N) and (N, N+1), so packing would require duplicating loads or restructuring the carry-forward; these use movh loads with register- register psadbw without packing. Old benchmarks (MMXEXT): pix_abs_1_0_c: 8.9 ( 1.00x) pix_abs_1_0_mmxext: 6.4 ( 1.38x) pix_abs_1_1_c: 85.3 ( 1.00x) pix_abs_1_1_mmxext: 9.2 ( 9.29x) pix_abs_1_2_c: 9.9 ( 1.00x) pix_abs_1_2_mmxext: 9.5 ( 1.04x) sad_1_c: 12.8 ( 1.00x) sad_1_mmxext: 6.5 ( 1.98x) vsad_5_c: 45.7 ( 1.00x) vsad_5_mmxext: 4.9 ( 9.39x) New benchmarks (SSE2): pix_abs_1_0_c: 7.9 ( 1.00x) pix_abs_1_0_sse2: 6.0 ( 1.32x) pix_abs_1_1_c: 89.5 ( 1.00x) pix_abs_1_1_sse2: 9.1 ( 9.84x) pix_abs_1_2_c: 10.4 ( 1.00x) pix_abs_1_2_sse2: 7.6 ( 1.37x) sad_1_c: 7.7 ( 1.00x) sad_1_sse2: 5.9 ( 1.30x) vsad_5_c: 53.2 ( 1.00x) vsad_5_sse2: 5.3 (10.04x) Signed-off-by: dgavriloff <[email protected]> --- libavcodec/x86/me_cmp.asm | 177 ++++++++++++++++++++++++++++++------------- libavcodec/x86/me_cmp_init.c | 53 ++++++------- 2 files changed, 149 insertions(+), 81 deletions(-) diff --git a/libavcodec/x86/me_cmp.asm b/libavcodec/x86/me_cmp.asm index f06d703020..1512775bf6 100644 --- a/libavcodec/x86/me_cmp.asm +++ b/libavcodec/x86/me_cmp.asm @@ -390,6 +390,13 @@ cglobal sad%1u, 5, 5, 5, v, pix1, pix2, stride, h %else cglobal sad%1, 5, 5, 3, v, pix1, pix2, stride, h %endif +%if %1 < mmsize + movh m2, [pix2q] + movhps m2, [pix2q+strideq] + movh m0, [pix1q] + movhps m0, [pix1q+strideq] + psadbw m2, m0 +%else movu m2, [pix2q] movu m1, [pix2q+strideq] %ifidn %2, u @@ -402,12 +409,21 @@ cglobal sad%1, 5, 5, 3, v, pix1, pix2, stride, h psadbw m1, [pix1q+strideq] %endif paddw m2, m1 +%endif sub hd, 2 align 16 .loop: lea pix1q, [pix1q+strideq*2] lea pix2q, [pix2q+strideq*2] +%if %1 < mmsize + movh m0, [pix2q] + movhps m0, [pix2q+strideq] + movh m1, [pix1q] + movhps m1, [pix1q+strideq] + psadbw m0, m1 + paddw m2, m0 +%else movu m0, [pix2q] movu m1, [pix2q+strideq] %ifidn %2, u @@ -421,19 +437,17 @@ align 16 %endif paddw m2, m0 paddw m2, m1 +%endif sub hd, 2 jg .loop -%if mmsize == 16 movhlps m0, m2 paddw m2, m0 -%endif movd eax, m2 RET %endmacro -INIT_MMX mmxext -SAD 8 INIT_XMM sse2 +SAD 8 SAD 16 SAD 16, u @@ -443,54 +457,64 @@ SAD 16, u ;%1 = 8/16 %macro SAD_X2 1 cglobal sad%1_x2, 5, 5, 5, v, pix1, pix2, stride, h +%if %1 < mmsize + movh m0, [pix2q] + movhps m0, [pix2q+strideq] + movh m3, [pix2q+1] + movhps m3, [pix2q+strideq+1] + pavgb m0, m3 + movh m1, [pix1q] + movhps m1, [pix1q+strideq] + psadbw m0, m1 +%else movu m0, [pix2q] movu m2, [pix2q+strideq] -%if mmsize == 16 movu m3, [pix2q+1] movu m4, [pix2q+strideq+1] pavgb m0, m3 pavgb m2, m4 -%else - pavgb m0, [pix2q+1] - pavgb m2, [pix2q+strideq+1] -%endif psadbw m0, [pix1q] psadbw m2, [pix1q+strideq] paddw m0, m2 +%endif sub hd, 2 align 16 .loop: lea pix1q, [pix1q+2*strideq] lea pix2q, [pix2q+2*strideq] +%if %1 < mmsize + movh m1, [pix2q] + movhps m1, [pix2q+strideq] + movh m3, [pix2q+1] + movhps m3, [pix2q+strideq+1] + pavgb m1, m3 + movh m2, [pix1q] + movhps m2, [pix1q+strideq] + psadbw m1, m2 + paddw m0, m1 +%else movu m1, [pix2q] movu m2, [pix2q+strideq] -%if mmsize == 16 movu m3, [pix2q+1] movu m4, [pix2q+strideq+1] pavgb m1, m3 pavgb m2, m4 -%else - pavgb m1, [pix2q+1] - pavgb m2, [pix2q+strideq+1] -%endif psadbw m1, [pix1q] psadbw m2, [pix1q+strideq] paddw m0, m1 paddw m0, m2 +%endif sub hd, 2 jg .loop -%if mmsize == 16 movhlps m1, m0 paddw m0, m1 -%endif movd eax, m0 RET %endmacro -INIT_MMX mmxext -SAD_X2 8 INIT_XMM sse2 +SAD_X2 8 SAD_X2 16 ;------------------------------------------------------------------------------------------ @@ -499,6 +523,19 @@ SAD_X2 16 ;%1 = 8/16 %macro SAD_Y2 1 cglobal sad%1_y2, 5, 5, 4, v, pix1, pix2, stride, h +%if %1 < mmsize + movh m1, [pix2q] + movh m2, [pix2q+strideq] + movh m3, [pix2q+2*strideq] + punpcklqdq m1, m2 + punpcklqdq m2, m3 + pavgb m1, m2 + movh m2, [pix1q] + movhps m2, [pix1q+strideq] + psadbw m1, m2 + mova m0, m1 + mova m1, m3 +%else movu m1, [pix2q] movu m0, [pix2q+strideq] movu m3, [pix2q+2*strideq] @@ -508,6 +545,7 @@ cglobal sad%1_y2, 5, 5, 4, v, pix1, pix2, stride, h psadbw m0, [pix1q+strideq] paddw m0, m1 mova m1, m3 +%endif add pix2q, strideq sub hd, 2 @@ -515,6 +553,18 @@ align 16 .loop: lea pix1q, [pix1q+2*strideq] lea pix2q, [pix2q+2*strideq] +%if %1 < mmsize + movh m2, [pix2q] + movh m3, [pix2q+strideq] + punpcklqdq m1, m2 + punpcklqdq m2, m3 + pavgb m1, m2 + movh m2, [pix1q] + movhps m2, [pix1q+strideq] + psadbw m1, m2 + paddw m0, m1 + mova m1, m3 +%else movu m2, [pix2q] movu m3, [pix2q+strideq] pavgb m1, m2 @@ -524,19 +574,17 @@ align 16 paddw m0, m1 paddw m0, m2 mova m1, m3 +%endif sub hd, 2 jg .loop -%if mmsize == 16 movhlps m1, m0 paddw m0, m1 -%endif movd eax, m0 RET %endmacro -INIT_MMX mmxext -SAD_Y2 8 INIT_XMM sse2 +SAD_Y2 8 SAD_Y2 16 ;------------------------------------------------------------------------------------------ @@ -642,27 +690,40 @@ SAD_XY2 16, a, u %macro SAD_APPROX_XY2 1 cglobal sad%1_approx_xy2, 5, 5, 7, v, pix1, pix2, stride, h mova m4, [pb_1] +%if %1 < mmsize + movh m1, [pix2q] + movh m5, [pix2q+1] + pavgb m1, m5 + movh m0, [pix2q+strideq] + movh m5, [pix2q+strideq+1] + pavgb m0, m5 + psubusb m0, m4 + movh m3, [pix2q+2*strideq] + movh m5, [pix2q+2*strideq+1] + pavgb m3, m5 + punpcklqdq m1, m0 + punpcklqdq m0, m3 + pavgb m0, m1 + movh m2, [pix1q] + movhps m2, [pix1q+strideq] + psadbw m0, m2 +%else movu m1, [pix2q] movu m0, [pix2q+strideq] movu m3, [pix2q+2*strideq] -%if mmsize == 16 movu m5, [pix2q+1] movu m6, [pix2q+strideq+1] movu m2, [pix2q+2*strideq+1] pavgb m1, m5 pavgb m0, m6 pavgb m3, m2 -%else - pavgb m1, [pix2q+1] - pavgb m0, [pix2q+strideq+1] - pavgb m3, [pix2q+2*strideq+1] -%endif psubusb m0, m4 pavgb m1, m0 pavgb m0, m3 psadbw m1, [pix1q] psadbw m0, [pix1q+strideq] paddw m0, m1 +%endif mova m1, m3 add pix2q, strideq sub hd, 2 @@ -671,17 +732,29 @@ align 16 .loop: lea pix1q, [pix1q+2*strideq] lea pix2q, [pix2q+2*strideq] +%if %1 < mmsize + movh m2, [pix2q] + movh m5, [pix2q+1] + pavgb m2, m5 + psubusb m2, m4 + movh m3, [pix2q+strideq] + movh m5, [pix2q+strideq+1] + pavgb m3, m5 + punpcklqdq m1, m2 + punpcklqdq m2, m3 + pavgb m1, m2 + movh m5, [pix1q] + movhps m5, [pix1q+strideq] + psadbw m1, m5 + paddw m0, m1 + mova m1, m3 +%else movu m2, [pix2q] movu m3, [pix2q+strideq] -%if mmsize == 16 movu m5, [pix2q+1] movu m6, [pix2q+strideq+1] pavgb m2, m5 pavgb m3, m6 -%else - pavgb m2, [pix2q+1] - pavgb m3, [pix2q+strideq+1] -%endif psubusb m2, m4 pavgb m1, m2 pavgb m2, m3 @@ -690,19 +763,17 @@ align 16 paddw m0, m1 paddw m0, m2 mova m1, m3 +%endif sub hd, 2 jg .loop -%if mmsize == 16 movhlps m1, m0 paddw m0, m1 -%endif movd eax, m0 RET %endmacro -INIT_MMX mmxext -SAD_APPROX_XY2 8 INIT_XMM sse2 +SAD_APPROX_XY2 8 SAD_APPROX_XY2 16 ;-------------------------------------------------------------------- @@ -732,7 +803,7 @@ cglobal vsad_intra%1, 5, 5, 3, v, pix1, pix2, lsize, h sub hd, 2 jg .loop -%if mmsize == 16 +%if %1 >= mmsize pshufd m1, m0, 0xe paddd m0, m1 %endif @@ -740,9 +811,8 @@ cglobal vsad_intra%1, 5, 5, 3, v, pix1, pix2, lsize, h RET %endmacro -INIT_MMX mmxext -VSAD_INTRA 8, a INIT_XMM sse2 +VSAD_INTRA 8, h VSAD_INTRA 16, a VSAD_INTRA 16, u @@ -760,15 +830,15 @@ cglobal vsad%1_approx, 5, 5, 5, v, pix1, pix2, lsize, h mova m1, [pb_80] mov%2 m0, [pix1q] mov%2 m4, [pix1q+lsizeq] -%if mmsize == 16 +%if %1 < mmsize + movh m3, [pix2q] + movh m2, [pix2q+lsizeq] +%else movu m3, [pix2q] movu m2, [pix2q+lsizeq] +%endif psubb m0, m3 psubb m4, m2 -%else - psubb m0, [pix2q] - psubb m4, [pix2q+lsizeq] -%endif pxor m0, m1 pxor m4, m1 psadbw m0, m4 @@ -778,17 +848,21 @@ cglobal vsad%1_approx, 5, 5, 5, v, pix1, pix2, lsize, h lea pix1q, [pix1q + 2*lsizeq] lea pix2q, [pix2q + 2*lsizeq] mov%2 m2, [pix1q] -%if mmsize == 16 - movu m3, [pix2q] - psubb m2, m3 +%if %1 < mmsize + movh m3, [pix2q] %else - psubb m2, [pix2q] + movu m3, [pix2q] %endif + psubb m2, m3 pxor m2, m1 psadbw m4, m2 paddw m0, m4 mov%2 m4, [pix1q+lsizeq] +%if %1 < mmsize + movh m3, [pix2q+lsizeq] +%else movu m3, [pix2q+lsizeq] +%endif psubb m4, m3 pxor m4, m1 psadbw m2, m4 @@ -796,7 +870,7 @@ cglobal vsad%1_approx, 5, 5, 5, v, pix1, pix2, lsize, h sub hd, 2 jg .loop -%if mmsize == 16 +%if %1 >= mmsize pshufd m1, m0, 0xe paddd m0, m1 %endif @@ -804,9 +878,8 @@ cglobal vsad%1_approx, 5, 5, 5, v, pix1, pix2, lsize, h RET %endmacro -INIT_MMX mmxext -VSAD_APPROX 8, a INIT_XMM sse2 +VSAD_APPROX 8, h VSAD_APPROX 16, a VSAD_APPROX 16, u diff --git a/libavcodec/x86/me_cmp_init.c b/libavcodec/x86/me_cmp_init.c index 1ba4003923..c960ec88fc 100644 --- a/libavcodec/x86/me_cmp_init.c +++ b/libavcodec/x86/me_cmp_init.c @@ -37,38 +37,38 @@ int ff_sse16_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); int ff_hf_noise8_ssse3(const uint8_t *pix1, ptrdiff_t stride, int h); int ff_hf_noise16_ssse3(const uint8_t *pix1, ptrdiff_t stride, int h); -int ff_sad8_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, - ptrdiff_t stride, int h); +int ff_sad8_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, + ptrdiff_t stride, int h); int ff_sad16_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); int ff_sad16u_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); -int ff_sad8_x2_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, - ptrdiff_t stride, int h); +int ff_sad8_x2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, + ptrdiff_t stride, int h); int ff_sad16_x2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); -int ff_sad8_y2_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, - ptrdiff_t stride, int h); +int ff_sad8_y2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, + ptrdiff_t stride, int h); int ff_sad16_y2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); -int ff_sad8_approx_xy2_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, - ptrdiff_t stride, int h); +int ff_sad8_approx_xy2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, + ptrdiff_t stride, int h); int ff_sad8_xy2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); int ff_sad16_approx_xy2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); int ff_sad16_xy2_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); -int ff_vsad_intra8_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, - ptrdiff_t stride, int h); +int ff_vsad_intra8_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, + ptrdiff_t stride, int h); int ff_vsad_intra16_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); int ff_vsad_intra16u_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); -int ff_vsad8_approx_mmxext(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, - ptrdiff_t stride, int h); +int ff_vsad8_approx_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, + ptrdiff_t stride, int h); int ff_vsad16_approx_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, - ptrdiff_t stride, int h); + ptrdiff_t stride, int h); int ff_vsad16u_approx_sse2(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h); int ff_median_sad16_ssse3(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, @@ -115,38 +115,29 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx) { int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_MMXEXT(cpu_flags)) { - c->sad[1] = ff_sad8_mmxext; - - c->pix_abs[1][0] = ff_sad8_mmxext; - c->pix_abs[1][1] = ff_sad8_x2_mmxext; - c->pix_abs[1][2] = ff_sad8_y2_mmxext; - - c->vsad[5] = ff_vsad_intra8_mmxext; - - if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { - c->pix_abs[1][3] = ff_sad8_approx_xy2_mmxext; - - c->vsad[1] = ff_vsad8_approx_mmxext; - } - } - if (EXTERNAL_SSE2(cpu_flags)) { c->sse[0] = ff_sse16_sse2; c->sse[1] = ff_sse8_sse2; c->sum_abs_dctelem = ff_sum_abs_dctelem_sse2; + c->sad[1] = ff_sad8_sse2; + c->pix_abs[0][0] = ff_sad16_sse2; c->pix_abs[0][1] = ff_sad16_x2_sse2; c->pix_abs[0][2] = ff_sad16_y2_sse2; c->pix_abs[0][3] = ff_sad16_xy2_sse2; + c->pix_abs[1][0] = ff_sad8_sse2; + c->pix_abs[1][1] = ff_sad8_x2_sse2; + c->pix_abs[1][2] = ff_sad8_y2_sse2; c->hadamard8_diff[0] = ff_hadamard8_diff16_sse2; c->hadamard8_diff[1] = ff_hadamard8_diff_sse2; + if (avctx->codec_id != AV_CODEC_ID_SNOW) { c->sad[0] = ff_sad16_sse2; c->vsad[4] = ff_vsad_intra16_sse2; + c->vsad[5] = ff_vsad_intra8_sse2; if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { c->vsad[0] = ff_vsad16_approx_sse2; } @@ -156,6 +147,7 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx) c->sad[0] = ff_sad16u_sse2; c->vsad[4] = ff_vsad_intra16u_sse2; + c->vsad[5] = ff_vsad_intra8_sse2; if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { c->vsad[0] = ff_vsad16u_approx_sse2; } @@ -164,6 +156,9 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx) c->pix_abs[1][3] = ff_sad8_xy2_sse2; } else { c->pix_abs[0][3] = ff_sad16_approx_xy2_sse2; + c->pix_abs[1][3] = ff_sad8_approx_xy2_sse2; + + c->vsad[1] = ff_vsad8_approx_sse2; } } -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
