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 )
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
......
......@@ -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 );
}
......
......@@ -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 );
}
......
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