summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-12-19 21:29:46 +0100
committerwm4 <wm4@nowhere>2016-12-19 21:29:46 +0100
commit3b5777d86a62b9975c4c0fd224140e494db66ada (patch)
tree9121a0244005cbc2c0f051425dc018d219f9d7a5 /demux
parente57037dc952def5c2b2d2be7535052f94dfb9294 (diff)
downloadmpv-3b5777d86a62b9975c4c0fd224140e494db66ada.tar.bz2
mpv-3b5777d86a62b9975c4c0fd224140e494db66ada.tar.xz
demux_mkv: fix seeking in some broken files
Some files have audio tracks with packets that do not have a keyframe flag set at all. I don't think there's any audio codec which actually needs keyframe flags, so always assume an audio packet is a keyframe (which, in Matroska terminology, means it can start decoding from that packet). The file in question had these set: | + Multiplexing application: Lavf57.56.100 at 313 | + Writing application: Lavf57.56.100 at 329 Garbage produced by garbage... There are other such files produced by mkvmerge, though. It's not perfectly sure whether these have been produced by FFmpeg as well (mkvmerge often trusts the information in the source file, even if it's wrong - so other samples could have been remuxed from FFmpeg). Fixes #3920.
Diffstat (limited to 'demux')
-rw-r--r--demux/demux_mkv.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 5598cf8374..d127e517dc 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;
@@ -1752,6 +1754,10 @@ 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.
+ track->require_keyframes = true;
+
sh_a->extradata = extradata;
sh_a->extradata_size = extradata_len;
@@ -2474,6 +2480,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;