static const char *const mode_list_text[] = {
N_("Discard"), N_("Blend"), N_("Mean"), N_("Bob"), N_("Linear"), "X" };
-vlc_module_begin();
- set_description( N_("Deinterlacing video filter") );
- set_shortname( N_("Deinterlace" ));
- set_capability( "video filter", 0 );
- set_category( CAT_VIDEO );
- set_subcategory( SUBCAT_VIDEO_VFILTER );
-
- set_section( N_("Display"),NULL);
+vlc_module_begin ()
+ set_description( N_("Deinterlacing video filter") )
+ set_shortname( N_("Deinterlace" ))
+ set_capability( "video filter", 0 )
+ set_category( CAT_VIDEO )
+ set_subcategory( SUBCAT_VIDEO_VFILTER )
+
+ set_section( N_("Display"),NULL)
add_string( "deinterlace-mode", "discard", NULL, MODE_TEXT,
MODE_LONGTEXT, false );
change_string_list( mode_list, mode_list_text, 0 );
- add_shortcut( "deinterlace" );
- set_callbacks( Create, Destroy );
+ add_shortcut( "deinterlace" )
+ set_callbacks( Create, Destroy )
- add_submodule();
- set_capability( "video filter2", 0 );
- set_section( N_("Streaming"),NULL);
+ add_submodule ()
+ set_capability( "video filter2", 0 )
+ set_section( N_("Streaming"),NULL)
add_string( FILTER_CFG_PREFIX "mode", "blend", NULL, SOUT_MODE_TEXT,
SOUT_MODE_LONGTEXT, false );
change_string_list( mode_list, mode_list_text, 0 );
- set_callbacks( OpenFilter, CloseFilter );
-vlc_module_end();
+ set_callbacks( OpenFilter, CloseFilter )
+vlc_module_end ()
static const char *const ppsz_filter_options[] = {
"mode", NULL
{
int i_mode; /* Deinterlace mode */
bool b_double_rate; /* Shall we double the framerate? */
+ bool b_half_height; /* Shall be devide the height by 2 */
mtime_t last_date;
mtime_t next_date;
p_vout->p_sys->i_mode = DEINTERLACE_DISCARD;
p_vout->p_sys->b_double_rate = false;
+ p_vout->p_sys->b_half_height = true;
p_vout->p_sys->last_date = 0;
p_vout->p_sys->p_vout = 0;
vlc_mutex_init( &p_vout->p_sys->filter_lock );
*****************************************************************************/
static void SetFilterMethod( vout_thread_t *p_vout, char *psz_method )
{
- if( !strcmp( psz_method, "discard" ) )
- {
- p_vout->p_sys->i_mode = DEINTERLACE_DISCARD;
- p_vout->p_sys->b_double_rate = false;
- }
- else if( !strcmp( psz_method, "mean" ) )
+ if( !strcmp( psz_method, "mean" ) )
{
p_vout->p_sys->i_mode = DEINTERLACE_MEAN;
p_vout->p_sys->b_double_rate = false;
+ p_vout->p_sys->b_half_height = true;
}
else if( !strcmp( psz_method, "blend" )
|| !strcmp( psz_method, "average" )
{
p_vout->p_sys->i_mode = DEINTERLACE_BLEND;
p_vout->p_sys->b_double_rate = false;
+ p_vout->p_sys->b_half_height = false;
}
else if( !strcmp( psz_method, "bob" )
|| !strcmp( psz_method, "progressive-scan" ) )
{
p_vout->p_sys->i_mode = DEINTERLACE_BOB;
p_vout->p_sys->b_double_rate = true;
+ p_vout->p_sys->b_half_height = false;
}
else if( !strcmp( psz_method, "linear" ) )
{
p_vout->p_sys->i_mode = DEINTERLACE_LINEAR;
p_vout->p_sys->b_double_rate = true;
+ p_vout->p_sys->b_half_height = false;
}
else if( !strcmp( psz_method, "x" ) )
{
p_vout->p_sys->i_mode = DEINTERLACE_X;
p_vout->p_sys->b_double_rate = false;
+ p_vout->p_sys->b_half_height = false;
}
else
{
- msg_Err( p_vout, "no valid deinterlace mode provided, "
- "using \"discard\"" );
+ const bool b_i422 = p_vout->render.i_chroma == VLC_FOURCC('I','4','2','2');
+ if( strcmp( psz_method, "discard" ) )
+ msg_Err( p_vout, "no valid deinterlace mode provided, "
+ "using \"discard\"" );
+
+ p_vout->p_sys->i_mode = DEINTERLACE_DISCARD;
+ p_vout->p_sys->b_double_rate = false;
+ p_vout->p_sys->b_half_height = !b_i422;
}
msg_Dbg( p_vout, "using %s deinterlace method", psz_method );
msg_Dbg( p_vout, "spawning the real video output" );
fmt = p_vout->fmt_out;
+ if( p_vout->p_sys->b_half_height )
+ {
+ fmt.i_height /= 2; fmt.i_visible_height /= 2; fmt.i_y_offset /= 2;
+ fmt.i_sar_den *= 2;
+ }
switch( p_vout->render.i_chroma )
{
case VLC_FOURCC('I','4','2','0'):
case VLC_FOURCC('I','Y','U','V'):
case VLC_FOURCC('Y','V','1','2'):
+ p_real_vout = vout_Create( p_vout, &fmt );
+ break;
+
+ case VLC_FOURCC('I','4','2','2'):
switch( p_vout->p_sys->i_mode )
{
case DEINTERLACE_MEAN:
- case DEINTERLACE_DISCARD:
- fmt.i_height /= 2; fmt.i_visible_height /= 2; fmt.i_y_offset /= 2;
- fmt.i_sar_den *= 2;
- p_real_vout = vout_Create( p_vout, &fmt );
- break;
-
- case DEINTERLACE_BOB:
- case DEINTERLACE_BLEND:
case DEINTERLACE_LINEAR:
case DEINTERLACE_X:
- p_real_vout = vout_Create( p_vout, &fmt );
+ fmt.i_chroma = VLC_FOURCC('I','4','2','2');
+ break;
+ default:
+ fmt.i_chroma = VLC_FOURCC('I','4','2','0');
break;
}
- break;
-
- case VLC_FOURCC('I','4','2','2'):
- fmt.i_chroma = VLC_FOURCC('I','4','2','0');
p_real_vout = vout_Create( p_vout, &fmt );
break;
vout_sys_t *p_sys = p_vout->p_sys;
picture_t *pp_outpic[2];
- p_vout->fmt_out.i_x_offset = p_sys->p_vout->fmt_in.i_x_offset =
- p_vout->fmt_in.i_x_offset;
- p_vout->fmt_out.i_y_offset = p_sys->p_vout->fmt_in.i_y_offset =
- p_vout->fmt_in.i_y_offset;
- p_vout->fmt_out.i_visible_width = p_sys->p_vout->fmt_in.i_visible_width =
- p_vout->fmt_in.i_visible_width;
- p_vout->fmt_out.i_visible_height = p_sys->p_vout->fmt_in.i_visible_height =
- p_vout->fmt_in.i_visible_height;
- if( p_vout->p_sys->i_mode == DEINTERLACE_MEAN ||
- p_vout->p_sys->i_mode == DEINTERLACE_DISCARD )
- {
- p_vout->fmt_out.i_y_offset /= 2; p_sys->p_vout->fmt_in.i_y_offset /= 2;
- p_vout->fmt_out.i_visible_height /= 2;
+ /* FIXME are they needed ? */
+ p_vout->fmt_out.i_x_offset = p_vout->fmt_in.i_x_offset;
+ p_vout->fmt_out.i_y_offset = p_vout->fmt_in.i_y_offset;
+ p_vout->fmt_out.i_visible_width = p_vout->fmt_in.i_visible_width;
+ p_vout->fmt_out.i_visible_height = p_vout->fmt_in.i_visible_height;
+
+ /* FIXME p_sys->p_vout->* should NOT be changed FIXME */
+ p_sys->p_vout->fmt_in.i_x_offset = p_vout->fmt_out.i_x_offset;
+ p_sys->p_vout->fmt_in.i_y_offset = p_vout->fmt_out.i_y_offset;
+ p_sys->p_vout->fmt_in.i_visible_width = p_vout->fmt_out.i_visible_width;
+ p_sys->p_vout->fmt_in.i_visible_height = p_vout->fmt_in.i_visible_height;
+ if( p_vout->p_sys->b_half_height )
+ {
+ p_sys->p_vout->fmt_in.i_y_offset /= 2;
p_sys->p_vout->fmt_in.i_visible_height /= 2;
}
-
+
+ if( p_vout->i_changes & VOUT_ASPECT_CHANGE )
+ {
+ p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;
+
+ p_vout->fmt_out.i_aspect = p_vout->fmt_in.i_aspect;
+ p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;
+ p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;
+
+ video_format_t fmt = p_vout->fmt_out;
+ if( p_vout->p_sys->b_half_height )
+ {
+ fmt.i_height /= 2; fmt.i_visible_height /= 2; fmt.i_y_offset /= 2;
+ fmt.i_sar_den *= 2;
+ }
+
+ p_sys->p_vout = vout_Request( p_vout, p_sys->p_vout, &fmt );
+ }
+ if( !p_sys->p_vout )
+ return;
+
pp_outpic[0] = pp_outpic[1] = NULL;
vlc_mutex_lock( &p_vout->p_sys->filter_lock );
0, 0, 0 ) )
== NULL )
{
- if( !vlc_object_alive (p_vout) || p_vout->b_error )
+ if( !vlc_object_alive( p_vout ) || p_vout->b_error )
{
vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
return;
msleep( VOUT_OUTMEM_SLEEP );
}
- vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[0], p_pic->date );
+ pp_outpic[0]->date = p_pic->date;
/* If we are using double rate, get an additional new picture */
if( p_vout->p_sys->b_double_rate )
0, 0, 0 ) )
== NULL )
{
- if( !vlc_object_alive (p_vout) || p_vout->b_error )
+ if( !vlc_object_alive( p_vout ) || p_vout->b_error )
{
vout_DestroyPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
/* 20ms is a bit arbitrary, but it's only for the first image we get */
if( !p_vout->p_sys->last_date )
- {
- vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[1],
- p_pic->date + 20000 );
- }
+ pp_outpic[1]->date = p_pic->date + 20000;
else
- {
- vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[1],
- (3 * p_pic->date - p_vout->p_sys->last_date) / 2 );
- }
+ pp_outpic[1]->date = (3 * p_pic->date - p_vout->p_sys->last_date) / 2;
p_vout->p_sys->last_date = p_pic->date;
}
vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
vlc_value_t sentval = newval;
- if( !strcmp( psz_var, "mouse-y" ) )
- {
- switch( p_vout->p_sys->i_mode )
- {
- case DEINTERLACE_MEAN:
- case DEINTERLACE_DISCARD:
- sentval.i_int *= 2;
- break;
- }
- }
+ if( !strcmp( psz_var, "mouse-y" ) && p_vout->p_sys->b_half_height )
+ sentval.i_int *= 2;
var_Set( p_vout, psz_var, sentval );
{
VLC_UNUSED(psz_cmd); VLC_UNUSED(p_data); VLC_UNUSED(oldval);
vout_thread_t * p_vout = (vout_thread_t *)p_this;
- int i_old_mode = p_vout->p_sys->i_mode;
msg_Dbg( p_vout, "using %s deinterlace mode", newval.psz_string );
vlc_mutex_lock( &p_vout->p_sys->filter_lock );
+ const bool b_old_half_height = p_vout->p_sys->b_half_height;
SetFilterMethod( p_vout, newval.psz_string );
- switch( p_vout->render.i_chroma )
+ if( !b_old_half_height == !p_vout->p_sys->b_half_height )
{
- case VLC_FOURCC('I','4','2','2'):
vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
return VLC_SUCCESS;
- break;
-
- case VLC_FOURCC('I','4','2','0'):
- case VLC_FOURCC('I','Y','U','V'):
- case VLC_FOURCC('Y','V','1','2'):
- switch( p_vout->p_sys->i_mode )
- {
- case DEINTERLACE_MEAN:
- case DEINTERLACE_DISCARD:
- if( ( i_old_mode == DEINTERLACE_MEAN )
- || ( i_old_mode == DEINTERLACE_DISCARD ) )
- {
- vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
- return VLC_SUCCESS;
- }
- break;
-
- case DEINTERLACE_BOB:
- case DEINTERLACE_BLEND:
- case DEINTERLACE_LINEAR:
- if( ( i_old_mode == DEINTERLACE_BOB )
- || ( i_old_mode == DEINTERLACE_BLEND )
- || ( i_old_mode == DEINTERLACE_LINEAR ) )
- {
- vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
- return VLC_SUCCESS;
- }
- break;
- }
- break;
-
- default:
- break;
}
/* We need to kill the old vout */
var_Get( p_filter, FILTER_CFG_PREFIX "mode", &val );
var_Create( p_filter, "deinterlace-mode", VLC_VAR_STRING );
var_Set( p_filter, "deinterlace-mode", val );
+ free( val.psz_string );
if ( Create( VLC_OBJECT(p_vout) ) != VLC_SUCCESS )
{