[vlc-devel] [PATCH 2/2] preparser: add an option to force preparsing
Rémi Denis-Courmont
remi at remlab.net
Thu Mar 19 18:23:05 CET 2015
Le jeudi 19 mars 2015, 18:06:29 Thomas Guillem a écrit :
> When a preparse request comes from the user, ie from playlist_AddInput or
"i.e."
> from libvlc_MetaRequest, force the preparsing of the item regardless of its
> type.
How does that affect capture devices or HTTP URLs? We really really don´t want
to *pre*parse any of those. For hardware, preparsing would cause spurious
errors with concurrent access, etc. For non-FS network resources, access might
not be idempotent, and even for FS resources ones, preparsing may cause
undesirable traffic.
> ---
> src/libvlc.c | 2 +-
> src/playlist/item.c | 11 ++++++-----
> src/playlist/preparser.c | 42 +++++++++++++++++++++++++++++++++---------
> src/playlist/preparser.h | 3 ++-
> 4 files changed, 42 insertions(+), 16 deletions(-)
>
> diff --git a/src/libvlc.c b/src/libvlc.c
> index cff3784..2d85972 100644
> --- a/src/libvlc.c
> +++ b/src/libvlc.c
> @@ -608,7 +608,7 @@ int libvlc_MetaRequest(libvlc_int_t *libvlc,
> input_item_t *item, if (unlikely(priv->parser == NULL))
> return VLC_ENOMEM;
>
> - playlist_preparser_Push(priv->parser, item, i_options);
> + playlist_preparser_Push(priv->parser, item, i_options, true);
> return VLC_SUCCESS;
> }
>
> diff --git a/src/playlist/item.c b/src/playlist/item.c
> index 5ce59f3..1780dd7 100644
> --- a/src/playlist/item.c
> +++ b/src/playlist/item.c
> @@ -34,7 +34,7 @@
> static void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
> playlist_item_t *p_node, int i_mode, int i_pos );
> static void GoAndPreparse( playlist_t *p_playlist, int i_mode,
> - playlist_item_t * );
> + playlist_item_t *, bool );
> static void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item
> );
>
> static int RecursiveAddIntoParent (
> @@ -462,7 +462,7 @@ int playlist_AddInput( playlist_t* p_playlist,
> input_item_t *p_input, b_playlist ? p_playlist->p_playing :
> p_playlist->p_media_library , i_mode, i_pos );
>
> - GoAndPreparse( p_playlist, i_mode, p_item );
> + GoAndPreparse( p_playlist, i_mode, p_item, true );
>
> PL_UNLOCK_IF( !b_locked );
> return VLC_SUCCESS;
> @@ -498,7 +498,7 @@ playlist_item_t * playlist_NodeAddInput( playlist_t
> *p_playlist, goto end;
> AddItem( p_playlist, p_item, p_parent, i_mode, i_pos );
>
> - GoAndPreparse( p_playlist, i_mode, p_item );
> + GoAndPreparse( p_playlist, i_mode, p_item, false );
>
> end:
> PL_UNLOCK_IF( !b_locked );
> @@ -744,7 +744,7 @@ mtime_t playlist_GetNodeDuration( playlist_item_t* node
> )
>
> /* Enqueue an item for preparsing, and play it, if needed */
> static void GoAndPreparse( playlist_t *p_playlist, int i_mode,
> - playlist_item_t *p_item )
> + playlist_item_t *p_item, bool b_user_request )
> {
> playlist_private_t *sys = pl_priv(p_playlist);
>
> @@ -765,7 +765,8 @@ 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 );
> + playlist_preparser_Push( sys->p_preparser, p_item->p_input, 0,
> + b_user_request );
> free( psz_artist );
> free( psz_album );
> }
> diff --git a/src/playlist/preparser.c b/src/playlist/preparser.c
> index 2d3887d..fd25d66 100644
> --- a/src/playlist/preparser.c
> +++ b/src/playlist/preparser.c
> @@ -34,6 +34,14 @@
> /**************************************************************************
> *** * Structures/definitions
>
> ***************************************************************************
> **/ +typedef struct preparser_entry_t preparser_entry_t;
> +
> +struct preparser_entry_t
> +{
> + input_item_t *p_item;
> + bool b_user_request;
> +};
> +
> struct playlist_preparser_t
> {
> vlc_object_t *object;
> @@ -42,7 +50,7 @@ struct playlist_preparser_t
> vlc_mutex_t lock;
> vlc_cond_t wait;
> bool b_live;
> - input_item_t **pp_waiting;
> + preparser_entry_t **pp_waiting;
> int i_waiting;
> };
>
> @@ -72,14 +80,21 @@ 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 ) +
> input_item_meta_request_option_t i_options, +
> bool b_user_request )
> {
> - vlc_gc_incref( p_item );
> VLC_UNUSED( i_options );
> + preparser_entry_t *p_entry = malloc( sizeof(preparser_entry_t) );
> +
> + if ( !p_entry )
> + return;
> + p_entry->p_item = p_item;
> + p_entry->b_user_request = b_user_request;
> + vlc_gc_incref( p_entry->p_item );
>
> vlc_mutex_lock( &p_preparser->lock );
> INSERT_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting,
> - p_preparser->i_waiting, p_item );
> + p_preparser->i_waiting, p_entry );
> if( !p_preparser->b_live )
> {
> if( vlc_clone_detach( NULL, Thread, p_preparser,
> @@ -104,7 +119,9 @@ void playlist_preparser_Delete( playlist_preparser_t
> *p_preparser ) /* Remove pending item to speed up preparser thread exit */
> while( p_preparser->i_waiting > 0 )
> {
> - vlc_gc_decref( p_preparser->pp_waiting[0] );
> + preparser_entry_t *p_entry = p_preparser->pp_waiting[0];
> + vlc_gc_decref( p_entry->p_item );
> + free( p_entry );
> REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
> }
>
> @@ -127,13 +144,16 @@ void playlist_preparser_Delete( playlist_preparser_t
> *p_preparser ) /**
> * This function preparses an item when needed.
> */
> -static void Preparse( vlc_object_t *obj, input_item_t *p_item )
> +static void Preparse( vlc_object_t *obj, input_item_t *p_item,
> + bool b_user_request )
> {
> vlc_mutex_lock( &p_item->lock );
> int i_type = p_item->i_type;
> vlc_mutex_unlock( &p_item->lock );
>
> - if( i_type != ITEM_TYPE_FILE )
> + /* if the request comes from an user, preparse the item regardless of
> its + * type */
> + if( !b_user_request && i_type != ITEM_TYPE_FILE )
> {
> input_item_SetPreparsed( p_item, true );
> input_item_SignalPreparseEnded( p_item );
> @@ -203,12 +223,16 @@ static void *Thread( void *data )
> for( ;; )
> {
> input_item_t *p_current;
> + bool b_user_request;
>
> /* */
> vlc_mutex_lock( &p_preparser->lock );
> if( p_preparser->i_waiting > 0 )
> {
> - p_current = p_preparser->pp_waiting[0];
> + preparser_entry_t *p_entry = p_preparser->pp_waiting[0];
> + p_current = p_entry->p_item;
> + b_user_request = p_entry->b_user_request;
> + free( p_entry );
> REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0
> ); }
> else
> @@ -222,7 +246,7 @@ static void *Thread( void *data )
> if( !p_current )
> break;
>
> - Preparse( obj, p_current );
> + Preparse( obj, p_current, b_user_request );
>
> Art( p_preparser, p_current );
> vlc_gc_decref(p_current);
> diff --git a/src/playlist/preparser.h b/src/playlist/preparser.h
> index 2b28863..1eea8d5 100644
> --- a/src/playlist/preparser.h
> +++ b/src/playlist/preparser.h
> @@ -49,7 +49,8 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t
> * ); * preparsed.
> */
> void playlist_preparser_Push( playlist_preparser_t *, input_item_t *,
> - input_item_meta_request_option_t );
> + input_item_meta_request_option_t,
> + bool );
>
> void playlist_preparser_fetcher_Push( playlist_preparser_t *, input_item_t
> *, input_item_meta_request_option_t );
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list