]> git.sesse.net Git - vlc/blobdiff - src/video_output/video_output.c
playlist: Use vlc_object_alive().
[vlc] / src / video_output / video_output.c
index 0706c6d2d9abd47ba6daedc6632751ba713636e8..74bcacdebfac32bec0cbfa36a0ce3531e730eaff 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <vlc/vlc.h>
 
 #include <stdlib.h>                                                /* free() */
@@ -62,12 +66,13 @@ static int      InitThread        ( vout_thread_t * );
 static void     RunThread         ( vout_thread_t * );
 static void     ErrorThread       ( vout_thread_t * );
 static void     EndThread         ( vout_thread_t * );
-static void     DestroyThread     ( vout_thread_t * );
 
 static void     AspectRatio       ( int, int *, int * );
 static int      BinaryLog         ( uint32_t );
 static void     MaskToShift       ( int *, int *, uint32_t );
 
+static void     vout_Destructor   ( vlc_object_t * p_this );
+
 /* Object variables callbacks */
 static int DeinterlaceCallback( vlc_object_t *, char const *,
                                 vlc_value_t, vlc_value_t, void * );
@@ -123,11 +128,9 @@ vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
         /* Reattach video output to playlist before bailing out */
         if( p_vout )
         {
-            playlist_t  *p_playlist = pl_Yield( p_this );
             spu_Attach( p_vout->p_spu, p_this, VLC_FALSE );
             vlc_object_detach( p_vout );
-            vlc_object_attach( p_vout, p_playlist );
-            pl_Release( p_this );
+            vlc_object_attach( p_vout, p_this->p_libvlc );
         }
         return NULL;
     }
@@ -143,20 +146,16 @@ vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
 
         if( !p_vout )
         {
-            playlist_t *p_playlist = pl_Yield( p_this );
-            vlc_mutex_lock( &p_playlist->gc_lock );
-            p_vout = vlc_object_find( p_playlist,
+            p_vout = vlc_object_find( p_this->p_libvlc,
                                       VLC_OBJECT_VOUT, FIND_CHILD );
             /* only first children of p_input for unused vout */
-            if( p_vout && p_vout->p_parent != (vlc_object_t *)p_playlist )
+            if( p_vout && p_vout->p_parent != VLC_OBJECT(p_this->p_libvlc) )
             {
                 vlc_object_release( p_vout );
                 p_vout = NULL;
             }
             if( p_vout )
                 vlc_object_detach( p_vout );    /* Remove it from the GC */
-            vlc_mutex_unlock( &p_playlist->gc_lock );
-            pl_Release( p_this );
         }
     }
 
@@ -189,7 +188,7 @@ vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
                 p_vout->b_filter_change = VLC_FALSE;
             }
 
-            if( psz_filter_chain ) free( psz_filter_chain );
+            free( psz_filter_chain );
         }
 
         if( ( p_vout->fmt_render.i_width != p_fmt->i_width ) ||
@@ -394,14 +393,14 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
     p_vout->p_cfg = p_cfg;
     p_vout->p_module = module_Need( p_vout,
         ( p_vout->psz_filter_chain && *p_vout->psz_filter_chain ) ?
-        "video filter" : "video output", psz_name, 0 );
+        "video filter" : "video output", psz_name, p_vout->psz_filter_chain && *p_vout->psz_filter_chain );
     free( psz_name );
 
     if( p_vout->p_module == NULL )
     {
         msg_Err( p_vout, "no suitable vout module" );
         vlc_object_detach( p_vout );
-        vlc_object_destroy( p_vout );
+        vlc_object_release( p_vout );
         return NULL;
     }
 
@@ -427,7 +426,7 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
     if( var_Get( p_vout, "deinterlace-mode", &val ) == VLC_SUCCESS )
     {
         var_Set( p_vout, "deinterlace", val );
-        if( val.psz_string ) free( val.psz_string );
+        free( val.psz_string );
     }
     var_AddCallback( p_vout, "deinterlace", DeinterlaceCallback, NULL );
 
@@ -454,8 +453,7 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
     {
         msg_Err( p_vout, "out of memory" );
         module_Unneed( p_vout, p_vout->p_module );
-        vlc_object_detach( p_vout );
-        vlc_object_destroy( p_vout );
+        vlc_object_release( p_vout );
         return NULL;
     }
 
