From: Laurent Aimar Date: Tue, 25 May 2010 18:31:13 +0000 (+0200) Subject: Made object created by input_resource attached to a high level object. X-Git-Tag: 1.2.0-pre1~6504 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=211f72ff01d9f6fcfefc6801503b01b3a4e935a4;p=vlc Made object created by input_resource attached to a high level object. The high level object must at least live as long as the input_resource, I used playlist, vlm or libvlc_media_player. It avoids invalid reparent of the vout, aout and sout on input changes. It breaks support for per input options used for creating vout, aout and sout (:sout= is not impacted). I will fix the vout case. It breaks invalid usages of vlc_object_find(INPUT, PARENT) used at least by : - the sout modules describe and display. - the sout statistics. - the vout splitter change - the snapshot vout display. I will fix the vout related ones. --- diff --git a/include/vlc_input.h b/include/vlc_input.h index ac90b1092e..2650e8ea58 100644 --- a/include/vlc_input.h +++ b/include/vlc_input.h @@ -655,16 +655,15 @@ VLC_EXPORT( void, input_SplitMRL, ( const char **ppsz_access, const char **ppsz_ VLC_EXPORT( char *, input_CreateFilename, ( vlc_object_t *, const char *psz_path, const char *psz_prefix, const char *psz_extension ) ); /** - * This function detaches resources from a dead input. + * It creates an empty input resource handler. * - * It MUST be called on a dead input (p_input->b_dead true) otherwise - * it will assert. - * It does not support concurrent calls. + * The given object MUST stay alive as long as the input_resource_t is + * not deleted. */ -VLC_EXPORT(input_resource_t *, input_DetachResource, ( input_thread_t * ) ); +VLC_EXPORT( input_resource_t *, input_resource_New, ( vlc_object_t * ) ); /** - * This function releases the input resource. + * It deletes an input resource. */ VLC_EXPORT(void, input_resource_Delete, ( input_resource_t * ) ); diff --git a/src/control/media_player.c b/src/control/media_player.c index cac7a2052b..b70e167a24 100644 --- a/src/control/media_player.c +++ b/src/control/media_player.c @@ -127,10 +127,6 @@ static void release_input_thread( libvlc_media_player_t *p_mi, bool b_input_abor assert( p_input_thread->b_dead ); - /* Store the input resource for future use. */ - assert( p_mi->input.p_resource == NULL ); - p_mi->input.p_resource = input_DetachResource( p_input_thread ); - p_mi->input.p_thread = NULL; vlc_object_release( p_input_thread ); } @@ -656,6 +652,8 @@ int libvlc_media_player_play( libvlc_media_player_t *p_mi ) return -1; } + if( !p_mi->input.p_resource ) + p_mi->input.p_resource = input_resource_New( VLC_OBJECT( p_mi ) ); p_input_thread = input_Create( p_mi, p_mi->p_md->p_input_item, NULL, p_mi->input.p_resource ); unlock(p_mi); @@ -666,8 +664,6 @@ int libvlc_media_player_play( libvlc_media_player_t *p_mi ) return -1; } - p_mi->input.p_resource = NULL; - var_AddCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi ); var_AddCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi ); var_AddCallback( p_input_thread, "intf-event", input_event_changed, p_mi ); diff --git a/src/input/input.c b/src/input/input.c index 5c0181f5f5..2947634b72 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -244,18 +244,6 @@ void input_Stop( input_thread_t *p_input, bool b_abort ) input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL ); } -input_resource_t *input_DetachResource( input_thread_t *p_input ) -{ - assert( p_input->b_dead ); - - input_resource_SetInput( p_input->p->p_resource, NULL ); - - input_resource_t *p_resource = input_resource_Detach( p_input->p->p_resource ); - p_input->p->p_sout = NULL; - - return p_resource; -} - /** * Get the item from an input thread * FIXME it does not increase ref count of the item. @@ -396,9 +384,15 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, /* */ if( p_resource ) + { + p_input->p->p_resource_private = NULL; p_input->p->p_resource = p_resource; + } else - p_input->p->p_resource = input_resource_New(); + { + p_input->p->p_resource_private = input_resource_New( VLC_OBJECT( p_input ) ); + p_input->p->p_resource = p_input->p->p_resource_private; + } input_resource_SetInput( p_input->p->p_resource, p_input ); /* Init control buffer */ @@ -506,8 +500,8 @@ static void Destructor( input_thread_t * p_input ) if( p_input->p->p_es_out_display ) es_out_Delete( p_input->p->p_es_out_display ); - if( p_input->p->p_resource ) - input_resource_Delete( p_input->p->p_resource ); + if( p_input->p->p_resource_private ) + input_resource_Delete( p_input->p->p_resource_private ); vlc_gc_decref( p_input->p->p_item ); @@ -1304,6 +1298,8 @@ error: input_resource_RequestSout( p_input->p->p_resource, p_input->p->p_sout, NULL ); input_resource_SetInput( p_input->p->p_resource, NULL ); + if( p_input->p->p_resource_private ) + input_resource_Terminate( p_input->p->p_resource_private ); } if( !p_input->b_preparsing && libvlc_stats( p_input ) ) @@ -1423,6 +1419,8 @@ static void End( input_thread_t * p_input ) input_resource_RequestSout( p_input->p->p_resource, p_input->p->p_sout, NULL ); input_resource_SetInput( p_input->p->p_resource, NULL ); + if( p_input->p->p_resource_private ) + input_resource_Terminate( p_input->p->p_resource_private ); } /***************************************************************************** diff --git a/src/input/input_internal.h b/src/input/input_internal.h index 6549130958..7cd39f75ba 100644 --- a/src/input/input_internal.h +++ b/src/input/input_internal.h @@ -137,6 +137,7 @@ struct input_thread_private_t /* Resources */ input_resource_t *p_resource; + input_resource_t *p_resource_private; /* Stats counters */ struct { diff --git a/src/input/resource.c b/src/input/resource.c index b357cff182..677b50e163 100644 --- a/src/input/resource.c +++ b/src/input/resource.c @@ -44,6 +44,8 @@ struct input_resource_t { + vlc_object_t *p_parent; + /* This lock is used to serialize request and protect * our variables */ vlc_mutex_t lock; @@ -79,14 +81,6 @@ static void DestroySout( input_resource_t *p_resource ) p_resource->p_sout = NULL; } -static sout_instance_t *DetachSout( input_resource_t *p_resource ) -{ - sout_instance_t *p_sout = p_resource->p_sout; - p_resource->p_sout = NULL; - - return p_sout; -} - static sout_instance_t *RequestSout( input_resource_t *p_resource, sout_instance_t *p_sout, const char *psz_sout ) { @@ -106,7 +100,7 @@ static sout_instance_t *RequestSout( input_resource_t *p_resource, if( p_resource->p_sout && strcmp( p_resource->p_sout->psz_sout, psz_sout ) ) { - msg_Dbg( p_resource->p_input, "destroying unusable sout" ); + msg_Dbg( p_resource->p_parent, "destroying unusable sout" ); DestroySout( p_resource ); } @@ -115,14 +109,13 @@ static sout_instance_t *RequestSout( input_resource_t *p_resource, if( p_resource->p_sout ) { /* Reuse it */ - msg_Dbg( p_resource->p_input, "reusing sout" ); - msg_Dbg( p_resource->p_input, "you probably want to use gather stream_out" ); - vlc_object_attach( p_resource->p_sout, p_resource->p_input ); + msg_Dbg( p_resource->p_parent, "reusing sout" ); + msg_Dbg( p_resource->p_parent, "you probably want to use gather stream_out" ); } else { /* Create a new one */ - p_resource->p_sout = sout_NewInstance( p_resource->p_input, psz_sout ); + p_resource->p_sout = sout_NewInstance( p_resource->p_parent, psz_sout ); } p_sout = p_resource->p_sout; @@ -132,9 +125,7 @@ static sout_instance_t *RequestSout( input_resource_t *p_resource, } else { - vlc_object_detach( p_sout ); p_resource->p_sout = p_sout; - return NULL; } #else @@ -152,15 +143,6 @@ static void DestroyVout( input_resource_t *p_resource ) p_resource->p_vout_free = NULL; } -static vout_thread_t *DetachVout( input_resource_t *p_resource ) -{ - vlc_assert_locked( &p_resource->lock ); - assert( p_resource->i_vout == 0 ); - vout_thread_t *p_vout = p_resource->p_vout_free; - p_resource->p_vout_free = NULL; - - return p_vout; -} static void DisplayVoutTitle( input_resource_t *p_resource, vout_thread_t *p_vout ) @@ -228,7 +210,7 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, /* */ if( !p_vout && p_resource->p_vout_free ) { - msg_Dbg( p_resource->p_input, "trying to reuse free vout" ); + msg_Dbg( p_resource->p_parent, "trying to reuse free vout" ); p_vout = p_resource->p_vout_free; p_resource->p_vout_free = NULL; @@ -250,7 +232,7 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, .fmt = p_fmt, .dpb_size = dpb_size, }; - p_vout = vout_Request( p_resource->p_input, &cfg ); + p_vout = vout_Request( p_resource->p_parent, &cfg ); if( !p_vout ) return NULL; @@ -274,12 +256,12 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, if( p_resource->p_vout_free || i_vout_active > 0 || !b_recycle ) { if( b_recycle ) - msg_Dbg( p_resource->p_input, "detroying vout (already one saved or active)" ); + msg_Dbg( p_resource->p_parent, "detroying vout (already one saved or active)" ); vout_CloseAndRelease( p_vout ); } else { - msg_Dbg( p_resource->p_input, "saving a free vout" ); + msg_Dbg( p_resource->p_parent, "saving a free vout" ); vout_Flush( p_vout, 1 ); vout_FlushSubpictureChannel( p_vout, -1 ); @@ -290,7 +272,7 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, .fmt = NULL, .dpb_size = 0, }; - p_resource->p_vout_free = vout_Request( p_resource->p_input, &cfg ); + p_resource->p_vout_free = vout_Request( p_resource->p_parent, &cfg ); } return NULL; } @@ -346,19 +328,6 @@ static void DestroyAout( input_resource_t *p_resource ) vlc_object_release( p_resource->p_aout ); p_resource->p_aout = NULL; } -static aout_instance_t *DetachAout( input_resource_t *p_resource ) -{ - vlc_assert_locked( &p_resource->lock ); - vlc_mutex_lock( &p_resource->lock_hold ); - - aout_instance_t *p_aout = p_resource->p_aout; - p_resource->p_aout = NULL; - - vlc_mutex_unlock( &p_resource->lock_hold ); - - return p_aout; -} - static aout_instance_t *RequestAout( input_resource_t *p_resource, aout_instance_t *p_aout ) { vlc_assert_locked( &p_resource->lock ); @@ -366,7 +335,7 @@ static aout_instance_t *RequestAout( input_resource_t *p_resource, aout_instance if( p_aout ) { - msg_Dbg( p_resource->p_input, "releasing aout" ); + msg_Dbg( p_resource->p_parent, "releasing aout" ); vlc_object_release( p_aout ); return NULL; } @@ -375,8 +344,8 @@ static aout_instance_t *RequestAout( input_resource_t *p_resource, aout_instance p_aout = p_resource->p_aout; if( !p_aout ) { - msg_Dbg( p_resource->p_input, "creating aout" ); - p_aout = aout_New( p_resource->p_input ); + msg_Dbg( p_resource->p_parent, "creating aout" ); + p_aout = aout_New( p_resource->p_parent ); vlc_mutex_lock( &p_resource->lock_hold ); p_resource->p_aout = p_aout; @@ -384,14 +353,11 @@ static aout_instance_t *RequestAout( input_resource_t *p_resource, aout_instance } else { - msg_Dbg( p_resource->p_input, "reusing aout" ); + msg_Dbg( p_resource->p_parent, "reusing aout" ); } if( !p_aout ) return NULL; - - vlc_object_detach( p_aout ); - vlc_object_attach( p_aout, p_resource->p_input ); vlc_object_hold( p_aout ); return p_aout; } @@ -408,14 +374,28 @@ static aout_instance_t *HoldAout( input_resource_t *p_resource ) return p_aout; } +static void TerminateAout( input_resource_t *p_resource ) +{ + vlc_mutex_lock( &p_resource->lock_hold ); + + aout_instance_t *p_aout = p_resource->p_aout; + p_resource->p_aout = NULL; + + vlc_mutex_unlock( &p_resource->lock_hold ); + + if( p_aout ) + vlc_object_release( p_aout ); +} + /* */ -input_resource_t *input_resource_New( void ) +input_resource_t *input_resource_New( vlc_object_t *p_parent ) { input_resource_t *p_resource = calloc( 1, sizeof(*p_resource) ); if( !p_resource ) return NULL; + p_resource->p_parent = p_parent; vlc_mutex_init( &p_resource->lock ); vlc_mutex_init( &p_resource->lock_hold ); return p_resource; @@ -437,17 +417,7 @@ void input_resource_SetInput( input_resource_t *p_resource, input_thread_t *p_in vlc_mutex_lock( &p_resource->lock ); if( p_resource->p_input && !p_input ) - { - if( p_resource->p_aout ) - vlc_object_detach( p_resource->p_aout ); - assert( p_resource->i_vout == 0 ); - if( p_resource->p_vout_free ) - vlc_object_detach( p_resource->p_vout_free ); - - if( p_resource->p_sout ) - vlc_object_detach( p_resource->p_sout ); - } /* */ p_resource->p_input = p_input; @@ -455,22 +425,6 @@ void input_resource_SetInput( input_resource_t *p_resource, input_thread_t *p_in vlc_mutex_unlock( &p_resource->lock ); } -input_resource_t *input_resource_Detach( input_resource_t *p_resource ) -{ - input_resource_t *p_ret = input_resource_New(); - if( !p_ret ) - return NULL; - - vlc_mutex_lock( &p_resource->lock ); - assert( !p_resource->p_input ); - p_ret->p_sout = DetachSout( p_resource ); - p_ret->p_vout_free = DetachVout( p_resource ); - p_ret->p_aout = DetachAout( p_resource ); - vlc_mutex_unlock( &p_resource->lock ); - - return p_ret; -} - vout_thread_t *input_resource_RequestVout( input_resource_t *p_resource, vout_thread_t *p_vout, video_format_t *p_fmt, unsigned dpb_size, @@ -520,6 +474,7 @@ aout_instance_t *input_resource_HoldAout( input_resource_t *p_resource ) { return HoldAout( p_resource ); } + /* */ sout_instance_t *input_resource_RequestSout( input_resource_t *p_resource, sout_instance_t *p_sout, const char *psz_sout ) { @@ -534,3 +489,14 @@ void input_resource_TerminateSout( input_resource_t *p_resource ) input_resource_RequestSout( p_resource, NULL, NULL ); } +void input_resource_Terminate( input_resource_t *p_resource ) +{ + input_resource_TerminateSout( p_resource ); + + vlc_mutex_lock( &p_resource->lock ); + TerminateAout( p_resource ); + vlc_mutex_unlock( &p_resource->lock ); + + input_resource_TerminateVout( p_resource ); +} + diff --git a/src/input/resource.h b/src/input/resource.h index 431c237e32..d8b45f2ed7 100644 --- a/src/input/resource.h +++ b/src/input/resource.h @@ -30,23 +30,11 @@ #include -/** - * This function creates an empty input_resource_t. - */ -input_resource_t *input_resource_New( void ); - /** * This function set the associated input. */ void input_resource_SetInput( input_resource_t *, input_thread_t * ); -/** - * This function return a input_resource_t with all resources detach from the - * given input_resource_t. - * It must not be associated to an input. - */ -input_resource_t *input_resource_Detach( input_resource_t * ); - /** * This function handles sout request. */ @@ -83,5 +71,10 @@ vout_thread_t *input_resource_HoldVout( input_resource_t * ); */ void input_resource_HoldVouts( input_resource_t *, vout_thread_t ***, size_t * ); +/** + * This function releases all resources (object). + */ +void input_resource_Terminate( input_resource_t * ); + #endif diff --git a/src/input/vlm.c b/src/input/vlm.c index facc49c001..ffcf57d02c 100644 --- a/src/input/vlm.c +++ b/src/input/vlm.c @@ -859,14 +859,9 @@ static void vlm_MediaInstanceDelete( vlm_t *p_vlm, int64_t id, vlm_media_instanc input_thread_t *p_input = p_instance->p_input; if( p_input ) { - input_resource_t *p_resource; - input_Stop( p_input, true ); vlc_thread_join( p_input ); - p_resource = input_DetachResource( p_input ); - input_resource_Delete( p_resource ); - var_DelCallback( p_instance->p_input, "intf-event", InputEvent, p_media ); vlc_object_release( p_input ); @@ -950,8 +945,6 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char * input_Stop( p_input, true ); vlc_thread_join( p_input ); - p_instance->p_input_resource = input_DetachResource( p_input ); - var_DelCallback( p_instance->p_input, "intf-event", InputEvent, p_media ); vlc_object_release( p_input ); @@ -971,6 +964,8 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char * vlc_object_t *p_parent = p_media->cfg.b_vod ? VLC_OBJECT(p_vlm->p_vod) : VLC_OBJECT(p_vlm->p_libvlc); + if( !p_instance->p_input_resource ) + p_instance->p_input_resource = input_resource_New( VLC_OBJECT( p_vlm ) ); p_instance->p_input = input_Create( p_parent, p_instance->p_item, psz_log, p_instance->p_input_resource ); if( p_instance->p_input ) @@ -983,7 +978,6 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char * p_instance->p_input = NULL; } } - p_instance->p_input_resource = NULL; if( !p_instance->p_input ) { diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 4c4d5b0247..6767a6b6c0 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -186,7 +186,6 @@ input_CreateFilename input_DecoderDecode input_DecoderDelete input_DecoderNew -input_DetachResource input_GetItem input_item_AddInfo input_item_AddOption @@ -219,6 +218,7 @@ input_item_SetName input_item_SetURI input_item_WriteMeta input_Read +input_resource_New input_resource_Delete input_SplitMRL input_Start diff --git a/src/playlist/thread.c b/src/playlist/thread.c index b0d9be2c4a..0ed215e7e7 100644 --- a/src/playlist/thread.c +++ b/src/playlist/thread.c @@ -230,6 +230,8 @@ static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item ) assert( p_sys->p_input == NULL ); + if( !p_sys->p_input_resource ) + p_sys->p_input_resource = input_resource_New( VLC_OBJECT( p_playlist ) ); input_thread_t *p_input_thread = input_Create( p_playlist, p_input, NULL, p_sys->p_input_resource ); if( p_input_thread ) { @@ -245,8 +247,6 @@ static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item ) } } - p_sys->p_input_resource = NULL; - char *psz_uri = input_item_GetURI( p_item->p_input ); if( psz_uri && ( !strncmp( psz_uri, "directory:", 10 ) || !strncmp( psz_uri, "vlc:", 4 ) ) ) @@ -465,10 +465,6 @@ static int LoopInput( playlist_t *p_playlist ) { PL_DEBUG( "dead input" ); - assert( p_sys->p_input_resource == NULL ); - - p_sys->p_input_resource = input_DetachResource( p_input ); - PL_UNLOCK; /* We can unlock as we return VLC_EGENERIC (no event will be lost) */ diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index ebf4c4d91a..0bf78c8d73 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -186,9 +186,6 @@ vout_thread_t *(vout_Request)(vlc_object_t *object, /* If a vout is provided, try reusing it */ if (vout) { - vlc_object_detach(vout); - vlc_object_attach(vout, object); - if (vout->p->input != cfg->input) { if (vout->p->input) spu_Attach(vout->p->p_spu, vout->p->input, false);