Force VLM stream to not use sout-keep.
authorLaurent Aimar <fenrir@videolan.org>
Mon, 26 Feb 2007 19:27:35 +0000 (19:27 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Mon, 26 Feb 2007 19:27:35 +0000 (19:27 +0000)
Fixed race condition with sout-keep.
Fixed broken sout-keep behaviour (currently active sout can be used
 twice or destroyed..., it might fixed segfaults reported by xxcv))

src/input/input.c
src/input/vlm.c
src/stream_output/stream_output.c

index 65a65b5..4b14a3d 100644 (file)
@@ -1186,15 +1186,18 @@ static void End( input_thread_t * p_input )
 
             if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool )
             {
+                playlist_t  *p_playlist = pl_Yield( p_input );
+
                 /* attach sout to the playlist */
-                msg_Dbg( p_input, "keeping sout" );
                 vlc_object_detach( p_input->p->p_sout );
-                vlc_object_attach( p_input->p->p_sout, p_input->p_libvlc->p_playlist );
+                vlc_object_attach( p_input->p->p_sout, p_playlist );
+                pl_Release( p_input );
+                msg_Dbg( p_input, "kept sout" );
             }
             else
             {
-                msg_Dbg( p_input, "destroying sout" );
                 sout_DeleteInstance( p_input->p->p_sout );
+                msg_Dbg( p_input, "destroyed sout" );
             }
         }
 #undef CL_CO
index 2d4de14..95eb590 100644 (file)
@@ -87,11 +87,10 @@ vlm_t *__vlm_New ( vlc_object_t *p_this )
         }
 
         vlc_mutex_init( p_this->p_libvlc, &p_vlm->lock );
-        p_vlm->i_media      = 0;
-        p_vlm->media        = NULL;
-        p_vlm->i_vod        = 0;
-        p_vlm->i_schedule   = 0;
-        p_vlm->schedule     = NULL;
+        TAB_INIT( p_vlm->i_media, p_vlm->media );
+        TAB_INIT( p_vlm->i_schedule, p_vlm->schedule );
+        p_vlm->i_vod = 0;
+        p_vlm->vod = NULL;
 
         vlc_object_yield( p_vlm );
         vlc_object_attach( p_vlm, p_this->p_libvlc );
@@ -1114,6 +1113,7 @@ int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd,
             input_thread_t *p_input;
             char *psz_output;
             char *psz_header;
+            char *psz_dup;
             int i;
 
             input_ItemClean( &media->item );
@@ -1125,25 +1125,26 @@ int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd,
                 asprintf( &psz_output, "#description" );
 
             media->item.psz_uri = strdup( media->input[0] );
-            media->item.ppsz_options = malloc( sizeof( char* ) );
-            asprintf( &media->item.ppsz_options[0], "sout=%s", psz_output);
-            media->item.i_options = 1;
+
+            TAB_INIT( media->item.i_options, media->item.ppsz_options );
+
+            asprintf( &psz_dup, "sout=%s", psz_output);
+            TAB_APPEND( media->item.i_options, media->item.ppsz_options, psz_dup );
             for( i = 0; i < media->i_option; i++ )
             {
-                media->item.i_options++;
-                media->item.ppsz_options =
-                    realloc( media->item.ppsz_options,
-                             media->item.i_options * sizeof( char* ) );
-                media->item.ppsz_options[ media->item.i_options - 1 ] =
-                    strdup( media->option[i] );
+                psz_dup = strdup( media->option[i] );
+                TAB_APPEND( media->item.i_options, media->item.ppsz_options, psz_dup );
             }
