diff options
author | wm4 <wm4@nowhere> | 2016-05-21 16:39:44 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-05-21 16:39:44 +0200 |
commit | 035297212a22f219cdc7bcf4341a154fd2516c28 (patch) | |
tree | 9628927266e1c3970d8b4cde6ba282be2d344bed /demux/demux_mkv.c | |
parent | 79afa347cc8eb0a52e3acc11598eb6d497b938d5 (diff) | |
download | mpv-035297212a22f219cdc7bcf4341a154fd2516c28.tar.bz2 mpv-035297212a22f219cdc7bcf4341a154fd2516c28.tar.xz |
demux_mkv: better resync behavior for broken google-created webms
I've got a broken webm that fails to seek correctly with "--start=0".
The problem is that every index entry points to 1 byte before cluster
start (!!!). demux_mkv tries to resync to the next cluster, but since it
already has read 2 bytes with ebml_read_id(), it doesn't get the first
cluster, but the following one. Actually, it can be any amount of bytes
from 1-4, whatever happens to look valid at this essentially random byte
position.
Improve this by resyncing from the original position, instead of the one
after the EBML element ID has been attempted to be read.
The file shows the following headers:
| + Muxing application: google at 177
| + Writing application: google at 186
Indeed, the file was downloaded with youtube-dl. I can only guess that
Google got it completely wrong.
Diffstat (limited to 'demux/demux_mkv.c')
-rw-r--r-- | demux/demux_mkv.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 210f4d643f..a77b2501b3 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -2610,6 +2610,7 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block) find_next_cluster: mkv_d->cluster_end = 0; for (;;) { + stream_peek(s, 4); // guarantee we can undo ebml_read_id() below mkv_d->cluster_start = stream_tell(s); uint32_t id = ebml_read_id(s); if (id == MATROSKA_ID_CLUSTER) @@ -2628,6 +2629,7 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block) if ((!ebml_is_mkv_level1_id(id) && id != EBML_ID_VOID) || ebml_read_skip(demuxer->log, -1, s) != 0) { + stream_seek(s, mkv_d->cluster_start); ebml_resync_cluster(demuxer->log, s); } } |