summaryrefslogtreecommitdiffstats
path: root/libmpdemux/demux_mkv.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2011-08-04 08:38:39 +0300
committerUoti Urpala <uau@mplayer2.org>2011-08-04 08:38:39 +0300
commit0ece360eeaf95f2c33df2c0177cb98ffd5fc0338 (patch)
tree3717c71405b255342f75008b8d357f421f9f24f0 /libmpdemux/demux_mkv.c
parent1f3ad329601486e2e2e36ddef4d79f0f486ddc99 (diff)
downloadmpv-0ece360eeaf95f2c33df2c0177cb98ffd5fc0338.tar.bz2
mpv-0ece360eeaf95f2c33df2c0177cb98ffd5fc0338.tar.xz
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.
Diffstat (limited to 'libmpdemux/demux_mkv.c')
-rw-r--r--libmpdemux/demux_mkv.c82
1 files changed, 50 insertions, 32 deletions
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
};