diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-02-18 02:05:06 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-02-18 02:05:06 +0000 |
commit | 86fb7993334c17d19567aec084bfc50d1d5579c5 (patch) | |
tree | 6f549e4e2fe033c9773540c074a965b8024707e1 | |
parent | 31c216d7c3195e7975040ceb5445f200db384c84 (diff) | |
download | xine-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.c | 77 | ||||
-rw-r--r-- | src/video_out/deinterlace.h | 3 | ||||
-rw-r--r-- | src/video_out/video_out_xv.c | 23 |
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; |