Commit c884cebc authored by Laurent Aimar's avatar Laurent Aimar

Activated vout/aout recycling with playlist inputs.

parent 3b40c174
...@@ -662,6 +662,10 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced ) ...@@ -662,6 +662,10 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
msg_Dbg( p_sys->p_input, "Decoder buffering done in %d ms", msg_Dbg( p_sys->p_input, "Decoder buffering done in %d ms",
(int)(mdate() - i_decoder_buffering_start)/1000 ); (int)(mdate() - i_decoder_buffering_start)/1000 );
/* Here is a good place to destroy unused vout with every demuxer */
input_ressource_TerminateVout( p_sys->p_input->p->p_ressource );
/* */
const mtime_t i_wakeup_delay = 10*1000; /* FIXME CLEANUP thread wake up time*/ const mtime_t i_wakeup_delay = 10*1000; /* FIXME CLEANUP thread wake up time*/
const mtime_t i_current_date = p_sys->b_paused ? p_sys->i_pause_date : mdate(); const mtime_t i_current_date = p_sys->b_paused ? p_sys->i_pause_date : mdate();
...@@ -2014,6 +2018,20 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) ...@@ -2014,6 +2018,20 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
case ES_OUT_SET_ACTIVE: case ES_OUT_SET_ACTIVE:
{ {
b = (bool) va_arg( args, int ); b = (bool) va_arg( args, int );
if( b && !p_sys->b_active && p_sys->i_es > 0 )
{
/* XXX Terminate vout if there are tracks but no video one.
* This one is not mandatory but is he earliest place where it
* can be done */
for( i = 0; i < p_sys->i_es; i++ )
{
es_out_id_t *p_es = p_sys->es[i];
if( p_es->fmt.i_cat == VIDEO_ES )
break;
}
if( i >= p_sys->i_es )
input_ressource_TerminateVout( p_sys->p_input->p->p_ressource );
}
p_sys->b_active = b; p_sys->b_active = b;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -2295,7 +2313,13 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) ...@@ -2295,7 +2313,13 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
assert(0); assert(0);
} }
/* TODO if the lock is made non recursive it should be changed */ /* TODO if the lock is made non recursive it should be changed */
return es_out_Control( out, i_new_query, p_es ); int i_ret = es_out_Control( out, i_new_query, p_es );
/* Clean up vout after user action (in active mode only).
* FIXME it does not work well with multiple video windows */
if( p_sys->b_active )
input_ressource_TerminateVout( p_sys->p_input->p->p_ressource );
return i_ret;
} }
case ES_OUT_GET_BUFFERING: case ES_OUT_GET_BUFFERING:
......
...@@ -66,7 +66,7 @@ static void *Run ( vlc_object_t *p_this ); ...@@ -66,7 +66,7 @@ static void *Run ( vlc_object_t *p_this );
static void *RunAndDestroy ( vlc_object_t *p_this ); static void *RunAndDestroy ( vlc_object_t *p_this );
static input_thread_t * Create ( vlc_object_t *, input_item_t *, static input_thread_t * Create ( vlc_object_t *, input_item_t *,
const char *, bool, sout_instance_t * ); const char *, bool, input_ressource_t * );
static int Init ( input_thread_t *p_input ); static int Init ( input_thread_t *p_input );
static void WaitDie ( input_thread_t *p_input ); static void WaitDie ( input_thread_t *p_input );
static void End ( input_thread_t *p_input ); static void End ( input_thread_t *p_input );
...@@ -118,7 +118,7 @@ static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO f ...@@ -118,7 +118,7 @@ static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO f
*****************************************************************************/ *****************************************************************************/
static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
const char *psz_header, bool b_quick, const char *psz_header, bool b_quick,
sout_instance_t *p_sout ) input_ressource_t *p_ressource )
{ {
static const char input_name[] = "input"; static const char input_name[] = "input";
input_thread_t *p_input = NULL; /* thread descriptor */ input_thread_t *p_input = NULL; /* thread descriptor */
...@@ -214,6 +214,9 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, ...@@ -214,6 +214,9 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
p_input->p->slave = NULL; p_input->p->slave = NULL;
/* */ /* */
if( p_ressource )
p_input->p->p_ressource = p_ressource;
else
p_input->p->p_ressource = input_ressource_New(); p_input->p->p_ressource = input_ressource_New();
input_ressource_SetInput( p_input->p->p_ressource, p_input ); input_ressource_SetInput( p_input->p->p_ressource, p_input );
...@@ -298,9 +301,6 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, ...@@ -298,9 +301,6 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
p_input->i_flags |= OBJECT_FLAGS_QUIET | OBJECT_FLAGS_NOINTERACT; p_input->i_flags |= OBJECT_FLAGS_QUIET | OBJECT_FLAGS_NOINTERACT;
/* */ /* */
if( p_sout )
input_ressource_RequestSout( p_input->p->p_ressource, p_sout, NULL );
memset( &p_input->p->counters, 0, sizeof( p_input->p->counters ) ); memset( &p_input->p->counters, 0, sizeof( p_input->p->counters ) );
vlc_mutex_init( &p_input->p->counters.counters_lock ); vlc_mutex_init( &p_input->p->counters.counters_lock );
...@@ -356,11 +356,11 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent, ...@@ -356,11 +356,11 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
/* */ /* */
input_thread_t *__input_CreateThreadExtended( vlc_object_t *p_parent, input_thread_t *__input_CreateThreadExtended( vlc_object_t *p_parent,
input_item_t *p_item, input_item_t *p_item,
const char *psz_log, sout_instance_t *p_sout ) const char *psz_log, input_ressource_t *p_ressource )
{ {
input_thread_t *p_input; input_thread_t *p_input;
p_input = Create( p_parent, p_item, psz_log, false, p_sout ); p_input = Create( p_parent, p_item, psz_log, false, p_ressource );
if( !p_input ) if( !p_input )
return NULL; return NULL;
......
...@@ -53,16 +53,23 @@ typedef struct input_ressource_t input_ressource_t; ...@@ -53,16 +53,23 @@ typedef struct input_ressource_t input_ressource_t;
void input_ressource_Delete( input_ressource_t * ); void input_ressource_Delete( input_ressource_t * );
/** /**
* This function return the current sout (if any) from the ressource * This function deletes the current sout in the ressources.
* and stop tracking it.
* *
* You are then responsible of its release. * It can only be called on detached ressources.
*/ */
sout_instance_t *input_ressource_ExtractSout( input_ressource_t *p_ressource ); void input_ressource_TerminateSout( input_ressource_t *p_ressource );
/**
* This function deletes the current vout in the ressources.
*
* It can only be called on detached ressources.
*/
void input_ressource_TerminateVout( input_ressource_t *p_ressource );
/* input.c */ /* input.c */
#define input_CreateThreadExtended(a,b,c,d) __input_CreateThreadExtended(VLC_OBJECT(a),b,c,d) #define input_CreateThreadExtended(a,b,c,d) __input_CreateThreadExtended(VLC_OBJECT(a),b,c,d)
input_thread_t *__input_CreateThreadExtended ( vlc_object_t *, input_item_t *, const char *, sout_instance_t * ); input_thread_t *__input_CreateThreadExtended ( vlc_object_t *, input_item_t *, const char *, input_ressource_t * );
/** /**
* This function detaches ressources from a dead input. * This function detaches ressources from a dead input.
......
...@@ -60,28 +60,20 @@ static void DestroySout( input_ressource_t *p_ressource ) ...@@ -60,28 +60,20 @@ static void DestroySout( input_ressource_t *p_ressource )
sout_DeleteInstance( p_ressource->p_sout ); sout_DeleteInstance( p_ressource->p_sout );
p_ressource->p_sout = NULL; p_ressource->p_sout = NULL;
} }
static sout_instance_t *ExtractSout( input_ressource_t *p_ressource )
{
sout_instance_t *p_sout = p_ressource->p_sout;
p_ressource->p_sout = NULL;
return p_sout;
}
static sout_instance_t *RequestSout( input_ressource_t *p_ressource, static sout_instance_t *RequestSout( input_ressource_t *p_ressource,
sout_instance_t *p_sout, const char *psz_sout ) sout_instance_t *p_sout, const char *psz_sout )
{ {
assert( p_ressource->p_input );
assert( !p_sout || ( !p_ressource->p_sout && !psz_sout ) );
if( !p_sout && !psz_sout ) if( !p_sout && !psz_sout )
{ {
if( p_ressource->p_sout ) if( p_ressource->p_sout )
msg_Dbg( p_ressource->p_input, "destroying useless sout" ); msg_Dbg( p_ressource->p_sout, "destroying useless sout" );
DestroySout( p_ressource ); DestroySout( p_ressource );
return NULL; return NULL;
} }
assert( p_ressource->p_input );
assert( !p_sout || ( !p_ressource->p_sout && !psz_sout ) );
/* Check the validity of the sout */ /* Check the validity of the sout */
if( p_ressource->p_sout && if( p_ressource->p_sout &&
strcmp( p_ressource->p_sout->psz_sout, psz_sout ) ) strcmp( p_ressource->p_sout->psz_sout, psz_sout ) )
...@@ -104,7 +96,11 @@ static sout_instance_t *RequestSout( input_ressource_t *p_ressource, ...@@ -104,7 +96,11 @@ static sout_instance_t *RequestSout( input_ressource_t *p_ressource,
/* Create a new one */ /* Create a new one */
p_ressource->p_sout = sout_NewInstance( p_ressource->p_input, psz_sout ); p_ressource->p_sout = sout_NewInstance( p_ressource->p_input, psz_sout );
} }
return ExtractSout( p_ressource );
p_sout = p_ressource->p_sout;
p_ressource->p_sout = NULL;
return p_sout;
} }
else else
{ {
...@@ -128,25 +124,24 @@ static void DestroyVout( input_ressource_t *p_ressource ) ...@@ -128,25 +124,24 @@ static void DestroyVout( input_ressource_t *p_ressource )
static vout_thread_t *RequestVout( input_ressource_t *p_ressource, static vout_thread_t *RequestVout( input_ressource_t *p_ressource,
vout_thread_t *p_vout, video_format_t *p_fmt ) vout_thread_t *p_vout, video_format_t *p_fmt )
{ {
assert( p_ressource->p_input );
if( !p_vout && !p_fmt ) if( !p_vout && !p_fmt )
{ {
if( p_ressource->p_vout_free ) if( p_ressource->p_vout_free )
{ {
msg_Err( p_ressource->p_input, "destroying useless vout" ); msg_Dbg( p_ressource->p_vout_free, "destroying useless vout" );
vout_CloseAndRelease( p_ressource->p_vout_free ); vout_CloseAndRelease( p_ressource->p_vout_free );
p_ressource->p_vout_free = NULL; p_ressource->p_vout_free = NULL;
} }
return NULL; return NULL;
} }
assert( p_ressource->p_input );
if( p_fmt ) if( p_fmt )
{ {
/* */ /* */
if( !p_vout && p_ressource->p_vout_free ) if( !p_vout && p_ressource->p_vout_free )
{ {
msg_Err( p_ressource->p_input, "trying to reuse free vout" ); msg_Dbg( p_ressource->p_input, "trying to reuse free vout" );
p_vout = p_ressource->p_vout_free; p_vout = p_ressource->p_vout_free;
p_ressource->p_vout_free = NULL; p_ressource->p_vout_free = NULL;
...@@ -171,12 +166,12 @@ static vout_thread_t *RequestVout( input_ressource_t *p_ressource, ...@@ -171,12 +166,12 @@ static vout_thread_t *RequestVout( input_ressource_t *p_ressource,
TAB_REMOVE( p_ressource->i_vout, p_ressource->pp_vout, p_vout ); TAB_REMOVE( p_ressource->i_vout, p_ressource->pp_vout, p_vout );
if( p_ressource->p_vout_free ) if( p_ressource->p_vout_free )
{ {
msg_Err( p_ressource->p_input, "detroying vout (already one saved)" ); msg_Dbg( p_ressource->p_input, "detroying vout (already one saved)" );
vout_CloseAndRelease( p_vout ); vout_CloseAndRelease( p_vout );
} }
else else
{ {
msg_Err( p_ressource->p_input, "saving a free vout" ); msg_Dbg( p_ressource->p_input, "saving a free vout" );
p_ressource->p_vout_free = p_vout; p_ressource->p_vout_free = p_vout;
} }
return NULL; return NULL;
...@@ -208,7 +203,7 @@ static aout_instance_t *RequestAout( input_ressource_t *p_ressource, aout_instan ...@@ -208,7 +203,7 @@ static aout_instance_t *RequestAout( input_ressource_t *p_ressource, aout_instan
if( p_aout ) if( p_aout )
{ {
msg_Err( p_ressource->p_input, "releasing aout" ); msg_Dbg( p_ressource->p_input, "releasing aout" );
vlc_object_release( p_aout ); vlc_object_release( p_aout );
return NULL; return NULL;
} }
...@@ -216,19 +211,19 @@ static aout_instance_t *RequestAout( input_ressource_t *p_ressource, aout_instan ...@@ -216,19 +211,19 @@ static aout_instance_t *RequestAout( input_ressource_t *p_ressource, aout_instan
{ {
if( !p_ressource->p_aout ) if( !p_ressource->p_aout )
{ {
msg_Err( p_ressource->p_input, "creating aout" ); msg_Dbg( p_ressource->p_input, "creating aout" );
p_ressource->p_aout = aout_New( p_ressource->p_input ); p_ressource->p_aout = aout_New( p_ressource->p_input );
} }
else else
{ {
msg_Err( p_ressource->p_input, "reusing aout" ); msg_Dbg( p_ressource->p_input, "reusing aout" );
vlc_object_attach( p_ressource->p_aout, p_ressource->p_input );
} }
if( !p_ressource->p_aout ) if( !p_ressource->p_aout )
return NULL; return NULL;
vlc_object_detach( p_ressource->p_aout );
vlc_object_attach( p_ressource->p_aout, p_ressource->p_input );
vlc_object_hold( p_ressource->p_aout ); vlc_object_hold( p_ressource->p_aout );
return p_ressource->p_aout; return p_ressource->p_aout;
} }
...@@ -295,6 +290,10 @@ vout_thread_t *input_ressource_HoldVout( input_ressource_t *p_ressource ) ...@@ -295,6 +290,10 @@ vout_thread_t *input_ressource_HoldVout( input_ressource_t *p_ressource )
return p_ret; return p_ret;
} }
void input_ressource_TerminateVout( input_ressource_t *p_ressource )
{
input_ressource_RequestVout( p_ressource, NULL, NULL );
}
/* */ /* */
aout_instance_t *input_ressource_RequestAout( input_ressource_t *p_ressource, aout_instance_t *p_aout ) aout_instance_t *input_ressource_RequestAout( input_ressource_t *p_ressource, aout_instance_t *p_aout )
...@@ -315,13 +314,8 @@ sout_instance_t *input_ressource_RequestSout( input_ressource_t *p_ressource, so ...@@ -315,13 +314,8 @@ sout_instance_t *input_ressource_RequestSout( input_ressource_t *p_ressource, so
return p_ret; return p_ret;
} }
sout_instance_t *input_ressource_ExtractSout( input_ressource_t *p_ressource ) void input_ressource_TerminateSout( input_ressource_t *p_ressource )
{ {
vlc_mutex_lock( &p_ressource->lock ); input_ressource_RequestSout( p_ressource, NULL, NULL );
sout_instance_t *p_ret = ExtractSout( p_ressource );
vlc_mutex_unlock( &p_ressource->lock );
return p_ret;
} }
...@@ -755,7 +755,7 @@ static vlm_media_instance_sys_t *vlm_MediaInstanceNew( vlm_t *p_vlm, const char ...@@ -755,7 +755,7 @@ static vlm_media_instance_sys_t *vlm_MediaInstanceNew( vlm_t *p_vlm, const char
p_instance->i_index = 0; p_instance->i_index = 0;
p_instance->b_sout_keep = false; p_instance->b_sout_keep = false;
p_instance->p_input = NULL; p_instance->p_input = NULL;
p_instance->p_sout = NULL; p_instance->p_input_ressource = NULL;
return p_instance; return p_instance;
} }
...@@ -774,8 +774,8 @@ static void vlm_MediaInstanceDelete( vlm_media_instance_sys_t *p_instance ) ...@@ -774,8 +774,8 @@ static void vlm_MediaInstanceDelete( vlm_media_instance_sys_t *p_instance )
vlc_object_release( p_input ); vlc_object_release( p_input );
} }
if( p_instance->p_sout ) if( p_instance->p_input_ressource )
sout_DeleteInstance( p_instance->p_sout ); input_ressource_Delete( p_instance->p_input_ressource );
vlc_gc_decref( p_instance->p_item ); vlc_gc_decref( p_instance->p_item );
free( p_instance->psz_name ); free( p_instance->psz_name );
...@@ -839,8 +839,6 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char * ...@@ -839,8 +839,6 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char *
input_thread_t *p_input = p_instance->p_input; input_thread_t *p_input = p_instance->p_input;
if( p_input ) if( p_input )
{ {
input_ressource_t *p_ressource;
if( p_instance->i_index == i_input_index && if( p_instance->i_index == i_input_index &&
!p_input->b_eof && !p_input->b_error ) !p_input->b_eof && !p_input->b_error )
{ {
...@@ -852,13 +850,13 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char * ...@@ -852,13 +850,13 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char *
input_StopThread( p_input ); input_StopThread( p_input );
vlc_thread_join( p_input ); vlc_thread_join( p_input );
p_ressource = input_DetachRessource( p_input ); p_instance->p_input_ressource = input_DetachRessource( p_input );
vlc_object_release( p_input ); vlc_object_release( p_input );
if( p_instance->b_sout_keep ) if( !p_instance->b_sout_keep )
p_instance->p_sout = input_ressource_ExtractSout( p_ressource ); input_ressource_TerminateSout( p_instance->p_input_ressource );
input_ressource_Delete( p_ressource ); input_ressource_TerminateVout( p_instance->p_input_ressource );
} }
/* Start new one */ /* Start new one */
...@@ -867,16 +865,15 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char * ...@@ -867,16 +865,15 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char *
if( asprintf( &psz_log, _("Media: %s"), p_media->cfg.psz_name ) != -1 ) if( asprintf( &psz_log, _("Media: %s"), p_media->cfg.psz_name ) != -1 )
{ {
p_instance->p_input = input_CreateThreadExtended( p_vlm, p_instance->p_item, psz_log, p_instance->p_sout ); p_instance->p_input = input_CreateThreadExtended( p_vlm, p_instance->p_item,
psz_log, p_instance->p_input_ressource );
p_instance->p_input_ressource = NULL;
if( !p_instance->p_input ) if( !p_instance->p_input )
{ {
TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance ); TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance );
vlm_MediaInstanceDelete( p_instance ); vlm_MediaInstanceDelete( p_instance );
} }
else
{
p_instance->p_sout = NULL;
}
free( psz_log ); free( psz_log );
} }
......
...@@ -43,7 +43,7 @@ typedef struct ...@@ -43,7 +43,7 @@ typedef struct
input_item_t *p_item; input_item_t *p_item;
input_thread_t *p_input; input_thread_t *p_input;
sout_instance_t *p_sout; input_ressource_t *p_input_ressource;
} vlm_media_instance_sys_t; } vlm_media_instance_sys_t;
......
...@@ -175,7 +175,7 @@ static void playlist_Destructor( vlc_object_t * p_this ) ...@@ -175,7 +175,7 @@ static void playlist_Destructor( vlc_object_t * p_this )
playlist_private_t *p_sys = pl_priv(p_playlist); playlist_private_t *p_sys = pl_priv(p_playlist);
assert( !p_sys->p_input ); assert( !p_sys->p_input );
assert( !p_sys->p_sout ); assert( !p_sys->p_input_ressource );
assert( !p_sys->p_preparser ); assert( !p_sys->p_preparser );
assert( !p_sys->p_fetcher ); assert( !p_sys->p_fetcher );
......
...@@ -46,7 +46,6 @@ typedef struct playlist_private_t ...@@ -46,7 +46,6 @@ typedef struct playlist_private_t
playlist_t public_data; playlist_t public_data;
playlist_preparser_t *p_preparser; /**< Preparser data */ playlist_preparser_t *p_preparser; /**< Preparser data */
playlist_fetcher_t *p_fetcher; /**< Meta and art fetcher data */ playlist_fetcher_t *p_fetcher; /**< Meta and art fetcher data */
sout_instance_t *p_sout; /**< Kept sout instance */
playlist_item_array_t items_to_delete; /**< Array of items and nodes to playlist_item_array_t items_to_delete; /**< Array of items and nodes to
delete... At the very end. This sucks. */ delete... At the very end. This sucks. */
...@@ -60,6 +59,7 @@ typedef struct playlist_private_t ...@@ -60,6 +59,7 @@ typedef struct playlist_private_t
int i_sds; /**< Number of service discovery modules */ int i_sds; /**< Number of service discovery modules */
input_thread_t * p_input; /**< the input thread associated input_thread_t * p_input; /**< the input thread associated
* with the current item */ * with the current item */
input_ressource_t * p_input_ressource; /**< input ressources */
struct { struct {
/* Current status. These fields are readonly, only the playlist /* Current status. These fields are readonly, only the playlist
* main loop can touch it*/ * main loop can touch it*/
......
...@@ -98,10 +98,10 @@ void playlist_Deactivate( playlist_t *p_playlist ) ...@@ -98,10 +98,10 @@ void playlist_Deactivate( playlist_t *p_playlist )
if( p_fetcher ) if( p_fetcher )
playlist_fetcher_Delete( p_fetcher ); playlist_fetcher_Delete( p_fetcher );
/* close the remaining sout-keep */ /* release input ressources */
if( p_sys->p_sout ) if( p_sys->p_input_ressource )
sout_DeleteInstance( p_sys->p_sout ); input_ressource_Delete( p_sys->p_input_ressource );
p_sys->p_sout = NULL; p_sys->p_input_ressource = NULL;
/* */ /* */
playlist_MLDump( p_playlist ); playlist_MLDump( p_playlist );
...@@ -263,7 +263,7 @@ static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item ) ...@@ -263,7 +263,7 @@ static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
assert( p_sys->p_input == NULL ); assert( p_sys->p_input == NULL );
input_thread_t *p_input_thread = input_thread_t *p_input_thread =
input_CreateThreadExtended( p_playlist, p_input, NULL, p_sys->p_sout ); input_CreateThreadExtended( p_playlist, p_input, NULL, p_sys->p_input_ressource );
if( p_input_thread ) if( p_input_thread )
{ {
...@@ -272,7 +272,7 @@ static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item ) ...@@ -272,7 +272,7 @@ static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
var_AddCallback( p_input_thread, "intf-event", InputEvent, p_playlist ); var_AddCallback( p_input_thread, "intf-event", InputEvent, p_playlist );
} }
p_sys->p_sout = NULL; p_sys->p_input_ressource = NULL;
char *psz_uri = input_item_GetURI( p_item->p_input ); char *psz_uri = input_item_GetURI( p_item->p_input );
if( psz_uri && ( !strncmp( psz_uri, "directory:", 10 ) || if( psz_uri && ( !strncmp( psz_uri, "directory:", 10 ) ||
...@@ -492,13 +492,11 @@ static int LoopInput( playlist_t *p_playlist ) ...@@ -492,13 +492,11 @@ static int LoopInput( playlist_t *p_playlist )
{ {
PL_DEBUG( "dead input" ); PL_DEBUG( "dead input" );
assert( p_sys->p_sout == NULL ); assert( p_sys->p_input_ressource == NULL );
input_ressource_t *p_ressource = input_DetachRessource( p_input ); p_sys->p_input_ressource = input_DetachRessource( p_input );
if( !var_CreateGetBool( p_input, "sout-keep" ) )
if( var_CreateGetBool( p_input, "sout-keep" ) ) input_ressource_TerminateSout( p_sys->p_input_ressource );
p_sys->p_sout = input_ressource_ExtractSout( p_ressource );
input_ressource_Delete( p_ressource );
/* The DelCallback must be issued without playlist lock /* The DelCallback must be issued without playlist lock
* It is not a problem as we return VLC_EGENERIC */ * It is not a problem as we return VLC_EGENERIC */
...@@ -546,6 +544,9 @@ static void LoopRequest( playlist_t *p_playlist ) ...@@ -546,6 +544,9 @@ static void LoopRequest( playlist_t *p_playlist )
{ {
p_sys->status.i_status = PLAYLIST_STOPPED; p_sys->status.i_status = PLAYLIST_STOPPED;
if( p_sys->p_input_ressource )
input_ressource_TerminateVout( p_sys->p_input_ressource );
if( vlc_object_alive( p_playlist ) ) if( vlc_object_alive( p_playlist ) )
vlc_object_wait( p_playlist ); vlc_object_wait( p_playlist );
return; return;
......
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