1
mirror of https://github.com/mpv-player/mpv synced 2024-11-07 01:47:00 +01:00

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.
This commit is contained in:
wm4 2013-09-08 06:32:48 +02:00
parent 1aae5981a7
commit ba07000b88
3 changed files with 86 additions and 50 deletions

View File

@ -542,6 +542,7 @@ static struct demuxer *open_given_type(struct MPOpts *opts,
.filepos = -1, .filepos = -1,
.opts = opts, .opts = opts,
.filename = talloc_strdup(demuxer, stream->url), .filename = talloc_strdup(demuxer, stream->url),
.metadata = talloc_zero(demuxer, struct mp_tags),
}; };
demuxer->params = params; // temporary during open() demuxer->params = params; // temporary during open()
stream_seek(stream, stream->start_pos); stream_seek(stream, stream->start_pos);
@ -684,6 +685,42 @@ int demux_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
return 1; 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) int demux_info_add(demuxer_t *demuxer, const char *opt, const char *param)
{ {
return demux_info_add_bstr(demuxer, bstr0(opt), bstr0(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) int demux_info_add_bstr(demuxer_t *demuxer, struct bstr opt, struct bstr param)
{ {
char **info = demuxer->info; char *oldval = mp_tags_get_bstr(demuxer->metadata, opt);
int n = 0; if (oldval) {
if (bstrcmp0(param, oldval) == 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);
return 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)); mp_tags_set_bstr(demuxer->metadata, opt, param);
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 *));
return 1; return 1;
} }
int demux_info_print(demuxer_t *demuxer) int demux_info_print(demuxer_t *demuxer)
{ {
char **info = demuxer->info; struct mp_tags *info = demuxer->metadata;
int n; int n;
if (!info) if (!info)
return 0; return 0;
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Clip info:\n"); mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Clip info:\n");
for (n = 0; info[2 * n] != NULL; n++) { for (n = 0; n < info->num_keys; n++) {
mp_msg(MSGT_DEMUX, MSGL_INFO, " %s: %s\n", info[2 * n], mp_msg(MSGT_DEMUX, MSGL_INFO, " %s: %s\n", info->keys[n],
info[2 * n + 1]); info->values[n]);
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CLIP_INFO_NAME%d=%s\n", 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, 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); 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) char *demux_info_get(demuxer_t *demuxer, const char *opt)
{ {
int i; return mp_tags_get_str(demuxer->metadata, opt);
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;
} }
void demux_info_update(struct demuxer *demuxer) void demux_info_update(struct demuxer *demuxer)

View File

@ -111,6 +111,12 @@ typedef struct demuxer_desc {
int (*control)(struct demuxer *demuxer, int cmd, void *arg); int (*control)(struct demuxer *demuxer, int cmd, void *arg);
} demuxer_desc_t; } demuxer_desc_t;
struct mp_tags {
char **keys;
char **values;
int num_keys;
};
typedef struct demux_chapter typedef struct demux_chapter
{ {
int original_index; int original_index;
@ -185,8 +191,9 @@ typedef struct demuxer {
// If the file is a playlist file // If the file is a playlist file
struct playlist *playlist; struct playlist *playlist;
struct mp_tags *metadata;
void *priv; // demuxer-specific internal data void *priv; // demuxer-specific internal data
char **info; // metadata
struct MPOpts *opts; struct MPOpts *opts;
struct demuxer_params *params; struct demuxer_params *params;
} demuxer_t; } 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, struct demux_packet *demux_packet_list_fill(struct demux_packet **pkts,
int num_pkts, int *current); 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 */ #endif /* MPLAYER_DEMUXER_H */

View File

@ -636,39 +636,38 @@ static int mp_property_angle(m_option_t *prop, int action, void *arg,
return M_PROPERTY_NOT_IMPLEMENTED; return M_PROPERTY_NOT_IMPLEMENTED;
} }
/// Demuxer meta data static int tag_property(m_option_t *prop, int action, void *arg,
static int mp_property_metadata(m_option_t *prop, int action, void *arg, struct mp_tags *tags)
MPContext *mpctx)
{ {
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer)
return M_PROPERTY_UNAVAILABLE;
static const m_option_t key_type = 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) { switch (action) {
case M_PROPERTY_GET: { case M_PROPERTY_GET: {
char **slist = NULL; 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; *(char ***)arg = slist;
return M_PROPERTY_OK; return M_PROPERTY_OK;
} }
case M_PROPERTY_PRINT: { case M_PROPERTY_PRINT: {
char **list = demuxer->info;
char *res = NULL; 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", res = talloc_asprintf_append_buffer(res, "%s: %s\n",
list[n], list[n + 1]); tags->keys[n], tags->values[n]);
} }
*(char **)arg = res; *(char **)arg = res;
return res ? M_PROPERTY_OK : M_PROPERTY_UNAVAILABLE; return res ? M_PROPERTY_OK : M_PROPERTY_UNAVAILABLE;
} }
case M_PROPERTY_KEY_ACTION: { case M_PROPERTY_KEY_ACTION: {
struct m_property_action_arg *ka = arg; 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) if (!meta)
return M_PROPERTY_UNKNOWN; return M_PROPERTY_UNKNOWN;
switch (ka->action) { 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; 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, static int mp_property_pause(m_option_t *prop, int action, void *arg,
void *ctx) void *ctx)
{ {