summaryrefslogtreecommitdiffstats
path: root/libmpdemux/demux_mkv.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2010-01-25 13:19:09 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-01-27 14:26:48 +0200
commitd8a6af2980e7ecfee0a3e53896f4617d981ce56c (patch)
treedecc5630641083c7add9fc7b6b7b18d21e471718 /libmpdemux/demux_mkv.c
parentf90e9a86d133a32d5b15b5ee3472f1a49cabc206 (diff)
downloadmpv-d8a6af2980e7ecfee0a3e53896f4617d981ce56c.tar.bz2
mpv-d8a6af2980e7ecfee0a3e53896f4617d981ce56c.tar.xz
demux_mkv: improve Cues parsing
Rewrite Cues parsing code using the new EBML parser. The new version fixes a hang in some cases of incomplete files and supports a cuepoint specifying multiple tracks per timecode (the previous code added an index entry for the track mentioned last only).
Diffstat (limited to 'libmpdemux/demux_mkv.c')
-rw-r--r--libmpdemux/demux_mkv.c83
1 files changed, 18 insertions, 65 deletions
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c
index fe925f15ec..8a60da0836 100644
--- a/libmpdemux/demux_mkv.c
+++ b/libmpdemux/demux_mkv.c
@@ -955,8 +955,6 @@ static int demux_mkv_read_cues(demuxer_t *demuxer)
{
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
stream_t *s = demuxer->stream;
- uint64_t length, l, time, track, pos;
- int i, il;
if (index_mode == 0 || index_mode == 2) {
ebml_read_skip(s, NULL);
@@ -964,69 +962,22 @@ static int demux_mkv_read_cues(demuxer_t *demuxer)
}
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing cues ] -----------\n");
- length = ebml_read_length(s, NULL);
-
- while (length > 0) {
- time = track = pos = EBML_UINT_INVALID;
-
- switch (ebml_read_id(s, &il)) {
- case MATROSKA_ID_CUEPOINT:;
- uint64_t len;
-
- len = ebml_read_length(s, &i);
- l = len + i;
-
- while (len > 0) {
- uint64_t l;
- int il;
-
- switch (ebml_read_id(s, &il)) {
- case MATROSKA_ID_CUETIME:
- time = ebml_read_uint(s, &l);
- break;
-
- case MATROSKA_ID_CUETRACKPOSITIONS:;
- uint64_t le = ebml_read_length(s, &i);
- l = le + i;
-
- while (le > 0) {
- uint64_t l;
- int il;
-
- switch (ebml_read_id(s, &il)) {
- case MATROSKA_ID_CUETRACK:
- track = ebml_read_uint(s, &l);
- break;
-
- case MATROSKA_ID_CUECLUSTERPOSITION:
- pos = ebml_read_uint(s, &l);
- break;
-
- default:
- ebml_read_skip(s, &l);
- break;
- }
- le -= l + il;
- }
- break;
-
- default:
- ebml_read_skip(s, &l);
- break;
- }
- len -= l + il;
- }
- break;
-
- default:
- ebml_read_skip(s, &l);
- break;
+ struct ebml_cues cues = {};
+ struct ebml_parse_ctx parse_ctx = {};
+ if (ebml_read_element(s, &parse_ctx, &cues, &ebml_cues_desc) < 0)
+ goto out;
+ 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_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Malformed CuePoint element\n");
+ continue;
}
-
- length -= l + il;
-
- if (time != EBML_UINT_INVALID && track != EBML_UINT_INVALID
- && pos != EBML_UINT_INVALID) {
+ uint64_t time = cuepoint->cue_time;
+ for (int i = 0; i < cuepoint->n_cue_track_positions; i++) {
+ struct ebml_cue_track_positions *trackpos =
+ &cuepoint->cue_track_positions[i];
+ uint64_t track = trackpos->cue_track;
+ uint64_t pos = trackpos->cue_cluster_position;
mkv_d->indexes =
grow_array(mkv_d->indexes, mkv_d->num_indexes,
sizeof(mkv_index_t));
@@ -1035,14 +986,16 @@ static int demux_mkv_read_cues(demuxer_t *demuxer)
mkv_d->indexes[mkv_d->num_indexes].filepos =
mkv_d->segment_start + pos;
mp_msg(MSGT_DEMUX, MSGL_DBG2,
- "[mkv] |+ found cue point " "for track %" PRIu64
+ "[mkv] |+ found cue point for track %" PRIu64
": timecode %" PRIu64 ", filepos: %" PRIu64 "\n", track,
time, mkv_d->segment_start + pos);
mkv_d->num_indexes++;
}
}
+ out:
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing cues ] -----------\n");
+ talloc_free(parse_ctx.talloc_ctx);
return 0;
}