summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2001-09-20 22:58:31 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2001-09-20 22:58:31 +0000
commit3b97563f35cb5af373f42ee3bbc9c244a31cbabe (patch)
treedbb02f4e02f2eb2201e744f7109869d2b180aa55
parent221c4dd014abdc2ae1ba384b4fb790bb3f99f660 (diff)
downloadxine-lib-3b97563f35cb5af373f42ee3bbc9c244a31cbabe.tar.gz
xine-lib-3b97563f35cb5af373f42ee3bbc9c244a31cbabe.tar.bz2
- new deinterlacing method "onefield" (just interpolate)
- warning fixes on other archs CVS patchset: 677 CVS date: 2001/09/20 22:58:31
-rw-r--r--src/video_out/deinterlace.c88
-rw-r--r--src/video_out/deinterlace.h1
2 files changed, 88 insertions, 1 deletions
diff --git a/src/video_out/deinterlace.c b/src/video_out/deinterlace.c
index d82a67800..f9d028805 100644
--- a/src/video_out/deinterlace.c
+++ b/src/video_out/deinterlace.c
@@ -361,8 +361,9 @@ static int deinterlace_weave_yuv_mmx( uint8_t *pdst, uint8_t *psrc[],
// again
emms();
- return 1;
#endif
+
+ return 1;
}
@@ -531,7 +532,86 @@ static int deinterlace_greedy_yuv_mmx( uint8_t *pdst, uint8_t *psrc[],
// clear out the MMX registers ready for doing floating point again
emms();
+#endif
+
return 1;
+}
+
+/* Use one field to interpolate the other (low cpu utilization)
+ Will lose resolution but does not produce weaving effect
+ (good for fast moving scenes)
+*/
+static void deinterlace_onefield_yuv_mmx( uint8_t *pdst, uint8_t *psrc[],
+ int width, int height )
+{
+#ifdef ARCH_X86
+ int Line;
+ uint64_t *YVal1;
+ uint64_t *YVal3;
+ uint64_t *Dest;
+ uint8_t* pEvenLines = psrc[0];
+ uint8_t* pOddLines = psrc[0]+width;
+ int LineLength = width;
+ int SourcePitch = width * 2;
+ int IsOdd = 1;
+
+ int n;
+
+ static uint8_t Mask[] ATTR_ALIGN(8) = {0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe};
+
+ // copy first even line no matter what, and the first odd line if we're
+ // processing an odd field.
+ memcpy(pdst, pEvenLines, LineLength);
+ if (IsOdd)
+ memcpy(pdst + LineLength, pOddLines, LineLength);
+
+ height = height / 2;
+ for (Line = 0; Line < height - 1; ++Line)
+ {
+ if (IsOdd)
+ {
+ YVal1 = (uint64_t *)(pOddLines + Line * SourcePitch);
+ YVal3 = (uint64_t *)(pOddLines + (Line + 1) * SourcePitch);
+ Dest = (uint64_t *)(pdst + (Line * 2 + 2) * LineLength);
+ }
+ else
+ {
+ YVal1 = (uint64_t *)(pEvenLines + Line * SourcePitch);
+ YVal3 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch);
+ Dest = (uint64_t *)(pdst + (Line * 2 + 1) * LineLength);
+ }
+
+ // Copy the odd line to the overlay verbatim.
+ memcpy((char *)Dest + LineLength, YVal3, LineLength);
+
+ n = LineLength >> 3;
+ while( n-- )
+ {
+ movq_m2r (*YVal1++, mm0);
+ movq_m2r (*YVal3++, mm2);
+
+ // get average in mm0
+ pand_m2r ( *Mask, mm0 );
+ pand_m2r ( *Mask, mm2 );
+ psrlw_i2r ( 01, mm0 );
+ psrlw_i2r ( 01, mm2 );
+ paddw_r2r ( mm2, mm0 );
+
+ movq_r2m ( mm0, *Dest++ );
+ }
+ }
+
+ // Copy last odd line if we're processing an even field.
+ if (! IsOdd)
+ {
+ memcpy(pdst + (height * 2 - 1) * LineLength,
+ pOddLines + (height - 1) * SourcePitch,
+ LineLength);
+ }
+
+ // clear out the MMX registers ready for doing floating point
+ // again
+ emms();
#endif
}
@@ -596,5 +676,11 @@ void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[],
else /* FIXME: provide an alternative? */
abort_mmx_missing();
break;
+ case DEINTERLACE_ONEFIELD:
+ if( check_for_mmx() )
+ deinterlace_onefield_yuv_mmx(pdst,psrc,width,height);
+ else /* FIXME: provide an alternative? */
+ abort_mmx_missing();
+ break;
}
}
diff --git a/src/video_out/deinterlace.h b/src/video_out/deinterlace.h
index a1a759648..833401259 100644
--- a/src/video_out/deinterlace.h
+++ b/src/video_out/deinterlace.h
@@ -36,5 +36,6 @@ void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[],
#define DEINTERLACE_BOB 1
#define DEINTERLACE_WEAVE 2
#define DEINTERLACE_GREEDY 3
+#define DEINTERLACE_ONEFIELD 4
#endif