]> git.sesse.net Git - vlc/commitdiff
* src/video_output/video_output.c, include/video_output.h: modified vout_Request...
authorGildas Bazin <gbazin@videolan.org>
Tue, 28 Jan 2003 12:30:44 +0000 (12:30 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 28 Jan 2003 12:30:44 +0000 (12:30 +0000)
filter chain. If the filter chain has changed, a new vout will be respawned allowing to switch filters on
the fly. This is still a bit hacky but to do it nicely will require implementing inheritance in object
variables.
* modules/video_filter/deinterlace/deinterlace.c: added a "deinterlace-mode" object variable to allow
switching deinterlace modes on the fly.
* modules/gui/gtk/menu.c: updated the deinterlace menu.
* include/vlc_common.h: compilation fixes for gtk_main and gnome_main.

include/video_output.h
include/vlc_common.h
modules/gui/gtk/menu.c
modules/video_filter/deinterlace/deinterlace.c
src/video_output/video_output.c

index ef4e3cbfd0f641146681e07bce2aa820556a9b51..143e6869175e6c88b0e7af09ec51d430471d8d1e 100644 (file)
@@ -5,7 +5,7 @@
  * thread, and destroy a previously opened video output thread.
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_output.h,v 1.90 2003/01/28 02:03:32 sam Exp $
+ * $Id: video_output.h,v 1.91 2003/01/28 12:30:44 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
@@ -116,6 +116,7 @@ struct vout_thread_t
 
     /* Filter chain */
     char *psz_filter_chain;
+    vlc_bool_t b_filter_change;
 };
 
 #define I_OUTPUTPICTURES p_vout->output.i_pictures
index e9abc95995d3a08ca98cdb2cf32074560a157e86..73be4c05ebc9d1f0dc668be6b1b7f9ce0411e9df 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.50 2003/01/28 03:11:02 sam Exp $
+ * $Id: vlc_common.h,v 1.51 2003/01/28 12:30:44 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -649,7 +649,6 @@ VLC_EXPORT( char *, vlc_dgettext, ( const char *package, const char *msgid ) );
 
 #if defined( ENABLE_NLS ) && \
      (defined(MODULE_NAME_IS_gnome)||defined(MODULE_NAME_IS_gtk) \
-      ||defined(MODULE_NAME_IS_gnome_main)||defined(MODULE_NAME_IS_gtk_main) \
       ||defined(MODULE_NAME_IS_familiar))
     /* Declare nothing: gtk.h will do it for us */
 #elif defined( ENABLE_NLS ) && defined( HAVE_INCLUDED_GETTEXT )
index e9e789215bdf03159a124bfd9ff2ee752f8abe48..c65f1ff9f37c00f023879ba827500115dd38729d 100644 (file)
@@ -2,7 +2,7 @@
  * menu.c : functions to handle menu items.
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
- * $Id: menu.c,v 1.6 2003/01/23 15:52:04 sam Exp $
+ * $Id: menu.c,v 1.7 2003/01/28 12:30:44 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Stéphane Borel <stef@via.ecp.fr>
@@ -364,8 +364,6 @@ static void GtkDeinterlaceUpdate( intf_thread_t *p_intf, char *psz_mode )
             }
             config_PutPsz( p_intf, "filter", psz_filter );
         }
-
-        config_PutPsz( p_intf, "deinterlace-mode", psz_mode );
     }
 
     if( psz_filter )
@@ -374,7 +372,18 @@ static void GtkDeinterlaceUpdate( intf_thread_t *p_intf, char *psz_mode )
     /* now restart all video stream */
     if( p_intf->p_sys->p_input )
     {
+        vout_thread_t *p_vout;
         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
+
+        /* Warn the vout we are about to change the filter chain */
+        p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
+                                  FIND_ANYWHERE );
+        if( p_vout )
+        {
+            p_vout->b_filter_change = VLC_TRUE;
+            vlc_object_release( p_vout );
+        }
+
 #define ES p_intf->p_sys->p_input->stream.pp_es[i]
         /* create a set of language buttons and append them to the container */
         for( i = 0 ; i < p_intf->p_sys->p_input->stream.i_es_number ; i++ )
