path: root/demux
diff options
authorwm4 <wm4@nowhere>2016-05-21 16:39:44 +0200
committerwm4 <wm4@nowhere>2016-05-21 16:39:44 +0200
commit035297212a22f219cdc7bcf4341a154fd2516c28 (patch)
tree9628927266e1c3970d8b4cde6ba282be2d344bed /demux
parent79afa347cc8eb0a52e3acc11598eb6d497b938d5 (diff)
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')
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)
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);
@@ -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);