mirror of https://github.com/mpv-player/mpv
demux, stream: add option to prevent opening referenced files
Quite irresponsibly hacked together. Sue me.
This commit is contained in:
parent
83c5f704e7
commit
ceb2e1026d
|
@ -267,6 +267,26 @@ Playback Control
|
|||
Note that ``--playlist`` always loads all entries, so you use that instead
|
||||
if you really have the need for this functionality.
|
||||
|
||||
``--access-references=<yes|no>``
|
||||
Follow any references in the file being opened (default: yes). Disabling
|
||||
this is helpful if the file is automatically scanned (e.g. thumbnail
|
||||
generation). If the thumbnail scanner for example encounters a playlist
|
||||
file, which contains network URLs, and the scanner should not open these,
|
||||
enabling this option will prevent it. This option also disables ordered
|
||||
chapters, mov reference files, opening of archives, and a number of other
|
||||
features.
|
||||
|
||||
On older FFmpeg versions, this will not work in some cases. Some FFmpeg
|
||||
demuxers might not respect this option.
|
||||
|
||||
This option does not prevent opening of paired subtitle files and such. Use
|
||||
``--autoload-files=no`` to prevent this.
|
||||
|
||||
This option does not always work if you open non-files (for example using
|
||||
``dvd://directory`` would open a whole bunch of files in the given
|
||||
directory). Prefixing the filename with ``./`` if it doesn't start with
|
||||
a ``/`` will avoid this.
|
||||
|
||||
``--loop-file=<N|inf|no>``
|
||||
Loop a single file N times. ``inf`` means forever, ``no`` means normal
|
||||
playback. For compatibility, ``--loop-file`` and ``--loop-file=yes`` are
|
||||
|
|
|
@ -89,6 +89,7 @@ struct demux_opts {
|
|||
double min_secs;
|
||||
int force_seekable;
|
||||
double min_secs_cache;
|
||||
int access_references;
|
||||
};
|
||||
|
||||
#define OPT_BASE_STRUCT struct demux_opts
|
||||
|
@ -100,6 +101,7 @@ const struct m_sub_options demux_conf = {
|
|||
OPT_INTRANGE("demuxer-max-bytes", max_bytes, 0, 0, INT_MAX),
|
||||
OPT_FLAG("force-seekable", force_seekable, 0),
|
||||
OPT_DOUBLE("cache-secs", min_secs_cache, M_OPT_MIN, .min = 0),
|
||||
OPT_FLAG("access-references", access_references, 0),
|
||||
{0}
|
||||
},
|
||||
.size = sizeof(struct demux_opts),
|
||||
|
@ -108,6 +110,7 @@ const struct m_sub_options demux_conf = {
|
|||
.max_bytes = 400 * 1024 * 1024,
|
||||
.min_secs = 1.0,
|
||||
.min_secs_cache = 10.0,
|
||||
.access_references = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1213,6 +1216,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
|
|||
return NULL;
|
||||
|
||||
struct demuxer *demuxer = talloc_ptrtype(NULL, demuxer);
|
||||
struct demux_opts *opts = mp_get_config_group(demuxer, global, &demux_conf);
|
||||
*demuxer = (struct demuxer) {
|
||||
.desc = desc,
|
||||
.stream = stream,
|
||||
|
@ -1223,6 +1227,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
|
|||
.glog = log,
|
||||
.filename = talloc_strdup(demuxer, stream->url),
|
||||
.is_network = stream->is_network,
|
||||
.access_references = opts->access_references,
|
||||
.events = DEMUX_EVENT_ALL,
|
||||
};
|
||||
demuxer->seekable = stream->seekable;
|
||||
|
@ -1230,8 +1235,6 @@ static struct demuxer *open_given_type(struct mpv_global *global,
|
|||
!demuxer->stream->uncached_stream->seekable)
|
||||
demuxer->seekable = false;
|
||||
|
||||
struct demux_opts *opts = mp_get_config_group(demuxer, global, &demux_conf);
|
||||
|
||||
struct demux_internal *in = demuxer->in = talloc_ptrtype(demuxer, in);
|
||||
*in = (struct demux_internal){
|
||||
.log = demuxer->log,
|
||||
|
|
|
@ -186,6 +186,7 @@ typedef struct demuxer {
|
|||
// Typical examples: text subtitles, playlists
|
||||
bool fully_read;
|
||||
bool is_network; // opened directly from a network stream
|
||||
bool access_references; // allow opening other files/URLs
|
||||
|
||||
// Bitmask of DEMUX_EVENT_*
|
||||
int events;
|
||||
|
|
|
@ -253,6 +253,9 @@ out:
|
|||
|
||||
static int try_open_file(struct demuxer *demuxer, enum demux_check check)
|
||||
{
|
||||
if (!demuxer->access_references)
|
||||
return -1;
|
||||
|
||||
struct stream *s = demuxer->stream;
|
||||
if (check >= DEMUX_CHECK_UNSAFE) {
|
||||
bstr d = stream_peek(s, PROBE_SIZE);
|
||||
|
|
|
@ -295,6 +295,9 @@ static void build_mpv_edl_timeline(struct timeline *tl)
|
|||
|
||||
static int try_open_file(struct demuxer *demuxer, enum demux_check check)
|
||||
{
|
||||
if (!demuxer->access_references)
|
||||
return -1;
|
||||
|
||||
struct priv *p = talloc_zero(demuxer, struct priv);
|
||||
demuxer->priv = p;
|
||||
demuxer->fully_read = true;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "config.h"
|
||||
|
@ -754,6 +755,14 @@ static int interrupt_cb(void *ctx)
|
|||
return mp_cancel_test(priv->stream->cancel);
|
||||
}
|
||||
|
||||
static int block_io_open(struct AVFormatContext *s, AVIOContext **pb,
|
||||
const char *url, int flags, AVDictionary **options)
|
||||
{
|
||||
struct demuxer *demuxer = s->opaque;
|
||||
MP_ERR(demuxer, "Not opening '%s' due to --access-references=no.\n", url);
|
||||
return AVERROR(EACCES);
|
||||
}
|
||||
|
||||
static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
|
||||
{
|
||||
AVFormatContext *avfc;
|
||||
|
@ -855,6 +864,12 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
|
|||
.opaque = demuxer,
|
||||
};
|
||||
|
||||
#if HAVE_AVFORMAT_IOOPEN
|
||||
avfc->opaque = demuxer;
|
||||
if (!demuxer->access_references)
|
||||
avfc->io_open = block_io_open;
|
||||
#endif
|
||||
|
||||
mp_set_avdict(&dopts, lavfdopts->avopts);
|
||||
|
||||
if (avformat_open_input(&avfc, priv->filename, priv->avif, &dopts) < 0) {
|
||||
|
|
|
@ -32,6 +32,9 @@ static int cmp_filename(const void *a, const void *b)
|
|||
|
||||
static int open_file(struct demuxer *demuxer, enum demux_check check)
|
||||
{
|
||||
if (!demuxer->access_references)
|
||||
return -1;
|
||||
|
||||
int flags = 0;
|
||||
int probe_size = STREAM_BUFFER_SIZE;
|
||||
if (check <= DEMUX_CHECK_REQUEST) {
|
||||
|
|
|
@ -519,7 +519,7 @@ void build_ordered_chapter_timeline(struct timeline *tl)
|
|||
.opts = mp_get_config_group(ctx, tl->global, NULL),
|
||||
};
|
||||
|
||||
if (!ctx->opts->ordered_chapters) {
|
||||
if (!ctx->opts->ordered_chapters || !demuxer->access_references) {
|
||||
MP_INFO(demuxer, "File uses ordered chapters, but "
|
||||
"you have disabled support for them. Ignoring.\n");
|
||||
talloc_free(ctx);
|
||||
|
|
|
@ -283,6 +283,8 @@ static int parse_dir(struct pl_parser *p)
|
|||
return 0;
|
||||
|
||||
char *path = mp_file_get_path(p, bstr0(p->real_stream->url));
|
||||
if (!path)
|
||||
return -1;
|
||||
|
||||
char **files = NULL;
|
||||
int num_files = 0;
|
||||
|
@ -339,6 +341,9 @@ static const struct pl_format *probe_pl(struct pl_parser *p)
|
|||
|
||||
static int open_file(struct demuxer *demuxer, enum demux_check check)
|
||||
{
|
||||
if (!demuxer->access_references)
|
||||
return -1;
|
||||
|
||||
bool force = check < DEMUX_CHECK_UNSAFE || check == DEMUX_CHECK_REQUEST;
|
||||
|
||||
struct pl_parser *p = talloc_zero(NULL, struct pl_parser);
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
|
||||
static int open_file(struct demuxer *demuxer, enum demux_check check)
|
||||
{
|
||||
if (!demuxer->access_references)
|
||||
return -1;
|
||||
|
||||
if (RarProbe(demuxer->stream))
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -230,6 +230,12 @@ static int open_internal(const stream_info_t *sinfo, const char *url, int flags,
|
|||
s->is_network = sinfo->is_network;
|
||||
s->mode = flags & (STREAM_READ | STREAM_WRITE);
|
||||
|
||||
if (global->config) {
|
||||
int opt;
|
||||
mp_read_option_raw(global, "access-references", &m_option_type_flag, &opt);
|
||||
s->access_references = opt;
|
||||
}
|
||||
|
||||
MP_VERBOSE(s, "Opening %s\n", url);
|
||||
|
||||
if ((s->mode & STREAM_WRITE) && !sinfo->can_write) {
|
||||
|
|
|
@ -197,6 +197,7 @@ typedef struct stream {
|
|||
bool fast_skip : 1; // consider stream fast enough to fw-seek by skipping
|
||||
bool is_network : 1; // original stream_info_t.is_network flag
|
||||
bool allow_caching : 1; // stream cache makes sense
|
||||
bool access_references : 1; // open other streams
|
||||
struct mp_log *log;
|
||||
struct mpv_global *global;
|
||||
|
||||
|
|
|
@ -569,6 +569,9 @@ static int bdmv_dir_stream_open(stream_t *stream)
|
|||
.cfg_title = BLURAY_DEFAULT_TITLE,
|
||||
};
|
||||
|
||||
if (!stream->access_references)
|
||||
goto unsupported;
|
||||
|
||||
char *path = mp_file_get_path(priv, bstr0(stream->url));
|
||||
if (!path)
|
||||
goto unsupported;
|
||||
|
|
|
@ -951,6 +951,9 @@ static int ifo_stream_open(stream_t *stream)
|
|||
dvd_priv_t *priv = talloc_zero(stream, dvd_priv_t);
|
||||
stream->priv = priv;
|
||||
|
||||
if (!stream->access_references)
|
||||
goto unsupported;
|
||||
|
||||
char *path = mp_file_get_path(priv, bstr0(stream->url));
|
||||
if (!path)
|
||||
goto unsupported;
|
||||
|
|
|
@ -562,6 +562,9 @@ static int ifo_dvdnav_stream_open(stream_t *stream)
|
|||
struct priv *priv = talloc_zero(stream, struct priv);
|
||||
stream->priv = priv;
|
||||
|
||||
if (!stream->access_references)
|
||||
goto unsupported;
|
||||
|
||||
priv->track = TITLE_LONGEST;
|
||||
|
||||
char *path = mp_file_get_path(priv, bstr0(stream->url));
|
||||
|
|
6
wscript
6
wscript
|
@ -528,6 +528,12 @@ FFmpeg/Libav libraries. You need at least {0}. Aborting.".format(libav_versions_
|
|||
'func': check_statement('libavutil/frame.h',
|
||||
'AV_FRAME_DATA_MASTERING_DISPLAY_METADATA',
|
||||
use='libav'),
|
||||
}, {
|
||||
'name': 'avformat-ioopen',
|
||||
'desc': 'libavformat io_open callback',
|
||||
'func': check_statement('libavformat/avformat.h',
|
||||
'offsetof(AVFormatContext, io_open)',
|
||||
use='libav'),
|
||||
}
|
||||
]
|
||||
|
||||
|
|
Loading…
Reference in New Issue