@@ -389,6 +398,26 @@ static void GtkDeinterlaceUpdate( intf_thread_t *p_intf, char *psz_mode )
         }
         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
     }
+
+    if( strcmp( psz_mode, "None" ) )
+    {
+        vout_thread_t *p_vout;
+       p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
+                                 FIND_ANYWHERE );
+       if( p_vout )
+       {
+           vlc_value_t val;
+
+           val.psz_string = psz_mode;
+           if( var_Set( p_vout, "deinterlace-mode", val ) != VLC_SUCCESS )
+                config_PutPsz( p_intf, "deinterlace-mode", psz_mode );
+
+           vlc_object_release( p_vout );
+       }
+       else
+            config_PutPsz( p_intf, "deinterlace-mode", psz_mode );
+
+    }
 }
 
 static void GtkMenubarDeinterlaceToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
@@ -1175,10 +1204,23 @@ static gint GtkDeinterlaceMenus( gpointer          p_data,
     {
        if( strstr ( psz_filter, "deinterlace" ) )
        {
-            free( psz_deinterlace_option );
-            psz_deinterlace_option = config_GetPsz( p_intf, "deinterlace-mode" );
-            if( !psz_deinterlace_option )
-                psz_deinterlace_option = strdup( "None" );
+            vlc_value_t val;
+            vout_thread_t *p_vout;
+
+            p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
+                                      FIND_ANYWHERE );
+            if( p_vout &&
+                var_Get( p_vout, "deinterlace-mode", &val ) == VLC_SUCCESS )
+            {
+                if( val.psz_string && *val.psz_string )
+                {
+                    free( psz_deinterlace_option );
+                    psz_deinterlace_option = val.psz_string;
+                }
+                else if( val.psz_string ) free( val.psz_string );
+            }
+
+            if( p_vout ) vlc_object_release( p_vout );
        }
     }
     if( psz_filter )
index 38ac04701697de83368e59f13d4a1f597fe4fbfd..7e7b88d139eee7383d85ce63df4aaf73b2660ba1 100644 (file)
@@ -2,7 +2,7 @@
  * deinterlace.c : deinterlacer plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000, 2001, 2002, 2003 VideoLAN
- * $Id: deinterlace.c,v 1.6 2003/01/17 16:18:03 sam Exp $
+ * $Id: deinterlace.c,v 1.7 2003/01/28 12:30:44 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -60,6 +60,15 @@ static void Merge        ( void *, const void *, const void *, size_t );
 static int  SendEvents   ( vlc_object_t *, char const *,
                            vlc_value_t, vlc_value_t, void * );
 
+static void SetFilterMethod( vout_thread_t *p_vout, char *psz_method );
+static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * Callback prototypes
+ *****************************************************************************/
+static int FilterCallback ( vlc_object_t *, char const *,
+                            vlc_value_t, vlc_value_t, void * );
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -93,6 +102,8 @@ struct vout_sys_t
     mtime_t    next_date;
 
     vout_thread_t *p_vout;
+
+    vlc_mutex_t filter_lock;
 };
 
 /*****************************************************************************
@@ -103,7 +114,7 @@ struct vout_sys_t
 static int Create( vlc_object_t *p_this )
 {
     vout_thread_t *p_vout = (vout_thread_t *)p_this;
-    char *psz_method;
+    vlc_value_t val;
 
     /* Allocate structure */
     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
@@ -122,55 +133,73 @@ static int Create( vlc_object_t *p_this )
     p_vout->p_sys->i_mode = DEINTERLACE_DISCARD;
     p_vout->p_sys->b_double_rate = 0;
     p_vout->p_sys->last_date = 0;
+    vlc_mutex_init( p_vout, &p_vout->p_sys->filter_lock );
 
     /* Look what method was requested */
-    psz_method = config_GetPsz( p_vout, "deinterlace-mode" );
+    val.psz_string = config_GetPsz( p_vout, "deinterlace-mode" );
 
