[vlc-devel] [PATCH] Fix folder opening regression

Thomas Guillem thomas at gllm.fr
Wed Feb 11 16:11:44 CET 2015


Don't always parse for sub items from input_Preparse (used by playlist
preparser).

Add libvlc_PreparseRequest that extends libvlc_MetaRequest with a new
b_parse_sub_items argument. This new function is used by lib/media.c that need
to parse sub items.

This fixes a regression brought by 4bc33dbc16a4dc749c006a58ddb8701d1a146ec9
Close #13850 #13872
---
 include/vlc_input_item.h    |  3 +++
 lib/media.c                 |  2 +-
 src/input/input.c           | 27 ++++++++++++++++-----------
 src/input/input_interface.h |  2 +-
 src/libvlc.c                | 21 +++++++++++++++++----
 src/libvlccore.sym          |  1 +
 src/playlist/item.c         |  2 +-
 src/playlist/preparser.c    | 14 ++++++++++----
 src/playlist/preparser.h    |  3 ++-
 9 files changed, 52 insertions(+), 23 deletions(-)

diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h
index 8502dd3..003cd95 100644
--- a/include/vlc_input_item.h
+++ b/include/vlc_input_item.h
@@ -292,6 +292,9 @@ typedef enum input_item_meta_request_option_t
     META_REQUEST_OPTION_SCOPE_ANY     = 0x03
 } input_item_meta_request_option_t;
 
+VLC_API int libvlc_PreparseRequest(libvlc_int_t *, input_item_t *,
+                                   input_item_meta_request_option_t,
+                                   bool b_parse_sub_items);
 VLC_API int libvlc_MetaRequest(libvlc_int_t *, input_item_t *,
                                input_item_meta_request_option_t );
 VLC_API int libvlc_ArtRequest(libvlc_int_t *, input_item_t *,
diff --git a/lib/media.c b/lib/media.c
index 9ccfb25..238ba5b 100644
--- a/lib/media.c
+++ b/lib/media.c
@@ -726,7 +726,7 @@ static int media_parse(libvlc_media_t *media, bool b_async,
 
         if (parse_flag & libvlc_media_parse_network)
             parse_scope |= META_REQUEST_OPTION_SCOPE_NETWORK;
-        ret = libvlc_MetaRequest(libvlc, item, parse_scope);
+        ret = libvlc_PreparseRequest(libvlc, item, parse_scope, true);
         if (ret != VLC_SUCCESS)
             return ret;
     }
diff --git a/src/input/input.c b/src/input/input.c
index 8c81e67..7a67aa8 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -181,9 +181,11 @@ int input_Read( vlc_object_t *p_parent, input_item_t *p_item )
  *
  * \param p_parent a vlc_object_t
  * \param p_item an input item
+ * \param b_parse_sub_items parse sub items if possible
  * \return VLC_SUCCESS or an error
  */
-int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
+int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item,
+                    bool b_parse_sub_items )
 {
     input_thread_t *p_input;
 
@@ -193,16 +195,19 @@ int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
         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 ( 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 );
+        if( b_parse_sub_items )
+        {
+            /* 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 ( 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 );
     }
 
diff --git a/src/input/input_interface.h b/src/input/input_interface.h
index e7b634a..566ec9f 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 * );
+int input_Preparse( vlc_object_t *, input_item_t *, bool );
 
 /* misc/stats.c
  * FIXME it should NOT be defined here or not coded in misc/stats.c */
diff --git a/src/libvlc.c b/src/libvlc.c
index cff3784..c137c3f 100644
--- a/src/libvlc.c
+++ b/src/libvlc.c
@@ -597,22 +597,35 @@ static void GetFilenames( libvlc_int_t *p_vlc, unsigned n,
 }
 
 /**
- * Requests extraction of the meta data for an input item (a.k.a. preparsing).
+ * Requests preparsing for an input item.
  * The actual extraction is asynchronous.
+ * \param b_parse_sub_items if true, parse for sub items if it's possible (if
+ * item is a playlist, a directory or an archive).
  */
-int libvlc_MetaRequest(libvlc_int_t *libvlc, input_item_t *item,
-                       input_item_meta_request_option_t i_options)
+int libvlc_PreparseRequest(libvlc_int_t *libvlc, input_item_t *item,
+                           input_item_meta_request_option_t i_options,
+                           bool b_parse_sub_items)
 {
     libvlc_priv_t *priv = libvlc_priv(libvlc);
 
     if (unlikely(priv->parser == NULL))
         return VLC_ENOMEM;
 
-    playlist_preparser_Push(priv->parser, item, i_options);
+    playlist_preparser_Push(priv->parser, item, i_options, b_parse_sub_items);
     return VLC_SUCCESS;
 }
 
 /**
+ * Requests extraction of the meta data for an input item (a.k.a. preparsing).
+ * The actual extraction is asynchronous.
+ */
+int libvlc_MetaRequest(libvlc_int_t *libvlc, input_item_t *item,
+                       input_item_meta_request_option_t i_options)
+{
+    return libvlc_PreparseRequest(libvlc, item, i_options, false);
+}
+
+/**
  * Requests retrieving/downloading art for an input item.
  * The retrieval is performed asynchronously.
  */
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 7f06ed6..916b5a1 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -236,6 +236,7 @@ libvlc_InternalDestroy
 libvlc_InternalInit
 libvlc_Quit
 libvlc_SetExitHandler
+libvlc_PreparseRequest
 libvlc_MetaRequest
 libvlc_ArtRequest
 vlc_UrlParse
diff --git a/src/playlist/item.c b/src/playlist/item.c
index 5ce59f3..e00acb6 100644
--- a/src/playlist/item.c
+++ b/src/playlist/item.c
@@ -765,7 +765,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 );
+        playlist_preparser_Push( sys->p_preparser, p_item->p_input, 0, false );
     free( psz_artist );
     free( psz_album );
 }
