]> git.sesse.net Git - vlc/blobdiff - src/video_output/video_output.c
video_output.c: Don't rely on the playlist to store vout, but store them in libvlc.
[vlc] / src / video_output / video_output.c
index d7a92f8e8d87bd0b4477aa1a8a1b729257894b7b..81efa98f591bc51f8e0b8bcdf23ff27948275b6f 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <vlc/vlc.h>
 
 #include <stdlib.h>                                                /* free() */
@@ -68,6 +72,8 @@ 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 +129,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 +147,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,12 +189,11 @@ 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 ) ||
             ( p_vout->fmt_render.i_height != p_fmt->i_height ) ||
-            ( p_vout->fmt_render.i_chroma != p_fmt->i_chroma ) ||
             ( p_vout->fmt_render.i_aspect != p_fmt->i_aspect ) ||
             p_vout->b_filter_change )
         {
@@ -395,14 +394,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;
     }
 
@@ -428,7 +427,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 );
 
@@ -455,8 +454,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;
     }
 
@@ -465,14 +463,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;
 }
 
@@ -486,27 +482,29 @@ 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;
 
-    if( p_vout->psz_filter_chain ) free( p_vout->psz_filter_chain );
+    free( p_vout->psz_filter_chain );
 
     config_ChainDestroy( p_vout->p_cfg );
 
-    /* Free structure */
-    vlc_object_destroy( p_vout );
 #ifndef __APPLE__
+    vout_thread_t *p_another_vout;
+    playlist_t *p_playlist = pl_Yield( p_vout );
+
     /* 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,
+    p_another_vout = vlc_object_find( p_this->p_libvlc,
                                       VLC_OBJECT_VOUT, FIND_ANYWHERE );
     if( p_another_vout == NULL )
     {
@@ -518,8 +516,8 @@ void vout_Destroy( vout_thread_t *p_vout )
     {
         vlc_object_release( p_another_vout );
     }
-#endif
     vlc_object_release( p_playlist );
+#endif
 }
 
 /*****************************************************************************
@@ -781,8 +779,6 @@ static void RunThread( vout_thread_t *p_vout)
         }
 
         i_loops++;
-        if( i_loops % 20 == 0 )
-        {
             if( !p_input )
             {
                 p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
@@ -799,7 +795,6 @@ static void RunThread( vout_thread_t *p_vout)
                 i_displayed = i_lost = 0;
                 vlc_mutex_unlock( &p_input->p->counters.counters_lock );
             }
-        }
 #if 0
         p_vout->c_loops++;
         if( !(p_vout->c_loops % VOUT_STATS_NB_LOOPS) )
@@ -998,7 +993,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;
@@ -1448,7 +1443,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 );
 }
 
 /*****************************************************************************
@@ -1505,7 +1500,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;
 }
@@ -1564,11 +1559,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 )
@@ -1626,7 +1618,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;
 }
@@ -1647,10 +1639,10 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout )
         char *psz_artist = input_item_GetArtist( input_GetItem( p_input ) );
         char *psz_name = input_item_GetTitle( input_GetItem( p_input ) );
         if( EMPTY_STR( psz_name ) )
-            {
-                free( psz_name );
-                psz_name = input_item_GetName( input_GetItem( p_input ) );
-            }
+        {
+            free( psz_name );
+            psz_name = input_item_GetName( input_GetItem( p_input ) );
+        }
         if( !EMPTY_STR( psz_nowplaying ) )
         {
             vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN,
@@ -1665,12 +1657,8 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout )
         else if( !EMPTY_STR( psz_artist ) )
         {
             char *psz_string = NULL;
-
-            psz_string = malloc( strlen( psz_name ) + strlen( psz_artist ) );
-            if( psz_string )
+            if( asprintf( &psz_string, "%s - %s", psz_name, psz_artist ) != -1 )
             {
-                sprintf( psz_string, "%s - %s", psz_name, psz_artist );
-
                 vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN,
                                        psz_string, NULL,
                                        p_vout->i_title_position,
@@ -1699,3 +1687,4 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout )
         free( psz_nowplaying );
     }
 }
+