vlc | branch: master | Thomas Guillem <[email protected]> | Sun Jun 5 10:41:24 2016 +0200| [f93621c6d518f5bd213fee409dd42d4b0780e317] | committer: Thomas Guillem
preparser: add a timeout in playlist_preparser_Push By default, the timeout is 5 seconds, see "preparse_timeout" option. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f93621c6d518f5bd213fee409dd42d4b0780e317 --- include/vlc_input_item.h | 1 + src/libvlc-module.c | 7 +++++++ src/libvlc.c | 2 +- src/playlist/item.c | 2 +- src/playlist/preparser.c | 28 ++++++++++++++++++++++++---- src/playlist/preparser.h | 6 +++++- 6 files changed, 39 insertions(+), 7 deletions(-) diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h index 85ad72c..f16491d 100644 --- a/include/vlc_input_item.h +++ b/include/vlc_input_item.h @@ -395,6 +395,7 @@ enum input_item_preparse_status { ITEM_PREPARSE_SKIPPED, ITEM_PREPARSE_FAILED, + ITEM_PREPARSE_TIMEOUT, ITEM_PREPARSE_DONE }; diff --git a/src/libvlc-module.c b/src/libvlc-module.c index 9ba4980..0fee435 100644 --- a/src/libvlc-module.c +++ b/src/libvlc-module.c @@ -1103,6 +1103,10 @@ static const char *const ppsz_prefres[] = { "Automatically preparse files added to the playlist " \ "(to retrieve some metadata)." ) +#define PREPARSE_TIMEOUT_TEXT N_( "Preparsing timeout" ) +#define PREPARSE_TIMEOUT_LONGTEXT N_( \ + "Maximum time allowed to preparse a file" ) + #define METADATA_NETWORK_TEXT N_( "Allow metadata network access" ) #define SD_TEXT N_( "Services discovery modules") @@ -2032,6 +2036,9 @@ vlc_module_begin () add_bool( "auto-preparse", true, PREPARSE_TEXT, PREPARSE_LONGTEXT, false ) + add_integer( "preparse-timeout", 5000, PREPARSE_TIMEOUT_TEXT, + PREPARSE_TIMEOUT_LONGTEXT, false ) + add_obsolete_integer( "album-art" ) add_bool( "metadata-network-access", false, METADATA_NETWORK_TEXT, METADATA_NETWORK_TEXT, false ) diff --git a/src/libvlc.c b/src/libvlc.c index 694e3bb..316f481 100644 --- a/src/libvlc.c +++ b/src/libvlc.c @@ -627,7 +627,7 @@ int libvlc_MetaRequest(libvlc_int_t *libvlc, input_item_t *item, if( i_options & META_REQUEST_OPTION_DO_INTERACT ) item->b_preparse_interact = true; vlc_mutex_unlock( &item->lock ); - playlist_preparser_Push(priv->parser, item, i_options, NULL); + playlist_preparser_Push(priv->parser, item, i_options, -1, NULL); return VLC_SUCCESS; } diff --git a/src/playlist/item.c b/src/playlist/item.c index 00bd046..7d3c218 100644 --- a/src/playlist/item.c +++ b/src/playlist/item.c @@ -781,7 +781,7 @@ static void GoAndPreparse( playlist_t *p_playlist, int i_mode, char *psz_album = input_item_GetAlbum( p_item->p_input ); if( sys->p_preparser != NULL && !input_item_IsPreparsed( p_item->p_input ) && (EMPTY_STR(psz_artist) || EMPTY_STR(psz_album)) ) - playlist_preparser_Push( sys->p_preparser, p_item->p_input, 0, NULL ); + playlist_preparser_Push( sys->p_preparser, p_item->p_input, 0, -1, NULL ); free( psz_artist ); free( psz_album ); } diff --git a/src/playlist/preparser.c b/src/playlist/preparser.c index 52742d7..c820d6a 100644 --- a/src/playlist/preparser.c +++ b/src/playlist/preparser.c @@ -43,12 +43,14 @@ struct preparser_entry_t input_item_t *p_item; input_item_meta_request_option_t i_options; void *id; + mtime_t timeout; }; struct playlist_preparser_t { vlc_object_t *object; playlist_fetcher_t *p_fetcher; + mtime_t default_timeout; input_thread_t *input; void *input_id; @@ -77,6 +79,7 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent ) p_preparser->input_id = NULL; p_preparser->input_done = false; p_preparser->object = parent; + p_preparser->default_timeout = var_InheritInteger( parent, "preparse-timeout" ); p_preparser->p_fetcher = playlist_fetcher_New( parent ); if( unlikely(p_preparser->p_fetcher == NULL) ) msg_Err( parent, "cannot create fetcher" ); @@ -93,7 +96,7 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent ) void playlist_preparser_Push( playlist_preparser_t *p_preparser, input_item_t *p_item, input_item_meta_request_option_t i_options, - void *id ) + int timeout, void *id ) { preparser_entry_t *p_entry = malloc( sizeof(preparser_entry_t) ); @@ -102,6 +105,7 @@ void playlist_preparser_Push( playlist_preparser_t *p_preparser, input_item_t *p p_entry->p_item = p_item; p_entry->i_options = i_options; p_entry->id = id; + p_entry->timeout = (timeout < 0 ? p_preparser->default_timeout : timeout) * 1000; vlc_gc_incref( p_entry->p_item ); vlc_mutex_lock( &p_preparser->lock ); @@ -227,6 +231,7 @@ static void Preparse( playlist_preparser_t *preparser, /* Do not preparse if it is already done (like by playing it) */ if( b_preparse && !input_item_IsPreparsed( p_item ) ) { + int status; preparser->input = input_CreatePreparser( preparser->object, p_item ); if( preparser->input == NULL ) { @@ -240,9 +245,24 @@ static void Preparse( playlist_preparser_t *preparser, preparser ); if( input_Start( preparser->input ) == VLC_SUCCESS ) { - while( !preparser->input_done ) - vlc_cond_wait( &preparser->thread_wait, &preparser->lock ); + if( p_entry->timeout > 0 ) + { + mtime_t deadline = mdate() + p_entry->timeout; + int ret = 0; + while( !preparser->input_done && ret == 0 ) + ret = vlc_cond_timedwait( &preparser->thread_wait, + &preparser->lock, deadline ); + status = ret == 0 ? ITEM_PREPARSE_DONE : ITEM_PREPARSE_TIMEOUT; + } + else + { + while( !preparser->input_done ) + vlc_cond_wait( &preparser->thread_wait, &preparser->lock ); + status = ITEM_PREPARSE_DONE; + } } + else + status = ITEM_PREPARSE_FAILED; var_DelCallback( preparser->input, "intf-event", InputEvent, preparser ); @@ -252,7 +272,7 @@ static void Preparse( playlist_preparser_t *preparser, var_SetAddress( preparser->object, "item-change", p_item ); input_item_SetPreparsed( p_item, true ); - input_item_SignalPreparseEnded( p_item, ITEM_PREPARSE_DONE ); + input_item_SignalPreparseEnded( p_item, status ); } else if (!b_preparse) input_item_SignalPreparseEnded( p_item, ITEM_PREPARSE_SKIPPED ); diff --git a/src/playlist/preparser.h b/src/playlist/preparser.h index fb2b105..d1cd69e 100644 --- a/src/playlist/preparser.h +++ b/src/playlist/preparser.h @@ -48,11 +48,15 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t * ); * Listen to vlc_InputItemPreparseEnded event to get notified when item is * preparsed. * + * @param timeout maximum time allowed to preparse the item. If -1, the default + * "preparse-timeout" option will be used as a timeout. If 0, it will wait + * indefinitely. If > 0, the timeout will be used (in milliseconds). * @param id unique id provided by the caller. This is can be used to cancel * the request with playlist_preparser_Cancel() */ void playlist_preparser_Push( playlist_preparser_t *, input_item_t *, - input_item_meta_request_option_t, void *id ); + input_item_meta_request_option_t, + int timeout, void *id ); void playlist_preparser_fetcher_Push( playlist_preparser_t *, input_item_t *, input_item_meta_request_option_t ); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
