summaryrefslogtreecommitdiff
path: root/libavcodec/x86
diff options
context:
space:
mode:
authorLoren Merritt <lorenm@u.washington.edu>2009-02-08 17:45:30 +0000
committerLoren Merritt <lorenm@u.washington.edu>2009-02-08 17:45:30 +0000
commit3daa434a40c56deef91c9d545552349d661105e9 (patch)
treea6baca6ac5d30f4f665918fddd0cf3b5e774d5d9 /libavcodec/x86
parent6166516d1f0df6cc8f96e7685e78ef75541b9698 (diff)
ff_add_hfyu_median_prediction_mmx2
overall ffvhuff decoding speedup: 28% on core2, 25% on k8. Originally committed as revision 17059 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/x86')
-rw-r--r--libavcodec/x86/dsputil_mmx.c44
-rw-r--r--libavcodec/x86/dsputil_yasm.asm60
2 files changed, 104 insertions, 0 deletions
diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c
index a457d55ad7..0cab053c4e 100644
--- a/libavcodec/x86/dsputil_mmx.c
+++ b/libavcodec/x86/dsputil_mmx.c
@@ -548,6 +548,41 @@ static void add_bytes_l2_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){
dst[i] = src1[i] + src2[i];
}
+#if HAVE_7REGS
+static void add_hfyu_median_prediction_cmov(uint8_t *dst, uint8_t *top, uint8_t *diff, int w, int *left, int *left_top) {
+ x86_reg w2 = -w;
+ x86_reg x;
+ int l = *left & 0xff;
+ int tl = *left_top & 0xff;
+ int t;
+ __asm__ volatile(
+ "mov %7, %3 \n"
+ "1: \n"
+ "movzx (%3,%4), %2 \n"
+ "mov %2, %k3 \n"
+ "sub %b1, %b3 \n"
+ "add %b0, %b3 \n"
+ "mov %2, %1 \n"
+ "cmp %0, %2 \n"
+ "cmovg %0, %2 \n"
+ "cmovg %1, %0 \n"
+ "cmp %k3, %0 \n"
+ "cmovg %k3, %0 \n"
+ "mov %7, %3 \n"
+ "cmp %2, %0 \n"
+ "cmovl %2, %0 \n"
+ "add (%6,%4), %b0 \n"
+ "mov %b0, (%5,%4) \n"
+ "inc %4 \n"
+ "jl 1b \n"
+ :"+&q"(l), "+&q"(tl), "=&r"(t), "=&q"(x), "+&r"(w2)
+ :"r"(dst+w), "r"(diff+w), "rm"(top+w)
+ );
+ *left = l;
+ *left_top = tl;
+}
+#endif
+
#define H263_LOOP_FILTER \
"pxor %%mm7, %%mm7 \n\t"\
"movq %0, %%mm0 \n\t"\
@@ -2328,6 +2363,7 @@ static void float_to_int16_sse2(int16_t *dst, const float *src, long len){
void ff_float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len);
void ff_float_to_int16_interleave6_3dnow(int16_t *dst, const float **src, int len);
void ff_float_to_int16_interleave6_3dn2(int16_t *dst, const float **src, int len);
+void ff_add_hfyu_median_prediction_mmx2(uint8_t *dst, uint8_t *top, uint8_t *diff, int w, int *left, int *left_top);
void ff_x264_deblock_v_luma_sse2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0);
void ff_x264_deblock_h_luma_sse2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0);
void ff_x264_deblock_v8_luma_intra_mmxext(uint8_t *pix, int stride, int alpha, int beta);
@@ -2760,6 +2796,14 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
c->biweight_h264_pixels_tab[6]= ff_h264_biweight_4x4_mmx2;
c->biweight_h264_pixels_tab[7]= ff_h264_biweight_4x2_mmx2;
+#if HAVE_YASM
+ c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmx2;
+#endif
+#if HAVE_7REGS
+ if( mm_flags&FF_MM_3DNOW )
+ c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov;
+#endif
+
if (CONFIG_CAVS_DECODER)
ff_cavsdsp_init_mmx2(c, avctx);
diff --git a/libavcodec/x86/dsputil_yasm.asm b/libavcodec/x86/dsputil_yasm.asm
index 91165f2fb7..9d5e62e57d 100644
--- a/libavcodec/x86/dsputil_yasm.asm
+++ b/libavcodec/x86/dsputil_yasm.asm
@@ -90,3 +90,63 @@ FLOAT_TO_INT16_INTERLEAVE6 3dnow
FLOAT_TO_INT16_INTERLEAVE6 3dn2
%undef cvtps2pi
+
+
+; void ff_add_hfyu_median_prediction_mmx2(uint8_t *dst, uint8_t *top, uint8_t *diff, int w, int *left, int *left_top)
+cglobal add_hfyu_median_prediction_mmx2, 6,6,0, dst, top, diff, w, left, left_top
+ movq mm0, [topq]
+ movq mm2, mm0
+ movd mm4, [left_topq]
+ psllq mm2, 8
+ movq mm1, mm0
+ por mm4, mm2
+ movd mm3, [leftq]
+ psubb mm0, mm4 ; t-tl
+ add dstq, wq
+ add topq, wq
+ add diffq, wq
+ neg wq
+ jmp .skip
+.loop:
+ movq mm4, [topq+wq]
+ movq mm0, mm4
+ psllq mm4, 8
+ por mm4, mm1
+ movq mm1, mm0 ; t
+ psubb mm0, mm4 ; t-tl
+.skip:
+ movq mm2, [diffq+wq]
+%assign i 0
+%rep 8
+ movq mm4, mm0
+ paddb mm4, mm3 ; t-tl+l
+ movq mm5, mm3
+ pmaxub mm3, mm1
+ pminub mm5, mm1
+ pminub mm3, mm4
+ pmaxub mm3, mm5 ; median
+ paddb mm3, mm2 ; +residual
+%if i==0
+ movq mm7, mm3
+ psllq mm7, 56
+%else
+ movq mm6, mm3
+ psrlq mm7, 8
+ psllq mm6, 56
+ por mm7, mm6
+%endif
+%if i<7
+ psrlq mm0, 8
+ psrlq mm1, 8
+ psrlq mm2, 8
+%endif
+%assign i i+1
+%endrep
+ movq [dstq+wq], mm7
+ add wq, 8
+ jl .loop
+ movzx r2d, byte [dstq-1]
+ mov [leftq], r2d
+ movzx r2d, byte [topq-1]
+ mov [left_topq], r2d
+ RET