-    if( psz_method == NULL )
+    var_Create( p_vout, "deinterlace-mode", VLC_VAR_STRING );
+
+    if( val.psz_string == NULL )
     {
         msg_Err( p_vout, "configuration variable %s empty",
                          "deinterlace-mode" );
         msg_Err( p_vout, "no deinterlace mode provided, using \"discard\"" );
-    }
-    else
-    {
-        if( !strcmp( psz_method, "discard" ) )
-        {
-            p_vout->p_sys->i_mode = DEINTERLACE_DISCARD;
-        }
-        else if( !strcmp( psz_method, "mean" ) )
-        {
-            p_vout->p_sys->i_mode = DEINTERLACE_MEAN;
-        }
-        else if( !strcmp( psz_method, "blend" )
-                  || !strcmp( psz_method, "average" )
-                  || !strcmp( psz_method, "combine-fields" ) )
-        {
-            p_vout->p_sys->i_mode = DEINTERLACE_BLEND;
-        }
-        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 = 1;
-        }
-        else if( !strcmp( psz_method, "linear" ) )
-        {
-            p_vout->p_sys->i_mode = DEINTERLACE_LINEAR;
-            p_vout->p_sys->b_double_rate = 1;
-        }
-        else
-        {
-            msg_Err( p_vout, "no valid deinterlace mode provided, "
-                             "using \"discard\"" );
-        }
 
-        free( psz_method );
+        val.psz_string = strdup( "discard" );
     }
 
+    var_Set( p_vout, "deinterlace-mode", val );
+
+    SetFilterMethod( p_vout, val.psz_string );
+
+    free( val.psz_string );
+
+    var_AddCallback( p_vout, "deinterlace-mode", FilterCallback, NULL );
+
     return VLC_SUCCESS;
 }
 
+/*****************************************************************************
+ * SetFilterMethod: setup the deinterlace method to use.
+ *****************************************************************************/
+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 = 0;
+    }
+    else if( !strcmp( psz_method, "mean" ) )
+    {
+        p_vout->p_sys->i_mode = DEINTERLACE_MEAN;
+        p_vout->p_sys->b_double_rate = 0;
+    }
+    else if( !strcmp( psz_method, "blend" )
+             || !strcmp( psz_method, "average" )
+             || !strcmp( psz_method, "combine-fields" ) )
+    {
+        p_vout->p_sys->i_mode = DEINTERLACE_BLEND;
+        p_vout->p_sys->b_double_rate = 0;
+    }
+    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 = 1;
+    }
+    else if( !strcmp( psz_method, "linear" ) )
+    {
+        p_vout->p_sys->i_mode = DEINTERLACE_LINEAR;
+        p_vout->p_sys->b_double_rate = 1;
+    }
+    else
+    {
+        msg_Err( p_vout, "no valid deinterlace mode provided, "
+                 "using \"discard\"" );
+    }
+}
+
 /*****************************************************************************
  * Init: initialize Deinterlace video thread output method
  *****************************************************************************/
@@ -200,7 +229,31 @@ static int Init( vout_thread_t *p_vout )
             break;
     }
 
