summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-05-21 16:39:44 +0200
committerwm4 <wm4@nowhere>2016-05-21 16:39:44 +0200
commit035297212a22f219cdc7bcf4341a154fd2516c28 (patch)
tree9628927266e1c3970d8b4cde6ba282be2d344bed
parent79afa347cc8eb0a52e3acc11598eb6d497b938d5 (diff)
downloadmpv-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.
-rw-r--r--demux/demux_mkv.c2
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);
}
}