[vlc-devel] [RFC PATCH 7/7] input: handle recursive parsing in preparser
Thomas Guillem
thomas at gllm.fr
Fri Mar 20 17:38:38 CET 2015
Add i_preparse_depth in input_item to handle how many level of sub items can be
parsed.
The "recursive" option is now moved from access/file to the playlist category.
You can now abort a long local directory opening.
NET items won't be parsed recursively since playlist_preparser_Push is not
called with the META_REQUEST_OPTION_SCOPE_NETWORK argument.
Fixes #13850
Fixes #11921
Fixes #13872
---
include/vlc_input_item.h | 3 +++
modules/access/directory.c | 24 +-----------------------
modules/access/fs.c | 14 --------------
src/input/input.c | 23 ++++++++++++++++++++++-
src/input/item.c | 22 ++++++++++++++++++++++
src/input/item.h | 1 +
src/libvlc-module.c | 15 +++++++++++++++
7 files changed, 64 insertions(+), 38 deletions(-)
diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h
index 2a9b13f..874df00 100644
--- a/include/vlc_input_item.h
+++ b/include/vlc_input_item.h
@@ -87,6 +87,9 @@ struct input_item_t
uint8_t i_type; /**< Type (file, disc, ... see input_item_type_e) */
uint8_t i_browsable; /**< Browsable (see input_item_browsable_e) */
bool b_error_when_reading;/**< Error When Reading */
+
+ int i_preparse_depth; /**< How many level of sub items can be preparsed:
+ -1: recursive, 0: none, >0: n levels */
};
TYPEDEF_ARRAY(input_item_t*, input_item_array_t)
diff --git a/modules/access/directory.c b/modules/access/directory.c
index 5c471a2..7209978 100644
--- a/modules/access/directory.c
+++ b/modules/access/directory.c
@@ -326,17 +326,6 @@ int DirInit (access_t *p_access, DIR *handle)
p_access->p_sys = p_sys;
p_sys->ignored_exts = var_InheritString (p_access, "ignore-filetypes");
-
- /* Handle mode */
- char *psz_rec = var_InheritString (p_access, "recursive");
- if (psz_rec == NULL || !strcasecmp (psz_rec, "none"))
- p_sys->mode = MODE_NONE;
- else if (!strcasecmp (psz_rec, "collapse"))
- p_sys->mode = MODE_COLLAPSE;
- else
- p_sys->mode = MODE_EXPAND;
- free (psz_rec);
-
p_access->pf_readdir = DirRead;
p_access->pf_control = DirControl;
@@ -392,7 +381,6 @@ int DirRead (access_t *p_access, input_item_node_t *p_current_node)
i_res = directory_open (p_current, psz_entry, &handle);
if (i_res == ENTRY_EACCESS
- || (i_res == ENTRY_DIR && p_sys->mode == MODE_NONE)
|| (i_res == ENTRY_ENOTDIR && has_ext (p_sys->ignored_exts, psz_entry)))
continue;
@@ -421,17 +409,7 @@ int DirRead (access_t *p_access, input_item_node_t *p_current_node)
}
input_item_CopyOptions (p_current_node->p_item, p_new);
- input_item_node_t *p_new_node = input_item_node_AppendItem (p_current_node, p_new);
-
- /* Handle directory flags and recursion if in EXPAND mode */
- if (i_res == ENTRY_DIR)
- {
- if (p_sys->mode == MODE_EXPAND
- && directory_push (p_sys, handle, psz_full_uri))
- {
- p_current_node = p_new_node;
- }
- }
+ input_item_node_AppendItem (p_current_node, p_new);
free (psz_full_uri);
input_item_Release (p_new);
diff --git a/modules/access/fs.c b/modules/access/fs.c
index 175c549..43714ea 100644
--- a/modules/access/fs.c
+++ b/modules/access/fs.c
@@ -30,17 +30,6 @@
#include "fs.h"
#include <vlc_plugin.h>
-#define RECURSIVE_TEXT N_("Subdirectory behavior")
-#define RECURSIVE_LONGTEXT N_( \
- "Select whether subdirectories must be expanded.\n" \
- "none: subdirectories do not appear in the playlist.\n" \
- "collapse: subdirectories appear but are expanded on first play.\n" \
- "expand: all subdirectories are expanded.\n" )
-
-static const char *const psz_recursive_list[] = { "none", "collapse", "expand" };
-static const char *const psz_recursive_list_text[] = {
- N_("None"), N_("Collapse"), N_("Expand") };
-
#define IGNORE_TEXT N_("Ignored extensions")
#define IGNORE_LONGTEXT N_( \
"Files with these extensions will not be added to playlist when " \
@@ -71,9 +60,6 @@ vlc_module_begin ()
add_submodule()
set_section( N_("Directory" ), NULL )
set_capability( "access", 55 )
- add_string( "recursive", "expand" , RECURSIVE_TEXT,
- RECURSIVE_LONGTEXT, false )
- change_string_list( psz_recursive_list, psz_recursive_list_text )
add_string( "ignore-filetypes", "m3u,db,nfo,ini,jpg,jpeg,ljpg,gif,png,pgm,pgmyuv,pbm,pam,tga,bmp,pnm,xpm,xcf,pcx,tif,tiff,lbm,sfv,txt,sub,idx,srt,cue,ssa",
IGNORE_TEXT, IGNORE_LONGTEXT, false )
add_string( "directory-sort", "collate", SORT_TEXT, SORT_LONGTEXT, false )
diff --git a/src/input/input.c b/src/input/input.c
index 98f3567..1afeebb 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -197,7 +197,8 @@ int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
* demux_Demux in order to fetch sub items */
bool b_is_playlist = false;
- if ( demux_Control( p_input->p->input.p_demux,
+ if ( input_item_ShouldPreparseSubItems( p_item )
+ && demux_Control( p_input->p->input.p_demux,
DEMUX_IS_PLAYLIST,
&b_is_playlist ) )
b_is_playlist = false;
@@ -370,6 +371,26 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
if( !p_item->p_stats )
p_item->p_stats = stats_NewInputStats( p_input );
+
+ /* setup the preparse depth of the item
+ * if we are preparsing, use the i_preparse_depth of the parent item */
+ if( !p_input->b_preparsing )
+ {
+ char *psz_rec = var_InheritString( p_parent, "recursive" );
+
+ if( psz_rec != NULL )
+ {
+ if ( !strcasecmp( psz_rec, "none" ) )
+ p_item->i_preparse_depth = 0;
+ else if ( !strcasecmp( psz_rec, "collapse" ) )
+ p_item->i_preparse_depth = 1;
+ else
+ p_item->i_preparse_depth = -1; /* default is expand */
+ free (psz_rec);
+ } else
+ p_item->i_preparse_depth = -1;
+ }
+
vlc_mutex_unlock( &p_item->lock );
/* No slave */
diff --git a/src/input/item.c b/src/input/item.c
index c3c3de8..30d04d5 100644
--- a/src/input/item.c
+++ b/src/input/item.c
@@ -423,6 +423,17 @@ bool input_item_IsArtFetched( input_item_t *p_item )
return b_fetched;
}
+bool input_item_ShouldPreparseSubItems( input_item_t *p_item )
+{
+ bool b_ret;
+
+ vlc_mutex_lock( &p_item->lock );
+ b_ret = p_item->i_preparse_depth == -1 ? true : p_item->i_preparse_depth > 0;
+ vlc_mutex_unlock( &p_item->lock );
+
+ return b_ret;
+}
+
input_item_t *input_item_Hold( input_item_t *p_item )
{
input_item_owner_t *owner = item_owner(p_item);
@@ -1067,8 +1078,19 @@ void input_item_node_Delete( input_item_node_t *p_node )
input_item_node_t *input_item_node_AppendItem( input_item_node_t *p_node, input_item_t *p_item )
{
+ int i_preparse_depth;
input_item_node_t *p_new_child = input_item_node_Create( p_item );
if( !p_new_child ) return NULL;
+
+ vlc_mutex_lock( &p_node->p_item->lock );
+ vlc_mutex_lock( &p_item->lock );
+ i_preparse_depth = p_node->p_item->i_preparse_depth;
+ p_item->i_preparse_depth = i_preparse_depth > 0 ?
+ i_preparse_depth -1 :
+ i_preparse_depth;
+ vlc_mutex_unlock( &p_item->lock );
+ vlc_mutex_unlock( &p_node->p_item->lock );
+
input_item_node_AppendNode( p_node, p_new_child );
return p_new_child;
}
diff --git a/src/input/item.h b/src/input/item.h
index aa31d05..f4b89a4 100644
--- a/src/input/item.h
+++ b/src/input/item.h
@@ -29,6 +29,7 @@
void input_item_SetErrorWhenReading( input_item_t *p_i, bool b_error );
void input_item_UpdateTracksInfo( input_item_t *item, const es_format_t *fmt );
+bool input_item_ShouldPreparseSubItems( input_item_t *p_i );
typedef struct input_item_owner
{
diff --git a/src/libvlc-module.c b/src/libvlc-module.c
index 31037b4..a2474cb 100644
--- a/src/libvlc-module.c
+++ b/src/libvlc-module.c
@@ -1091,6 +1091,17 @@ static const char *const ppsz_prefres[] = {
"Automatically preparse files added to the playlist " \
"(to retrieve some metadata)." )
+#define RECURSIVE_TEXT N_("Subdirectory behavior")
+#define RECURSIVE_LONGTEXT N_( \
+ "Select whether subdirectories must be expanded.\n" \
+ "none: subdirectories do not appear in the playlist.\n" \
+ "collapse: subdirectories appear but are expanded on first play.\n" \
+ "expand: all subdirectories are expanded.\n" )
+
+static const char *const psz_recursive_list[] = { "none", "collapse", "expand" };
+static const char *const psz_recursive_list_text[] = {
+ N_("None"), N_("Collapse"), N_("Expand"), N_("Expand distant files") };
+
#define METADATA_NETWORK_TEXT N_( "Allow metadata network access" )
#define SD_TEXT N_( "Services discovery modules")
@@ -2006,6 +2017,10 @@ vlc_module_begin ()
add_bool( "auto-preparse", true, PREPARSE_TEXT,
PREPARSE_LONGTEXT, false )
+ add_string( "recursive", "collapse" , RECURSIVE_TEXT,
+ RECURSIVE_LONGTEXT, false )
+ change_string_list( psz_recursive_list, psz_recursive_list_text )
+
add_obsolete_integer( "album-art" )
add_bool( "metadata-network-access", false, METADATA_NETWORK_TEXT,
METADATA_NETWORK_TEXT, false )
--
2.1.3
More information about the vlc-devel
mailing list