-    /* Try to open the real video output, with half the height our images */
+    /* Try to open the real video output */
+    p_vout->p_sys->p_vout = SpawnRealVout( p_vout );
+
+    if( p_vout->p_sys->p_vout == NULL )
+    {
+        /* Everything failed */
+        msg_Err( p_vout, "cannot open vout, aborting" );
+
+        return VLC_EGENERIC;
+    }
+
+    ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
+
+    ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * SpawnRealVout: spawn the real video output.
+ *****************************************************************************/
+static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout )
+{
+    vout_thread_t *p_real_vout = NULL;
+
     msg_Dbg( p_vout, "spawning the real video output" );
 
     switch( p_vout->render.i_chroma )
@@ -212,7 +265,7 @@ static int Init( vout_thread_t *p_vout )
         {
         case DEINTERLACE_MEAN:
         case DEINTERLACE_DISCARD:
-            p_vout->p_sys->p_vout =
+            p_real_vout =
                 vout_Create( p_vout,
                        p_vout->output.i_width, p_vout->output.i_height / 2,
                        p_vout->output.i_chroma, p_vout->output.i_aspect );
@@ -221,7 +274,7 @@ static int Init( vout_thread_t *p_vout )
         case DEINTERLACE_BOB:
         case DEINTERLACE_BLEND:
         case DEINTERLACE_LINEAR:
-            p_vout->p_sys->p_vout =
+            p_real_vout =
                 vout_Create( p_vout,
                        p_vout->output.i_width, p_vout->output.i_height,
                        p_vout->output.i_chroma, p_vout->output.i_aspect );
@@ -230,7 +283,7 @@ static int Init( vout_thread_t *p_vout )
         break;
 
     case VLC_FOURCC('I','4','2','2'):
-        p_vout->p_sys->p_vout =
+        p_real_vout =
             vout_Create( p_vout,
                        p_vout->output.i_width, p_vout->output.i_height,
                        VLC_FOURCC('I','4','2','0'), p_vout->output.i_aspect );
@@ -240,19 +293,7 @@ static int Init( vout_thread_t *p_vout )
         break;
     }
 
-    /* Everything failed */
-    if( p_vout->p_sys->p_vout == NULL )
-    {
-        msg_Err( p_vout, "cannot open vout, aborting" );
-
-        return VLC_EGENERIC;
-    }
-
-    ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
-
-    ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
-
-    return VLC_SUCCESS;
+    return p_real_vout;
 }
 
 /*****************************************************************************
@@ -281,6 +322,7 @@ static void Destroy( vlc_object_t *p_this )
 
     DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
 
+    vlc_object_detach( p_vout->p_sys->p_vout );
     vout_Destroy( p_vout->p_sys->p_vout );
 
     free( p_vout->p_sys );
@@ -297,6 +339,8 @@ static void Render ( vout_thread_t *p_vout, picture_t *p_pic )
 {
     picture_t *pp_outpic[2];
 
+    vlc_mutex_lock( &p_vout->p_sys->filter_lock );
+
     /* Get a new picture */
     while( ( pp_outpic[0] = vout_CreatePicture( p_vout->p_sys->p_vout,
                                              0, 0, 0 ) )
@@ -304,10 +348,11 @@ static void Render ( vout_thread_t *p_vout, picture_t *p_pic )
     {
         if( p_vout->b_die || 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 );
 
@@ -321,9 +366,10 @@ static void Render ( vout_thread_t *p_vout, picture_t *p_pic )
             if( p_vout->b_die || p_vout->b_error )
             {
                 vout_DestroyPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
+                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
                 return;
             }
-            msleep( VOUT_OUTMEM_SLEEP );
+           msleep( VOUT_OUTMEM_SLEEP );
         }
 
         /* 20ms is a bit arbitrary, but it's only for the first image we get */
@@ -371,6 +417,8 @@ static void Render ( vout_thread_t *p_vout, picture_t *p_pic )
             vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
             break;
     }
+
+    vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
 }
 
 /*****************************************************************************
@@ -668,3 +716,82 @@ static int SendEvents( vlc_object_t *p_this, char const *psz_var,
     return VLC_SUCCESS;
 }
 
+/*****************************************************************************
+ * FilterCallback: called when changing the deinterlace method on the fly.
+ *****************************************************************************/
+static int FilterCallback( 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;
+    int i_old_mode = p_vout->p_sys->i_mode;
+
+    vlc_mutex_lock( &p_vout->p_sys->filter_lock );
+    msg_Err( p_vout, "filter method: %s", newval.psz_string );
+
+    SetFilterMethod( p_vout, newval.psz_string );
+
+    switch( p_vout->render.i_chroma )
+    {
+    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 */
+
+    DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
+
+    vlc_object_detach( p_vout->p_sys->p_vout );
+    vout_Destroy( p_vout->p_sys->p_vout );
+
+    /* Try to open a new video output */
+    p_vout->p_sys->p_vout = SpawnRealVout( p_vout );
+
+    if( p_vout->p_sys->p_vout == NULL )
+    {
+        /* Everything failed */
+        msg_Err( p_vout, "cannot open vout, aborting" );
+
+        vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+        return VLC_EGENERIC;
+    }
+
+    ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
+
+    vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
+    return VLC_SUCCESS;
+}
index eed2c83a4ccca1a8e4404d1161a9d6353f517828..6b36c9af019cd7a4faaa106d97db862087958e13 100644 (file)
@@ -5,7 +5,7 @@
  * thread, and destroy a previously oppened video output thread.
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: video_output.c,v 1.207 2003/01/22 10:44:50 fenrir Exp $
+ * $Id: video_output.c,v 1.208 2003/01/28 12:30:44 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -81,7 +81,7 @@ vout_thread_t * __vout_Request ( vlc_object_t *p_this, vout_thread_t *p_vout,
             else
             {
                 vlc_object_detach( p_vout );
-//                vlc_object_release( p_vout );
+                vlc_object_release( p_vout );
                 vout_Destroy( p_vout );
             }
             if( psz_sout ) free( psz_sout );
@@ -108,10 +108,39 @@ vout_thread_t * __vout_Request ( vlc_object_t *p_this, vout_thread_t *p_vout,
     /* If we now have a video output, check it has the right properties */
     if( p_vout )
     {
+        char *psz_filter_chain;
+
+        /* We don't directly check for the "filter" variable for obvious
+         * performance reasons. */
+        if( p_vout->b_filter_change )
+        {
+            psz_filter_chain = config_GetPsz( p_this, "filter" );
+
+            if( psz_filter_chain && !*psz_filter_chain )
+            {
+                free( psz_filter_chain );
+                psz_filter_chain = NULL;
+            }
+            if( p_vout->psz_filter_chain && !*p_vout->psz_filter_chain )
+            {
+                free( p_vout->psz_filter_chain );
+                p_vout->psz_filter_chain = NULL;
+            }
+
+            if( ( !psz_filter_chain && !p_vout->psz_filter_chain ) ||
+                ( psz_filter_chain && p_vout->psz_filter_chain &&
+                  !strcmp( psz_filter_chain, p_vout->psz_filter_chain ) ) )
+            {
+                p_vout->b_filter_change = VLC_FALSE;
+            }
+
+        }
+
         if( ( p_vout->render.i_width != i_width ) ||
             ( p_vout->render.i_height != i_height ) ||
             ( p_vout->render.i_chroma != i_chroma ) ||
-            ( p_vout->render.i_aspect != i_aspect ) )
+            ( p_vout->render.i_aspect != i_aspect ) ||
+            p_vout->b_filter_change )
         {
             /* We are not interested in this format, close this vout */
             vlc_object_detach( p_vout );
@@ -126,6 +155,8 @@ vout_thread_t * __vout_Request ( vlc_object_t *p_this, vout_thread_t *p_vout,
             vlc_object_attach( p_vout, p_this );
             vlc_object_release( p_vout );
         }
+
+        if( psz_filter_chain ) free( psz_filter_chain );
     }
 
     if( !p_vout )
@@ -218,7 +249,7 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent,
     }
 
     /* Choose the video output module */
-    if( !p_vout->psz_filter_chain )
+    if( !p_vout->psz_filter_chain || !*p_vout->psz_filter_chain )
     {
         psz_plugin = config_GetPsz( p_parent, "vout" );
     }
@@ -287,6 +318,7 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent,
     p_vout->b_fullscreen = 0;
     p_vout->render_time  = 10;
     p_vout->c_fps_samples= 0;
+    p_vout->b_filter_change = 0;
 
     /* Mouse coordinates */
     var_Create( p_vout, "mouse-x", VLC_VAR_INTEGER );
@@ -307,7 +339,8 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent,
 
 
     p_vout->p_module = module_Need( p_vout,
-                           ( p_vout->psz_filter_chain ) ?
+                           ( p_vout->psz_filter_chain &&
+                               *p_vout->psz_filter_chain ) ?
                            "video filter" : "video output",
                            psz_plugin );