From ba07000b886802909a52810568705897d600263a Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 8 Sep 2013 06:32:48 +0200 Subject: demux: refactor tag handling Make the code somewhat reuseable, instead of bound to a single demuxer instance. The plan is to add support for per-chapter tags later. --- demux/demux.c | 86 ++++++++++++++++++++++++++++++++----------------------- demux/demux.h | 14 ++++++++- mpvcore/command.c | 36 ++++++++++++++--------- 3 files changed, 86 insertions(+), 50 deletions(-) diff --git a/demux/demux.c b/demux/demux.c index f8653b4411..8d84d4450c 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -542,6 +542,7 @@ static struct demuxer *open_given_type(struct MPOpts *opts, .filepos = -1, .opts = opts, .filename = talloc_strdup(demuxer, stream->url), + .metadata = talloc_zero(demuxer, struct mp_tags), }; demuxer->params = params; // temporary during open() stream_seek(stream, stream->start_pos); @@ -684,6 +685,42 @@ int demux_seek(demuxer_t *demuxer, float rel_seek_secs, int flags) return 1; } +void mp_tags_set_str(struct mp_tags *tags, const char *key, const char *value) +{ + mp_tags_set_bstr(tags, bstr0(key), bstr0(value)); +} + +void mp_tags_set_bstr(struct mp_tags *tags, bstr key, bstr value) +{ + for (int n = 0; n < tags->num_keys; n++) { + if (bstrcasecmp0(key, tags->keys[n]) == 0) { + talloc_free(tags->values[n]); + tags->values[n] = talloc_strndup(tags, value.start, value.len); + return; + } + } + + MP_RESIZE_ARRAY(tags, tags->keys, tags->num_keys + 1); + MP_RESIZE_ARRAY(tags, tags->values, tags->num_keys + 1); + tags->keys[tags->num_keys] = talloc_strndup(tags, key.start, key.len); + tags->values[tags->num_keys] = talloc_strndup(tags, value.start, value.len); + tags->num_keys++; +} + +char *mp_tags_get_str(struct mp_tags *tags, const char *key) +{ + return mp_tags_get_bstr(tags, bstr0(key)); +} + +char *mp_tags_get_bstr(struct mp_tags *tags, bstr key) +{ + for (int n = 0; n < tags->num_keys; n++) { + if (bstrcasecmp0(key, tags->keys[n]) == 0) + return tags->values[n]; + } + return NULL; +} + int demux_info_add(demuxer_t *demuxer, const char *opt, const char *param) { return demux_info_add_bstr(demuxer, bstr0(opt), bstr0(param)); @@ -691,49 +728,34 @@ int demux_info_add(demuxer_t *demuxer, const char *opt, const char *param) int demux_info_add_bstr(demuxer_t *demuxer, struct bstr opt, struct bstr param) { - char **info = demuxer->info; - int n = 0; - - - for (n = 0; info && info[2 * n] != NULL; n++) { - if (!bstrcasecmp(opt, bstr0(info[2*n]))) { - if (!bstrcmp(param, bstr0(info[2*n + 1]))) { - mp_msg(MSGT_DEMUX, MSGL_V, "Demuxer info %.*s set to unchanged value %.*s\n", - BSTR_P(opt), BSTR_P(param)); - return 0; - } - mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Demuxer info %.*s changed to %.*s\n", - BSTR_P(opt), BSTR_P(param)); - talloc_free(info[2*n + 1]); - info[2*n + 1] = talloc_strndup(demuxer->info, param.start, param.len); + char *oldval = mp_tags_get_bstr(demuxer->metadata, opt); + if (oldval) { + if (bstrcmp0(param, oldval) == 0) return 0; - } + mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Demuxer info %.*s changed to %.*s\n", + BSTR_P(opt), BSTR_P(param)); } - info = demuxer->info = talloc_realloc(demuxer, info, char *, 2 * (n + 2)); - info[2*n] = talloc_strndup(demuxer->info, opt.start, opt.len); - info[2*n + 1] = talloc_strndup(demuxer->info, param.start, param.len); - memset(&info[2 * (n + 1)], 0, 2 * sizeof(char *)); - + mp_tags_set_bstr(demuxer->metadata, opt, param); return 1; } int demux_info_print(demuxer_t *demuxer) { - char **info = demuxer->info; + struct mp_tags *info = demuxer->metadata; int n; if (!info) return 0; mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Clip info:\n"); - for (n = 0; info[2 * n] != NULL; n++) { - mp_msg(MSGT_DEMUX, MSGL_INFO, " %s: %s\n", info[2 * n], - info[2 * n + 1]); + for (n = 0; n < info->num_keys; n++) { + mp_msg(MSGT_DEMUX, MSGL_INFO, " %s: %s\n", info->keys[n], + info->values[n]); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CLIP_INFO_NAME%d=%s\n", n, - info[2 * n]); + info->keys[n]); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CLIP_INFO_VALUE%d=%s\n", n, - info[2 * n + 1]); + info->values[n]); } mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CLIP_INFO_N=%d\n", n); @@ -742,15 +764,7 @@ int demux_info_print(demuxer_t *demuxer) char *demux_info_get(demuxer_t *demuxer, const char *opt) { - int i; - char **info = demuxer->info; - - for (i = 0; info && info[2 * i] != NULL; i++) { - if (!strcasecmp(opt, info[2 * i])) - return info[2 * i + 1]; - } - - return NULL; + return mp_tags_get_str(demuxer->metadata, opt); } void demux_info_update(struct demuxer *demuxer) diff --git a/demux/demux.h b/demux/demux.h index 6976982e15..00758ea012 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -111,6 +111,12 @@ typedef struct demuxer_desc { int (*control)(struct demuxer *demuxer, int cmd, void *arg); } demuxer_desc_t; +struct mp_tags { + char **keys; + char **values; + int num_keys; +}; + typedef struct demux_chapter { int original_index; @@ -185,8 +191,9 @@ typedef struct demuxer { // If the file is a playlist file struct playlist *playlist; + struct mp_tags *metadata; + void *priv; // demuxer-specific internal data - char **info; // metadata struct MPOpts *opts; struct demuxer_params *params; } demuxer_t; @@ -282,4 +289,9 @@ double demux_packet_list_duration(struct demux_packet **pkts, int num_pkts); struct demux_packet *demux_packet_list_fill(struct demux_packet **pkts, int num_pkts, int *current); +void mp_tags_set_str(struct mp_tags *tags, const char *key, const char *value); +void mp_tags_set_bstr(struct mp_tags *tags, bstr key, bstr value); +char *mp_tags_get_str(struct mp_tags *tags, const char *key); +char *mp_tags_get_bstr(struct mp_tags *tags, bstr key); + #endif /* MPLAYER_DEMUXER_H */ diff --git a/mpvcore/command.c b/mpvcore/command.c index f7bed60713..d8642e40fa 100644 --- a/mpvcore/command.c +++ b/mpvcore/command.c @@ -636,39 +636,38 @@ static int mp_property_angle(m_option_t *prop, int action, void *arg, return M_PROPERTY_NOT_IMPLEMENTED; } -/// Demuxer meta data -static int mp_property_metadata(m_option_t *prop, int action, void *arg, - MPContext *mpctx) +static int tag_property(m_option_t *prop, int action, void *arg, + struct mp_tags *tags) { - struct demuxer *demuxer = mpctx->master_demuxer; - if (!demuxer) - return M_PROPERTY_UNAVAILABLE; - static const m_option_t key_type = { - "metadata", NULL, CONF_TYPE_STRING, 0, 0, 0, NULL + "tags", NULL, CONF_TYPE_STRING, 0, 0, 0, NULL }; switch (action) { case M_PROPERTY_GET: { char **slist = NULL; - m_option_copy(prop, &slist, &demuxer->info); + int num = 0; + for (int n = 0; n < tags->num_keys; n++) { + MP_TARRAY_APPEND(NULL, slist, num, tags->keys[n]); + MP_TARRAY_APPEND(NULL, slist, num, tags->values[n]); + } + MP_TARRAY_APPEND(NULL, slist, num, NULL); *(char ***)arg = slist; return M_PROPERTY_OK; } case M_PROPERTY_PRINT: { - char **list = demuxer->info; char *res = NULL; - for (int n = 0; list && list[n]; n += 2) { + for (int n = 0; n < tags->num_keys; n++) { res = talloc_asprintf_append_buffer(res, "%s: %s\n", - list[n], list[n + 1]); + tags->keys[n], tags->values[n]); } *(char **)arg = res; return res ? M_PROPERTY_OK : M_PROPERTY_UNAVAILABLE; } case M_PROPERTY_KEY_ACTION: { struct m_property_action_arg *ka = arg; - char *meta = demux_info_get(demuxer, ka->key); + char *meta = mp_tags_get_str(tags, ka->key); if (!meta) return M_PROPERTY_UNKNOWN; switch (ka->action) { @@ -684,6 +683,17 @@ static int mp_property_metadata(m_option_t *prop, int action, void *arg, return M_PROPERTY_NOT_IMPLEMENTED; } +/// Demuxer meta data +static int mp_property_metadata(m_option_t *prop, int action, void *arg, + MPContext *mpctx) +{ + struct demuxer *demuxer = mpctx->master_demuxer; + if (!demuxer) + return M_PROPERTY_UNAVAILABLE; + + return tag_property(prop, action, arg, demuxer->metadata); +} + static int mp_property_pause(m_option_t *prop, int action, void *arg, void *ctx) { -- cgit v1.2.3