summaryrefslogtreecommitdiffstats
path: root/demux/demux_playlist.c
diff options
context:
space:
mode:
authorChristoph Heinrich <christoph.heinrich@student.tugraz.at>2023-02-11 21:08:38 +0100
committerDudemanguy <random342@airmail.cc>2023-07-06 18:17:45 +0000
commitf266eadf1eae920d645477b9658c6847aca47ff5 (patch)
tree20ecfe5810a91a40771b432676b4d6c4bf08786b /demux/demux_playlist.c
parent9ad14e08863463accdf88cf9e9818e5ee0fd1d23 (diff)
downloadmpv-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.c49
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,