diff options
-rw-r--r-- | DOCS/man/input.rst | 3 | ||||
-rw-r--r-- | audio/filter/af.c | 11 | ||||
-rw-r--r-- | audio/filter/af.h | 2 | ||||
-rw-r--r-- | audio/filter/af_lavfi.c | 8 | ||||
-rw-r--r-- | input/cmd_list.c | 1 | ||||
-rw-r--r-- | input/cmd_list.h | 1 | ||||
-rw-r--r-- | player/command.c | 6 |
7 files changed, 32 insertions, 0 deletions
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 86a80a8929..e7f5b31b9d 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -700,6 +700,9 @@ Input Commands that are Possibly Subject to Change specific. Currently, this only works with the ``lavfi`` filter - see the libavfilter documentation for which commands a filter supports. +``af-command "<label>" "<cmd>" "<args>"`` + Same as ``vf-command``, but for video filters. + Undocumented commands: ``tv-last-channel`` (TV/DVB only), ``ao-reload`` (experimental/internal). diff --git a/audio/filter/af.c b/audio/filter/af.c index 475016d2ea..18019d8930 100644 --- a/audio/filter/af.c +++ b/audio/filter/af.c @@ -696,6 +696,17 @@ int af_control_by_label(struct af_stream *s, int cmd, void *arg, bstr label) } } +int af_send_command(struct af_stream *s, char *label, char *cmd, char *arg) +{ + char *args[2] = {cmd, arg}; + if (strcmp(label, "all") == 0) { + af_control_all(s, AF_CONTROL_COMMAND, args); + return 0; + } else { + return af_control_by_label(s, AF_CONTROL_COMMAND, args, bstr0(label)); + } +} + // 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 0e73693ac9..9c49081f66 100644 --- a/audio/filter/af.h +++ b/audio/filter/af.h @@ -124,6 +124,7 @@ enum af_control { AF_CONTROL_SET_PLAYBACK_SPEED, AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE, AF_CONTROL_GET_METADATA, + AF_CONTROL_COMMAND, }; // Argument for AF_CONTROL_SET_PAN_LEVEL @@ -144,6 +145,7 @@ 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); +int af_send_command(struct af_stream *s, char *label, char *cmd, char *arg); void af_add_output_frame(struct af_instance *af, struct mp_audio *frame); int af_filter_frame(struct af_stream *s, struct mp_audio *frame); diff --git a/audio/filter/af_lavfi.c b/audio/filter/af_lavfi.c index 1960ddc247..616c5425e1 100644 --- a/audio/filter/af_lavfi.c +++ b/audio/filter/af_lavfi.c @@ -222,6 +222,14 @@ 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_COMMAND: { + if (!p->graph) + break; + char **args = arg; + return avfilter_graph_send_command(p->graph, "all", + args[0], args[1], &(char){0}, 0, 0) + >= 0 ? CONTROL_OK : CONTROL_ERROR; + } case AF_CONTROL_GET_METADATA: if (p->metadata) { *(struct mp_tags *)arg = *p->metadata; diff --git a/input/cmd_list.c b/input/cmd_list.c index a5fc342615..b5e29aab0e 100644 --- a/input/cmd_list.c +++ b/input/cmd_list.c @@ -180,6 +180,7 @@ const struct mp_cmd_def mp_cmds[] = { { MP_CMD_DROP_BUFFERS, "drop-buffers", }, { MP_CMD_AF, "af", { ARG_STRING, ARG_STRING } }, + { MP_CMD_AF_COMMAND, "af-command", { ARG_STRING, ARG_STRING, ARG_STRING } }, { MP_CMD_AO_RELOAD, "ao-reload", }, { MP_CMD_VF, "vf", { ARG_STRING, ARG_STRING } }, diff --git a/input/cmd_list.h b/input/cmd_list.h index 876fe4fd71..4e324bf01c 100644 --- a/input/cmd_list.h +++ b/input/cmd_list.h @@ -92,6 +92,7 @@ enum mp_command_type { /// Audio Filter commands MP_CMD_AF, + MP_CMD_AF_COMMAND, MP_CMD_AO_RELOAD, /// Video filter commands diff --git a/player/command.c b/player/command.c index 7bcdffc1c4..d5cccd2474 100644 --- a/player/command.c +++ b/player/command.c @@ -4937,6 +4937,12 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re return vf_send_command(mpctx->vo_chain->vf, cmd->args[0].v.s, cmd->args[1].v.s, cmd->args[2].v.s); + case MP_CMD_AF_COMMAND: + if (!mpctx->ao_chain) + return -1; + return af_send_command(mpctx->ao_chain->af, cmd->args[0].v.s, + cmd->args[1].v.s, cmd->args[2].v.s); + case MP_CMD_SCRIPT_BINDING: { mpv_event_client_message event = {0}; char *name = cmd->args[0].v.s; |