@@ -464,14 +462,12 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
         msg_Err( p_vout, "video output creation failed" );
 
         /* Make sure the thread is destroyed */
-        vlc_object_kill( p_vout );
-        vlc_thread_join( p_vout );
-
-        vlc_object_detach( p_vout );
-        vlc_object_destroy( p_vout );
+        vlc_object_release( p_vout );
         return NULL;
     }
 
+    vlc_object_set_destructor( p_vout, vout_Destructor );
+
     return p_vout;
 }
 
@@ -485,40 +481,55 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
  *****************************************************************************/
 void vout_Destroy( vout_thread_t *p_vout )
 {
-    vout_thread_t *p_another_vout;
-    playlist_t *p_playlist = pl_Yield( p_vout );
+    /* XXX: should go in the destructor */
+    var_Destroy( p_vout, "intf-change" );
 
-    /* Request thread destruction */
-    vlc_object_kill( p_vout );
-    vlc_thread_join( p_vout );
+    vlc_object_release( p_vout );
+}
 
-    var_Destroy( p_vout, "intf-change" );
+static void vout_Destructor( vlc_object_t * p_this )
+{
+    vout_thread_t *p_vout = (vout_thread_t *)p_this;
+
+    /* Destroy the locks */
+    vlc_mutex_destroy( &p_vout->picture_lock );
+    vlc_mutex_destroy( &p_vout->change_lock );
+    vlc_mutex_destroy( &p_vout->vfilter_lock );
 
-    if( p_vout->psz_filter_chain ) free( p_vout->psz_filter_chain );
+    /* Release the module */
+    if( p_vout->p_module )
+    {
+        module_Unneed( p_vout, p_vout->p_module );
+    }
+
+    free( p_vout->psz_filter_chain );
 
     config_ChainDestroy( p_vout->p_cfg );
 
-    /* Free structure */
-    vlc_object_destroy( p_vout );
 #ifndef __APPLE__
-    /* This is a dirty hack for mostly Linux, where there is no way to get the GUI
-       back if you closed it while playing video. This is solved in Mac OS X,
-       where we have this novelty called menubar, that will always allow you access
-       to the applications main functionality. They should try that on linux sometime */
-    p_another_vout = vlc_object_find( p_playlist,
-                                      VLC_OBJECT_VOUT, FIND_ANYWHERE );
-    if( p_another_vout == NULL )
-    {
-        vlc_value_t val;
-        val.b_bool = VLC_TRUE;
-        var_Set( p_playlist, "intf-show", val );
+    vout_thread_t *p_another_vout;
+
+    playlist_t *p_playlist = pl_Get( p_vout );
+    if( p_playlist->b_die ) return;
+    vlc_object_yield( p_playlist );
+/* This is a dirty hack for mostly Linux, where there is no way to get the GUI
+   back if you closed it while playing video. This is solved in Mac OS X,
+   where we have this novelty called menubar, that will always allow you access
+   to the applications main functionality. They should try that on linux sometime */
+        p_another_vout = vlc_object_find( p_this->p_libvlc,
+                                          VLC_OBJECT_VOUT, FIND_ANYWHERE );
+        if( p_another_vout == NULL )
+        {
+            vlc_value_t val;
+            val.b_bool = VLC_TRUE;
+            var_Set( p_playlist, "intf-show", val );
     }
     else
     {
         vlc_object_release( p_another_vout );
     }
-#endif
     vlc_object_release( p_playlist );
+#endif
 }
 
 /*****************************************************************************
@@ -753,11 +764,7 @@ static void RunThread( vout_thread_t *p_vout)
     vlc_thread_ready( p_vout );
 
     if( p_vout->b_error )
-    {
-        /* Destroy thread structures allocated by Create and InitThread */
-        DestroyThread( p_vout );
         return;
-    }
 
     if( p_vout->b_title_show )
         DisplayTitleOnOSD( p_vout );
@@ -773,15 +780,7 @@ static void RunThread( vout_thread_t *p_vout)
         display_date = 0;
         current_date = mdate();
 
-        if( p_input && p_input->b_die )
-        {
-            vlc_object_release( p_input );
-            p_input = NULL;
-        }
-
         i_loops++;
