Commit d7bc817f authored by Laurent Aimar's avatar Laurent Aimar

Force VLM stream to not use sout-keep.

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))
parent f6b77b24
...@@ -1186,15 +1186,18 @@ static void End( input_thread_t * p_input ) ...@@ -1186,15 +1186,18 @@ static void End( input_thread_t * p_input )
if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool ) 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 */ /* attach sout to the playlist */
msg_Dbg( p_input, "keeping sout" );
vlc_object_detach( p_input->p->p_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 else
{ {
msg_Dbg( p_input, "destroying sout" );
sout_DeleteInstance( p_input->p->p_sout ); sout_DeleteInstance( p_input->p->p_sout );
msg_Dbg( p_input, "destroyed sout" );
} }
} }
#undef CL_CO #undef CL_CO
......
...@@ -87,11 +87,10 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) ...@@ -87,11 +87,10 @@ vlm_t *__vlm_New ( vlc_object_t *p_this )
} }
vlc_mutex_init( p_this->p_libvlc, &p_vlm->lock ); vlc_mutex_init( p_this->p_libvlc, &p_vlm->lock );
p_vlm->i_media = 0; TAB_INIT( p_vlm->i_media, p_vlm->media );
p_vlm->media = NULL; TAB_INIT( p_vlm->i_schedule, p_vlm->schedule );
p_vlm->i_vod = 0; p_vlm->i_vod = 0;
p_vlm->i_schedule = 0; p_vlm->vod = NULL;
p_vlm->schedule = NULL;
vlc_object_yield( p_vlm ); vlc_object_yield( p_vlm );
vlc_object_attach( p_vlm, p_this->p_libvlc ); 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, ...@@ -1114,6 +1113,7 @@ int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd,
input_thread_t *p_input; input_thread_t *p_input;
char *psz_output; char *psz_output;
char *psz_header; char *psz_header;
char *psz_dup;
int i; int i;
input_ItemClean( &media->item ); input_ItemClean( &media->item );
...@@ -1125,25 +1125,26 @@ int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd, ...@@ -1125,25 +1125,26 @@ int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd,
asprintf( &psz_output, "#description" ); asprintf( &psz_output, "#description" );
media->item.psz_uri = strdup( media->input[0] ); 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); TAB_INIT( media->item.i_options, media->item.ppsz_options );
media->item.i_options = 1;
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++ ) for( i = 0; i < media->i_option; i++ )
{ {
media->item.i_options++; psz_dup = strdup( media->option[i] );
media->item.ppsz_options = TAB_APPEND( media->item.i_options, media->item.ppsz_options, psz_dup );
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( "no-sout-keep" );
TAB_APPEND( media->item.i_options, media->item.ppsz_options, psz_dup );
asprintf( &psz_header, _("Media: %s"), media->psz_name ); asprintf( &psz_header, _("Media: %s"), media->psz_name );
if( (p_input = input_CreateThread2( vlm, &media->item, psz_header 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_StopThread( p_input );
input_DestroyThread( p_input ); input_DestroyThread( p_input );
...@@ -1195,34 +1196,37 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id, ...@@ -1195,34 +1196,37 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id,
if( !p_instance ) if( !p_instance )
{ {
char *psz_dup;
p_instance = malloc( sizeof(vlm_media_instance_t) ); 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) ); 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 ); input_ItemInit( VLC_OBJECT(vlm), &p_instance->item );
p_instance->p_input = NULL; 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( &psz_dup, "sout=%s%s%s",
asprintf( &p_instance->item.ppsz_options[0], "sout=%s%s%s",
media->psz_output ? media->psz_output : "", media->psz_output ? media->psz_output : "",
(media->psz_output && media->psz_vod_output) ? (media->psz_output && media->psz_vod_output) ? ":" : media->psz_vod_output ? "#" : "",
":" : media->psz_vod_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++ ) for( i = 0; i < media->i_option; i++ )
{ {
p_instance->item.i_options++; psz_dup = strdup( media->option[i] );
p_instance->item.ppsz_options = TAB_APPEND( p_instance->item.i_options, p_instance->item.ppsz_options, psz_dup );
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( "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 ); TAB_APPEND( media->i_instance, media->instance, p_instance );
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <string.h> /* strerror() */ #include <string.h> /* strerror() */
#include <vlc_sout.h> #include <vlc_sout.h>
#include <vlc_playlist.h>
#include "stream_output.h" #include "stream_output.h"
...@@ -74,40 +75,39 @@ sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, char * psz_dest ) ...@@ -74,40 +75,39 @@ sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, char * psz_dest )
sout_instance_t *p_sout; sout_instance_t *p_sout;
vlc_value_t keep; 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" ); /* Remove the sout from the playlist garbage collector */
keep.b_bool = VLC_FALSE; playlist_t *p_playlist = pl_Yield( p_parent );
}
if( keep.b_bool ) vlc_mutex_lock( &p_playlist->gc_lock );
{ p_sout = vlc_object_find( p_playlist, VLC_OBJECT_SOUT, FIND_CHILD );
if( ( p_sout = vlc_object_find( p_parent, VLC_OBJECT_SOUT, if( p_sout && p_sout->p_parent != (vlc_object_t *)p_playlist )
FIND_ANYWHERE ) ) != NULL ) {
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 ) ) if( !strcmp( p_sout->psz_sout, psz_dest ) )
{ {
msg_Dbg( p_parent, "sout keep: reusing sout" ); msg_Dbg( p_parent, "sout keep: reusing sout" );
msg_Dbg( p_parent, "sout keep: you probably want to use " msg_Dbg( p_parent, "sout keep: you probably want to use "
"gather stream_out" ); "gather stream_out" );
vlc_object_detach( p_sout );
vlc_object_attach( p_sout, p_parent ); vlc_object_attach( p_sout, p_parent );
vlc_object_release( p_sout ); vlc_object_release( p_sout );
return p_sout; return p_sout;
} }
else
{ msg_Dbg( p_parent, "sout keep: destroying unusable sout" );
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" );
vlc_object_release( p_sout ); vlc_object_release( p_sout );
sout_DeleteInstance( p_sout ); sout_DeleteInstance( p_sout );
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment