summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst12
-rw-r--r--demux/demux_libarchive.c20
-rw-r--r--stream/stream_libarchive.c8
-rw-r--r--stream/stream_libarchive.h3
4 files changed, 39 insertions, 4 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 9eaf2b2791..dcd68194c2 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -3458,6 +3458,18 @@ Demuxer
after the initial caching. This option is useless if the file cannot be
cached completely.
+``--rar-list-all-volumes=<yes|no>``
+ When opening multi-volume rar files, open all volumes to create a full list
+ of contained files (default: no). If disabled, only the archive entries
+ whose headers are located within the first volume are listed (and thus
+ played when opening a .rar file with mpv). Doing so speeds up opening, and
+ the typical idiotic use-case of playing uncompressed multi-volume rar files
+ that contain a single media file is made faster.
+
+ Opening is still slow, because for unknown, idiotic, and unnecessary reasons
+ libarchive opens all volumes anyway when playing the main file, even though
+ mpv iterated no archive entries yet.
+
Input
-----
diff --git a/demux/demux_libarchive.c b/demux/demux_libarchive.c
index 31e0c2b418..4be5193b22 100644
--- a/demux/demux_libarchive.c
+++ b/demux/demux_libarchive.c
@@ -20,12 +20,17 @@
#include "common/common.h"
#include "common/playlist.h"
+#include "options/m_config.h"
#include "stream/stream.h"
#include "misc/natural_sort.h"
#include "demux.h"
#include "stream/stream_libarchive.h"
+struct demux_libarchive_opts {
+ int rar_list_all_volumes;
+};
+
static int cmp_filename(const void *a, const void *b)
{
return mp_natural_sort_cmp(*(char **)a, *(char **)b);
@@ -57,6 +62,12 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
if (!ok)
return -1;
+ struct demux_libarchive_opts *opts =
+ mp_get_config_group(demuxer, demuxer->global, demuxer->desc->options);
+
+ if (!opts->rar_list_all_volumes)
+ flags |= MP_ARCHIVE_FLAG_NO_RAR_VOLUMES;
+
mpa = mp_archive_new(demuxer->log, demuxer->stream, flags, 0);
if (!mpa)
return -1;
@@ -93,8 +104,17 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
return 0;
}
+#define OPT_BASE_STRUCT struct demux_libarchive_opts
+
const struct demuxer_desc demuxer_desc_libarchive = {
.name = "libarchive",
.desc = "libarchive wrapper",
.open = open_file,
+ .options = &(const struct m_sub_options){
+ .opts = (const struct m_option[]) {
+ OPT_FLAG("rar-list-all-volumes", rar_list_all_volumes, 0),
+ {0}
+ },
+ .size = sizeof(OPT_BASE_STRUCT),
+ },
};
diff --git a/stream/stream_libarchive.c b/stream/stream_libarchive.c
index 7c48f3a135..a43f2e633f 100644
--- a/stream/stream_libarchive.c
+++ b/stream/stream_libarchive.c
@@ -264,9 +264,11 @@ struct mp_archive *mp_archive_new(struct mp_log *log, struct stream *src,
if (!add_volume(mpa, src, src->url, 0))
goto err;
- // try to open other volumes
- if (!find_volumes(mpa))
- goto err;
+ if (!(flags & MP_ARCHIVE_FLAG_NO_RAR_VOLUMES)) {
+ // try to open other volumes
+ if (!find_volumes(mpa))
+ goto err;
+ }
locale_t oldlocale = uselocale(mpa->locale);
diff --git a/stream/stream_libarchive.h b/stream/stream_libarchive.h
index bb5dee432b..f9e05fcbee 100644
--- a/stream/stream_libarchive.h
+++ b/stream/stream_libarchive.h
@@ -24,7 +24,8 @@ struct mp_archive {
void mp_archive_free(struct mp_archive *mpa);
-#define MP_ARCHIVE_FLAG_UNSAFE 1
+#define MP_ARCHIVE_FLAG_UNSAFE (1 << 0)
+#define MP_ARCHIVE_FLAG_NO_RAR_VOLUMES (1 << 1)
struct mp_archive *mp_archive_new(struct mp_log *log, struct stream *src,
int flags, int max_volumes);