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:
parent
e57037dc95
commit
3b5777d86a
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user