summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/en/input.rst1
-rw-r--r--demux/demux.c19
-rw-r--r--demux/demux.h6
-rw-r--r--demux/demux_lavf.c7
-rw-r--r--demux/demux_mkv.c19
-rw-r--r--mpvcore/command.c17
6 files changed, 59 insertions, 10 deletions
diff --git a/DOCS/man/en/input.rst b/DOCS/man/en/input.rst
index bacb99c14b..c05fb664de 100644
--- a/DOCS/man/en/input.rst
+++ b/DOCS/man/en/input.rst
@@ -412,6 +412,7 @@ Name W Comment
``angle`` x current DVD angle
``metadata`` metadata key/value pairs
``metadata/<key>`` value of metadata entry ``<key>``
+``chapter-metadata`` metadata of current chapter (works similar)
``pause`` x pause status (bool)
``cache`` network cache fill state (0-100)
``pts-association-mode`` x see ``--pts-association-mode``
diff --git a/demux/demux.c b/demux/demux.c
index 8d84d4450c..c3635b9ab1 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -870,18 +870,33 @@ void demuxer_sort_chapters(demuxer_t *demuxer)
}
int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name,
- uint64_t start, uint64_t end)
+ uint64_t start, uint64_t end, uint64_t demuxer_id)
{
struct demux_chapter new = {
.original_index = demuxer->num_chapters,
.start = start,
.end = end,
.name = name.len ? bstrdup0(demuxer, name) : NULL,
+ .metadata = talloc_zero(demuxer, struct mp_tags),
+ .demuxer_id = demuxer_id,
};
+ mp_tags_set_bstr(new.metadata, bstr0("title"), name);
MP_TARRAY_APPEND(demuxer, demuxer->chapters, demuxer->num_chapters, new);
return 0;
}
+void demuxer_add_chapter_info(struct demuxer *demuxer, uint64_t demuxer_id,
+ bstr key, bstr value)
+{
+ for (int n = 0; n < demuxer->num_chapters; n++) {
+ struct demux_chapter *ch = &demuxer->chapters[n];
+ if (ch->demuxer_id == demuxer_id) {
+ mp_tags_set_bstr(ch->metadata, key, value);
+ return;
+ }
+ }
+}
+
static void add_stream_chapters(struct demuxer *demuxer)
{
if (demuxer->num_chapters)
@@ -892,7 +907,7 @@ static void add_stream_chapters(struct demuxer *demuxer)
if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p)
!= STREAM_OK)
return;
- demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0);
+ demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0, 0);
}
}
diff --git a/demux/demux.h b/demux/demux.h
index 00758ea012..c42c964fa9 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -122,6 +122,8 @@ typedef struct demux_chapter
int original_index;
uint64_t start, end;
char *name;
+ struct mp_tags *metadata;
+ uint64_t demuxer_id; // for mapping to internal demuxer data structures
} demux_chapter_t;
struct matroska_data {
@@ -253,7 +255,9 @@ void demuxer_help(void);
int demuxer_add_attachment(struct demuxer *demuxer, struct bstr name,
struct bstr type, struct bstr data);
int demuxer_add_chapter(struct demuxer *demuxer, struct bstr name,
- uint64_t start, uint64_t end);
+ uint64_t start, uint64_t end, uint64_t demuxer_id);
+void demuxer_add_chapter_info(struct demuxer *demuxer, uint64_t demuxer_id,
+ bstr key, bstr value);
int demuxer_seek_chapter(struct demuxer *demuxer, int chapter,
double *seek_pts);
void demuxer_sort_chapters(demuxer_t *demuxer);
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 908eb3c111..dbe16a76b9 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -627,7 +627,12 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
(AVRational){1, 1000000000});
t = av_dict_get(c->metadata, "title", NULL, 0);
demuxer_add_chapter(demuxer, t ? bstr0(t->value) : bstr0(NULL),
- start, end);
+ start, end, i);
+ AVDictionaryEntry *t = NULL;
+ while ((t = av_dict_get(c->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
+ demuxer_add_chapter_info(demuxer, i, bstr0(t->key),
+ bstr0(t->value));
+ }
}
add_new_streams(demuxer);
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index a391dde5a6..120bbbb93a 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -878,7 +878,8 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
BSTR_P(name));
if (idx == selected_edition){
- demuxer_add_chapter(demuxer, name, chapter.start, chapter.end);
+ demuxer_add_chapter(demuxer, name, chapter.start, chapter.end,
+ ca->chapter_uid);
if (editions[idx].edition_flag_ordered) {
chapter.name = talloc_strndup(m_chapters, name.start,
name.len);
@@ -913,11 +914,21 @@ static int demux_mkv_read_tags(demuxer_t *demuxer)
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_chapter_uid || tag.targets.target_attachment_uid)
+ tag.targets.target_attachment_uid)
continue;
- for (int j = 0; j < tag.n_simple_tag; j++)
- demux_info_add_bstr(demuxer, tag.simple_tag[j].tag_name, tag.simple_tag[j].tag_string);
+ if (tag.targets.target_chapter_uid) {
+ for (int j = 0; j < tag.n_simple_tag; j++) {
+ demuxer_add_chapter_info(demuxer, tag.targets.target_chapter_uid,
+ 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,
+ tag.simple_tag[j].tag_string);
+ }
+ }
}
talloc_free(parse_ctx.talloc_ctx);
diff --git a/mpvcore/command.c b/mpvcore/command.c
index d8642e40fa..d986ae1a64 100644
--- a/mpvcore/command.c
+++ b/mpvcore/command.c
@@ -694,6 +694,19 @@ static int mp_property_metadata(m_option_t *prop, int action, void *arg,
return tag_property(prop, action, arg, demuxer->metadata);
}
+static int mp_property_chapter_metadata(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
+ struct demuxer *demuxer = mpctx->master_demuxer;
+ int chapter = get_current_chapter(mpctx);
+ if (!demuxer || chapter < 0)
+ return M_PROPERTY_UNAVAILABLE;
+
+ assert(chapter < demuxer->num_chapters);
+
+ return tag_property(prop, action, arg, demuxer->chapters[chapter].metadata);
+}
+
static int mp_property_pause(m_option_t *prop, int action, void *arg,
void *ctx)
{
@@ -1741,8 +1754,8 @@ static const m_option_t mp_properties[] = {
0, 0, 0, NULL },
{ "editions", mp_property_editions, CONF_TYPE_INT },
{ "angle", mp_property_angle, &m_option_type_dummy },
- { "metadata", mp_property_metadata, CONF_TYPE_STRING_LIST,
- 0, 0, 0, NULL },
+ { "metadata", mp_property_metadata, CONF_TYPE_STRING_LIST },
+ { "chapter-metadata", mp_property_chapter_metadata, CONF_TYPE_STRING_LIST },
M_OPTION_PROPERTY_CUSTOM("pause", mp_property_pause),
{ "cache", mp_property_cache, CONF_TYPE_INT },
M_OPTION_PROPERTY("pts-association-mode"),