summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-02-18 02:05:06 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-02-18 02:05:06 +0000
commit86fb7993334c17d19567aec084bfc50d1d5579c5 (patch)
tree6f549e4e2fe033c9773540c074a965b8024707e1
parent31c216d7c3195e7975040ceb5445f200db384c84 (diff)
downloadxine-lib-86fb7993334c17d19567aec084bfc50d1d5579c5.tar.gz
xine-lib-86fb7993334c17d19567aec084bfc50d1d5579c5.tar.bz2
new deinterlacing method (linear blend).
CVS patchset: 1504 CVS date: 2002/02/18 02:05:06
-rw-r--r--src/video_out/deinterlace.c77
-rw-r--r--src/video_out/deinterlace.h3
-rw-r--r--src/video_out/video_out_xv.c23
3 files changed, 91 insertions, 12 deletions
diff --git a/src/video_out/deinterlace.c b/src/video_out/deinterlace.c
index 73fe341ab..cb8773321 100644
--- a/src/video_out/deinterlace.c
+++ b/src/video_out/deinterlace.c
@@ -22,6 +22,12 @@
*
* Currently only available for Xv driver and MMX extensions
*
+ * small todo list:
+ * - implement non-MMX versions for all methods
+ * - support MMX2 instructions
+ * - move some generic code from xv driver to this file
+ * - make it also work for yuy2 frames
+ *
*/
#include <stdio.h>
@@ -541,7 +547,7 @@ static int deinterlace_greedy_yuv_mmx( uint8_t *pdst, uint8_t *psrc[],
/* Use one field to interpolate the other (low cpu utilization)
Will lose resolution but does not produce weaving effect
- (good for fast moving scenes)
+ (good for fast moving scenes) also know as "linear interpolation"
*/
static void deinterlace_onefield_yuv_mmx( uint8_t *pdst, uint8_t *psrc[],
int width, int height )
@@ -621,6 +627,59 @@ static void deinterlace_onefield_yuv_mmx( uint8_t *pdst, uint8_t *psrc[],
#endif
}
+/* Linear Blend filter - does a kind of vertical blurring on the image.
+ (idea borrowed from mplayer's sources)
+*/
+static void deinterlace_linearblend_yuv_mmx( uint8_t *pdst, uint8_t *psrc[],
+ int width, int height )
+{
+#ifdef ARCH_X86
+ int Line;
+ uint64_t *YVal1;
+ uint64_t *YVal2;
+ uint64_t *YVal3;
+ uint64_t *Dest;
+ int LineLength = width;
+
+ 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);
+ YVal2 = (uint64_t *)(psrc[0] + (Line + 1) * LineLength);
+ YVal3 = (uint64_t *)(psrc[0] + (Line + 2) * LineLength);
+ Dest = (uint64_t *)(pdst + Line * LineLength);
+
+ n = LineLength >> 3;
+ while( n-- )
+ {
+ 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 );
+
+ movq_r2m ( mm0, *Dest++ );
+ }
+ }
+
+ /* clear out the MMX registers ready for doing floating point
+ * again
+ */
+ emms();
+#endif
+}
static int check_for_mmx(void)
{
@@ -691,11 +750,27 @@ void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[],
case DEINTERLACE_ONEFIELDXV:
printf("deinterlace: ONEFIELDXV must be handled by the video driver.\n");
break;
+ case DEINTERLACE_LINEARBLEND:
+ if( check_for_mmx() )
+ deinterlace_linearblend_yuv_mmx(pdst,psrc,width,height);
+ else /* FIXME: provide an alternative? */
+ abort_mmx_missing();
+ break;
default:
printf("deinterlace: unknow method %d.\n",method);
break;
}
}
+char *deinterlace_methods[] = {
+ "none",
+ "bob",
+ "weave",
+ "greedy",
+ "onefield",
+ "onefield_xv",
+ "linearblend",
+ NULL
+};
diff --git a/src/video_out/deinterlace.h b/src/video_out/deinterlace.h
index 04153d742..4381701f5 100644
--- a/src/video_out/deinterlace.h
+++ b/src/video_out/deinterlace.h
@@ -38,5 +38,8 @@ void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[],
#define DEINTERLACE_GREEDY 3
#define DEINTERLACE_ONEFIELD 4
#define DEINTERLACE_ONEFIELDXV 5
+#define DEINTERLACE_LINEARBLEND 6
+
+extern char *deinterlace_methods[];
#endif
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index 1b3183f18..22d993f05 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_xv.c,v 1.92 2002/02/16 22:43:24 guenter Exp $
+ * $Id: video_out_xv.c,v 1.93 2002/02/18 02:05:06 miguelfreitas Exp $
*
* video_out_xv.c, X11 video extension interface for xine
*
@@ -839,9 +839,9 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
xv_frame_t *frame = (xv_frame_t *) frame_gen;
-
+ /*
printf ("video_out_xv: xv_display_frame...\n");
-
+ */
if (this->expecting_event) {
frame->vo_frame.displayed (&frame->vo_frame);
@@ -861,15 +861,17 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
xv_calc_format (this, frame->width, frame->height, frame->ratio_code);
}
- if (this->deinterlace_enabled && this->deinterlace_method)
+ /* currently only working for YUV images */
+ if (this->deinterlace_enabled && this->deinterlace_method &&
+ frame->format == IMGFMT_YV12 )
xv_deinterlace_frame (this);
-
+ /*
printf ("video_out_xv: xv_display_frame... lock display...\n");
-
+ */
XLockDisplay (this->display);
-
+ /*
printf ("video_out_xv: xv_display_frame... lock display...locked\n");
-
+ */
if (this->use_shm) {
XvShmPutImage(this->display, this->xv_port,
this->drawable, this->gc, this->cur_frame->image,
@@ -893,8 +895,9 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
XUnlockDisplay (this->display);
}
-
+ /*
printf ("video_out_xv: xv_display_frame... done\n");
+ */
}
static int xv_get_property (vo_driver_t *this_gen, int property) {
@@ -1255,8 +1258,6 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
XColor dummy;
XvImage *myimage;
XShmSegmentInfo myshminfo;
- static char *deinterlace_methods[] = {"none", "bob", "weave", "greedy", "onefield",
- "onefield_xv", NULL};
display = visual->display;