+            psz_dup = strdup( "no-sout-keep" );
+            TAB_APPEND( media->item.i_options, media->item.ppsz_options, psz_dup );
 
             asprintf( &psz_header, _("Media: %s"), media->psz_name );
 
             if( (p_input = input_CreateThread2( vlm, &media->item, psz_header
                                               ) ) )
             {
-                while( !p_input->b_eof && !p_input->b_error ) msleep( 100000 );
+                while( !p_input->b_eof && !p_input->b_error )
+                    msleep( 100000 );
 
                 input_StopThread( p_input );
                 input_DestroyThread( p_input );
@@ -1195,34 +1196,37 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id,
 
         if( !p_instance )
         {
+            char *psz_dup;
+
             p_instance = malloc( sizeof(vlm_media_instance_t) );
-            if( !p_instance ) return VLC_EGENERIC;
+            if( !p_instance )
+                return VLC_ENOMEM;
+
             memset( p_instance, 0, sizeof(vlm_media_instance_t) );
+
+            p_instance->psz_name = psz_id ? strdup( psz_id ) : NULL;
             input_ItemInit( VLC_OBJECT(vlm), &p_instance->item );
             p_instance->p_input = NULL;
 
-            if( ( media->psz_output != NULL ) || ( media->psz_vod_output != NULL ) )
+            TAB_INIT( p_instance->item.i_options, p_instance->item.ppsz_options );
+
+            if( media->psz_output != NULL || media->psz_vod_output != NULL )
             {
-                p_instance->item.ppsz_options = malloc( sizeof( char* ) );
-                asprintf( &p_instance->item.ppsz_options[0], "sout=%s%s%s",
+                asprintf( &psz_dup, "sout=%s%s%s",
                           media->psz_output ? media->psz_output : "",
-                          (media->psz_output && media->psz_vod_output) ?
-                          ":" : media->psz_vod_output ? "#" : "",
+                          (media->psz_output && media->psz_vod_output) ? ":" : media->psz_vod_output ? "#" : "",
                           media->psz_vod_output ? media->psz_vod_output : "" );
-                p_instance->item.i_options = 1;
+                TAB_APPEND( p_instance->item.i_options, p_instance->item.ppsz_options, psz_dup );
             }
 
             for( i = 0; i < media->i_option; i++ )
             {
-                p_instance->item.i_options++;
-                p_instance->item.ppsz_options =
-                    realloc( p_instance->item.ppsz_options,
-                             p_instance->item.i_options * sizeof( char* ) );
-                p_instance->item.ppsz_options[p_instance->item.i_options - 1] =
-                    strdup( media->option[i] );
+                psz_dup = strdup( media->option[i] );
+                TAB_APPEND( p_instance->item.i_options, p_instance->item.ppsz_options, psz_dup );
             }
+            psz_dup = strdup( "no-sout-keep" );
+            TAB_APPEND( p_instance->item.i_options, p_instance->item.ppsz_options, psz_dup );
 
-            p_instance->psz_name = psz_id ? strdup( psz_id ) : NULL;
             TAB_APPEND( media->i_instance, media->instance, p_instance );
         }
 
index c4532c4..dc58641 100644 (file)
@@ -34,6 +34,7 @@
 #include <string.h>                                            /* strerror() */
 
 #include <vlc_sout.h>
+#include <vlc_playlist.h>
 
 #include "stream_output.h"
 
@@ -74,40 +75,39 @@ sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, char * psz_dest )
     sout_instance_t *p_sout;
     vlc_value_t keep;
 
-    if( var_Get( p_parent, "sout-keep", &keep ) < 0 )
+    if( var_Get( p_parent, "sout-keep", &keep ) >= 0 && keep.b_bool )
     {
-        msg_Warn( p_parent, "cannot get sout-keep value" );
-        keep.b_bool = VLC_FALSE;
-    }
-    if( keep.b_bool )
-    {
-        if( ( p_sout = vlc_object_find( p_parent, VLC_OBJECT_SOUT,
-                                        FIND_ANYWHERE ) ) != NULL )
+        /* Remove the sout from the playlist garbage collector */
+        playlist_t *p_playlist = pl_Yield( p_parent );
+
+        vlc_mutex_lock( &p_playlist->gc_lock );
+        p_sout = vlc_object_find( p_playlist, VLC_OBJECT_SOUT, FIND_CHILD );
+        if( p_sout && p_sout->p_parent != (vlc_object_t *)p_playlist )
+        {
+            vlc_object_release( p_sout );
+            p_sout = NULL;
+        }
+        if( p_sout )
+            vlc_object_detach( p_sout );    /* Remove it from the GC */
+        vlc_mutex_unlock( &p_playlist->gc_lock );
+
+        pl_Release( p_parent );
+
+        /* */
+
+        if( p_sout )
         {
             if( !strcmp( p_sout->psz_sout, psz_dest ) )
             {
                 msg_Dbg( p_parent, "sout keep: reusing sout" );
                 msg_Dbg( p_parent, "sout keep: you probably want to use "
                           "gather stream_out" );
-                vlc_object_detach( p_sout );
                 vlc_object_attach( p_sout, p_parent );
                 vlc_object_release( p_sout );
                 return p_sout;
             }
-            else
-            {
-                msg_Dbg( p_parent, "sout keep: destroying unusable sout" );
-                vlc_object_release( p_sout );
-                sout_DeleteInstance( p_sout );
-            }
-        }
-    }
-    else if( !keep.b_bool )
-    {
-        while( ( p_sout = vlc_object_find( p_parent, VLC_OBJECT_SOUT,
-                                           FIND_PARENT ) ) != NULL )
-        {
-            msg_Dbg( p_parent, "sout keep: destroying old sout" );
+
+            msg_Dbg( p_parent, "sout keep: destroying unusable sout" );
             vlc_object_release( p_sout );
             sout_DeleteInstance( p_sout );
         }