1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-19 05:15:12 +00:00

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.
This commit is contained in:
wm4 2016-12-19 21:29:46 +01:00
parent e57037dc95
commit 3b5777d86a

View File

@ -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;