From 2fe2be4df36c17b460bd9588e9276a2e14e4aca9 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 26 Sep 2013 02:53:54 -0400 Subject: matroska: select the edition using the requested edition uid --- demux/demux_mkv.c | 23 +++++++++++++++++++++-- mpvcore/timeline/tl_matroska.c | 13 ++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 8c827f4131..88e91a3717 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -785,6 +785,12 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer) struct MPOpts *opts = demuxer->opts; stream_t *s = demuxer->stream; int wanted_edition = opts->edition_id; + uint64_t wanted_edition_uid = demuxer->matroska_data.uid.edition; + + /* A specific edition UID was requested; ignore the user option which is + * only applicable to the top-level file. */ + if (wanted_edition_uid) + wanted_edition = -1; mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n"); struct ebml_chapters file_chapters = {}; @@ -793,7 +799,7 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer) &ebml_chapters_desc) < 0) return -1; - int selected_edition = 0; + int selected_edition = -1; int num_editions = file_chapters.n_edition_entry; struct ebml_edition_entry *editions = file_chapters.edition_entry; if (wanted_edition >= 0 && wanted_edition < num_editions) { @@ -802,11 +808,24 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer) selected_edition); } else for (int i = 0; i < num_editions; i++) - if (editions[i].edition_flag_default) { + if (wanted_edition_uid && + editions[i].edition_uid == wanted_edition_uid) { + selected_edition = i; + break; + } else if (editions[i].edition_flag_default) { selected_edition = i; mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Default edition: %d\n", i); break; } + if (selected_edition < 0) { + if (wanted_edition_uid) { + mp_msg(MSGT_DEMUX, MSGL_ERR, + "[mkv] Unable to find expected edition uid: %"PRIu64"\n", + wanted_edition_uid); + return -1; + } else + selected_edition = 0; + } struct matroska_chapter *m_chapters = NULL; if (editions[selected_edition].edition_flag_ordered) { int count = editions[selected_edition].n_chapter_atom; diff --git a/mpvcore/timeline/tl_matroska.c b/mpvcore/timeline/tl_matroska.c index 220aa34ece..51ee657e2a 100644 --- a/mpvcore/timeline/tl_matroska.c +++ b/mpvcore/timeline/tl_matroska.c @@ -175,7 +175,10 @@ static bool check_file_seg(struct MPContext *mpctx, struct demuxer **sources, struct matroska_segment_uid *uid = uids + i; if (sources[i]) continue; - if (!memcmp(uid->segment, m->uid.segment, 16)) { + /* Accept the source if the segment uid matches and the edition + * either matches or isn't specified. */ + if (!memcmp(uid->segment, m->uid.segment, 16) && + (!uid->edition || uid->edition == m->uid.edition)) { mp_msg(MSGT_CPLAYER, MSGL_INFO, "Match for source %d: %s\n", i, d->filename); @@ -294,7 +297,11 @@ void build_ordered_chapter_timeline(struct MPContext *mpctx) memcpy(c->uid.segment, m->uid.segment, 16); for (int j = 0; j < num_sources; j++) - if (!memcmp(c->uid.segment, uids[j].segment, 16)) + /* If there isn't a segment uid, we are the source. If the segment + * uid is our segment uid and the edition matches. We can't accept + * the "don't care" edition value of 0 since the user may have + * requested a non-default edition. */ + if (demux_matroska_uid_cmp(&c->uid, uids + j)) goto found1; memcpy(uids + num_sources, &c->uid, sizeof(c->uid)); sources[num_sources] = NULL; @@ -321,7 +328,7 @@ void build_ordered_chapter_timeline(struct MPContext *mpctx) int j; for (j = 0; j < num_sources; j++) { - if (!memcmp(c->uid.segment, uids[j].segment, 16)) + if (demux_matroska_uid_cmp(&c->uid, uids + j)) goto found2; } missing_time += c->end - c->start; -- cgit v1.2.3