summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/post/deinterlace/speedy.c69
-rw-r--r--src/post/deinterlace/speedy.h2
-rw-r--r--src/post/deinterlace/xine_plugin.c37
3 files changed, 107 insertions, 1 deletions
diff --git a/src/post/deinterlace/speedy.c b/src/post/deinterlace/speedy.c
index 3a94cec55..c782f873f 100644
--- a/src/post/deinterlace/speedy.c
+++ b/src/post/deinterlace/speedy.c
@@ -70,6 +70,8 @@ void (*filter_luma_14641_packed422_inplace_scanline)( uint8_t *data, int width )
unsigned int (*diff_factor_packed422_scanline)( uint8_t *cur, uint8_t *old, int width );
unsigned int (*comb_factor_packed422_scanline)( uint8_t *top, uint8_t *mid,
uint8_t *bot, int width );
+void (*linearblend_chroma_packed422_scanline)( uint8_t *output, int width,
+ uint8_t *m, uint8_t *t, uint8_t *b);
void (*kill_chroma_packed422_inplace_scanline)( uint8_t *data, int width );
void (*mirror_packed422_inplace_scanline)( uint8_t *data, int width );
void (*halfmirror_packed422_inplace_scanline)( uint8_t *data, int width );
@@ -521,6 +523,70 @@ void packed422_to_packed444_rec601_scanline( uint8_t *dest, uint8_t *src, int wi
}
}
+static void linearblend_chroma_packed422_scanline_mmx( uint8_t *output, int width,
+ uint8_t *m, uint8_t *t, uint8_t *b)
+{
+#ifdef ARCH_X86
+ int i;
+ const mmx_t ymask = { 0x00ff00ff00ff00ffULL };
+ const mmx_t cmask = { 0xff00ff00ff00ff00ULL };
+
+ // Get width in bytes.
+ width *= 2;
+ i = width / 8;
+ width -= i * 8;
+
+ movq_m2r( ymask, mm7 );
+ movq_m2r( cmask, mm6 );
+
+ while( i-- ) {
+ movq_m2r( *t, mm0 );
+ movq_m2r( *b, mm1 );
+ movq_m2r( *m, mm2 );
+
+ movq_r2r ( mm2, mm3 );
+ pand_r2r ( mm7, mm3 );
+
+ pand_r2r ( mm6, mm0 );
+ pand_r2r ( mm6, mm1 );
+ pand_r2r ( mm6, mm2 );
+
+ psrlq_i2r( 8, mm0 );
+ psrlq_i2r( 8, mm1 );
+ psrlq_i2r( 7, mm2 );
+
+ paddw_r2r( mm0, mm2 );
+ paddw_r2r( mm1, mm2 );
+
+ psllw_i2r( 6, mm2 );
+ pand_r2r( mm6, mm2 );
+
+ por_r2r ( mm3, mm2 );
+
+ movq_r2m( mm2, *output );
+ output += 8;
+ t += 8;
+ b += 8;
+ m += 8;
+ }
+ while( width-- ) {
+ output++; t++; b++; m++;
+ *output++ = (*t++ + *b++ + (*m++ << 1)) >> 2;
+ }
+
+ emms();
+#endif
+}
+
+static void linearblend_chroma_packed422_scanline_c( uint8_t *output, int width,
+ uint8_t *m, uint8_t *t, uint8_t *b)
+{
+ while( width-- ) {
+ output++; t++; b++; m++;
+ *output++ = (*t++ + *b++ + (*m++ << 1)) >> 2;
+ }
+}
+
static void kill_chroma_packed422_inplace_scanline_mmx( uint8_t *data, int width )
{
#ifdef ARCH_X86
@@ -2016,6 +2082,7 @@ void setup_speedy_calls( uint32_t accel, int verbose )
filter_luma_14641_packed422_inplace_scanline = filter_luma_14641_packed422_inplace_scanline_c;
comb_factor_packed422_scanline = 0;
diff_factor_packed422_scanline = diff_factor_packed422_scanline_c;
+ linearblend_chroma_packed422_scanline = linearblend_chroma_packed422_scanline_c;
kill_chroma_packed422_inplace_scanline = kill_chroma_packed422_inplace_scanline_c;
mirror_packed422_inplace_scanline = mirror_packed422_inplace_scanline_c;
halfmirror_packed422_inplace_scanline = halfmirror_packed422_inplace_scanline_c;
@@ -2038,6 +2105,7 @@ void setup_speedy_calls( uint32_t accel, int verbose )
composite_packed4444_alpha_to_packed422_scanline = composite_packed4444_alpha_to_packed422_scanline_mmxext;
composite_alphamask_to_packed4444_scanline = composite_alphamask_to_packed4444_scanline_mmxext;
premultiply_packed4444_scanline = premultiply_packed4444_scanline_mmxext;
+ linearblend_chroma_packed422_scanline = linearblend_chroma_packed422_scanline_mmx;
kill_chroma_packed422_inplace_scanline = kill_chroma_packed422_inplace_scanline_mmx;
blend_packed422_scanline = blend_packed422_scanline_mmxext;
diff_factor_packed422_scanline = diff_factor_packed422_scanline_mmx;
@@ -2055,6 +2123,7 @@ void setup_speedy_calls( uint32_t accel, int verbose )
blit_packed422_scanline = blit_packed422_scanline_mmx;
diff_factor_packed422_scanline = diff_factor_packed422_scanline_mmx;
comb_factor_packed422_scanline = comb_factor_packed422_scanline_mmx;
+ linearblend_chroma_packed422_scanline = linearblend_chroma_packed422_scanline_mmx;
kill_chroma_packed422_inplace_scanline = kill_chroma_packed422_inplace_scanline_mmx;
diff_packed422_block8x8 = diff_packed422_block8x8_mmx;
speedy_memcpy = speedy_memcpy_mmx;
diff --git a/src/post/deinterlace/speedy.h b/src/post/deinterlace/speedy.h
index 734050b40..b84615584 100644
--- a/src/post/deinterlace/speedy.h
+++ b/src/post/deinterlace/speedy.h
@@ -110,6 +110,8 @@ extern void (*filter_luma_14641_packed422_inplace_scanline)( uint8_t *data, int
extern unsigned int (*diff_factor_packed422_scanline)( uint8_t *cur, uint8_t *old, int width );
extern unsigned int (*comb_factor_packed422_scanline)( uint8_t *top, uint8_t *mid,
uint8_t *bot, int width );
+extern void (*linearblend_chroma_packed422_scanline)( uint8_t *output, int width,
+ uint8_t *m, uint8_t *t, uint8_t *b);
extern void (*kill_chroma_packed422_inplace_scanline)( uint8_t *data, int width );
extern void (*mirror_packed422_inplace_scanline)( uint8_t *data, int width );
extern void (*halfmirror_packed422_inplace_scanline)( uint8_t *data, int width );
diff --git a/src/post/deinterlace/xine_plugin.c b/src/post/deinterlace/xine_plugin.c
index 76bb1d46e..c27473978 100644
--- a/src/post/deinterlace/xine_plugin.c
+++ b/src/post/deinterlace/xine_plugin.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: xine_plugin.c,v 1.4 2003/06/16 18:28:11 miguelfreitas Exp $
+ * $Id: xine_plugin.c,v 1.5 2003/06/17 17:14:13 miguelfreitas Exp $
*
* advanced video deinterlacer plugin
* Jun/2003 by Miguel Freitas
@@ -67,6 +67,7 @@ typedef struct deinterlace_parameters_s {
int framerate_mode;
int judder_correction;
int use_progressive_frame_flag;
+ int chroma_filter;
} deinterlace_parameters_t;
@@ -86,6 +87,8 @@ PARAM_ITEM( POST_PARAM_TYPE_BOOL, judder_correction, NULL, 0, 1, 0,
"make frames evenly spaced for film mode (24 fps)" )
PARAM_ITEM( POST_PARAM_TYPE_BOOL, use_progressive_frame_flag, NULL, 0, 1, 0,
"disable deinterlacing when progressive_frame flag is set" )
+PARAM_ITEM( POST_PARAM_TYPE_BOOL, chroma_filter, NULL, 0, 1, 0,
+ "apply chroma filter after deinterlacing" )
END_PARAM_DESCR( param_descr )
@@ -107,6 +110,7 @@ struct post_plugin_deinterlace_s {
int framerate_mode;
int judder_correction;
int use_progressive_frame_flag;
+ int chroma_filter;
tvtime_t *tvtime;
int framecounter;
@@ -148,6 +152,7 @@ static int set_parameters (xine_post_t *this_gen, void *param_gen) {
this->framerate_mode = param->framerate_mode;
this->judder_correction = param->judder_correction;
this->use_progressive_frame_flag = param->use_progressive_frame_flag;
+ this->chroma_filter = param->chroma_filter;
this->tvtime->pulldown_alg = this->pulldown;
this->tvtime->curmethod = get_deinterlace_method( this->cur_method-1 );
@@ -167,6 +172,7 @@ int get_parameters (xine_post_t *this_gen, void *param_gen) {
param->framerate_mode = this->framerate_mode;
param->judder_correction = this->judder_correction;
param->use_progressive_frame_flag = this->use_progressive_frame_flag;
+ param->chroma_filter = this->chroma_filter;
return 1;
}
@@ -292,6 +298,7 @@ static post_plugin_t *deinterlace_open_plugin(post_class_t *class_gen, int input
this->framerate_mode = 0;
this->judder_correction = 1;
this->use_progressive_frame_flag = 1;
+ this->chroma_filter = 1;
this->framecounter = 0;
memset( &this->recent_frame, 0, sizeof(this->recent_frame) );
@@ -499,6 +506,22 @@ static void deinterlace_close(xine_video_port_t *port_gen, xine_stream_t *stream
}
+static void apply_chroma_filter( uint8_t *data, int stride, int width, int height )
+{
+ int i;
+
+ /* ok, using linearblend inplace is a bit weird: the result of a scanline
+ * interpolation will affect the next scanline. this might not be a problem
+ * at all, we just want a kind of filter here.
+ */
+ for( i = 0; i < height; i++, data += stride ) {
+ linearblend_chroma_packed422_scanline( data, width,
+ data,
+ (i) ? (data - stride) : data,
+ (i < height-1) ? (data + stride) : data );
+ }
+}
+
static int deinterlace_draw(vo_frame_t *frame, xine_stream_t *stream)
{
post_video_port_t *port = (post_video_port_t *)frame->port;
@@ -639,6 +662,9 @@ static int deinterlace_draw(vo_frame_t *frame, xine_stream_t *stream)
} else
deinterlaced_frame->pts = 0;
deinterlaced_frame->duration = FPS_24_DURATION;
+ if( this->chroma_filter )
+ apply_chroma_filter( deinterlaced_frame->base[0], deinterlaced_frame->pitches[0],
+ frame->width, frame->height );
skip = deinterlaced_frame->draw(deinterlaced_frame, stream);
} else {
skip = 0;
@@ -647,6 +673,9 @@ static int deinterlace_draw(vo_frame_t *frame, xine_stream_t *stream)
deinterlaced_frame->pts = frame->pts;
deinterlaced_frame->duration = (this->framerate_mode == FRAMERATE_FULL)?
frame->duration/2:frame->duration;
+ if( this->chroma_filter && !deinterlaced_frame->bad_frame )
+ apply_chroma_filter( deinterlaced_frame->base[0], deinterlaced_frame->pitches[0],
+ frame->width, frame->height );
skip = deinterlaced_frame->draw(deinterlaced_frame, stream);
}
@@ -704,6 +733,9 @@ static int deinterlace_draw(vo_frame_t *frame, xine_stream_t *stream)
} else
deinterlaced_frame->pts = 0;
deinterlaced_frame->duration = FPS_24_DURATION;
+ if( this->chroma_filter )
+ apply_chroma_filter( deinterlaced_frame->base[0], deinterlaced_frame->pitches[0],
+ frame->width, frame->height );
skip = deinterlaced_frame->draw(deinterlaced_frame, stream);
} else {
skip = 0;
@@ -711,6 +743,9 @@ static int deinterlace_draw(vo_frame_t *frame, xine_stream_t *stream)
} else {
deinterlaced_frame->pts = 0;
deinterlaced_frame->duration = frame->duration/2;
+ if( this->chroma_filter && !deinterlaced_frame->bad_frame )
+ apply_chroma_filter( deinterlaced_frame->base[0], deinterlaced_frame->pitches[0],
+ frame->width, frame->height );
skip = deinterlaced_frame->draw(deinterlaced_frame, stream);
}