summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
Diffstat (limited to 'demux')
-rw-r--r--demux/demux.c7
-rw-r--r--demux/demux.h1
-rw-r--r--demux/demux_cue.c3
-rw-r--r--demux/demux_edl.c3
-rw-r--r--demux/demux_lavf.c41
-rw-r--r--demux/demux_libarchive.c3
-rw-r--r--demux/demux_mkv.c24
-rw-r--r--demux/demux_mkv_timeline.c2
-rw-r--r--demux/demux_playlist.c5
-rw-r--r--demux/demux_rar.c3
-rw-r--r--demux/stheader.h2
11 files changed, 62 insertions, 32 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 8aa9989de3..18c9b3b5c1 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -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,
diff --git a/demux/demux.h b/demux/demux.h
index 18f52d463d..0e5a5e15c6 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -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;
diff --git a/demux/demux_cue.c b/demux/demux_cue.c
index 673e8b9f27..ba97ca0c1b 100644
--- a/demux/demux_cue.c
+++ b/demux/demux_cue.c
@@ -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);
diff --git a/demux/demux_edl.c b/demux/demux_edl.c
index 67a4290303..623cae35b3 100644
--- a/demux/demux_edl.c
+++ b/demux/demux_edl.c
@@ -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;
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 7857934642..124956378c 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -22,6 +22,7 @@
#include <stdbool.h>
#include <string.h>
#include <strings.h>
+#include <errno.h>
#include <assert.h>
#include "config.h"
@@ -167,6 +168,8 @@ static const struct format_hack format_hacks[] = {
BLACKLIST("bin"),
// Useless, does not work with custom streams.
BLACKLIST("image2"),
+ // Probably a security risk.
+ BLACKLIST("ffm"),
// Image demuxers ("<name>_pipe" is detected explicitly)
{"image2pipe", .image_format = true},
{0}
@@ -574,13 +577,8 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
AVFormatContext *avfc = priv->avfc;
AVStream *st = avfc->streams[i];
struct sh_stream *sh = NULL;
-#if HAVE_AVCODEC_HAS_CODECPAR
AVCodecParameters *codec = st->codecpar;
int lavc_delay = codec->initial_padding;
-#else
- AVCodecContext *codec = st->codec;
- int lavc_delay = codec->delay;
-#endif
switch (codec->codec_type) {
case AVMEDIA_TYPE_AUDIO: {
@@ -676,17 +674,9 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
sh->ff_index = st->index;
sh->codec->codec = mp_codec_from_av_codec_id(codec->codec_id);
sh->codec->codec_tag = codec->codec_tag;
-#if HAVE_AVCODEC_HAS_CODECPAR
sh->codec->lav_codecpar = avcodec_parameters_alloc();
if (sh->codec->lav_codecpar)
avcodec_parameters_copy(sh->codec->lav_codecpar, codec);
-#else
- sh->codec->codec = mp_codec_from_av_codec_id(codec->codec_id);
- sh->codec->codec_tag = codec->codec_tag;
- sh->codec->lav_headers = avcodec_alloc_context3(NULL);
- if (sh->codec->lav_headers)
- mp_copy_lav_codec_headers(sh->codec->lav_headers, codec);
-#endif
sh->codec->native_tb_num = st->time_base.num;
sh->codec->native_tb_den = st->time_base.den;
@@ -752,6 +742,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;
@@ -853,6 +851,10 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
.opaque = demuxer,
};
+ avfc->opaque = demuxer;
+ if (!demuxer->access_references)
+ avfc->io_open = block_io_open;
+
mp_set_avdict(&dopts, lavfdopts->avopts);
if (avformat_open_input(&avfc, priv->filename, priv->avif, &dopts) < 0) {
@@ -936,14 +938,9 @@ static int demux_lavf_fill_buffer(demuxer_t *demux)
if (pkt->dts != AV_NOPTS_VALUE)
dp->dts = pkt->dts * av_q2d(st->time_base);
dp->duration = pkt->duration * av_q2d(st->time_base);
-#if !HAVE_AV_AVPACKET_INT64_DURATION
- if (pkt->convergence_duration > 0)
- dp->duration = pkt->convergence_duration * av_q2d(st->time_base);
-#endif
dp->pos = pkt->pos;
dp->keyframe = pkt->flags & AV_PKT_FLAG_KEY;
-#if LIBAVFORMAT_VERSION_MICRO >= 100 && \
- LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 50, 100)
+#if LIBAVFORMAT_VERSION_MICRO >= 100
if (pkt->flags & AV_PKT_FLAG_DISCARD)
MP_ERR(demux, "Edit lists are not correctly supported (FFmpeg issue).\n");
#endif
@@ -1124,12 +1121,8 @@ static void demux_close_lavf(demuxer_t *demuxer)
av_freep(&priv->pb->buffer);
av_freep(&priv->pb);
for (int n = 0; n < priv->num_streams; n++) {
- if (priv->streams[n]) {
- avcodec_free_context(&priv->streams[n]->codec->lav_headers);
-#if HAVE_AVCODEC_HAS_CODECPAR
+ if (priv->streams[n])
avcodec_parameters_free(&priv->streams[n]->codec->lav_codecpar);
-#endif
- }
}
if (priv->own_stream)
free_stream(priv->stream);
diff --git a/demux/demux_libarchive.c b/demux/demux_libarchive.c
index dcdbe65fc0..41b05368ca 100644
--- a/demux/demux_libarchive.c
+++ b/demux/demux_libarchive.c
@@ -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) {
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 63b58cdb15..ddda2ecb61 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -128,6 +128,8 @@ typedef struct mkv_track {
AVCodecParserContext *av_parser;
AVCodecContext *av_parser_codec;
+ bool require_keyframes;
+
/* stuff for realaudio braincancer */
double ra_pts; /* previous audio timestamp */
uint32_t sub_packet_size; ///< sub packet size, per stream
@@ -200,7 +202,7 @@ typedef struct mkv_demuxer {
bool index_has_durations;
- bool eof_warning;
+ bool eof_warning, keyframe_warning;
struct block_info tmp_block;
} mkv_demuxer_t;
@@ -1511,7 +1513,7 @@ static void parse_flac_chmap(struct mp_chmap *channels, unsigned char *data,
}
static const char *const mkv_audio_tags[][2] = {
- { "A_MPEG/L2", "mp3" },
+ { "A_MPEG/L2", "mp2" },
{ "A_MPEG/L3", "mp3" },
{ "A_AC3", "ac3" },
{ "A_EAC3", "eac3" },
@@ -1701,7 +1703,9 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
mp_chmap_set_unknown(&sh_a->channels, track->a_channels);
const char *codec = sh_a->codec;
- if (!strcmp(codec, "mp3") || !strcmp(codec, "truehd")) {
+ if (!strcmp(codec, "mp2") || !strcmp(codec, "mp3") ||
+ !strcmp(codec, "truehd"))
+ {
track->parse = true;
} else if (!strcmp(codec, "flac")) {
unsigned char *ptr = extradata;
@@ -1750,6 +1754,11 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
if (sh_a->samplerate == 8000 && strcmp(codec, "ac3") == 0)
track->default_duration = 0;
+ // Deal with some FFmpeg-produced garbage, and assume all audio codecs can
+ // start decoding from anywhere.
+ if (strcmp(codec, "truehd") != 0)
+ track->require_keyframes = true;
+
sh_a->extradata = extradata;
sh_a->extradata_size = extradata_len;
@@ -2472,6 +2481,15 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
current_pts = tc / 1e9 - track->codec_delay;
+ if (track->require_keyframes && !keyframe) {
+ keyframe = true;
+ if (!mkv_d->keyframe_warning) {
+ MP_WARN(demuxer, "This is a broken file! Packets with incorrect "
+ "keyframe flag found. Enabling workaround.\n");
+ mkv_d->keyframe_warning = true;
+ }
+ }
+
if (track->type == MATROSKA_TRACK_AUDIO) {
if (mkv_d->a_skip_to_keyframe)
use_this_block &= keyframe;
diff --git a/demux/demux_mkv_timeline.c b/demux/demux_mkv_timeline.c
index 15f9a5d594..476551c58b 100644
--- a/demux/demux_mkv_timeline.c
+++ b/demux/demux_mkv_timeline.c
@@ -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);
diff --git a/demux/demux_playlist.c b/demux/demux_playlist.c
index 7479db149f..0f2ebedd76 100644
--- a/demux/demux_playlist.c
+++ b/demux/demux_playlist.c
@@ -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);
diff --git a/demux/demux_rar.c b/demux/demux_rar.c
index f35c2ccf66..7d9adfc28a 100644
--- a/demux/demux_rar.c
+++ b/demux/demux_rar.c
@@ -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;
diff --git a/demux/stheader.h b/demux/stheader.h
index 240be72a46..26c1246d66 100644
--- a/demux/stheader.h
+++ b/demux/stheader.h
@@ -71,8 +71,6 @@ struct mp_codec_params {
int extradata_size;
// Codec specific header data (set by demux_lavf.c only)
- // Which one is in use depends on HAVE_AVCODEC_HAS_CODECPAR.
- struct AVCodecContext *lav_headers;
struct AVCodecParameters *lav_codecpar;
// Timestamp granularity for converting double<->rational timestamps.