avcodec/x86/mpeg4videodsp: Use SSE2 emulated_edge_mc

Possible now that this function is no longer MMX.

Old benchmarks:
gmc_edge_emulation_c:                                  782.3 ( 1.00x)
gmc_edge_emulation_ssse3:                              220.3 ( 3.55x)

New benchmarks:
gmc_edge_emulation_c:                                  770.9 ( 1.00x)
gmc_edge_emulation_ssse3:                              111.0 ( 6.94x)

Reviewed-by: Lynne <dev@lynne.ee>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2026-03-14 23:28:45 +01:00
parent b33d1d1ba2
commit ba793127c4
6 changed files with 51 additions and 28 deletions

View File

@@ -40,9 +40,9 @@ av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
{
ctx->prefetch = just_return;
if (bpc <= 8) {
ctx->emulated_edge_mc = ff_emulated_edge_mc_8;
ctx->emulated_edge_mc = emulated_edge_mc_8;
} else {
ctx->emulated_edge_mc = ff_emulated_edge_mc_16;
ctx->emulated_edge_mc = emulated_edge_mc_16;
}
#if ARCH_AARCH64

View File

@@ -29,14 +29,6 @@
#include <stddef.h>
#include <stdint.h>
#define EMULATED_EDGE(depth) \
void ff_emulated_edge_mc_ ## depth(uint8_t *dst, const uint8_t *src, \
ptrdiff_t dst_stride, ptrdiff_t src_stride, \
int block_w, int block_h,\
int src_x, int src_y, int w, int h);
EMULATED_EDGE(8)
typedef struct VideoDSPContext {
/**
* Copy a rectangular area of samples to a temporary buffer and replicate

View File

@@ -20,15 +20,12 @@
*/
#include "bit_depth_template.c"
#if BIT_DEPTH != 8
// ff_emulated_edge_mc_8 is used by the x86 MpegVideoDSP API.
static
#endif
void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
ptrdiff_t buf_linesize,
ptrdiff_t src_linesize,
int block_w, int block_h,
int src_x, int src_y, int w, int h)
static void FUNC(emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
ptrdiff_t buf_linesize,
ptrdiff_t src_linesize,
int block_w, int block_h,
int src_x, int src_y, int w, int h)
{
int x, y;
int start_y, start_x, end_y, end_x;

View File

@@ -23,7 +23,7 @@
#include "libavutil/x86/asm.h"
#include "libavutil/x86/cpu.h"
#include "libavcodec/mpeg4videodsp.h"
#include "libavcodec/videodsp.h"
#include "videodsp.h"
#if HAVE_SSSE3_INLINE
@@ -83,7 +83,8 @@ static void gmc_ssse3(uint8_t *dst, const uint8_t *src,
const ptrdiff_t dst_stride = stride;
ptrdiff_t src_stride = stride;
if (need_emu) {
ff_emulated_edge_mc_8(edge_buf, src, EDGE_EMU_STRIDE, src_stride, w + 1, h + 1, ix, iy, width, height);
ff_emulated_edge_mc_sse2(edge_buf, src, EDGE_EMU_STRIDE, src_stride,
w + 1, h + 1, ix, iy, width, height);
src = edge_buf;
src_stride = EDGE_EMU_STRIDE;
}

32
libavcodec/x86/videodsp.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_X86_VIDEODSP_H
#define AVCODEC_X86_VIDEODSP_H
#include <stddef.h>
#include <stdint.h>
void ff_emulated_edge_mc_sse2(uint8_t *buf, const uint8_t *src,
ptrdiff_t buf_stride,
ptrdiff_t src_stride,
int block_w, int block_h,
int src_x, int src_y, int w,
int h);
#endif /* AVCODEC_X86_VIDEODSP_H */

View File

@@ -27,6 +27,7 @@
#include "libavutil/x86/asm.h"
#include "libavutil/x86/cpu.h"
#include "libavcodec/videodsp.h"
#include "videodsp.h"
typedef void emu_edge_vfix_func(uint8_t *dst, x86_reg dst_stride,
const uint8_t *src, x86_reg src_stride,
@@ -187,12 +188,12 @@ static av_always_inline void emulated_edge_mc(uint8_t *dst, const uint8_t *src,
}
}
static av_noinline void emulated_edge_mc_sse2(uint8_t *buf, const uint8_t *src,
ptrdiff_t buf_stride,
ptrdiff_t src_stride,
int block_w, int block_h,
int src_x, int src_y, int w,
int h)
void ff_emulated_edge_mc_sse2(uint8_t *buf, const uint8_t *src,
ptrdiff_t buf_stride,
ptrdiff_t src_stride,
int block_w, int block_h,
int src_x, int src_y, int w,
int h)
{
emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h,
src_x, src_y, w, h, vfixtbl_sse2, &ff_emu_edge_vvar_sse,
@@ -223,7 +224,7 @@ av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc)
ctx->prefetch = ff_prefetch_mmxext;
}
if (EXTERNAL_SSE2(cpu_flags) && bpc <= 8) {
ctx->emulated_edge_mc = emulated_edge_mc_sse2;
ctx->emulated_edge_mc = ff_emulated_edge_mc_sse2;
}
#if HAVE_AVX2_EXTERNAL
if (EXTERNAL_AVX2(cpu_flags) && bpc <= 8) {