From 035297212a22f219cdc7bcf4341a154fd2516c28 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 21 May 2016 16:39:44 +0200 Subject: 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. --- demux/demux_mkv.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'demux') 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); } } -- cgit v1.2.3