Modified deinterlace selection.
authorLaurent Aimar <fenrir@videolan.org>
Mon, 5 Oct 2009 21:26:05 +0000 (23:26 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Mon, 5 Oct 2009 21:34:01 +0000 (23:34 +0200)
At the core and vout, you now have 2 variables:
 - deinterlace: on/off/auto (off is default). It let you say if you
 want to deinterlace or not.
 - deinterlace-mode: discard, blend, ... (blend is default). It let you
 specify the mode used when deinterlacing is equal to on/auto.

 The mode auto is not yet supported and simply default to on.

src/libvlc-module.c
src/video_output/video_output.c

index 2f6b80c..a85b29f 100644 (file)
@@ -451,15 +451,25 @@ static const char *const ppsz_align_descriptions[] =
     "Hide mouse cursor and fullscreen controller after " \
     "n milliseconds, default is 3000 ms (3 sec.)")
 
+#define DEINTERLACE_TEXT N_("Deinterlace")
+#define DEINTERLACE_LONGTEXT N_(\
+    "Deinterlace")
+static const int pi_deinterlace[] = {
+    0, -1, 1
+};
+static const char * const  ppsz_deinterlace_text[] = {
+    "Off", "Automatic", "On"
+};
+
 #define DEINTERLACE_MODE_TEXT N_("Deinterlace mode")
 #define DEINTERLACE_MODE_LONGTEXT N_( \
     "Deinterlace method to use for video processing.")
 static const char * const ppsz_deinterlace_mode[] = {
-    "", "discard", "blend", "mean", "bob",
+    "discard", "blend", "mean", "bob",
     "linear", "x", "yadif", "yadif2x"
 };
 static const char * const ppsz_deinterlace_mode_text[] = {
-    N_("Disable"), N_("Discard"), N_("Blend"), N_("Mean"), N_("Bob"),
+    N_("Discard"), N_("Blend"), N_("Mean"), N_("Bob"),
     N_("Linear"), "X", "Yadif", "Yadif (2x)"
 };
 
@@ -1677,7 +1687,11 @@ vlc_module_begin ()
     add_integer( "align", 0, NULL, ALIGN_TEXT, ALIGN_LONGTEXT, true )
         change_integer_list( pi_align_values, ppsz_align_descriptions, NULL )
     add_float( "zoom", 1, NULL, ZOOM_TEXT, ZOOM_LONGTEXT, true )
-    add_string( "deinterlace-mode", "", NULL,
+    add_integer( "deinterlace", 0, NULL,
+                 DEINTERLACE_TEXT, DEINTERLACE_LONGTEXT, false )
+        change_integer_list( pi_deinterlace, ppsz_deinterlace_text, 0 )
+        change_safe()
+    add_string( "deinterlace-mode", "blend", NULL,
                 DEINTERLACE_MODE_TEXT, DEINTERLACE_MODE_LONGTEXT, false )
         change_string_list( ppsz_deinterlace_mode, ppsz_deinterlace_mode_text, 0 )
         change_safe()
index 31738fb..db7f298 100644 (file)
@@ -1881,75 +1881,94 @@ static void DeinterlaceAdd( vout_thread_t *p_vout, bool b_vout_filter )
     }
 }
 
+static void DeinterlaceSave( vout_thread_t *p_vout, int i_deinterlace, const char *psz_mode )
+{
+    /* We have to set input variable to ensure restart support
+     * XXX it is only needed because of vout-filter but must be done
+     * for non video filter anyway */
+    vlc_object_t *p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT );
+    if( !p_input )
+        return;
+
+    var_Create( p_input, "deinterlace", VLC_VAR_INTEGER );
+    var_SetInteger( p_input, "deinterlace", i_deinterlace );
+
+    static const char * const ppsz_variable[] = {
+        "deinterlace-mode",
+        "filter-deinterlace-mode",
+        "sout-deinterlace-mode",
+        NULL
+    };
+    for( int i = 0; ppsz_variable[i]; i++ )
+    {
+        var_Create( p_input, ppsz_variable[i], VLC_VAR_STRING );
+        var_SetString( p_input, ppsz_variable[i], psz_mode );
+    }
+
+    vlc_object_release( p_input );
+}
 static int DeinterlaceCallback( vlc_object_t *p_this, char const *psz_cmd,
                                 vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
     vout_thread_t *p_vout = (vout_thread_t *)p_this;
 
     /* */
-    const deinterlace_mode_t *p_mode;
-    for( p_mode = &p_deinterlace_mode[0]; p_mode->psz_mode; p_mode++ )
-    {
-        if( !strcmp( p_mode->psz_mode,
-                     newval.psz_string ? newval.psz_string : "" ) )
-            break;
-    }
-    if( !p_mode->psz_mode )
-    {
-        msg_Err( p_this, "Invalid value (%s) ignored", newval.psz_string );
+    const int i_deinterlace = var_GetInteger( p_this, "deinterlace" );
+    char      *psz_mode     = var_GetString( p_this, "deinterlace-mode" );
+    if( !psz_mode )
         return VLC_EGENERIC;
-    }
-
-    /* We have to set input variable to ensure restart support
-     * XXX it is only needed because of vout-filter but must be done
-     * for non video filter anyway */
-    input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_PARENT );
-    if( p_input )
-    {
-        var_Create( p_input, "deinterlace-mode", VLC_VAR_STRING );
-        var_SetString( p_input, "deinterlace-mode", *p_mode->psz_mode ? p_mode->psz_mode : "disable" );
-
-        var_Create( p_input, "filter-deinterlace-mode", VLC_VAR_STRING );
-        var_SetString( p_input, "filter-deinterlace-mode", p_mode->psz_mode );
 
-        var_Create( p_input, "sout-deinterlace-mode", VLC_VAR_STRING );
-        var_SetString( p_input, "sout-deinterlace-mode", p_mode->psz_mode );
+    DeinterlaceSave( p_vout, i_deinterlace, psz_mode );
 
-        vlc_object_release( p_input );
+    /* */
+    bool b_vout_filter = true;
+    for( const deinterlace_mode_t *p_mode = &p_deinterlace_mode[0]; p_mode->psz_mode; p_mode++ )
+    {
+        if( !strcmp( p_mode->psz_mode, psz_mode ) )
+        {
+            b_vout_filter = p_mode->b_vout_filter;
+            break;
+        }
     }
 
+    /* */
     char *psz_old;
-
-    if( p_mode->b_vout_filter )
+    if( b_vout_filter )
     {
         psz_old = var_CreateGetString( p_vout, "filter-deinterlace-mode" );
     }
     else
     {
         psz_old = var_CreateGetString( p_vout, "sout-deinterlace-mode" );
-        var_SetString( p_vout, "sout-deinterlace-mode", p_mode->psz_mode );
+        var_SetString( p_vout, "sout-deinterlace-mode", psz_mode );
     }
 
-    /* */
-    if( !strcmp( p_mode->psz_mode, "" ) )
+    if( i_deinterlace == 0 )
     {
         DeinterlaceRemove( p_vout, false );
         DeinterlaceRemove( p_vout, true );
     }
-    else if( !DeinterlaceIsPresent( p_vout, p_mode->b_vout_filter ) )
-    {
-        DeinterlaceRemove( p_vout, !p_mode->b_vout_filter );
-        DeinterlaceAdd( p_vout, p_mode->b_vout_filter );
-    }
     else
     {
-        DeinterlaceRemove( p_vout, !p_mode->b_vout_filter );
-        if( psz_old && strcmp( psz_old, p_mode->psz_mode ) )
-            var_TriggerCallback( p_vout, p_mode->b_vout_filter ? "vout-filter" : "video-filter" );
+        /* TODO auto mode(-1)
+         * It is assumed equal to "on" for now */
+        if( !DeinterlaceIsPresent( p_vout, b_vout_filter ) )
+        {
+            DeinterlaceRemove( p_vout, !b_vout_filter );
+            DeinterlaceAdd( p_vout, b_vout_filter );
+        }
+        else
+        {
+            /* The deinterlace filter was already inserted but we have changed the mode */
+            DeinterlaceRemove( p_vout, !b_vout_filter );
+            if( psz_old && strcmp( psz_old, psz_mode ) )
+                var_TriggerCallback( p_vout, b_vout_filter ? "vout-filter" : "video-filter" );
+        }
     }
-    free( psz_old );
 
-    (void)psz_cmd; (void) oldval; (void) p_data;
+    /* */
+    free( psz_old );
+    free( psz_mode );
     return VLC_SUCCESS;
 }
 
@@ -1962,39 +1981,58 @@ static void DeinterlaceEnable( vout_thread_t *p_vout )
 
     msg_Dbg( p_vout, "Deinterlacing available" );
 
