1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-19 06:17:00 +00:00

demux_mkv: fix ordered chapter sources with ordered editions

Commit f72a900892 (and others) added support for ordered editions that
recursively refer to other ordered editions. However, this recursion
code incorrectly activated if the source files had ordered chapters
even if the main file only wanted to use them as raw video, resulting
in broken timeline info overall.

Ordered chapters can specify a ChapterSegmentEditionUID value if they
want to use a specific edition from a source file. Otherwise the
source is supposed to be used as a raw video file. The code checked
demuxer->matroska_data.num_ordered_chapters for an opened source file
to see whether it was using a recursive ordered edition, but demux_mkv
could enable a default ordered edition for the file using the normal
playback rules even if the main file had not specified any
ChapterSegmentEditionUID. Thus this incorrectly enabled recursion if a
source file had a default edition using ordered chapters. Check
demuxer->matroska_data.uid.edition instead, and ensure it's never set
if a file is opened without ChapterSegmentEditionUID.

Also fix what seems like a memory leak in demux_mkv.c.

Signed-off-by: wm4 <wm4@nowhere>
This commit is contained in:
Uoti Urpala 2016-10-22 18:55:31 +03:00 committed by wm4
parent 3a78eefc88
commit 18681a7dd2
2 changed files with 18 additions and 13 deletions

View File

@ -862,6 +862,7 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
if (wanted_edition_uid) {
MP_ERR(demuxer, "Unable to find expected edition uid: %"PRIu64"\n",
wanted_edition_uid);
talloc_free(parse_ctx.talloc_ctx);
return -1;
} else {
selected_edition = 0;

View File

@ -188,27 +188,31 @@ static bool check_file_seg(struct tl_ctx *ctx, char *filename, int segment)
if (ctx->sources[i])
continue;
/* Accept the source if the segment uid matches and the edition
* either matches or isn't specified. */
* either matches or isn't specified. */
if (!memcmp(uid->segment, m->uid.segment, 16) &&
(!uid->edition || uid->edition == m->uid.edition))
{
MP_INFO(ctx, "Match for source %d: %s\n", i, d->filename);
for (int j = 0; j < m->num_ordered_chapters; j++) {
struct matroska_chapter *c = m->ordered_chapters + j;
if (!uid->edition) {
m->uid.edition = 0;
} else {
for (int j = 0; j < m->num_ordered_chapters; j++) {
struct matroska_chapter *c = m->ordered_chapters + j;
if (!c->has_segment_uid)
continue;
if (!c->has_segment_uid)
continue;
if (has_source_request(ctx, &c->uid))
continue;
if (has_source_request(ctx, &c->uid))
continue;
/* Set the requested segment. */
MP_TARRAY_GROW(NULL, ctx->uids, ctx->num_sources);
ctx->uids[ctx->num_sources] = c->uid;
/* Set the requested segment. */
MP_TARRAY_GROW(NULL, ctx->uids, ctx->num_sources);
ctx->uids[ctx->num_sources] = c->uid;
/* Add a new source slot. */
MP_TARRAY_APPEND(NULL, ctx->sources, ctx->num_sources, NULL);
/* Add a new source slot. */
MP_TARRAY_APPEND(NULL, ctx->sources, ctx->num_sources, NULL);
}
}
if (stream_wants_cache(d->stream, ctx->opts->stream_cache)) {
@ -379,7 +383,7 @@ static void build_timeline_loop(struct tl_ctx *ctx,
/* If we're the source or it's a non-ordered edition reference,
* just add a timeline part from the source. */
if (current_source == j || !linked_m->num_ordered_chapters) {
if (current_source == j || !linked_m->uid.edition) {
uint64_t source_full_length =
demuxer_get_time_length(linked_source) * 1e9;
uint64_t source_length = source_full_length - c->start;