summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-08-26 22:47:07 +0200
committerwm4 <wm4@nowhere>2015-08-26 22:47:07 +0200
commitba384fffca982465e63c3ffe3a3fb34c08e75de2 (patch)
treebdce42a10ea223eacbaa5e6509927e39ebf945de
parentdae464a4910e552e51357f697efdad17ba08b900 (diff)
downloadmpv-ba384fffca982465e63c3ffe3a3fb34c08e75de2.tar.bz2
mpv-ba384fffca982465e63c3ffe3a3fb34c08e75de2.tar.xz
demux_mkv: discard broken index
Add a simplistic heuristic for detecting broken indexes. This includes indexes with very few elements (apparently libavformat sometimes writes such indexes, or used to), and indexes with broken timestamps. The latter was apparently produced by very old HandBrake versions: | + Muxing application: libmkv 0.6.1.2 | + Writing application: HandBrake 0.9.1 These broken files seem to be common enough that libavformat added a workaround for them in 2008 (and maybe again in 2015). Apparently all timestamps are multiplied with the file's tc_scale twice, and FFmpeg attempts to fix them. We should throw away the whole thing.
-rw-r--r--demux/demux_mkv.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 89a7d42114..e2743d5ef8 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -735,15 +735,25 @@ static int demux_mkv_read_cues(demuxer_t *demuxer)
if (ebml_read_element(s, &parse_ctx, &cues, &ebml_cues_desc) < 0)
return -1;
- mkv_d->num_indexes = 0;
- mkv_d->index_has_durations = false;
-
for (int i = 0; i < cues.n_cue_point; i++) {
struct ebml_cue_point *cuepoint = &cues.cue_point[i];
if (cuepoint->n_cue_time != 1 || !cuepoint->n_cue_track_positions) {
MP_WARN(demuxer, "Malformed CuePoint element\n");
- continue;
+ goto done;
}
+ if (cuepoint->cue_time / 1e9 > mkv_d->duration / mkv_d->tc_scale * 10 &&
+ mkv_d->duration != 0)
+ goto done;
+ }
+ if (cues.n_cue_point <= 3) // probably too sparse and will just break seeking
+ goto done;
+
+ // Discard incremental index.
+ mkv_d->num_indexes = 0;
+ mkv_d->index_has_durations = false;
+
+ for (int i = 0; i < cues.n_cue_point; i++) {
+ struct ebml_cue_point *cuepoint = &cues.cue_point[i];
uint64_t time = cuepoint->cue_time;
for (int c = 0; c < cuepoint->n_cue_track_positions; c++) {
struct ebml_cue_track_positions *trackpos =
@@ -763,6 +773,9 @@ static int demux_mkv_read_cues(demuxer_t *demuxer)
// Do not attempt to create index on the fly.
mkv_d->index_complete = true;
+done:
+ if (!mkv_d->index_complete)
+ MP_WARN(demuxer, "Discarding potentially broken or useless index.\n");
talloc_free(parse_ctx.talloc_ctx);
return 0;
}