X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_filter%2Fdeinterlace.c;h=5fb23deca6d13ff424ed693fa71e066acf0ebc46;hb=HEAD;hp=11a0c4947882274530a5f773df8b5961d948328d;hpb=4e57bfa7f0ad081f216f4f99b7a3f84d40c493ca;p=vlc diff --git a/modules/video_filter/deinterlace.c b/modules/video_filter/deinterlace.c index 11a0c49478..5fb23deca6 100644 --- a/modules/video_filter/deinterlace.c +++ b/modules/video_filter/deinterlace.c @@ -137,6 +137,8 @@ struct filter_sys_t void (*pf_merge) ( void *, const void *, const void *, size_t ); void (*pf_end_merge) ( void ); + mtime_t i_last_date; + /* Yadif */ picture_t *pp_history[HISTORY_SIZE]; }; @@ -1521,6 +1523,7 @@ static int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src, } else if( !p_prev && !p_cur && p_next ) { + /* FIXME not good as it does not use i_order/i_field */ RenderX( p_dst, p_next ); return VLC_SUCCESS; } @@ -1536,81 +1539,99 @@ static int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src, static picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic ) { filter_sys_t *p_sys = p_filter->p_sys; - picture_t *p_pic_dst; + picture_t *p_dst[2]; /* Request output picture */ - p_pic_dst = filter_NewPicture( p_filter ); - if( p_pic_dst == NULL ) + p_dst[0] = filter_NewPicture( p_filter ); + if( p_dst[0] == NULL ) { picture_Release( p_pic ); return NULL; } + picture_CopyProperties( p_dst[0], p_pic ); - picture_CopyProperties( p_pic_dst, p_pic ); + if( p_sys->b_double_rate ) + { + p_dst[0]->p_next = + p_dst[1] = filter_NewPicture( p_filter ); + if( p_dst[1] ) + { + picture_CopyProperties( p_dst[1], p_pic ); + /* XXX it's not really good especially for the first picture, but + * I don't think that delaying by one frame is worth it */ + if( p_sys->i_last_date > VLC_TS_INVALID && p_pic->date > VLC_TS_INVALID ) + p_dst[1]->date = p_pic->date + (p_pic->date - p_sys->i_last_date) / 2; + } + p_sys->i_last_date = p_pic->date; + } + else + { + p_dst[1] = NULL; + } switch( p_sys->i_mode ) { case DEINTERLACE_DISCARD: - RenderDiscard( p_filter, p_pic_dst, p_pic, 0 ); + RenderDiscard( p_filter, p_dst[0], p_pic, 0 ); break; case DEINTERLACE_BOB: -#if 0 - RenderBob( p_filter, pp_outpic[0], p_pic, !p_pic->b_top_field_first ); - RenderBob( p_filter, pp_outpic[1], p_pic, p_pic->b_top_field_first ); - break; -#endif + RenderBob( p_filter, p_dst[0], p_pic, !p_pic->b_top_field_first ); + if( p_dst[1] ) + RenderBob( p_filter, p_dst[1], p_pic, p_pic->b_top_field_first ); + break;; case DEINTERLACE_LINEAR: -#if 0 - RenderLinear( p_filter, pp_outpic[0], p_pic, !p_pic->b_top_field_first ); - RenderLinear( p_filter, pp_outpic[1], p_pic, p_pic->b_top_field_first ); -#endif - msg_Err( p_filter, "doubling the frame rate is not supported yet" ); - picture_Release( p_pic_dst ); - picture_Release( p_pic ); - return NULL; + RenderLinear( p_filter, p_dst[0], p_pic, !p_pic->b_top_field_first ); + if( p_dst[1] ) + RenderLinear( p_filter, p_dst[1], p_pic, p_pic->b_top_field_first ); + break; case DEINTERLACE_MEAN: - RenderMean( p_filter, p_pic_dst, p_pic ); + RenderMean( p_filter, p_dst[0], p_pic ); break; case DEINTERLACE_BLEND: - RenderBlend( p_filter, p_pic_dst, p_pic ); + RenderBlend( p_filter, p_dst[0], p_pic ); break; case DEINTERLACE_X: - RenderX( p_pic_dst, p_pic ); + RenderX( p_dst[0], p_pic ); break; case DEINTERLACE_YADIF: - if( RenderYadif( p_filter, p_pic_dst, p_pic, 0, 0 ) ) - { - picture_Release( p_pic_dst ); - picture_Release( p_pic ); - return NULL; - } + if( RenderYadif( p_filter, p_dst[0], p_pic, 0, 0 ) ) + goto drop; break; case DEINTERLACE_YADIF2X: - msg_Err( p_filter, "doubling the frame rate is not supported yet" ); - //RenderYadif( p_vout, pp_outpic[0], p_pic, 0, !p_pic->b_top_field_first ); - //RenderYadif( p_vout, pp_outpic[1], p_pic, 1, p_pic->b_top_field_first ); - picture_Release( p_pic_dst ); - picture_Release( p_pic ); - return NULL; + if( RenderYadif( p_filter, p_dst[0], p_pic, 0, !p_pic->b_top_field_first ) ) + goto drop; + if( p_dst[1] ) + RenderYadif( p_filter, p_dst[1], p_pic, 1, p_pic->b_top_field_first ); + break; } - p_pic_dst->b_progressive = true; + p_dst[0]->b_progressive = true; + if( p_dst[1] ) + p_dst[1]->b_progressive = true; + + picture_Release( p_pic ); + return p_dst[0]; +drop: + picture_Release( p_dst[0] ); + if( p_dst[1] ) + picture_Release( p_dst[1] ); picture_Release( p_pic ); - return p_pic_dst; + return NULL; } static void Flush( filter_t *p_filter ) { filter_sys_t *p_sys = p_filter->p_sys; + p_sys->i_last_date = VLC_TS_INVALID; for( int i = 0; i < HISTORY_SIZE; i++ ) { if( p_sys->pp_history[i] ) @@ -1622,6 +1643,7 @@ static void Flush( filter_t *p_filter ) static int Mouse( filter_t *p_filter, vlc_mouse_t *p_mouse, const vlc_mouse_t *p_old, const vlc_mouse_t *p_new ) { + VLC_UNUSED(p_old); *p_mouse = *p_new; if( p_filter->p_sys->b_half_height ) p_mouse->i_y *= 2; @@ -1648,6 +1670,7 @@ static int Open( vlc_object_t *p_this ) p_sys->i_mode = DEINTERLACE_BLEND; p_sys->b_double_rate = false; p_sys->b_half_height = true; + p_sys->i_last_date = VLC_TS_INVALID; for( int i = 0; i < HISTORY_SIZE; i++ ) p_sys->pp_history[i] = NULL;