summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demux/demux.h7
-rw-r--r--demux/demux_mkv.c55
-rw-r--r--player/loadfile.c16
3 files changed, 65 insertions, 13 deletions
diff --git a/demux/demux.h b/demux/demux.h
index 6f9437f2d3..a979a357c1 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -120,6 +120,12 @@ typedef struct demux_chapter
uint64_t demuxer_id; // for mapping to internal demuxer data structures
} demux_chapter_t;
+struct demux_edition {
+ uint64_t demuxer_id;
+ bool default_edition;
+ struct mp_tags *metadata;
+};
+
struct matroska_segment_uid {
unsigned char segment[16];
uint64_t edition;
@@ -175,6 +181,7 @@ typedef struct demuxer {
int num_streams;
bool stream_autoselect;
+ struct demux_edition *editions;
int num_editions;
int edition;
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 29765ca3b4..52862cd3b8 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -173,6 +173,8 @@ typedef struct mkv_demuxer {
mkv_track_t **tracks;
int num_tracks;
+ struct ebml_tags *tags;
+
uint64_t tc_scale, cluster_tc;
uint64_t cluster_start;
@@ -783,6 +785,14 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
int selected_edition = -1;
int num_editions = file_chapters.n_edition_entry;
struct ebml_edition_entry *editions = file_chapters.edition_entry;
+ for (int i = 0; i < num_editions; i++) {
+ struct demux_edition new = {
+ .demuxer_id = editions[i].edition_uid,
+ .default_edition = editions[i].edition_flag_default,
+ .metadata = talloc_zero(demuxer, struct mp_tags),
+ };
+ MP_TARRAY_APPEND(demuxer, demuxer->editions, demuxer->num_editions, new);
+ }
if (wanted_edition >= 0 && wanted_edition < num_editions) {
selected_edition = wanted_edition;
MP_VERBOSE(demuxer, "User-specified edition: %d\n",
@@ -894,9 +904,6 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
}
}
}
- if (num_editions > 1)
- MP_INFO(demuxer, "Found %d editions, will play #%d (first is 0).\n",
- num_editions, selected_edition);
demuxer->num_editions = num_editions;
demuxer->edition = selected_edition;
@@ -908,6 +915,7 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
static int demux_mkv_read_tags(demuxer_t *demuxer)
{
+ struct mkv_demuxer *mkv_d = demuxer->priv;
stream_t *s = demuxer->stream;
struct ebml_parse_ctx parse_ctx = {demuxer->log};
@@ -915,10 +923,22 @@ static int demux_mkv_read_tags(demuxer_t *demuxer)
if (ebml_read_element(s, &parse_ctx, &tags, &ebml_tags_desc) < 0)
return -1;
- for (int i = 0; i < tags.n_tag; i++) {
- struct ebml_tag tag = tags.tag[i];
- if (tag.targets.target_track_uid || tag.targets.target_edition_uid ||
- tag.targets.target_attachment_uid)
+ mkv_d->tags = talloc_memdup(mkv_d, &tags, sizeof(tags));
+ talloc_steal(mkv_d->tags, parse_ctx.talloc_ctx);
+ return 0;
+}
+
+static void process_tags(demuxer_t *demuxer)
+{
+ struct mkv_demuxer *mkv_d = demuxer->priv;
+ struct ebml_tags *tags = mkv_d->tags;
+
+ if (!tags)
+ return;
+
+ for (int i = 0; i < tags->n_tag; i++) {
+ struct ebml_tag tag = tags->tag[i];
+ if (tag.targets.target_track_uid || tag.targets.target_attachment_uid)
continue;
if (tag.targets.target_chapter_uid) {
@@ -927,6 +947,23 @@ static int demux_mkv_read_tags(demuxer_t *demuxer)
tag.simple_tag[j].tag_name,
tag.simple_tag[j].tag_string);
}
+ } else if (tag.targets.target_edition_uid) {
+ struct demux_edition *edition = NULL;
+ for (int n = 0; n < demuxer->num_editions; n++) {
+ if (demuxer->editions[n].demuxer_id ==
+ tag.targets.target_edition_uid)
+ {
+ edition = &demuxer->editions[n];
+ break;
+ }
+ }
+ if (edition) {
+ for (int j = 0; j < tag.n_simple_tag; j++) {
+ mp_tags_set_bstr(edition->metadata,
+ tag.simple_tag[j].tag_name,
+ tag.simple_tag[j].tag_string);
+ }
+ }
} else {
for (int j = 0; j < tag.n_simple_tag; j++) {
demux_info_add_bstr(demuxer, tag.simple_tag[j].tag_name,
@@ -934,9 +971,6 @@ static int demux_mkv_read_tags(demuxer_t *demuxer)
}
}
}
-
- talloc_free(parse_ctx.talloc_ctx);
- return 0;
}
static int demux_mkv_read_attachments(demuxer_t *demuxer)
@@ -1798,6 +1832,7 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check)
MP_VERBOSE(demuxer, "All headers are parsed!\n");
+ process_tags(demuxer);
display_create_tracks(demuxer);
return 0;
diff --git a/player/loadfile.c b/player/loadfile.c
index d673a176c2..9116a0c0df 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -263,9 +263,19 @@ static void print_file_properties(struct MPContext *mpctx)
}
}
struct demuxer *demuxer = mpctx->master_demuxer;
- if (demuxer->num_editions > 1)
- MP_INFO(mpctx, "Playing edition %d of %d (--edition=%d).\n",
- demuxer->edition + 1, demuxer->num_editions, demuxer->edition);
+ if (demuxer->num_editions > 1) {
+ for (int n = 0; n < demuxer->num_editions; n++) {
+ struct demux_edition *edition = &demuxer->editions[n];
+ MP_INFO(mpctx, "[edition] %3s --edition=%d",
+ n == demuxer->edition ? "(+)" : "", n);
+ char *name = mp_tags_get_str(edition->metadata, "title");
+ if (name)
+ MP_INFO(mpctx, " '%s'", name);
+ if (edition->default_edition)
+ MP_INFO(mpctx, " (*)");
+ MP_INFO(mpctx, "\n");
+ }
+ }
for (int t = 0; t < STREAM_TYPE_COUNT; t++) {
for (int n = 0; n < mpctx->num_tracks; n++)
if (mpctx->tracks[n]->type == t)