Commit 4455e6d2 authored by Thomas Guillem's avatar Thomas Guillem Committed by Jean-Baptiste Kempf

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's avatarJean-Baptiste Kempf <jb@videolan.org>
parent b710e510
......@@ -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)
......
......@@ -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);
......
......@@ -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 )
......
......@@ -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 */
......
......@@ -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;
}
......
......@@ -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
{
......
......@@ -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 )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment