From: Thomas Guillem Date: Tue, 24 Mar 2015 16:22:19 +0000 (+0000) Subject: input: handle recursive parsing in preparser X-Git-Url: https://git.sesse.net/?p=vlc;a=commitdiff_plain;h=4455e6d2935a498e02ac3c6ac144f0525d2e01f0 input: handle recursive parsing in preparser 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 Signed-off-by: Jean-Baptiste Kempf --- diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h index d0a6854eff..27398cc52a 100644 --- a/include/vlc_input_item.h +++ b/include/vlc_input_item.h @@ -88,6 +88,9 @@ struct input_item_t bool b_net; /**< Net: always true for TYPE_STREAM, it depends for others types */ 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 5c471a299e..7209978cd3 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 175c549a20..43714ea58a 100644 --- a/modules/access/fs.c +++ b/modules/access/fs.c @@ -30,17 +30,6 @@ #include "fs.h" #include -#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 7de30ecbf2..23ee04166f 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; @@ -364,6 +365,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 f907974043..226b14bf9c 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); @@ -1070,8 +1081,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 aa31d05e35..f4b89a411f 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 31037b4c2f..a2474cb345 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 )