mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-03-04 03:28:05 +00:00
x86/me_cmp: port mmxext vsad functions to yasm
Also add mmxext versions of vsad8 and vsad_intra8, and sse2 versions of vsad16 and vsad_intra16. Since vsad8 and vsad16 are not bitexact, they are accordingly marked as approximate. Reviewed-by: Michael Niedermayer <michaelni@gmx.at> Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
parent
5c073bbb57
commit
33c752be51
@ -26,6 +26,7 @@
|
|||||||
SECTION_RODATA
|
SECTION_RODATA
|
||||||
|
|
||||||
cextern pb_1
|
cextern pb_1
|
||||||
|
cextern pb_80
|
||||||
|
|
||||||
SECTION .text
|
SECTION .text
|
||||||
|
|
||||||
@ -772,3 +773,163 @@ SAD_APPROX_XY2 8
|
|||||||
SAD_APPROX_XY2 16
|
SAD_APPROX_XY2 16
|
||||||
INIT_XMM sse2
|
INIT_XMM sse2
|
||||||
SAD_APPROX_XY2 16
|
SAD_APPROX_XY2 16
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------
|
||||||
|
;int ff_vsad_intra(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
|
; int line_size, int h);
|
||||||
|
;--------------------------------------------------------------------
|
||||||
|
; %1 = 8/16
|
||||||
|
%macro VSAD_INTRA 1
|
||||||
|
cglobal vsad_intra%1, 5, 5, 3, v, pix1, pix2, lsize, h
|
||||||
|
mova m0, [pix1q]
|
||||||
|
%if %1 == mmsize
|
||||||
|
mova m2, [pix1q+lsizeq]
|
||||||
|
psadbw m0, m2
|
||||||
|
%else
|
||||||
|
mova m2, [pix1q+lsizeq]
|
||||||
|
mova m3, [pix1q+8]
|
||||||
|
mova m4, [pix1q+lsizeq+8]
|
||||||
|
psadbw m0, m2
|
||||||
|
psadbw m3, m4
|
||||||
|
paddw m0, m3
|
||||||
|
%endif
|
||||||
|
sub hd, 2
|
||||||
|
|
||||||
|
.loop
|
||||||
|
lea pix1q, [pix1q + 2*lsizeq]
|
||||||
|
%if %1 == mmsize
|
||||||
|
mova m1, [pix1q]
|
||||||
|
psadbw m2, m1
|
||||||
|
paddw m0, m2
|
||||||
|
mova m2, [pix1q+lsizeq]
|
||||||
|
psadbw m1, m2
|
||||||
|
paddw m0, m1
|
||||||
|
%else
|
||||||
|
mova m1, [pix1q]
|
||||||
|
mova m3, [pix1q+8]
|
||||||
|
psadbw m2, m1
|
||||||
|
psadbw m4, m3
|
||||||
|
paddw m0, m2
|
||||||
|
paddw m0, m4
|
||||||
|
mova m2, [pix1q+lsizeq]
|
||||||
|
mova m4, [pix1q+lsizeq+8]
|
||||||
|
psadbw m1, m2
|
||||||
|
psadbw m3, m4
|
||||||
|
paddw m0, m1
|
||||||
|
paddw m0, m3
|
||||||
|
%endif
|
||||||
|
sub hd, 2
|
||||||
|
jg .loop
|
||||||
|
|
||||||
|
%if mmsize == 16
|
||||||
|
pshufd m1, m0, 0xe
|
||||||
|
paddd m0, m1
|
||||||
|
%endif
|
||||||
|
movd eax, m0
|
||||||
|
RET
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
INIT_MMX mmxext
|
||||||
|
VSAD_INTRA 8
|
||||||
|
VSAD_INTRA 16
|
||||||
|
INIT_XMM sse2
|
||||||
|
VSAD_INTRA 16
|
||||||
|
|
||||||
|
;---------------------------------------------------------------------
|
||||||
|
;int ff_vsad_approx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
|
; int line_size, int h);
|
||||||
|
;---------------------------------------------------------------------
|
||||||
|
; %1 = 8/16
|
||||||
|
%macro VSAD_APPROX 1
|
||||||
|
cglobal vsad%1_approx, 5, 5, 5, v, pix1, pix2, lsize, h
|
||||||
|
mova m1, [pb_80]
|
||||||
|
mova m0, [pix1q]
|
||||||
|
%if %1 == mmsize ; vsad8_mmxext, vsad16_sse2
|
||||||
|
mova m4, [pix1q+lsizeq]
|
||||||
|
%if mmsize == 16
|
||||||
|
movu m3, [pix2q]
|
||||||
|
movu m2, [pix2q+lsizeq]
|
||||||
|
psubb m0, m3
|
||||||
|
psubb m4, m2
|
||||||
|
%else
|
||||||
|
psubb m0, [pix2q]
|
||||||
|
psubb m4, [pix2q+lsizeq]
|
||||||
|
%endif
|
||||||
|
pxor m0, m1
|
||||||
|
pxor m4, m1
|
||||||
|
psadbw m0, m4
|
||||||
|
%else ; vsad16_mmxext
|
||||||
|
mova m3, [pix1q+8]
|
||||||
|
psubb m0, [pix2q]
|
||||||
|
psubb m3, [pix2q+8]
|
||||||
|
pxor m0, m1
|
||||||
|
pxor m3, m1
|
||||||
|
mova m4, [pix1q+lsizeq]
|
||||||
|
mova m5, [pix1q+lsizeq+8]
|
||||||
|
psubb m4, [pix2q+lsizeq]
|
||||||
|
psubb m5, [pix2q+lsizeq+8]
|
||||||
|
pxor m4, m1
|
||||||
|
pxor m5, m1
|
||||||
|
psadbw m0, m4
|
||||||
|
psadbw m3, m5
|
||||||
|
paddw m0, m3
|
||||||
|
%endif
|
||||||
|
sub hd, 2
|
||||||
|
|
||||||
|
.loop
|
||||||
|
lea pix1q, [pix1q + 2*lsizeq]
|
||||||
|
lea pix2q, [pix2q + 2*lsizeq]
|
||||||
|
mova m2, [pix1q]
|
||||||
|
%if %1 == mmsize ; vsad8_mmxext, vsad16_sse2
|
||||||
|
%if mmsize == 16
|
||||||
|
movu m3, [pix2q]
|
||||||
|
psubb m2, m3
|
||||||
|
%else
|
||||||
|
psubb m2, [pix2q]
|
||||||
|
%endif
|
||||||
|
pxor m2, m1
|
||||||
|
psadbw m4, m2
|
||||||
|
paddw m0, m4
|
||||||
|
mova m4, [pix1q+lsizeq]
|
||||||
|
movu m3, [pix2q+lsizeq]
|
||||||
|
psubb m4, m3
|
||||||
|
pxor m4, m1
|
||||||
|
psadbw m2, m4
|
||||||
|
paddw m0, m2
|
||||||
|
%else ; vsad16_mmxext
|
||||||
|
mova m3, [pix1q+8]
|
||||||
|
psubb m2, [pix2q]
|
||||||
|
psubb m3, [pix2q+8]
|
||||||
|
pxor m2, m1
|
||||||
|
pxor m3, m1
|
||||||
|
psadbw m4, m2
|
||||||
|
psadbw m5, m3
|
||||||
|
paddw m0, m4
|
||||||
|
paddw m0, m5
|
||||||
|
mova m4, [pix1q+lsizeq]
|
||||||
|
mova m5, [pix1q+lsizeq+8]
|
||||||
|
psubb m4, [pix2q+lsizeq]
|
||||||
|
psubb m5, [pix2q+lsizeq+8]
|
||||||
|
pxor m4, m1
|
||||||
|
pxor m5, m1
|
||||||
|
psadbw m2, m4
|
||||||
|
psadbw m3, m5
|
||||||
|
paddw m0, m2
|
||||||
|
paddw m0, m3
|
||||||
|
%endif
|
||||||
|
sub hd, 2
|
||||||
|
jg .loop
|
||||||
|
|
||||||
|
%if mmsize == 16
|
||||||
|
pshufd m1, m0, 0xe
|
||||||
|
paddd m0, m1
|
||||||
|
%endif
|
||||||
|
movd eax, m0
|
||||||
|
RET
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
INIT_MMX mmxext
|
||||||
|
VSAD_APPROX 8
|
||||||
|
VSAD_APPROX 16
|
||||||
|
INIT_XMM sse2
|
||||||
|
VSAD_APPROX 16
|
||||||
|
@ -65,6 +65,18 @@ int ff_sad16_approx_xy2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
|||||||
int stride, int h);
|
int stride, int h);
|
||||||
int ff_sad16_approx_xy2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
int ff_sad16_approx_xy2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
int stride, int h);
|
int stride, int h);
|
||||||
|
int ff_vsad_intra8_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
|
int line_size, int h);
|
||||||
|
int ff_vsad_intra16_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
|
int line_size, int h);
|
||||||
|
int ff_vsad_intra16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
|
int line_size, int h);
|
||||||
|
int ff_vsad8_approx_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
|
int line_size, int h);
|
||||||
|
int ff_vsad16_approx_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
|
int line_size, int h);
|
||||||
|
int ff_vsad16_approx_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
|
int line_size, int h);
|
||||||
|
|
||||||
#define hadamard_func(cpu) \
|
#define hadamard_func(cpu) \
|
||||||
int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, uint8_t *src1, \
|
int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, uint8_t *src1, \
|
||||||
@ -177,49 +189,6 @@ static int vsad_intra16_mmx(MpegEncContext *v, uint8_t *pix, uint8_t *dummy,
|
|||||||
}
|
}
|
||||||
#undef SUM
|
#undef SUM
|
||||||
|
|
||||||
static int vsad_intra16_mmxext(MpegEncContext *v, uint8_t *pix, uint8_t *dummy,
|
|
||||||
int line_size, int h)
|
|
||||||
{
|
|
||||||
int tmp;
|
|
||||||
|
|
||||||
av_assert2((((int) pix) & 7) == 0);
|
|
||||||
av_assert2((line_size & 7) == 0);
|
|
||||||
|
|
||||||
#define SUM(in0, in1, out0, out1) \
|
|
||||||
"movq (%0), " #out0 "\n" \
|
|
||||||
"movq 8(%0), " #out1 "\n" \
|
|
||||||
"add %2, %0\n" \
|
|
||||||
"psadbw " #out0 ", " #in0 "\n" \
|
|
||||||
"psadbw " #out1 ", " #in1 "\n" \
|
|
||||||
"paddw " #in1 ", " #in0 "\n" \
|
|
||||||
"paddw " #in0 ", %%mm6\n"
|
|
||||||
|
|
||||||
__asm__ volatile (
|
|
||||||
"movl %3, %%ecx\n"
|
|
||||||
"pxor %%mm6, %%mm6\n"
|
|
||||||
"pxor %%mm7, %%mm7\n"
|
|
||||||
"movq (%0), %%mm0\n"
|
|
||||||
"movq 8(%0), %%mm1\n"
|
|
||||||
"add %2, %0\n"
|
|
||||||
"jmp 2f\n"
|
|
||||||
"1:\n"
|
|
||||||
|
|
||||||
SUM(%%mm4, %%mm5, %%mm0, %%mm1)
|
|
||||||
"2:\n"
|
|
||||||
SUM(%%mm0, %%mm1, %%mm4, %%mm5)
|
|
||||||
|
|
||||||
"subl $2, %%ecx\n"
|
|
||||||
"jnz 1b\n"
|
|
||||||
|
|
||||||
"movd %%mm6, %1\n"
|
|
||||||
: "+r" (pix), "=r" (tmp)
|
|
||||||
: "r" ((x86_reg) line_size), "m" (h)
|
|
||||||
: "%ecx");
|
|
||||||
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
#undef SUM
|
|
||||||
|
|
||||||
static int vsad16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
static int vsad16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
||||||
int line_size, int h)
|
int line_size, int h)
|
||||||
{
|
{
|
||||||
@ -301,68 +270,6 @@ static int vsad16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
|||||||
}
|
}
|
||||||
#undef SUM
|
#undef SUM
|
||||||
|
|
||||||
static int vsad16_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
|
|
||||||
int line_size, int h)
|
|
||||||
{
|
|
||||||
int tmp;
|
|
||||||
|
|
||||||
av_assert2((((int) pix1) & 7) == 0);
|
|
||||||
av_assert2((((int) pix2) & 7) == 0);
|
|
||||||
av_assert2((line_size & 7) == 0);
|
|
||||||
|
|
||||||
#define SUM(in0, in1, out0, out1) \
|
|
||||||
"movq (%0), " #out0 "\n" \
|
|
||||||
"movq (%1), %%mm2\n" \
|
|
||||||
"movq 8(%0), " #out1 "\n" \
|
|
||||||
"movq 8(%1), %%mm3\n" \
|
|
||||||
"add %3, %0\n" \
|
|
||||||
"add %3, %1\n" \
|
|
||||||
"psubb %%mm2, " #out0 "\n" \
|
|
||||||
"psubb %%mm3, " #out1 "\n" \
|
|
||||||
"pxor %%mm7, " #out0 "\n" \
|
|
||||||
"pxor %%mm7, " #out1 "\n" \
|
|
||||||
"psadbw " #out0 ", " #in0 "\n" \
|
|
||||||
"psadbw " #out1 ", " #in1 "\n" \
|
|
||||||
"paddw " #in1 ", " #in0 "\n" \
|
|
||||||
"paddw " #in0 ", %%mm6\n "
|
|
||||||
|
|
||||||
__asm__ volatile (
|
|
||||||
"movl %4, %%ecx\n"
|
|
||||||
"pxor %%mm6, %%mm6\n"
|
|
||||||
"pcmpeqw %%mm7, %%mm7\n"
|
|
||||||
"psllw $15, %%mm7\n"
|
|
||||||
"packsswb %%mm7, %%mm7\n"
|
|
||||||
"movq (%0), %%mm0\n"
|
|
||||||
"movq (%1), %%mm2\n"
|
|
||||||
"movq 8(%0), %%mm1\n"
|
|
||||||
"movq 8(%1), %%mm3\n"
|
|
||||||
"add %3, %0\n"
|
|
||||||
"add %3, %1\n"
|
|
||||||
"psubb %%mm2, %%mm0\n"
|
|
||||||
"psubb %%mm3, %%mm1\n"
|
|
||||||
"pxor %%mm7, %%mm0\n"
|
|
||||||
"pxor %%mm7, %%mm1\n"
|
|
||||||
"jmp 2f\n"
|
|
||||||
"1:\n"
|
|
||||||
|
|
||||||
SUM(%%mm4, %%mm5, %%mm0, %%mm1)
|
|
||||||
"2:\n"
|
|
||||||
SUM(%%mm0, %%mm1, %%mm4, %%mm5)
|
|
||||||
|
|
||||||
"subl $2, %%ecx\n"
|
|
||||||
"jnz 1b\n"
|
|
||||||
|
|
||||||
"movd %%mm6, %2\n"
|
|
||||||
: "+r" (pix1), "+r" (pix2), "=r" (tmp)
|
|
||||||
: "r" ((x86_reg) line_size), "m" (h)
|
|
||||||
: "%ecx");
|
|
||||||
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
#undef SUM
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DECLARE_ASM_CONST(8, uint64_t, round_tab)[3] = {
|
DECLARE_ASM_CONST(8, uint64_t, round_tab)[3] = {
|
||||||
0x0000000000000000ULL,
|
0x0000000000000000ULL,
|
||||||
0x0001000100010001ULL,
|
0x0001000100010001ULL,
|
||||||
@ -667,14 +574,6 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INLINE_MMXEXT(cpu_flags)) {
|
|
||||||
c->vsad[4] = vsad_intra16_mmxext;
|
|
||||||
|
|
||||||
if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
|
|
||||||
c->vsad[0] = vsad16_mmxext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_INLINE_ASM */
|
#endif /* HAVE_INLINE_ASM */
|
||||||
|
|
||||||
if (EXTERNAL_MMX(cpu_flags)) {
|
if (EXTERNAL_MMX(cpu_flags)) {
|
||||||
@ -704,9 +603,15 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx)
|
|||||||
c->pix_abs[1][1] = ff_sad8_x2_mmxext;
|
c->pix_abs[1][1] = ff_sad8_x2_mmxext;
|
||||||
c->pix_abs[1][2] = ff_sad8_y2_mmxext;
|
c->pix_abs[1][2] = ff_sad8_y2_mmxext;
|
||||||
|
|
||||||
|
c->vsad[4] = ff_vsad_intra16_mmxext;
|
||||||
|
c->vsad[5] = ff_vsad_intra8_mmxext;
|
||||||
|
|
||||||
if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
|
if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
|
||||||
c->pix_abs[0][3] = ff_sad16_approx_xy2_mmxext;
|
c->pix_abs[0][3] = ff_sad16_approx_xy2_mmxext;
|
||||||
c->pix_abs[1][3] = ff_sad8_approx_xy2_mmxext;
|
c->pix_abs[1][3] = ff_sad8_approx_xy2_mmxext;
|
||||||
|
|
||||||
|
c->vsad[0] = ff_vsad16_approx_mmxext;
|
||||||
|
c->vsad[1] = ff_vsad8_approx_mmxext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,8 +629,10 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx)
|
|||||||
c->pix_abs[0][1] = ff_sad16_x2_sse2;
|
c->pix_abs[0][1] = ff_sad16_x2_sse2;
|
||||||
c->pix_abs[0][2] = ff_sad16_y2_sse2;
|
c->pix_abs[0][2] = ff_sad16_y2_sse2;
|
||||||
|
|
||||||
|
c->vsad[4] = ff_vsad_intra16_sse2;
|
||||||
if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
|
if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
|
||||||
c->pix_abs[0][3] = ff_sad16_approx_xy2_sse2;
|
c->pix_abs[0][3] = ff_sad16_approx_xy2_sse2;
|
||||||
|
c->vsad[0] = ff_vsad16_approx_sse2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user