[vlc-devel] [PATCH 2/2] preparser: add an option to force preparsing

Thomas Guillem thomas at gllm.fr
Thu Mar 19 22:52:19 CET 2015


On Thu, Mar 19, 2015, at 18:23, Rémi Denis-Courmont wrote:
> 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.

OK so I shouldn't revert my first patch that prevent to preparse that
kind of items.

I'll try to find something else to prevent the recursive parsing.

I'm thinking about adding a i_parse_depth in input_item. It'll behave
like this:
-1: preparse and fetch all sub items recursively (used with the
--recursive option from file.c)
0: preparse but don't  fetch sub items.
>0: preparse and fetch sub items with subitem->i_parse_depth = MAX(item->i_parse_depth - 1, 0)


> 
> > ---
> >  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/
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel



More information about the vlc-devel mailing list