diff options
-rw-r--r-- | src/video_out/deinterlace.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/src/video_out/deinterlace.c b/src/video_out/deinterlace.c index 377baf57e..8fa80a752 100644 --- a/src/video_out/deinterlace.c +++ b/src/video_out/deinterlace.c @@ -643,9 +643,6 @@ static void deinterlace_linearblend_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], int n; - static mmx_t Mask1 = {ub:{0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe}}; - static mmx_t Mask2 = {ub:{0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc}}; - for (Line = 0; Line < height - 2; ++Line) { YVal1 = (uint64_t *)(psrc[0] + Line * LineLength); @@ -656,20 +653,39 @@ static void deinterlace_linearblend_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], n = LineLength >> 3; while( n-- ) { + /* load data from 3 lines */ movq_m2r (*YVal1++, mm0); movq_m2r (*YVal2++, mm1); movq_m2r (*YVal3++, mm2); - - // get (mm0/4 + mm1/2 + mm2/4) average in mm0 - pand_m2r ( Mask2, mm0 ); - pand_m2r ( Mask1, mm1 ); - pand_m2r ( Mask2, mm2 ); - psrlw_i2r ( 02, mm0 ); - psrlw_i2r ( 01, mm1 ); - psrlw_i2r ( 02, mm2 ); - paddw_r2r ( mm1, mm0 ); - paddw_r2r ( mm2, mm0 ); - + + /* expand bytes to words */ + punpckhbw_r2r (mm0, mm3); + punpckhbw_r2r (mm1, mm4); + punpckhbw_r2r (mm2, mm5); + punpcklbw_r2r (mm0, mm0); + punpcklbw_r2r (mm1, mm1); + punpcklbw_r2r (mm2, mm2); + + /* + * deinterlacing: + * deint_line = (line0 + 2*line1 + line2) / 4 + */ + psrlw_i2r (07, mm0); + psrlw_i2r (06, mm1); + psrlw_i2r (07, mm2); + psrlw_i2r (07, mm3); + psrlw_i2r (06, mm4); + psrlw_i2r (07, mm5); + paddw_r2r (mm1, mm0); + paddw_r2r (mm2, mm0); + paddw_r2r (mm4, mm3); + paddw_r2r (mm5, mm3); + psrlw_i2r (03, mm0); + psrlw_i2r (03, mm3); + + /* pack 8 words to 8 bytes in mm0 */ + packuswb_r2r (mm3, mm0); + movq_r2m ( mm0, *Dest++ ); } } |