vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Sun Jun 28 18:08:08 2015 +0300| [db17d8a433dbf5d4444b52bb80d7348f2a539fe5] | committer: Rémi Denis-Courmont
input: replace input_Preparse() with input_CreatePreparse() For simplicity, the preparser should run in a dedicated input thread, so that it can be stopped (refs #14571). > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=db17d8a433dbf5d4444b52bb80d7348f2a539fe5 --- src/input/input.c | 104 ++++++++++++++++++++++++++----------------- src/input/input_interface.h | 2 +- src/playlist/preparser.c | 4 +- 3 files changed, 66 insertions(+), 44 deletions(-) diff --git a/src/input/input.c b/src/input/input.c index 1260f2c..665a491 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -59,6 +59,7 @@ * Local prototypes *****************************************************************************/ static void *Run ( void * ); +static void *Preparse ( void * ); static input_thread_t * Create ( vlc_object_t *, input_item_t *, const char *, bool, input_resource_t * ); @@ -154,43 +155,6 @@ int input_Read( vlc_object_t *p_parent, input_item_t *p_item ) } /** - * Initialize an input and initialize it to preparse the item - * This function is blocking. It will only accept parsing regular files. - * - * \param p_parent a vlc_object_t - * \param p_item an input item - * \return VLC_SUCCESS or an error - */ -int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item ) -{ - input_thread_t *p_input; - - /* Allocate descriptor */ - p_input = Create( p_parent, p_item, NULL, true, NULL ); - if( !p_input ) - return VLC_EGENERIC; - - if( !Init( p_input ) ) { - /* if the demux is a playlist, call Mainloop that will call - * demux_Demux in order to fetch sub items */ - bool b_is_playlist = false; - - if ( input_item_ShouldPreparseSubItems( p_item ) - && demux_Control( p_input->p->input.p_demux, - DEMUX_IS_PLAYLIST, - &b_is_playlist ) ) - b_is_playlist = false; - if( b_is_playlist ) - MainLoop( p_input, false ); - End( p_input ); - } - - vlc_object_release( p_input ); - - return VLC_SUCCESS; -} - -/** * Start a input_thread_t created by input_Create. * * You must not start an already running input_thread_t. @@ -213,6 +177,36 @@ int input_Start( input_thread_t *p_input ) } /** + * Initialize an input and initialize it to preparse the item. + * + * Preparsing is performed asynchronously; use input_Stop() to abort it, or + * wait until the input goes dead on its own. Use input_Close() to wait for + * completion and clean up. + * + * \param p_parent a vlc_object_t + * \param p_item an input item + * \return an input thread or NULL on error + */ +input_thread_t *input_CreatePreparse( vlc_object_t *p_parent, + input_item_t *p_item ) +{ + input_thread_t *p_input = Create( p_parent, p_item, NULL, true, NULL ); + if( unlikely(p_input == NULL) ) + return NULL; + + p_input->p->is_running = !vlc_clone( &p_input->p->thread, Preparse, + p_input, VLC_THREAD_PRIORITY_INPUT ); + if( !p_input->p->is_running ) + { + input_ChangeState( p_input, ERROR_S ); + msg_Err( p_input, "cannot create input thread" ); + input_Close( p_input ); + p_input = NULL; + } + return p_input; +} + +/** * Request a running input thread to stop and die * * \param p_input the input thread to stop @@ -503,11 +497,13 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, return p_input; } -/***************************************************************************** - * Run: main thread loop - * This is the "normal" thread that spawns the input processing chain, - * reads the stream, cleans up and waits - *****************************************************************************/ +/** + * Normal input thread entry point. + * + * This is the "normal" thread. It spawns the input stream and elementary + * stream output, proceeds until the end of the stream is reached, then + * cleans up. + */ static void *Run( void *obj ) { input_thread_t *p_input = (input_thread_t *)obj; @@ -522,7 +518,31 @@ static void *Run( void *obj ) } input_SendEventDead( p_input ); + vlc_restorecancel( canc ); + return NULL; +} +static void *Preparse( void *obj ) +{ + input_thread_t *p_input = (input_thread_t *)obj; + const int canc = vlc_savecancel(); + + if( !Init( p_input ) ) + { /* If the demux is a playlist, call Mainloop(). It will call + * demux_Demux() in order to fetch the sub-items. */ + bool b_is_playlist = false; + + if ( input_item_ShouldPreparseSubItems( p_input->p->p_item ) + && demux_Control( p_input->p->input.p_demux, + DEMUX_IS_PLAYLIST, + &b_is_playlist ) ) + b_is_playlist = false; + if( b_is_playlist ) + MainLoop( p_input, false ); + End( p_input ); + } + + input_SendEventDead( p_input ); vlc_restorecancel( canc ); return NULL; } diff --git a/src/input/input_interface.h b/src/input/input_interface.h index e7b634a..43b2974 100644 --- a/src/input/input_interface.h +++ b/src/input/input_interface.h @@ -37,7 +37,7 @@ void input_item_SetArtFetched( input_item_t *p_i, bool b_art_fetched ); void input_item_SetEpg( input_item_t *p_item, const vlc_epg_t *p_epg ); void input_item_SetEpgOffline( input_item_t * ); -int input_Preparse( vlc_object_t *, input_item_t * ); +input_thread_t *input_CreatePreparse( vlc_object_t *, input_item_t * ); /* misc/stats.c * FIXME it should NOT be defined here or not coded in misc/stats.c */ diff --git a/src/playlist/preparser.c b/src/playlist/preparser.c index f1c1d1f..cf48f7e 100644 --- a/src/playlist/preparser.c +++ b/src/playlist/preparser.c @@ -170,7 +170,9 @@ static void Preparse( vlc_object_t *obj, input_item_t *p_item, /* Do not preparse if it is already done (like by playing it) */ if( !input_item_IsPreparsed( p_item ) ) { - input_Preparse( obj, p_item ); + input_thread_t *input = input_CreatePreparse( obj, p_item ); + if( input != NULL ) + input_Close( input ); input_item_SetPreparsed( p_item, true ); var_SetAddress( obj, "item-change", p_item ); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
