From 4e0e24c3c27362939d9f88d3e22267afef5f6d4f Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 11 Sep 2015 23:04:02 +0200 Subject: af_lavfi: implement af-metadata property Works like vf-metadata. Unfortunately requires some code duplication (even though it's not much). Fixes #2311. --- DOCS/interface-changes.rst | 2 ++ DOCS/man/input.rst | 3 +++ audio/filter/af.c | 12 ++++++++++++ audio/filter/af.h | 2 ++ audio/filter/af_lavfi.c | 23 +++++++++++++++++++++++ player/command.c | 31 +++++++++++++++++++++---------- 6 files changed, 63 insertions(+), 10 deletions(-) diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index d54477d94e..713dea8038 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -19,6 +19,8 @@ Interface changes :: + --- mpv 0.11.0 --- + - add "af-metadata" property --- mpv 0.10.0 --- - add --video-aspect-method option - add --playlist-pos option diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index b1ac03734c..3f4ed5c3dc 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -1091,6 +1091,9 @@ Property list An example of these kind of metadata are the cropping parameters added by ``--vf=lavfi=cropdetect``. +``af-metadata/`` + Equivalent to ``vf-metadata/``, but for audio filters. + ``pause`` (RW) Pause status. This is usually ``yes`` or ``no``. See ``--pause``. diff --git a/audio/filter/af.c b/audio/filter/af.c index ba08c1ed9b..3f73ad9c58 100644 --- a/audio/filter/af.c +++ b/audio/filter/af.c @@ -695,6 +695,18 @@ void af_control_all(struct af_stream *s, int cmd, void *arg) af->control(af, cmd, arg); } +int af_control_by_label(struct af_stream *s, int cmd, void *arg, bstr label) +{ + char *label_str = bstrdup0(NULL, label); + struct af_instance *cur = af_find_by_label(s, label_str); + talloc_free(label_str); + if (cur) { + return cur->control ? cur->control(cur, cmd, arg) : CONTROL_NA; + } else { + return CONTROL_UNKNOWN; + } +} + // Used by filters to add a filtered frame to the output queue. // Ownership of frame is transferred from caller to the filter chain. void af_add_output_frame(struct af_instance *af, struct mp_audio *frame) diff --git a/audio/filter/af.h b/audio/filter/af.h index 944ac54427..199486509c 100644 --- a/audio/filter/af.h +++ b/audio/filter/af.h @@ -127,6 +127,7 @@ enum af_control { AF_CONTROL_GET_PAN_BALANCE, AF_CONTROL_SET_PLAYBACK_SPEED, AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE, + AF_CONTROL_GET_METADATA, }; // Argument for AF_CONTROL_SET_PAN_LEVEL @@ -145,6 +146,7 @@ int af_remove_by_label(struct af_stream *s, char *label); struct af_instance *af_find_by_label(struct af_stream *s, char *label); struct af_instance *af_control_any_rev(struct af_stream *s, int cmd, void *arg); void af_control_all(struct af_stream *s, int cmd, void *arg); +int af_control_by_label(struct af_stream *s, int cmd, void *arg, bstr label); void af_seek_reset(struct af_stream *s); void af_add_output_frame(struct af_instance *af, struct mp_audio *frame); diff --git a/audio/filter/af_lavfi.c b/audio/filter/af_lavfi.c index 249a560fb6..a40904aa78 100644 --- a/audio/filter/af_lavfi.c +++ b/audio/filter/af_lavfi.c @@ -34,11 +34,14 @@ #include #include +#include "config.h" + #include "audio/format.h" #include "audio/fmt-conversion.h" #include "af.h" #include "common/av_common.h" +#include "common/tags.h" #include "options/m_option.h" @@ -63,6 +66,8 @@ struct priv { bool eof; + struct mp_tags *metadata; + // options char *cfg_graph; char **cfg_avopts; @@ -213,6 +218,12 @@ static int control(struct af_instance *af, int cmd, void *arg) return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE; } + case AF_CONTROL_GET_METADATA: + if (p->metadata) { + *(struct mp_tags *)arg = *p->metadata; + return CONTROL_OK; + } + return CONTROL_NA; case AF_CONTROL_RESET: reset(af); return AF_OK; @@ -220,6 +231,17 @@ static int control(struct af_instance *af, int cmd, void *arg) return AF_UNKNOWN; } +static void get_metadata_from_av_frame(struct af_instance *af, AVFrame *frame) +{ +#if HAVE_AVFRAME_METADATA + struct priv *p = af->priv; + if (!p->metadata) + p->metadata = talloc_zero(p, struct mp_tags); + + mp_tags_copy_from_av_dictionary(p->metadata, av_frame_get_metadata(frame)); +#endif +} + static int filter_frame(struct af_instance *af, struct mp_audio *data) { struct priv *p = af->priv; @@ -307,6 +329,7 @@ static int filter_out(struct af_instance *af) af->delay = in_time - out_time; } + get_metadata_from_av_frame(af, frame); af_add_output_frame(af, out); av_frame_free(&frame); return 0; diff --git a/player/command.c b/player/command.c index 19f725ba3a..6dcd200b29 100644 --- a/player/command.c +++ b/player/command.c @@ -1187,21 +1187,31 @@ static int mp_property_chapter_metadata(void *ctx, struct m_property *prop, return tag_property(action, arg, mpctx->chapters[chapter].metadata); } -static int mp_property_vf_metadata(void *ctx, struct m_property *prop, - int action, void *arg) +static int mp_property_filter_metadata(void *ctx, struct m_property *prop, + int action, void *arg) { MPContext *mpctx = ctx; - if (!(mpctx->d_video && mpctx->d_video->vfilter)) - return M_PROPERTY_UNAVAILABLE; - struct vf_chain *vf = mpctx->d_video->vfilter; + const char *type = prop->priv; if (action == M_PROPERTY_KEY_ACTION) { struct m_property_action_arg *ka = arg; bstr key; char *rem; m_property_split_path(ka->key, &key, &rem); - struct mp_tags vf_metadata = {0}; - switch (vf_control_by_label(vf, VFCTRL_GET_METADATA, &vf_metadata, key)) { + struct mp_tags metadata = {0}; + int res = CONTROL_UNKNOWN; + if (strcmp(type, "vf") == 0) { + if (!(mpctx->d_video && mpctx->d_video->vfilter)) + return M_PROPERTY_UNAVAILABLE; + struct vf_chain *vf = mpctx->d_video->vfilter; + res = vf_control_by_label(vf, VFCTRL_GET_METADATA, &metadata, key); + } else if (strcmp(type, "af") == 0) { + if (!(mpctx->d_audio && mpctx->d_audio->afilter)) + return M_PROPERTY_UNAVAILABLE; + struct af_stream *af = mpctx->d_audio->afilter; + res = af_control_by_label(af, AF_CONTROL_GET_METADATA, &metadata, key); + } + switch (res) { case CONTROL_UNKNOWN: return M_PROPERTY_UNKNOWN; case CONTROL_NA: // empty @@ -1209,9 +1219,9 @@ static int mp_property_vf_metadata(void *ctx, struct m_property *prop, if (strlen(rem)) { struct m_property_action_arg next_ka = *ka; next_ka.key = rem; - return tag_property(M_PROPERTY_KEY_ACTION, &next_ka, &vf_metadata); + return tag_property(M_PROPERTY_KEY_ACTION, &next_ka, &metadata); } else { - return tag_property(ka->action, ka->arg, &vf_metadata); + return tag_property(ka->action, ka->arg, &metadata); } return M_PROPERTY_OK; default: @@ -3379,7 +3389,8 @@ static const struct m_property mp_properties[] = { {"metadata", mp_property_metadata}, {"filtered-metadata", mp_property_filtered_metadata}, {"chapter-metadata", mp_property_chapter_metadata}, - {"vf-metadata", mp_property_vf_metadata}, + {"vf-metadata", mp_property_filter_metadata, .priv = "vf"}, + {"af-metadata", mp_property_filter_metadata, .priv = "af"}, {"pause", mp_property_pause}, {"core-idle", mp_property_core_idle}, {"eof-reached", mp_property_eof_reached}, -- cgit v1.2.3