static inline void mmx_end(uint8_t *src3, uint8_t *src5, uint8_t *dst, int X) { punpcklbw_m2r (mm_cpool[0], mm4); punpckhbw_m2r (mm_cpool[0], mm5); psubusw_r2r (mm2, mm0); psubusw_r2r (mm3, mm1); movq_m2r (src5[X], mm2); movq_m2r (src5[X], mm3); punpcklbw_m2r (mm_cpool[0], mm2); punpckhbw_m2r (mm_cpool[0], mm3); psubusw_r2r (mm2, mm0); psubusw_r2r (mm3, mm1); psrlw_i2r (3, mm0); psrlw_i2r (3, mm1); psubw_r2r (mm6, mm4); psubw_r2r (mm7, mm5); packuswb_r2r (mm1,mm0); movq_r2r (mm4, mm6); movq_r2r (mm5, mm7); pcmpgtw_m2r (mm_lthr, mm4); pcmpgtw_m2r (mm_lthr, mm5); pcmpgtw_m2r (mm_hthr, mm6); pcmpgtw_m2r (mm_hthr, mm7); packsswb_r2r (mm5, mm4); packsswb_r2r (mm7, mm6); pxor_r2r (mm6, mm4); movq_r2r (mm4, mm5); pandn_r2r (mm0, mm4); pand_m2r (src3[X], mm5); por_r2r (mm4, mm5); movq_r2m (mm5, dst[X]); }
static void deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4, uint8_t * lum_m3, uint8_t * lum_m2, uint8_t * lum_m1, uint8_t * lum, int size) { mmx_t rounder; rounder.uw[0] = 4; rounder.uw[1] = 4; rounder.uw[2] = 4; rounder.uw[3] = 4; pxor_r2r (mm7, mm7); movq_m2r (rounder, mm6); for (; size > 3; size -= 4) { movd_m2r (*lum_m4, mm0); movd_m2r (*lum_m3, mm1); movd_m2r (*lum_m2, mm2); movd_m2r (*lum_m1, mm3); movd_m2r (*lum, mm4); punpcklbw_r2r (mm7, mm0); punpcklbw_r2r (mm7, mm1); punpcklbw_r2r (mm7, mm2); punpcklbw_r2r (mm7, mm3); punpcklbw_r2r (mm7, mm4); paddw_r2r (mm3, mm1); psllw_i2r (1, mm2); paddw_r2r (mm4, mm0); psllw_i2r (2, mm1); // 2 paddw_r2r (mm6, mm2); paddw_r2r (mm2, mm1); psubusw_r2r (mm0, mm1); psrlw_i2r (3, mm1); // 3 packuswb_r2r (mm7, mm1); movd_r2m (mm1, *dst); lum_m4 += 4; lum_m3 += 4; lum_m2 += 4; lum_m1 += 4; lum += 4; dst += 4; } emms (); /* Handle odd widths */ if (size > 0) deinterlace_line_c (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size); }
static __inline__ int qblock_sad_mmx(uint8_t *refblk, uint32_t h, uint32_t rowstride) { int res; pxor_r2r (mm4,mm4); movq_r2r (mm0,mm5); /* First row */ movd_m2r (*refblk, mm6); pxor_r2r ( mm7, mm7); refblk += rowstride; punpcklbw_r2r ( mm7, mm5); punpcklbw_r2r ( mm7, mm6); movq_r2r ( mm5, mm7); psubusw_r2r ( mm6, mm5); psubusw_r2r ( mm7, mm6); paddw_r2r ( mm5, mm4); paddw_r2r ( mm6, mm4 ); movq_r2r (mm1,mm5); /* Second row */ movd_m2r (*refblk, mm6); pxor_r2r ( mm7, mm7); refblk += rowstride; punpcklbw_r2r ( mm7, mm5); punpcklbw_r2r ( mm7, mm6); movq_r2r ( mm5, mm7); psubusw_r2r ( mm6, mm5); psubusw_r2r ( mm7, mm6); paddw_r2r ( mm5, mm4); paddw_r2r ( mm6, mm4 ); if( h == 4 ) { movq_r2r (mm2,mm5); /* Third row */ movd_m2r (*refblk, mm6); pxor_r2r ( mm7, mm7); refblk += rowstride; punpcklbw_r2r ( mm7, mm5); punpcklbw_r2r ( mm7, mm6); movq_r2r ( mm5, mm7); psubusw_r2r ( mm6, mm5); psubusw_r2r ( mm7, mm6); paddw_r2r ( mm5, mm4); paddw_r2r ( mm6, mm4 ); movq_r2r (mm3,mm5); /* Fourth row */ movd_m2r (*refblk, mm6); pxor_r2r ( mm7, mm7); punpcklbw_r2r ( mm7, mm5); punpcklbw_r2r ( mm7, mm6); movq_r2r ( mm5, mm7); psubusw_r2r ( mm6, mm5); psubusw_r2r ( mm7, mm6); paddw_r2r ( mm5, mm4); paddw_r2r ( mm6, mm4 ); } movq_r2r ( mm4, mm5 ); psrlq_i2r ( 32, mm5 ); paddw_r2r ( mm5, mm4 ); movq_r2r ( mm4, mm6 ); psrlq_i2r ( 16, mm6 ); paddw_r2r ( mm6, mm4 ); movd_r2m ( mm4, res ); return res & 0xffff; }
static void deinterlace_line( uint8_t *dst, uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, int size ) { #if defined(__i386__) || defined(__x86_64__) mmx_t rounder; rounder.uw[0]=4; rounder.uw[1]=4; rounder.uw[2]=4; rounder.uw[3]=4; pxor_r2r(mm7,mm7); movq_m2r(rounder,mm6); for (;size > 3; size-=4) { movd_m2r(lum_m4[0],mm0); movd_m2r(lum_m3[0],mm1); movd_m2r(lum_m2[0],mm2); movd_m2r(lum_m1[0],mm3); movd_m2r(lum[0],mm4); punpcklbw_r2r(mm7,mm0); punpcklbw_r2r(mm7,mm1); punpcklbw_r2r(mm7,mm2); punpcklbw_r2r(mm7,mm3); punpcklbw_r2r(mm7,mm4); paddw_r2r(mm3,mm1); psllw_i2r(1,mm2); paddw_r2r(mm4,mm0); psllw_i2r(2,mm1);// 2 paddw_r2r(mm6,mm2); paddw_r2r(mm2,mm1); psubusw_r2r(mm0,mm1); psrlw_i2r(3,mm1); // 3 packuswb_r2r(mm7,mm1); movd_r2m(mm1,dst[0]); lum_m4+=4; lum_m3+=4; lum_m2+=4; lum_m1+=4; lum+=4; dst+=4; } emms(); #else /** * C implementation. */ int sum; for(;size > 0;size--) { sum = -lum_m4[0]; sum += lum_m3[0] << 2; sum += lum_m2[0] << 1; sum += lum_m1[0] << 2; sum += -lum[0]; dst[0] = (sum + 4) >> 3; // This needs to be clipped at 0 and 255: cm[(sum + 4) >> 3]; lum_m4++; lum_m3++; lum_m2++; lum_m1++; lum++; dst++; } #endif }