diff options
Diffstat (limited to 'demux')
-rw-r--r-- | demux/demux.c | 7 | ||||
-rw-r--r-- | demux/demux.h | 1 | ||||
-rw-r--r-- | demux/demux_cue.c | 3 | ||||
-rw-r--r-- | demux/demux_edl.c | 3 | ||||
-rw-r--r-- | demux/demux_lavf.c | 41 | ||||
-rw-r--r-- | demux/demux_libarchive.c | 3 | ||||
-rw-r--r-- | demux/demux_mkv.c | 24 | ||||
-rw-r--r-- | demux/demux_mkv_timeline.c | 2 | ||||
-rw-r--r-- | demux/demux_playlist.c | 5 | ||||
-rw-r--r-- | demux/demux_rar.c | 3 | ||||
-rw-r--r-- | demux/stheader.h | 2 |
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. |