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

Thomas Guillem thomas at gllm.fr
Thu Mar 19 18:06:29 CET 2015


When a preparse request comes from the user, ie from playlist_AddInput or from
libvlc_MetaRequest, force the preparsing of the item regardless of its type.
---
 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 );
-- 
2.1.3




More information about the vlc-devel mailing list