PR #25792 opened by mkver URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25792 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25792.patch
>From a579e74d7196dae31760f65c854c8b9841823510 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 11:31:41 +0100 Subject: [PATCH 01/16] tests/checkasm/qpeldsp: Don't use declare_func_emms Unnecessary since 5dc2dd9b9f291a373015500b11136bef39cbc6c0. Signed-off-by: Andreas Rheinhardt <[email protected]> --- tests/checkasm/qpeldsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/checkasm/qpeldsp.c b/tests/checkasm/qpeldsp.c index 2db720c130c..8cdec7d03c1 100644 --- a/tests/checkasm/qpeldsp.c +++ b/tests/checkasm/qpeldsp.c @@ -66,7 +66,7 @@ void checkasm_check_qpeldsp(void) TEST(avg_qpel_pixels_tab), TEST(put_no_rnd_qpel_pixels_tab), }; - declare_func_emms(AV_CPU_FLAG_MMXEXT, void, uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + declare_func(void, uint8_t *dst, const uint8_t *src, ptrdiff_t stride); ff_qpeldsp_init(&qdsp); -- 2.54.0 >From b9a7ca9485577c1ce18abd3a62baef5eeacf46b2 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 12:32:45 +0100 Subject: [PATCH 02/16] avcodec/h264{dec,_picture}: Remove obsolete emms_c The H.264 decoder does not use any mmx registers since aab6cec3e8415154b3f0570f8d131db07a9901de. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/h264_picture.c | 2 -- libavcodec/h264dec.c | 3 --- 2 files changed, 5 deletions(-) diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c index 8cb91e371c6..b287f59e1ae 100644 --- a/libavcodec/h264_picture.c +++ b/libavcodec/h264_picture.c @@ -26,7 +26,6 @@ */ #include "libavutil/avassert.h" -#include "libavutil/emms.h" #include "error_resilience.h" #include "avcodec.h" #include "h264dec.h" @@ -228,7 +227,6 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup) if (!in_setup && !h->droppable) ff_thread_report_progress(&cur->tf, INT_MAX, h->picture_structure == PICT_BOTTOM_FIELD); - emms_c(); h->current_slice = 0; diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 597bdae548a..fea2e2a6167 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -31,7 +31,6 @@ #include "libavutil/attributes.h" #include "libavutil/avassert.h" -#include "libavutil/emms.h" #include "libavutil/imgutils.h" #include "libavutil/mem.h" #include "libavutil/opt.h" @@ -134,8 +133,6 @@ void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, for (int i = 3; i < AV_NUM_DATA_POINTERS; i++) offset[i] = 0; - emms_c(); - avctx->draw_horiz_band(avctx, src, offset, y, h->picture_structure, height); } -- 2.54.0 >From 537afcee0a001c7aab8da05eba5cafda48c9a1b9 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 13:02:26 +0100 Subject: [PATCH 03/16] avcodec/dvenc: Remove obsolete emms_c Unnecessary since 57f9d96cacd2dd62fe8c126b840ff2d0676f383b. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/dvenc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c index b612ec5a1b8..b58e3000482 100644 --- a/libavcodec/dvenc.c +++ b/libavcodec/dvenc.c @@ -29,7 +29,6 @@ #include "config.h" #include "libavutil/attributes.h" -#include "libavutil/emms.h" #include "libavutil/internal.h" #include "libavutil/mem_internal.h" #include "libavutil/opt.h" @@ -1222,8 +1221,6 @@ static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt, c->execute(c, dv_encode_video_segment, s->work_chunks, NULL, dv_work_pool_size(s->sys), sizeof(DVwork_chunk)); - emms_c(); - *got_packet = 1; return 0; -- 2.54.0 >From d0003c59c0d85151e8470ad76bd817ef99220d42 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 13:06:15 +0100 Subject: [PATCH 04/16] avcodec/mpegutils: Remove obsolete emms_c After 5dc2dd9b9f291a373015500b11136bef39cbc6c0 of all the mpegvideo-based decoders only the VC-1 one uses any mmx regs at all; yet the VC-1 decoders don't call ff_draw_horiz_band() at all, so one can just remove the emms_c here. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/mpegutils.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavcodec/mpegutils.c b/libavcodec/mpegutils.c index 73b6650b70d..f827b00c564 100644 --- a/libavcodec/mpegutils.c +++ b/libavcodec/mpegutils.c @@ -22,7 +22,6 @@ #include "libavutil/bprint.h" #include "libavutil/common.h" -#include "libavutil/emms.h" #include "libavutil/frame.h" #include "libavutil/mem.h" #include "libavutil/pixdesc.h" @@ -91,8 +90,6 @@ void ff_draw_horiz_band(AVCodecContext *avctx, for (int i = 3; i < AV_NUM_DATA_POINTERS; i++) offset[i] = 0; - emms_c(); - avctx->draw_horiz_band(avctx, src, offset, y, picture_structure, h); } -- 2.54.0 >From 00eaf822c652c106d188ac317afb55ec68b26cb6 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 13:16:39 +0100 Subject: [PATCH 05/16] avcodec/mpegvideo_enc: Remove obsolete emms_c Unnecessary since 57f9d96cacd2dd62fe8c126b840ff2d0676f383b. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/mpegvideo_enc.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index c9da0326164..8180436ed1b 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -37,7 +37,6 @@ #include <stdint.h> #include "libavutil/attributes.h" -#include "libavutil/emms.h" #include "libavutil/internal.h" #include "libavutil/intmath.h" #include "libavutil/mathematics.h" @@ -1460,7 +1459,6 @@ static int skip_check(MPVMainEncContext *const m, } } } - emms_c(); if (score) score64 = score; @@ -2936,8 +2934,6 @@ int ff_mpv_reallocate_putbitbuffer(MPVEncContext *const s, size_t threshold, siz return AVERROR(ENOMEM); } - emms_c(); - av_fast_padded_malloc(&new_buffer, &new_buffer_size, s->c.avctx->internal->byte_buffer_size + size_increase); if (!new_buffer) @@ -3771,7 +3767,6 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt) merge_context_after_me(s, s->c.enc_contexts[i]); m->mc_mb_var_sum = s->me.mc_mb_var_sum_temp; m->mb_var_sum = s->me. mb_var_sum_temp; - emms_c(); if (s->me.scene_change_score > m->scenechange_threshold && s->c.pict_type == AV_PICTURE_TYPE_P) { @@ -3918,7 +3913,6 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt) set_put_bits_buffer_size(&s->pb, FFMIN(s->c.enc_contexts[i]->pb.buf_end - s->pb.buf, INT_MAX/8-BUF_BITS)); merge_context_after_encode(s, s->c.enc_contexts[i]); } - emms_c(); return 0; } @@ -4248,7 +4242,6 @@ static DECLARE_ALIGNED(16, int16_t, basis)[64][64]; static void build_basis(uint8_t *perm){ int i, j, x, y; - emms_c(); for(i=0; i<8; i++){ for(j=0; j<8; j++){ for(y=0; y<8; y++){ -- 2.54.0 >From 4018b4b8eb456f1c0375b140807176a2c293f5c6 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 13:25:15 +0100 Subject: [PATCH 06/16] avcodec/snowenc: Remove obsolete emms_c Unnecessary since 57f9d96cacd2dd62fe8c126b840ff2d0676f383b; notice that only the Snow decoder uses the SnowDWTContext functions that are still partially mmx. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/snowenc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 13ca651fcdb..c7a6c7c63de 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -20,7 +20,6 @@ #include <math.h> -#include "libavutil/emms.h" #include "libavutil/intmath.h" #include "libavutil/log.h" #include "libavutil/mem.h" @@ -1714,7 +1713,6 @@ static int ratecontrol_1pass(SnowEncContext *enc, AVFrame *pict) coef_sum+= abs(buf[x+y*stride]) * qdiv >> 16; } } - emms_c(); /* ugly, ratecontrol just takes a sqrt again */ av_assert0(coef_sum < INT_MAX); @@ -1958,7 +1956,6 @@ redo_frame: pic->pict_type= AV_PICTURE_TYPE_I; s->keyframe=1; s->current_picture->flags |= AV_FRAME_FLAG_KEY; - emms_c(); goto redo_frame; } @@ -2053,7 +2050,6 @@ redo_frame: } } - emms_c(); update_last_header_values(s); -- 2.54.0 >From 6355afddf70bc8936e1dda184babc91a517d5b03 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 13:34:36 +0100 Subject: [PATCH 07/16] avcodec/svq1enc: Remove obsolete emms_c Unnecessary since 57f9d96cacd2dd62fe8c126b840ff2d0676f383b. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/svq1enc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index d720b143abe..1c05e8d543b 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -26,7 +26,6 @@ * http://www.pcisys.net/~melanson/codecs/ */ -#include "libavutil/emms.h" #include "libavutil/mem.h" #include "avcodec.h" #include "codec_internal.h" @@ -653,7 +652,6 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, s->frame_height / (i ? 4 : 1), pict->linesize[i], s->current_picture->linesize[i]); - emms_c(); if (ret < 0) return ret; } -- 2.54.0 >From 66aed0d80969cf65b2e0f65cd7e3bb0a36fb16cd Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 14:24:32 +0100 Subject: [PATCH 08/16] avcodec/faani?dct: Remove obsolete emms_c None of the codecs using the FDCTDSP or IDCTDSP API clobber the FPU state at all any more (since 57f9d96cacd2dd62fe8c126b840ff2d0676f383b for the FDCTDSP, 5dc2dd9b9f291a373015500b11136bef39cbc6c0 for IDCTDSP), so one can remove the emms_c here and simply presume that the caller abides by the ABI. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/faandct.c | 5 ----- libavcodec/faanidct.c | 7 ------- 2 files changed, 12 deletions(-) diff --git a/libavcodec/faandct.c b/libavcodec/faandct.c index a474906c1b8..11237c64be1 100644 --- a/libavcodec/faandct.c +++ b/libavcodec/faandct.c @@ -28,7 +28,6 @@ #include <math.h> #include "faandct.h" -#include "libavutil/emms.h" #include "libavutil/internal.h" #include "libavutil/mathematics.h" @@ -122,8 +121,6 @@ void ff_faandct(int16_t *data) FLOAT temp[64]; int i; - emms_c(); - row_fdct(temp, data); for (i=0; i<8; i++) { @@ -175,8 +172,6 @@ void ff_faandct248(int16_t *data) FLOAT temp[64]; int i; - emms_c(); - row_fdct(temp, data); for (i=0; i<8; i++) { diff --git a/libavcodec/faanidct.c b/libavcodec/faanidct.c index f2667fb7168..55ddd84df32 100644 --- a/libavcodec/faanidct.c +++ b/libavcodec/faanidct.c @@ -20,7 +20,6 @@ */ #include "faanidct.h" #include "libavutil/common.h" -#include "libavutil/emms.h" /* To allow switching to double. */ typedef float FLOAT; @@ -129,8 +128,6 @@ void ff_faanidct(int16_t block[64]){ FLOAT temp[64]; int i; - emms_c(); - for(i=0; i<64; i++) temp[i] = block[i] * prescale[i]; @@ -143,8 +140,6 @@ void ff_faanidct_add(uint8_t *dest, ptrdiff_t line_size, int16_t block[64]) FLOAT temp[64]; int i; - emms_c(); - for(i=0; i<64; i++) temp[i] = block[i] * prescale[i]; @@ -157,8 +152,6 @@ void ff_faanidct_put(uint8_t *dest, ptrdiff_t line_size, int16_t block[64]) FLOAT temp[64]; int i; - emms_c(); - for(i=0; i<64; i++) temp[i] = block[i] * prescale[i]; -- 2.54.0 >From 149a6f1e9b8b458e34b7493cdacd94360375ffad Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 19:43:33 +0100 Subject: [PATCH 09/16] avcodec/x86/vp8dsp: Don't use MMX regs in bilinear mc Improves performance a bit for the horizontal case: Old benchmarks: vp8_put_bilin4_h_c: 71.5 vp8_put_bilin4_h_ssse3: 16.6 ( 4.27x) vp8_put_bilin4_hv_c: 99.8 vp8_put_bilin4_hv_ssse3: 64.8 ( 1.48x) vp8_put_bilin4_v_c: 41.1 vp8_put_bilin4_v_ssse3: 37.6 ( 0.95x) New benchmarks: vp8_put_bilin4_h_c: 70.2 vp8_put_bilin4_h_ssse3: 12.5 ( 5.58x) vp8_put_bilin4_hv_c: 100.4 vp8_put_bilin4_hv_ssse3: 64.0 ( 1.49x) vp8_put_bilin4_v_c: 41.1 vp8_put_bilin4_v_ssse3: 37.7 ( 0.93x) Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp8dsp.asm | 43 +++++++++++++++++++++++++-------------- tests/checkasm/vp8dsp.c | 2 +- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm index 825e64880f0..65b7d5a82c7 100644 --- a/libavcodec/x86/vp8dsp.asm +++ b/libavcodec/x86/vp8dsp.asm @@ -146,7 +146,8 @@ filter_h6_shuf1: db 0, 3, 1, 4, 2, 5, 3, 6, 4, 7, 5, 8, 6, 9, 7, 10 filter_h6_shuf2: db 1, 4, 2, 5, 3, 6, 4, 7, 5, 8, 6, 9, 7, 10, 8, 11 filter_h6_shuf3: db 2, 5, 3, 6, 4, 7, 5, 8, 6, 9, 7, 10, 8, 11, 9, 12 -filter_h2_shuf: db 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 +filter_h2_shuf: db 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 +filter_h2_shuf2: db 0, 1, 1, 2, 2, 3, 3, 4, 8, 9, 9, 10, 10, 11, 11, 12 pw_20091: times 4 dw 20091 pw_17734: times 4 dw 17734 @@ -646,6 +647,8 @@ cglobal put_vp8_epel8_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picre %macro FILTER_BILINEAR 1 %if cpuflag(ssse3) +%define mov8 movq +%define mov4 movd cglobal put_vp8_bilinear%1_v, 7, 7, 5, dst, dststride, src, srcstride, height, picreg, my shl myd, 4 %if PIC @@ -653,10 +656,10 @@ cglobal put_vp8_bilinear%1_v, 7, 7, 5, dst, dststride, src, srcstride, height, p %endif pxor m4, m4 mova m3, [bilinear_filter_vb+myq-16] - movh m0, [srcq+srcstrideq*0] + mov%1 m0, [srcq+srcstrideq*0] .nextrow: - movh m1, [srcq+srcstrideq*1] - movh m2, [srcq+srcstrideq*2] + mov%1 m1, [srcq+srcstrideq*1] + mov%1 m2, [srcq+srcstrideq*2] punpcklbw m0, m1 punpcklbw m1, m2 pmaddubsw m0, m3 @@ -666,11 +669,11 @@ cglobal put_vp8_bilinear%1_v, 7, 7, 5, dst, dststride, src, srcstride, height, p psraw m1, 2 pavgw m0, m4 pavgw m1, m4 -%if mmsize==8 +%if %1 == 4 packuswb m0, m0 packuswb m1, m1 - movh [dstq+dststrideq*0], m0 - movh [dstq+dststrideq*1], m1 + movd [dstq+dststrideq*0], m0 + movd [dstq+dststrideq*1], m1 %else packuswb m0, m1 movh [dstq+dststrideq*0], m0 @@ -723,9 +726,14 @@ cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 5, dst, dststride, src, srcstride lea picregq, [bilinear_filter_vb_m] %endif pxor m4, m4 +%if %1 != 4 mova m2, [filter_h2_shuf] +%else + mova m2, [filter_h2_shuf2] +%endif mova m3, [bilinear_filter_vb+mxq-16] .nextrow: +%if %1 != 4 movu m0, [srcq+srcstrideq*0] movu m1, [srcq+srcstrideq*1] pshufb m0, m2 @@ -737,15 +745,21 @@ cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 5, dst, dststride, src, srcstride psraw m1, 2 pavgw m0, m4 pavgw m1, m4 -%if mmsize==8 - packuswb m0, m0 - packuswb m1, m1 - movh [dstq+dststrideq*0], m0 - movh [dstq+dststrideq*1], m1 -%else packuswb m0, m1 movh [dstq+dststrideq*0], m0 movhps [dstq+dststrideq*1], m0 +%else + movq m0, [srcq+srcstrideq*0] + movhps m0, [srcq+srcstrideq*1] + pshufb m0, m2 + pmaddubsw m0, m3 + lea srcq, [srcq+srcstrideq*2] + psrlw m0, 2 + pavgw m0, m4 + packuswb m0, m0 + movd [dstq+dststrideq*0], m0 + psrldq m0, 4 + movd [dstq+dststrideq*1], m0 %endif %else ; cpuflag(ssse3) cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 7, dst, dststride, src, srcstride, height, mx, picreg @@ -790,9 +804,8 @@ cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 7, dst, dststride, src, srcstride INIT_XMM sse2 FILTER_BILINEAR 8 -INIT_MMX ssse3 -FILTER_BILINEAR 4 INIT_XMM ssse3 +FILTER_BILINEAR 4 FILTER_BILINEAR 8 INIT_XMM sse2 diff --git a/tests/checkasm/vp8dsp.c b/tests/checkasm/vp8dsp.c index 0df425a5241..eeb487c6b1e 100644 --- a/tests/checkasm/vp8dsp.c +++ b/tests/checkasm/vp8dsp.c @@ -262,7 +262,7 @@ static void check_mc(VP8DSPContext *d) BUF_RECT(uint8_t, dst0, 16, 16); BUF_RECT(uint8_t, dst1, 16, 16); int type, k, dx, dy; - declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, ptrdiff_t, + declare_func(void, uint8_t *, ptrdiff_t, const uint8_t *, ptrdiff_t, int, int, int); for (type = 0; type < 2; type++) { -- 2.54.0 >From 35f22880fa6d72e9106753fd8e8c7179442553a4 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 20:25:55 +0100 Subject: [PATCH 10/16] avutil/x86/x86util: Make STORE_DIFFx2 more flexible Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp8dsp.asm | 4 ++-- libavutil/x86/x86util.asm | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm index 65b7d5a82c7..41dea20c36d 100644 --- a/libavcodec/x86/vp8dsp.asm +++ b/libavcodec/x86/vp8dsp.asm @@ -1045,8 +1045,8 @@ cglobal vp8_idct_add, 3, 3, 0, dst, block, stride pxor m4, m4 DEFINE_ARGS dst1, dst2, stride lea dst2q, [dst1q+2*strideq] - STORE_DIFFx2 m0, m1, m6, m7, m4, 3, dst1q, strideq - STORE_DIFFx2 m2, m3, m6, m7, m4, 3, dst2q, strideq + STORE_DIFFx2 m0, m1, m6, m7, m4, 3, dst1q, strideq, movd + STORE_DIFFx2 m2, m3, m6, m7, m4, 3, dst2q, strideq, movd RET diff --git a/libavutil/x86/x86util.asm b/libavutil/x86/x86util.asm index 2365a1e65ce..e346f246b26 100644 --- a/libavutil/x86/x86util.asm +++ b/libavutil/x86/x86util.asm @@ -648,9 +648,9 @@ movh %4, %1 %endmacro -%macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride - movh %3, [%7] - movh %4, [%7+%8] +%macro STORE_DIFFx2 8-9 movh ; add1, add2, reg1, reg2, zero, shift, source, stride [, mov instr] + %9 %3, [%7] + %9 %4, [%7+%8] psraw %1, %6 psraw %2, %6 punpcklbw %3, %5 @@ -659,8 +659,8 @@ paddw %4, %2 packuswb %3, %5 packuswb %4, %5 - movh [%7], %3 - movh [%7+%8], %4 + %9 [%7], %3 + %9 [%7+%8], %4 %endmacro %macro SPLATW 2-3 0 -- 2.54.0 >From 579c82e8f2e0bbe658df9aba853675f5c47faff2 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 20:29:04 +0100 Subject: [PATCH 11/16] avcodec/x86/h264_idct: Remove STORE_DIFFx2 clone Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/h264_idct.asm | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm index d9fadabefc5..1f01b200d78 100644 --- a/libavcodec/x86/h264_idct.asm +++ b/libavcodec/x86/h264_idct.asm @@ -67,23 +67,6 @@ SECTION .text %endif %endmacro -; %1=uint8_t *dst, %2=int16_t *block, %3=ptrdiff_t stride -; STORE_DIFFx2 not suitable here: it uses movh -%macro STORE_DIFFx4 8 ; add1, add2, reg1, reg2, zero, shift, source, stride - movd %3, [%7] - movd %4, [%7+%8] - psraw %1, %6 - psraw %2, %6 - punpcklbw %3, %5 - punpcklbw %4, %5 - paddw %3, %1 - paddw %4, %2 - packuswb %3, %5 - packuswb %4, %5 - movd [%7], %3 - movd [%7+%8], %4 -%endmacro - %macro IDCT4_ADD 3 ; Load dct coeffs movq m0, [%2] @@ -115,9 +98,9 @@ SECTION .text movq [%2+24], m7 %endif - STORE_DIFFx4 m0, m1, m4, m5, m7, 6, %1, %3 + STORE_DIFFx2 m0, m1, m4, m5, m7, 6, %1, %3, movd lea %1, [%1+%3*2] - STORE_DIFFx4 m2, m3, m4, m5, m7, 6, %1, %3 + STORE_DIFFx2 m2, m3, m4, m5, m7, 6, %1, %3, movd %endmacro %macro IDCT8_1D 2 -- 2.54.0 >From 85924300fc95884d832f8f9c3b0300eda6e0ad8c Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 20:34:44 +0100 Subject: [PATCH 12/16] avcodec/x86/h264_idct: Remove some remnants of MMX Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/h264_idct.asm | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm index 1f01b200d78..1473767a611 100644 --- a/libavcodec/x86/h264_idct.asm +++ b/libavcodec/x86/h264_idct.asm @@ -1,5 +1,5 @@ ;***************************************************************************** -;* MMX/SSE2-optimized H.264 iDCT +;* ASM-optimized H.264 iDCT ;***************************************************************************** ;* Copyright (C) 2004-2005 Michael Niedermayer, Loren Merritt ;* Copyright (C) 2003-2008 x264 project @@ -76,27 +76,18 @@ SECTION .text IDCT4_1D w, 0, 1, 2, 3, 4, 5 mova m6, [pw_32] - %if mmsize == 8 - TRANSPOSE4x4W 0, 1, 2, 3, 4 - %else - punpcklwd m0, m1 - punpcklwd m2, m3 - SBUTTERFLY dq, 0, 2, 4 - MOVHL m1, m0 - MOVHL m3, m2 - %endif + + punpcklwd m0, m1 + punpcklwd m2, m3 + SBUTTERFLY dq, 0, 2, 4 + MOVHL m1, m0 + MOVHL m3, m2 + paddw m0, m6 IDCT4_1D w, 0, 1, 2, 3, 4, 5 pxor m7, m7 - %if mmsize == 16 - mova [%2+ 0], m7 - mova [%2+16], m7 - %else - movq [%2+ 0], m7 - movq [%2+ 8], m7 - movq [%2+16], m7 - movq [%2+24], m7 - %endif + mova [%2+ 0], m7 + mova [%2+16], m7 STORE_DIFFx2 m0, m1, m4, m5, m7, 6, %1, %3, movd lea %1, [%1+%3*2] -- 2.54.0 >From 8ff3e9b5b3af7c117abdd1357ea784872e5d9b1e Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 20:57:51 +0100 Subject: [PATCH 13/16] avcodec/x86/h264_idct: Deduplicate DC_ADD_INIT macro Also avoid some rex prefixes. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/h264_idct.asm | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm index 1473767a611..4f58552e068 100644 --- a/libavcodec/x86/h264_idct.asm +++ b/libavcodec/x86/h264_idct.asm @@ -220,18 +220,20 @@ cglobal h264_idct8_add_8, 3, 4, 10 IDCT8_ADD_SSE r0, r1, r2, r3 RET -%macro DC_ADD_SSE2_INIT 2 - add %1, 32 - sar %1, 6 +%macro DC_ADD_INIT 3 + add %1d, 32 + sar %1d, 6 movd m0, %1d - lea %1, [%2*3] + lea %1, [3*%2] pshuflw m0, m0, 0 pxor m1, m1 psubw m1, m0 packuswb m0, m0 packuswb m1, m1 +%if %3 > 4 pshufd m0, m0, 0 pshufd m1, m1, 0 +%endif %endmacro %macro DC_ADD_SSE2_OP 4 @@ -259,7 +261,7 @@ INIT_XMM sse2 cglobal h264_idct8_dc_add_8, 3, 4, 6 movsx r3, word [r1] mov dword [r1], 0 - DC_ADD_SSE2_INIT r3, r2 + DC_ADD_INIT r3, r2, 8 DC_ADD_SSE2_OP movq, r0, r2, r3 lea r0, [r0+r2*4] DC_ADD_SSE2_OP movq, r0, r2, r3 @@ -270,7 +272,7 @@ cglobal h264_idct8_dc_add_8, 2, 3, 6 movsx r2, word [r1] mov dword [r1], 0 mov r1, r2m - DC_ADD_SSE2_INIT r2, r1 + DC_ADD_INIT r2, r1, 8 DC_ADD_SSE2_OP movq, r0, r1, r2 lea r0, [r0+r1*4] DC_ADD_SSE2_OP movq, r0, r1, r2 @@ -297,7 +299,7 @@ cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, strid test r6, r6 jz .no_dc mov word [r2], 0 - DC_ADD_SSE2_INIT r6, r3 + DC_ADD_INIT r6, r3, 8 %if ARCH_X86_64 == 0 %define dst2q r1 %define dst2d r1d @@ -689,18 +691,6 @@ cglobal h264_luma_dc_dequant_idct, 3, 4, 6 DEQUANT_STORE m6 RET -%macro DC_ADD_INIT 1 - add %1d, 32 - sar %1d, 6 - movd m0, %1d - pshuflw m0, m0, 0 - lea %1, [3*stride_q] - pxor m1, m1 - psubw m1, m0 - packuswb m0, m0 - packuswb m1, m1 -%endmacro - %macro IDCT_XMM 1 INIT_XMM %1 @@ -712,7 +702,7 @@ RET cglobal h264_idct_dc_add_8, 3, 4, 6, dst_, block_, stride_ movsx r3d, word [block_q] mov dword [block_q], 0 - DC_ADD_INIT r3 + DC_ADD_INIT r3, stride_q, 4 DC_ADD_SSE2_OP movd, dst_q, stride_q, r3 RET -- 2.54.0 >From 701cc9f20bef5e0e83b238a6d698da2a08a52574 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 21:07:42 +0100 Subject: [PATCH 14/16] avcodec/x86/h264_idct: Avoid using nonvolatile xmm register Avoids a pop+push on Win64. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/h264_idct.asm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm index 4f58552e068..2014129e9fa 100644 --- a/libavcodec/x86/h264_idct.asm +++ b/libavcodec/x86/h264_idct.asm @@ -85,13 +85,13 @@ SECTION .text paddw m0, m6 IDCT4_1D w, 0, 1, 2, 3, 4, 5 - pxor m7, m7 - mova [%2+ 0], m7 - mova [%2+16], m7 + pxor m6, m6 + mova [%2+ 0], m6 + mova [%2+16], m6 - STORE_DIFFx2 m0, m1, m4, m5, m7, 6, %1, %3, movd + STORE_DIFFx2 m0, m1, m4, m5, m6, 6, %1, %3, movd lea %1, [%1+%3*2] - STORE_DIFFx2 m2, m3, m4, m5, m7, 6, %1, %3, movd + STORE_DIFFx2 m2, m3, m4, m5, m6, 6, %1, %3, movd %endmacro %macro IDCT8_1D 2 @@ -332,7 +332,7 @@ cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, strid RET INIT_XMM sse2 -cglobal h264_idct_add8_422_8, 5, 8 + npicregs, 8, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg +cglobal h264_idct_add8_422_8, 5, 8 + npicregs, 7, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg ; dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg %if PIC lea picregq, [scan8_mem] @@ -695,7 +695,7 @@ cglobal h264_luma_dc_dequant_idct, 3, 4, 6 INIT_XMM %1 -cglobal h264_idct_add_8, 3, 3, 8, dst_, block_, stride_ +cglobal h264_idct_add_8, 3, 3, 7, dst_, block_, stride_ IDCT4_ADD dst_q, block_q, stride_q RET -- 2.54.0 >From 0300bc69176804d855323a213eb9d81b9fe1e00e Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Thu, 5 Nov 2026 22:15:24 +0100 Subject: [PATCH 15/16] avcodec/x86/vp8dsp: Don't use mmx regs in vp8_idct_add This makes the VP8 decoder ABI compliant.* Old benchmarks: vp8_idct_add_c: 135.6 vp8_idct_add_sse: 35.3 ( 3.84x) New benchmarks: vp8_idct_add_c: 134.1 vp8_idct_add_sse2: 23.7 ( 5.66x) *: Previously, it was possible to call alloc/free functions via av_frame_ref() while having an invalid FPU state; this happens only when slice threading is in use or if the user has overridden the execute2 callback (the default one issues emms). Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/x86/vp8dsp.asm | 96 +++++++++++++++++++++--------------- libavcodec/x86/vp8dsp_init.c | 7 +-- tests/checkasm/vp8dsp.c | 2 +- 3 files changed, 60 insertions(+), 45 deletions(-) diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm index 41dea20c36d..26d747f8a50 100644 --- a/libavcodec/x86/vp8dsp.asm +++ b/libavcodec/x86/vp8dsp.asm @@ -149,8 +149,8 @@ filter_h6_shuf3: db 2, 5, 3, 6, 4, 7, 5, 8, 6, 9, 7, 10, 8, 11, 9, 12 filter_h2_shuf: db 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 filter_h2_shuf2: db 0, 1, 1, 2, 2, 3, 3, 4, 8, 9, 9, 10, 10, 11, 11, 12 -pw_20091: times 4 dw 20091 -pw_17734: times 4 dw 17734 +pw_20091: times 8 dw 20091 +pw_17734: times 8 dw 17734 pw_3_3_0_0: times 2 dw 3, 3, 0, 0 cextern pw_4 @@ -990,63 +990,81 @@ cglobal vp8_idct_dc_add4uv, 3, 3, 6, dst, block, stride ; void ff_vp8_idct_add_<opt>(uint8_t *dst, int16_t block[16], ptrdiff_t stride); ;----------------------------------------------------------------------------- -; calculate %1=mul_35468(%1)-mul_20091(%2); %2=mul_20091(%1)+mul_35468(%2) -; this macro assumes that m6/m7 have words for 20091/17734 loaded -%macro VP8_MULTIPLY_SUMSUB 4 - mova %3, %1 - mova %4, %2 - pmulhw %3, m6 ;20091(1) - pmulhw %4, m6 ;20091(2) - paddw %3, %1 - paddw %4, %2 - paddw %1, %1 - paddw %2, %2 - pmulhw %1, m7 ;35468(1) - pmulhw %2, m7 ;35468(2) - psubw %1, %4 - paddw %2, %3 +; calculate %1=mul_20091(low %1)+mul_35468(high %1), %2=mul_35468(low %1)-mul_20091(high %1); +; this macro assumes that m5/m6 have words for 17734/20091 loaded +%macro VP8_MULTIPLY_SUMSUB 3 + pmulhw %3, %1, m6 ; 20091(1, 3) + paddw %3, %1 ; MUL_20091(1, 3) + paddw %1, %1 + pmulhw %1, m5 ; MUL_35468(1, 3) + MOVHL %2, %3 ; MUL_20091(3) + psubw %2, %1 ; MUL_20091(3)-MUL_35468(1)=-t2 + punpckhqdq %1, %1 + paddw %1, %3 ; MUL_35468(3)+MUL_20091(1)=t3 %endmacro ; calculate x0=%1+%3; x1=%1-%3 -; x2=mul_35468(%2)-mul_20091(%4); x3=mul_20091(%2)+mul_35468(%4) +; Inputs 2 and 4 are supposed to be contained in the low and high half of %2 +; x2=mul_35468(2)-mul_20091(4); x3=mul_20091(2)+mul_35468(4) ; %1=x0+x3 (tmp0); %2=x1+x2 (tmp1); %3=x1-x2 (tmp2); %4=x0-x3 (tmp3) -; %5/%6 are temporary registers -; we assume m6/m7 have constant words 20091/17734 loaded in them -%macro VP8_IDCT_TRANSFORM4x4_1D 6 +; %5 is a clobber reg +; we assume m5/m6 have constant words 17734/20091 loaded in them +%macro VP8_IDCT_TRANSFORM4x4_1D 5 SUMSUB_BA w, %3, %1, %5 ;t0, t1 - VP8_MULTIPLY_SUMSUB m%2, m%4, m%5,m%6 ;t2, t3 - SUMSUB_BA w, %4, %3, %5 ;tmp0, tmp3 - SUMSUB_BA w, %2, %1, %5 ;tmp1, tmp2 - SWAP %4, %1 + VP8_MULTIPLY_SUMSUB m%2, m%4, m%5 ;t3, -t2 + + SUMSUB_BA w, %2, %3, %5 ;tmp0=t0+t3, tmp3=t0-t3 + SUMSUB_BA w, %4, %1, %5 ;tmp2=-t2+t1, tmp1=t1+t2 + SWAP %1, %2 ; %1 = tmp0, %2 = tmp1 SWAP %4, %3 %endmacro -INIT_MMX sse -cglobal vp8_idct_add, 3, 3, 0, dst, block, stride +%macro VP8_STORE_DIFFx2 8 ; add, tmp1, tmp2, tmp3, zero, shift, source, stride + movd %3, [%7] + movd %4, [%7+%8] + psraw %1, %6 + MOVHL %2, %1 + punpcklbw %3, %5 + punpcklbw %4, %5 + paddw %3, %1 + paddw %4, %2 + packuswb %3, %5 + packuswb %4, %5 + movd [%7], %3 + movd [%7+%8], %4 +%endmacro + +INIT_XMM sse2 +cglobal vp8_idct_add, 3, 3, 7, dst, block, stride ; load block data movq m0, [blockq+ 0] movq m1, [blockq+ 8] movq m2, [blockq+16] - movq m3, [blockq+24] - movq m6, [pw_20091] - movq m7, [pw_17734] - xorps xmm0, xmm0 - movaps [blockq+ 0], xmm0 - movaps [blockq+16], xmm0 + movhps m1, [blockq+24] + mova m6, [pw_20091] + mova m5, [pw_17734] + xorps m4, m4 + movaps [blockq+ 0], m4 + movaps [blockq+16], m4 ; actual IDCT - VP8_IDCT_TRANSFORM4x4_1D 0, 1, 2, 3, 4, 5 - TRANSPOSE4x4W 0, 1, 2, 3, 4 + VP8_IDCT_TRANSFORM4x4_1D 0, 1, 2, 3, 4 + punpcklwd m0, m1 + punpcklwd m2, m3 + SBUTTERFLY dq, 0, 2, 1 + punpckhqdq m1, m0, m2 paddw m0, [pw_4] - VP8_IDCT_TRANSFORM4x4_1D 0, 1, 2, 3, 4, 5 - TRANSPOSE4x4W 0, 1, 2, 3, 4 + VP8_IDCT_TRANSFORM4x4_1D 0, 1, 2, 3, 4 + punpcklwd m0, m1 + punpcklwd m2, m3 + SBUTTERFLY dq, 0, 2, 1 ; store pxor m4, m4 DEFINE_ARGS dst1, dst2, stride lea dst2q, [dst1q+2*strideq] - STORE_DIFFx2 m0, m1, m6, m7, m4, 3, dst1q, strideq, movd - STORE_DIFFx2 m2, m3, m6, m7, m4, 3, dst2q, strideq, movd + VP8_STORE_DIFFx2 m0, m1, m5, m6, m4, 3, dst1q, strideq + VP8_STORE_DIFFx2 m2, m3, m5, m6, m4, 3, dst2q, strideq RET diff --git a/libavcodec/x86/vp8dsp_init.c b/libavcodec/x86/vp8dsp_init.c index a12e64c5ce5..4b73dc39217 100644 --- a/libavcodec/x86/vp8dsp_init.c +++ b/libavcodec/x86/vp8dsp_init.c @@ -172,7 +172,7 @@ void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, int16_t block[4][16], void ff_vp8_idct_dc_add4uv_sse2(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); void ff_vp8_luma_dc_wht_sse2(int16_t block[4][4][16], int16_t dc[16]); -void ff_vp8_idct_add_sse(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +void ff_vp8_idct_add_sse2(uint8_t *dst, int16_t block[16], ptrdiff_t stride); #define DECLARE_LOOP_FILTER(NAME) \ void ff_vp8_v_loop_filter_simple_ ## NAME(uint8_t *dst, \ @@ -272,10 +272,6 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) { int cpu_flags = av_get_cpu_flags(); - if (EXTERNAL_SSE(cpu_flags)) { - c->vp8_idct_add = ff_vp8_idct_add_sse; - } - if (EXTERNAL_SSE2_SLOW(cpu_flags)) { c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_sse2; @@ -285,6 +281,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_sse2; c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_sse2; + c->vp8_idct_add = ff_vp8_idct_add_sse2; c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_sse2; } diff --git a/tests/checkasm/vp8dsp.c b/tests/checkasm/vp8dsp.c index eeb487c6b1e..43729689a02 100644 --- a/tests/checkasm/vp8dsp.c +++ b/tests/checkasm/vp8dsp.c @@ -120,7 +120,7 @@ static void check_idct(VP8DSPContext *d, bool is_vp7) LOCAL_ALIGNED_16(int16_t, subcoef0, [4 * 4]); LOCAL_ALIGNED_16(int16_t, subcoef1, [4 * 4]); int dc; - declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, int16_t *block, ptrdiff_t stride); + declare_func(void, uint8_t *dst, int16_t *block, ptrdiff_t stride); randomize_buffers(src, dst, 4, coef); -- 2.54.0 >From 942ed6afb2119d9525f6f48635723c3470b2140d Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 6 Nov 2026 00:26:13 +0100 Subject: [PATCH 16/16] avcodec/avcodec: Remove emms_c from avcodec_default_execute() funcs Fixing mmx issues by clearing the FPU state in these callbacks was always a bad design, as it does not fix issues when these callbacks are overridden (either by the user or our slice-threading code). Anyway, we got rid of so many mmx functions that these emms here are obsolete (the remaining codecs still using mmx are guaranteed not to call these functions). Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/avcodec.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 80f2598a921..4b2018d75f8 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -31,7 +31,6 @@ #include "libavutil/bprint.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" -#include "libavutil/emms.h" #include "libavutil/imgutils.h" #include "libavutil/mem.h" #include "libavutil/opt.h" @@ -81,7 +80,6 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v if (ret) ret[i] = r; } - emms_c(); return 0; } @@ -94,7 +92,6 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, if (ret) ret[i] = r; } - emms_c(); return 0; } -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
