summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-09-11 23:04:02 +0200
committerwm4 <wm4@nowhere>2015-09-11 23:04:02 +0200
commit4e0e24c3c27362939d9f88d3e22267afef5f6d4f (patch)
tree5d8ad6f4a3ed84071b79e07df48e9bfc818db07f
parentf095e86b61022613371334d80552b918946b9387 (diff)
downloadmpv-4e0e24c3c27362939d9f88d3e22267afef5f6d4f.tar.bz2
mpv-4e0e24c3c27362939d9f88d3e22267afef5f6d4f.tar.xz
af_lavfi: implement af-metadata property
Works like vf-metadata. Unfortunately requires some code duplication (even though it's not much). Fixes #2311.
-rw-r--r--DOCS/interface-changes.rst2
-rw-r--r--DOCS/man/input.rst3
-rw-r--r--audio/filter/af.c12
-rw-r--r--audio/filter/af.h2
-rw-r--r--audio/filter/af_lavfi.c23
-rw-r--r--player/command.c31
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/<filter-label>``
+ Equivalent to ``vf-metadata/<filter-label>``, 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 <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
+#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},