diff options
Diffstat (limited to 'src/post/deinterlace/plugins/linearblend.c')
-rw-r--r-- | src/post/deinterlace/plugins/linearblend.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/post/deinterlace/plugins/linearblend.c b/src/post/deinterlace/plugins/linearblend.c new file mode 100644 index 000000000..1da84c24b --- /dev/null +++ b/src/post/deinterlace/plugins/linearblend.c @@ -0,0 +1,180 @@ +/** + * Linear blend deinterlacing plugin. The algorithm for this filter is based + * on the mythtv sources, which took it from the mplayer sources. + * + * The file is postprocess_template.c in mplayer, and is + * + * Copyright (C) 2001-2002 Michael Niedermayer (michaelni@gmx.at) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdio.h> +#include <stdint.h> + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "attributes.h" +#include "xineutils.h" +#include "speedtools.h" +#include "speedy.h" +#include "deinterlace.h" + +static void deinterlace_scanline_linear_blend( uint8_t *output, + deinterlace_scanline_data_t *data, + int width ) +{ +#ifdef ARCH_X86 + uint8_t *t0 = data->t0; + uint8_t *b0 = data->b0; + uint8_t *m1 = data->m1; + int i; + + // Get width in bytes. + width *= 2; + i = width / 8; + width -= i * 8; + + pxor_r2r( mm7, mm7 ); + while( i-- ) { + movd_m2r( *t0, mm0 ); + movd_m2r( *b0, mm1 ); + movd_m2r( *m1, mm2 ); + + movd_m2r( *(t0+4), mm3 ); + movd_m2r( *(b0+4), mm4 ); + movd_m2r( *(m1+4), mm5 ); + + punpcklbw_r2r( mm7, mm0 ); + punpcklbw_r2r( mm7, mm1 ); + punpcklbw_r2r( mm7, mm2 ); + + punpcklbw_r2r( mm7, mm3 ); + punpcklbw_r2r( mm7, mm4 ); + punpcklbw_r2r( mm7, mm5 ); + + psllw_i2r( 1, mm2 ); + psllw_i2r( 1, mm5 ); + paddw_r2r( mm0, mm2 ); + paddw_r2r( mm3, mm5 ); + paddw_r2r( mm1, mm2 ); + paddw_r2r( mm4, mm5 ); + psrlw_i2r( 2, mm2 ); + psrlw_i2r( 2, mm5 ); + packuswb_r2r( mm2, mm2 ); + packuswb_r2r( mm5, mm5 ); + + movd_r2m( mm2, *output ); + movd_r2m( mm5, *(output+4) ); + output += 8; + t0 += 8; + b0 += 8; + m1 += 8; + } + while( width-- ) { + *output++ = (*t0++ + *b0++ + (2 * *m1++))>>2; + } + sfence(); + emms(); +#endif +} + +static void deinterlace_scanline_linear_blend2( uint8_t *output, + deinterlace_scanline_data_t *data, + int width ) +{ +#ifdef ARCH_X86 + uint8_t *m0 = data->m0; + uint8_t *t1 = data->t1; + uint8_t *b1 = data->b1; + int i; + + // Get width in bytes. + width *= 2; + i = width / 8; + width -= i * 8; + + pxor_r2r( mm7, mm7 ); + while( i-- ) { + movd_m2r( *t1, mm0 ); + movd_m2r( *b1, mm1 ); + movd_m2r( *m0, mm2 ); + + movd_m2r( *(t1+4), mm3 ); + movd_m2r( *(b1+4), mm4 ); + movd_m2r( *(m0+4), mm5 ); + + punpcklbw_r2r( mm7, mm0 ); + punpcklbw_r2r( mm7, mm1 ); + punpcklbw_r2r( mm7, mm2 ); + + punpcklbw_r2r( mm7, mm3 ); + punpcklbw_r2r( mm7, mm4 ); + punpcklbw_r2r( mm7, mm5 ); + + psllw_i2r( 1, mm2 ); + psllw_i2r( 1, mm5 ); + paddw_r2r( mm0, mm2 ); + paddw_r2r( mm3, mm5 ); + paddw_r2r( mm1, mm2 ); + paddw_r2r( mm4, mm5 ); + psrlw_i2r( 2, mm2 ); + psrlw_i2r( 2, mm5 ); + packuswb_r2r( mm2, mm2 ); + packuswb_r2r( mm5, mm5 ); + + movd_r2m( mm2, *output ); + movd_r2m( mm5, *(output+4) ); + output += 8; + t1 += 8; + b1 += 8; + m0 += 8; + } + while( width-- ) { + *output++ = (*t1++ + *b1++ + (2 * *m0++))>>2; + } + sfence(); + emms(); +#endif +} + + +static deinterlace_method_t linearblendmethod = +{ + DEINTERLACE_PLUGIN_API_VERSION, + "mplayer: Linear Blend", + "LinearBlend", + 2, + MM_ACCEL_X86_MMX, + 0, + 0, + 0, + 1, + deinterlace_scanline_linear_blend, + deinterlace_scanline_linear_blend2, + 0 +}; + +#ifdef BUILD_TVTIME_PLUGINS +void deinterlace_plugin_init( void ) +#else +void linearblend_plugin_init( void ) +#endif +{ + register_deinterlace_method( &linearblendmethod ); +} + |