-    /* Create the configuration variable */
+    /* Create the configuration variables */
+    /* */
+    var_Create( p_vout, "deinterlace", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT | VLC_VAR_HASCHOICE );
+    int i_deinterlace = var_GetInteger( p_vout, "deinterlace" );
+
+    text.psz_string = _("Deinterlace");
+    var_Change( p_vout, "deinterlace", VLC_VAR_SETTEXT, &text, NULL );
+
+    const module_config_t *p_optd = config_FindConfig( VLC_OBJECT(p_vout), "deinterlace" );
+    var_Change( p_vout, "deinterlace", VLC_VAR_CLEARCHOICES, NULL, NULL );
+    for( int i = 0; p_optd && i < p_optd->i_list; i++ )
+    {
+        val.i_int  = p_optd->pi_list[i];
+        text.psz_string = (char*)vlc_gettext(p_optd->ppsz_list_text[i]);
+        var_Change( p_vout, "deinterlace", VLC_VAR_ADDCHOICE, &val, &text );
+    }
+    var_AddCallback( p_vout, "deinterlace", DeinterlaceCallback, NULL );
+    /* */
     var_Create( p_vout, "deinterlace-mode", VLC_VAR_STRING | VLC_VAR_DOINHERIT | VLC_VAR_HASCHOICE );
     char *psz_deinterlace = var_GetNonEmptyString( p_vout, "deinterlace-mode" );
 
     text.psz_string = _("Deinterlace mode");
     var_Change( p_vout, "deinterlace-mode", VLC_VAR_SETTEXT, &text, NULL );
 
-    const module_config_t *p_opt = config_FindConfig( VLC_OBJECT(p_vout), "deinterlace-mode" );
+    const module_config_t *p_optm = config_FindConfig( VLC_OBJECT(p_vout), "deinterlace-mode" );
     var_Change( p_vout, "deinterlace-mode", VLC_VAR_CLEARCHOICES, NULL, NULL );
-    for( int i = 0; p_opt && i < p_opt->i_list; i++ )
+    for( int i = 0; p_optm && i < p_optm->i_list; i++ )
     {
-        val.psz_string  = p_opt->ppsz_list[i];
-        text.psz_string = (char*)vlc_gettext(p_opt->ppsz_list_text[i]);
+        val.psz_string  = p_optm->ppsz_list[i];
+        text.psz_string = (char*)vlc_gettext(p_optm->ppsz_list_text[i]);
         var_Change( p_vout, "deinterlace-mode", VLC_VAR_ADDCHOICE, &val, &text );
     }
     var_AddCallback( p_vout, "deinterlace-mode", DeinterlaceCallback, NULL );
 
-    /* */
-    char *psz_mode = psz_deinterlace;
-    if( psz_mode && !strcmp( psz_mode, "disable" ) )
+    /* Override the initial value from filters if present */
+    char *psz_filter_mode = NULL;
+    if( DeinterlaceIsPresent( p_vout, true ) )
+        psz_filter_mode = var_CreateGetNonEmptyString( p_vout, "filter-deinterlace-mode" );
+    else if( DeinterlaceIsPresent( p_vout, false ) )
+        psz_filter_mode = var_CreateGetNonEmptyString( p_vout, "sout-deinterlace-mode" );
+    if( psz_filter_mode )
     {
-        free( psz_mode );
-        psz_mode = strdup( "" );
+        free( psz_deinterlace );
+        i_deinterlace = 1;
+        psz_deinterlace = psz_filter_mode;
     }
-    if( !psz_mode )
-    {
-        /* Get the initial value from filters if present */
-        if( DeinterlaceIsPresent( p_vout, true ) )
-            psz_mode = var_CreateGetNonEmptyString( p_vout, "filter-deinterlace-mode" );
-        else if( DeinterlaceIsPresent( p_vout, false ) )
-            psz_mode = var_CreateGetNonEmptyString( p_vout, "sout-deinterlace-mode" );
-    }
-    var_SetString( p_vout, "deinterlace-mode", psz_mode ? psz_mode : "" );
-    free( psz_mode );
+
+    /* */
+    val.psz_string = psz_deinterlace ? psz_deinterlace : p_optm->orig.psz;
+    var_Change( p_vout, "deinterlace-mode", VLC_VAR_SETVALUE, &val, NULL );
+
+    var_SetInteger( p_vout, "deinterlace", i_deinterlace );
+    free( psz_deinterlace );
 }