mirror of
https://github.com/mpv-player/mpv
synced 2025-04-11 04:01:31 +00:00
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).
This commit is contained in:
parent
f90e9a86d1
commit
d8a6af2980
@ -955,8 +955,6 @@ static int demux_mkv_read_cues(demuxer_t *demuxer)
|
|||||||
{
|
{
|
||||||
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
||||||
stream_t *s = demuxer->stream;
|
stream_t *s = demuxer->stream;
|
||||||
uint64_t length, l, time, track, pos;
|
|
||||||
int i, il;
|
|
||||||
|
|
||||||
if (index_mode == 0 || index_mode == 2) {
|
if (index_mode == 0 || index_mode == 2) {
|
||||||
ebml_read_skip(s, NULL);
|
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");
|
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing cues ] -----------\n");
|
||||||
length = ebml_read_length(s, NULL);
|
struct ebml_cues cues = {};
|
||||||
|
struct ebml_parse_ctx parse_ctx = {};
|
||||||
while (length > 0) {
|
if (ebml_read_element(s, &parse_ctx, &cues, &ebml_cues_desc) < 0)
|
||||||
time = track = pos = EBML_UINT_INVALID;
|
goto out;
|
||||||
|
for (int i = 0; i < cues.n_cue_point; i++) {
|
||||||
switch (ebml_read_id(s, &il)) {
|
struct ebml_cue_point *cuepoint = &cues.cue_point[i];
|
||||||
case MATROSKA_ID_CUEPOINT:;
|
if (cuepoint->n_cue_time != 1 || !cuepoint->n_cue_track_positions) {
|
||||||
uint64_t len;
|
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Malformed CuePoint element\n");
|
||||||
|
continue;
|
||||||
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;
|
uint64_t time = cuepoint->cue_time;
|
||||||
}
|
for (int i = 0; i < cuepoint->n_cue_track_positions; i++) {
|
||||||
break;
|
struct ebml_cue_track_positions *trackpos =
|
||||||
|
&cuepoint->cue_track_positions[i];
|
||||||
default:
|
uint64_t track = trackpos->cue_track;
|
||||||
ebml_read_skip(s, &l);
|
uint64_t pos = trackpos->cue_cluster_position;
|
||||||
break;
|
|
||||||
}
|
|
||||||
len -= l + il;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ebml_read_skip(s, &l);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
length -= l + il;
|
|
||||||
|
|
||||||
if (time != EBML_UINT_INVALID && track != EBML_UINT_INVALID
|
|
||||||
&& pos != EBML_UINT_INVALID) {
|
|
||||||
mkv_d->indexes =
|
mkv_d->indexes =
|
||||||
grow_array(mkv_d->indexes, mkv_d->num_indexes,
|
grow_array(mkv_d->indexes, mkv_d->num_indexes,
|
||||||
sizeof(mkv_index_t));
|
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->indexes[mkv_d->num_indexes].filepos =
|
||||||
mkv_d->segment_start + pos;
|
mkv_d->segment_start + pos;
|
||||||
mp_msg(MSGT_DEMUX, MSGL_DBG2,
|
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,
|
": timecode %" PRIu64 ", filepos: %" PRIu64 "\n", track,
|
||||||
time, mkv_d->segment_start + pos);
|
time, mkv_d->segment_start + pos);
|
||||||
mkv_d->num_indexes++;
|
mkv_d->num_indexes++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing cues ] -----------\n");
|
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing cues ] -----------\n");
|
||||||
|
talloc_free(parse_ctx.talloc_ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user