From 0ece360eeaf95f2c33df2c0177cb98ffd5fc0338 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Thu, 4 Aug 2011 08:38:39 +0300 Subject: demux_mkv: skip files faster in ordered chapter file search Ordered chapter code tries opening files to find those matching the SegmentUID values specified in the timeline. Previously this scan did a full initialization of the Matroska demuxer for each file, then checked whether the UID value in the demuxer was a match. Make the scan code instead provide a list of searched-for UIDs to the demuxer open code, and make that do a comparison against the list as soon as it sees the UID in the file, aborting if there is no match. Also fix units used in "Merging timeline part" verbose message. --- libmpdemux/demux_mkv.c | 82 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 32 deletions(-) (limited to 'libmpdemux/demux_mkv.c') diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c index dadb3887cf..692bec9ecf 100644 --- a/libmpdemux/demux_mkv.c +++ b/libmpdemux/demux_mkv.c @@ -374,6 +374,7 @@ static int demux_mkv_read_info(demuxer_t *demuxer) { mkv_demuxer_t *mkv_d = demuxer->priv; stream_t *s = demuxer->stream; + int res = 0; mkv_d->tc_scale = 1000000; mkv_d->duration = 0; @@ -381,7 +382,7 @@ static int demux_mkv_read_info(demuxer_t *demuxer) struct ebml_info info = {}; struct ebml_parse_ctx parse_ctx = {}; if (ebml_read_element(s, &parse_ctx, &info, &ebml_info_desc) < 0) - return 1; + return -1; if (info.n_timecode_scale) { mkv_d->tc_scale = info.timecode_scale; mp_msg(MSGT_DEMUX, MSGL_V, @@ -407,8 +408,22 @@ static int demux_mkv_read_info(demuxer_t *demuxer) mp_msg(MSGT_DEMUX, MSGL_V, "\n"); } } + if (demuxer->params && demuxer->params->matroska_wanted_uids) { + unsigned char (*uids)[16] = demuxer->params->matroska_wanted_uids; + if (!info.n_segment_uid) + uids = NULL; + for (int i = 0; i < MP_TALLOC_ELEMS(uids); i++) { + if (!memcmp(info.segment_uid.start, uids[i], 16)) + goto out; + } + mp_tmsg(MSGT_DEMUX, MSGL_INFO, + "[mkv] This is not one of the wanted files. " + "Stopping attempt to open.\n"); + res = -2; + } + out: talloc_free(parse_ctx.talloc_ctx); - return 0; + return res; } static void parse_trackencodings(struct demuxer *demuxer, @@ -923,7 +938,7 @@ static int demux_mkv_read_seekhead(demuxer_t *demuxer) mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing seek head ] ---------\n"); if (ebml_read_element(s, &parse_ctx, &seekhead, &ebml_seek_head_desc) < 0) { - res = 1; + res = -1; goto out; } /* off now holds the position of the next element after the seek head. */ @@ -940,12 +955,16 @@ static int demux_mkv_read_seekhead(demuxer_t *demuxer) "end of file - incomplete file?\n"); continue; } - read_header_element(demuxer, seek->seek_id, pos); + int r = read_header_element(demuxer, seek->seek_id, pos); + if (r <= -2) { + res = r; + goto out; + } } if (!stream_seek(s, off)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Couldn't seek back after " "SeekHead??\n"); - res = 1; + res = -1; } out: mp_msg(MSGT_DEMUX, MSGL_V, @@ -982,7 +1001,7 @@ static int read_header_element(struct demuxer *demuxer, uint32_t id, return -1; mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] |+ segment information...\n"); mkv_d->parsed_info = true; - return demux_mkv_read_info(demuxer) ? -1 : 1; + return demux_mkv_read_info(demuxer); case MATROSKA_ID_TRACKS: if (mkv_d->parsed_tracks) @@ -1013,7 +1032,7 @@ static int read_header_element(struct demuxer *demuxer, uint32_t id, break; if (at_filepos && !seek_pos_id(s, at_filepos, id)) return -1; - return demux_mkv_read_seekhead(demuxer) ? -1 : 1; + return demux_mkv_read_seekhead(demuxer); case MATROSKA_ID_CHAPTERS: if (mkv_d->parsed_chapters) @@ -1602,12 +1621,22 @@ static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track, return 0; } +static void mkv_free(struct demuxer *demuxer) +{ + struct mkv_demuxer *mkv_d = demuxer->priv; + if (!mkv_d) + return; + for (int i = 0; i < mkv_d->num_tracks; i++) + demux_mkv_free_trackentry(mkv_d->tracks[i]); + free(mkv_d->indexes); + free(mkv_d->cluster_positions); +} + static int demux_mkv_open(demuxer_t *demuxer) { stream_t *s = demuxer->stream; mkv_demuxer_t *mkv_d; mkv_track_t *track; - int i, cont = 0; stream_seek(s, s->start_pos); if (ebml_read_id(s, NULL) != EBML_ID_EBML) @@ -1660,7 +1689,7 @@ static int demux_mkv_open(demuxer_t *demuxer) mkv_d->tc_scale = 1000000; mkv_d->segment_start = stream_tell(s); - while (!cont) { + while (1) { uint32_t id = ebml_read_id(s, NULL); switch (id) { case MATROSKA_ID_CLUSTER: @@ -1668,17 +1697,21 @@ static int demux_mkv_open(demuxer_t *demuxer) "[mkv] |+ found cluster, headers are " "parsed completely :)\n"); stream_seek(s, stream_tell(s) - 4); - cont = 1; - break; - - default: - cont = read_header_element(demuxer, id, 0) < 1; + goto headersdone; + default:; + int res = read_header_element(demuxer, id, 0); + if (res == -2) { + mkv_free(demuxer); + return 0; + } else if (res < 1) + goto headersdone; break; case EBML_ID_VOID: ebml_read_skip(s, NULL); break; } } + headersdone: display_create_tracks(demuxer); @@ -1686,7 +1719,7 @@ static int demux_mkv_open(demuxer_t *demuxer) track = NULL; if (demuxer->video->id == -1) { /* automatically select a video track */ /* search for a video track that has the 'default' flag set */ - for (i = 0; i < mkv_d->num_tracks; i++) + for (int i = 0; i < mkv_d->num_tracks; i++) if (mkv_d->tracks[i]->type == MATROSKA_TRACK_VIDEO && mkv_d->tracks[i]->default_track) { track = mkv_d->tracks[i]; @@ -1696,7 +1729,7 @@ static int demux_mkv_open(demuxer_t *demuxer) if (track == NULL) /* no track has the 'default' flag set */ /* let's take the first video track */ - for (i = 0; i < mkv_d->num_tracks; i++) + for (int i = 0; i < mkv_d->num_tracks; i++) if (mkv_d->tracks[i]->type == MATROSKA_TRACK_VIDEO && mkv_d->tracks[i]->id >= 0) { track = mkv_d->tracks[i]; @@ -1731,21 +1764,6 @@ static int demux_mkv_open(demuxer_t *demuxer) return DEMUXER_TYPE_MATROSKA; } -static void demux_close_mkv(demuxer_t *demuxer) -{ - mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; - - if (mkv_d) { - int i; - if (mkv_d->tracks) { - for (i = 0; i < mkv_d->num_tracks; i++) - demux_mkv_free_trackentry(mkv_d->tracks[i]); - } - free(mkv_d->indexes); - free(mkv_d->cluster_positions); - } -} - static int demux_mkv_read_block_lacing(uint8_t *buffer, uint64_t *size, uint8_t *laces, uint32_t **all_lace_sizes) @@ -2518,7 +2536,7 @@ const demuxer_desc_t demuxer_desc_matroska = { demux_mkv_open, demux_mkv_fill_buffer, NULL, - demux_close_mkv, + mkv_free, demux_mkv_seek, demux_mkv_control }; -- cgit v1.2.3