diff options
author | Christoph Heinrich <christoph.heinrich@student.tugraz.at> | 2023-02-11 21:08:38 +0100 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2023-07-06 18:17:45 +0000 |
commit | f266eadf1eae920d645477b9658c6847aca47ff5 (patch) | |
tree | 20ecfe5810a91a40771b432676b4d6c4bf08786b /demux/demux_playlist.c | |
parent | 9ad14e08863463accdf88cf9e9818e5ee0fd1d23 (diff) | |
download | mpv-f266eadf1eae920d645477b9658c6847aca47ff5.tar.bz2 mpv-f266eadf1eae920d645477b9658c6847aca47ff5.tar.xz |
demux_playlist: add option to control recursive directory loading
Directories were always loaded recursively, which can be slow
(e.g. one of the subdirectories is a mounting point to a slow device)
and can unexpectedly expand into a massive playlist.
Due to the problems described in 503dada42f1ea1007768da0dc6a41b67cdf89400,
this defaults to recursive loading.
ref. https://github.com/mpv-player/mpv/issues/9652
Diffstat (limited to 'demux/demux_playlist.c')
-rw-r--r-- | demux/demux_playlist.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/demux/demux_playlist.c b/demux/demux_playlist.c index a5f9f0af35..6b6b2be144 100644 --- a/demux/demux_playlist.c +++ b/demux/demux_playlist.c @@ -24,6 +24,7 @@ #include "common/common.h" #include "options/options.h" +#include "options/m_config.h" #include "common/msg.h" #include "common/playlist.h" #include "misc/thread_tools.h" @@ -35,6 +36,31 @@ #define PROBE_SIZE (8 * 1024) +enum dir_mode { + DIR_RECURSIVE, + DIR_LAZY, + DIR_IGNORE, +}; + +#define OPT_BASE_STRUCT struct demux_playlist_opts +struct demux_playlist_opts { + int dir_mode; +}; + +struct m_sub_options demux_playlist_conf = { + .opts = (const struct m_option[]) { + {"directory-mode", OPT_CHOICE(dir_mode, + {"recursive", DIR_RECURSIVE}, + {"lazy", DIR_LAZY}, + {"ignore", DIR_IGNORE})}, + {0} + }, + .size = sizeof(struct demux_playlist_opts), + .defaults = &(const struct demux_playlist_opts){ + .dir_mode = DIR_RECURSIVE, + }, +}; + static bool check_mimetype(struct stream *s, const char *const *list) { if (s->mime_type) { @@ -59,6 +85,7 @@ struct pl_parser { enum demux_check check_level; struct stream *real_stream; char *format; + struct demux_playlist_opts *opts; }; @@ -323,6 +350,7 @@ static bool scan_dir(struct pl_parser *p, char *path, return false; } + int dir_mode = p->opts->dir_mode; struct dirent *ep; while ((ep = readdir(dp))) { if (ep->d_name[0] == '.') @@ -334,16 +362,18 @@ static bool scan_dir(struct pl_parser *p, char *path, char *file = mp_path_join(p, path, ep->d_name); struct stat st; - if (stat(file, &st) == 0 && S_ISDIR(st.st_mode)) { - for (int n = 0; n < num_dir_stack; n++) { - if (same_st(&dir_stack[n], &st)) { - MP_VERBOSE(p, "Skip recursive entry: %s\n", file); - goto skip; + if (dir_mode != DIR_LAZY && stat(file, &st) == 0 && S_ISDIR(st.st_mode)) { + if (dir_mode != DIR_IGNORE) { + for (int n = 0; n < num_dir_stack; n++) { + if (same_st(&dir_stack[n], &st)) { + MP_VERBOSE(p, "Skip recursive entry: %s\n", file); + goto skip; + } } - } - dir_stack[num_dir_stack] = st; - scan_dir(p, file, dir_stack, num_dir_stack + 1, files, num_files); + dir_stack[num_dir_stack] = st; + scan_dir(p, file, dir_stack, num_dir_stack + 1, files, num_files); + } } else { MP_TARRAY_APPEND(p, *files, *num_files, file); } @@ -458,6 +488,7 @@ static int open_file(struct demuxer *demuxer, enum demux_check check) p->error = false; p->s = demuxer->stream; p->utf16 = stream_skip_bom(p->s); + p->opts = mp_get_config_group(demuxer, demuxer->global, &demux_playlist_conf); bool ok = fmt->parse(p) >= 0 && !p->error; if (p->add_base) playlist_add_base_path(p->pl, mp_dirname(demuxer->filename)); @@ -471,7 +502,7 @@ static int open_file(struct demuxer *demuxer, enum demux_check check) return ok ? 0 : -1; } -const struct demuxer_desc demuxer_desc_playlist = { +const demuxer_desc_t demuxer_desc_playlist = { .name = "playlist", .desc = "Playlist file", .open = open_file, |