-        if( i_loops % 20 == 0 )
-        {
             if( !p_input )
             {
                 p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
@@ -797,8 +796,9 @@ static void RunThread( vout_thread_t *p_vout)
                                      i_displayed , NULL);
                 i_displayed = i_lost = 0;
                 vlc_mutex_unlock( &p_input->p->counters.counters_lock );
+                vlc_object_release( p_input );
+                p_input = NULL;
             }
-        }
 #if 0
         p_vout->c_loops++;
         if( !(p_vout->c_loops % VOUT_STATS_NB_LOOPS) )
@@ -997,7 +997,7 @@ static void RunThread( vout_thread_t *p_vout)
                     msg_Err( p_vout, "no video filter found (%s)",
                              p_vout->psz_vfilters[i] );
                     vlc_object_detach( p_vfilter );
-                    vlc_object_destroy( p_vfilter );
+                    vlc_object_release( p_vfilter );
                 }
             }
             p_vout->b_vfilter_change = VLC_FALSE;
@@ -1054,6 +1054,9 @@ static void RunThread( vout_thread_t *p_vout)
             }
             p_subpic = spu_SortSubpictures( p_vout->p_spu, display_date,
             p_input ? var_GetBool( p_input, "state" ) == PAUSE_S : VLC_FALSE );
+            if( p_input )
+                vlc_object_release( p_input );
+            p_input = NULL;
         }
 
         /*
@@ -1217,9 +1220,6 @@ static void RunThread( vout_thread_t *p_vout)
 
     /* End of thread */
     EndThread( p_vout );
-
-    /* Destroy thread structures allocated by CreateThread */
-    DestroyThread( p_vout );
 }
 
 /*****************************************************************************
@@ -1287,26 +1287,6 @@ static void EndThread( vout_thread_t *p_vout )
     vlc_mutex_unlock( &p_vout->change_lock );
 }
 
-/*****************************************************************************
- * DestroyThread: thread destruction
- *****************************************************************************
- * This function is called when the thread ends. It frees all ressources
- * allocated by CreateThread. Status is available at this stage.
- *****************************************************************************/
-static void DestroyThread( vout_thread_t *p_vout )
-{
-    /* Destroy the locks */
-    vlc_mutex_destroy( &p_vout->picture_lock );
-    vlc_mutex_destroy( &p_vout->change_lock );
-    vlc_mutex_destroy( &p_vout->vfilter_lock );
-
-    /* Release the module */
-    if( p_vout && p_vout->p_module )
-    {
-        module_Unneed( p_vout, p_vout->p_module );
-    }
-}
-
 /* following functions are local */
 
 static int ReduceHeight( int i_ratio )
@@ -1447,7 +1427,7 @@ static void SuxorRestartVideoES( suxor_thread_t *p_this )
 
     vlc_object_release( p_this->p_input );
 
-    vlc_object_destroy( p_this );
+    vlc_object_release( p_this );
 }
 
 /*****************************************************************************
@@ -1504,7 +1484,7 @@ static int DeinterlaceCallback( vlc_object_t *p_this, char const *psz_cmd,
 
     val.psz_string = psz_filter;
     var_Set( p_vout, "vout-filter", val );
-    if( psz_filter ) free( psz_filter );
+    free( psz_filter );
 
     return VLC_SUCCESS;
 }
@@ -1563,11 +1543,8 @@ static int ParseVideoFilter2Chain( vout_thread_t *p_vout, char *psz_vfilters )
         struct config_chain_t *p_cfg =
             p_vout->p_vfilters_cfg[p_vout->i_vfilters_cfg];
         config_ChainDestroy( p_cfg );
-        if( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] )
-        {
-            free( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] );
-            p_vout->psz_vfilters[p_vout->i_vfilters_cfg] = NULL;
-        }
+        free( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] );
+        p_vout->psz_vfilters[p_vout->i_vfilters_cfg] = NULL;
     }
     p_vout->i_vfilters_cfg = 0;
     if( psz_vfilters && *psz_vfilters )
@@ -1625,7 +1602,7 @@ static void RemoveVideoFilters2( vout_thread_t *p_vout )
         }
 
         free( p_vout->pp_vfilters[i]->p_owner );
-        vlc_object_destroy( p_vout->pp_vfilters[i] );
+        vlc_object_release( p_vout->pp_vfilters[i] );
     }
     p_vout->i_vfilters = 0;
 }