diff --git a/src/playlist/preparser.c b/src/playlist/preparser.c
index e13862c..57970d7 100644
--- a/src/playlist/preparser.c
+++ b/src/playlist/preparser.c
@@ -40,6 +40,7 @@ struct preparser_entry_t
 {
     input_item_t    *p_item;
     input_item_meta_request_option_t i_options;
+    bool b_parse_sub_items;
 };
 
 struct playlist_preparser_t
@@ -80,7 +81,8 @@ 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_parse_sub_items )
 {
     preparser_entry_t *p_entry = malloc( sizeof(preparser_entry_t) );
 
@@ -88,6 +90,7 @@ void playlist_preparser_Push( playlist_preparser_t *p_preparser, input_item_t *p
         return;
     p_entry->p_item = p_item;
     p_entry->i_options = i_options;
+    p_entry->b_parse_sub_items = b_parse_sub_items;
     vlc_gc_incref( p_entry->p_item );
 
     vlc_mutex_lock( &p_preparser->lock );
@@ -143,7 +146,8 @@ 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,
-                      input_item_meta_request_option_t i_options )
+                      input_item_meta_request_option_t i_options,
+                      bool b_parse_sub_items )
 {
     vlc_mutex_lock( &p_item->lock );
     int i_type = p_item->i_type;
@@ -172,7 +176,7 @@ 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_Preparse( obj, p_item, b_parse_sub_items );
         input_item_SetPreparsed( p_item, true );
 
         var_SetAddress( obj, "item-change", p_item );
@@ -233,6 +237,7 @@ static void *Thread( void *data )
     {
         input_item_t *p_current;
         input_item_meta_request_option_t i_options;
+        bool b_parse_sub_items;
 
         /* */
         vlc_mutex_lock( &p_preparser->lock );
@@ -241,6 +246,7 @@ static void *Thread( void *data )
             preparser_entry_t *p_entry = p_preparser->pp_waiting[0];
             p_current = p_entry->p_item;
             i_options = p_entry->i_options;
+            b_parse_sub_items = p_entry->b_parse_sub_items;
             free( p_entry );
             REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
         }
@@ -255,7 +261,7 @@ static void *Thread( void *data )
         if( !p_current )
             break;
 
-        Preparse( obj, p_current, i_options );
+        Preparse( obj, p_current, i_options, b_parse_sub_items );
 
         Art( p_preparser, p_current );
         vlc_gc_decref(p_current);
diff --git a/src/playlist/preparser.h b/src/playlist/preparser.h
index 2b28863..4b17d80 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 b_parse_sub_items );
 
 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