[PATCH] avfilter: enhance command processing with chain propagation and direction control. (PR #20731)
PR #20731 opened by cenzhanquan1 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20731 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20731.patch The existing avfilter_process_command and avfilter_graph_send_command havelimitations in command propagation: they only handle commands for individualfilters and lack the ability to propagate commands through the entire filterchain, nor do they support directional traversal of the filter graph. Thismakes it difficult to control multiple filters in a chain (e.g., adjustingvolume for all related filters or enabling/disabling a series of filters)with a single command. This patch enhances the command processing logic to address these issues: Add two new flags to control command propagation: AVFILTER_CMD_FLAG_CHAIN: Enables command propagation through the entire filter chain. After processing the current filter, it traverses all associated links (inputs/outputs based on direction) and recursively forwards the command to subsequent filters, covering the full filter topology. AVFILTER_CMD_FLAG_REVERSE: Works with AVFILTER_CMD_FLAG_CHAIN to control traversal direction. Default (forward) follows data flow (source → destination filters), while reverse traversal goes against data flow (destination → source filters). Refactor avfilter_process_command to integrate chain propagation logic: Process the command for the current filter first, then check if chain propagation is enabled. Traverse all relevant links (inputs for reverse, outputs for forward) and recursively forward the command to next-level filters. Track processing status (processed) to determine if any filter in the chain handled the command. Respect AVFILTER_CMD_FLAG_ONE to stop propagation once a filter processes the command, and propagate critical errors. Improve command handling for built-in commands ("ping" and "enable") to workseamlessly with the new propagation logic, ensuring consistent behavioracross the chain. These changes enable flexible command control over entire filter chains,supporting use cases like batch adjustment of filters, topology-wide statuschecks (via "ping"), and coordinated enable/disable operations, whilemaintaining compatibility with existing filter command implementations. Signed-off-by: cenzhanquan1 <cenzhanquan1@xiaomi.com> From 9dba682222bd55c952e14e71789a7084529a74f7 Mon Sep 17 00:00:00 2001 From: cenzhanquan1 <cenzhanquan1@xiaomi.com> Date: Tue, 21 Oct 2025 17:34:22 +0800 Subject: [PATCH] avfilter: enhance command processing with chain propagation and direction control. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing avfilter_process_command and avfilter_graph_send_command havelimitations in command propagation: they only handle commands for individualfilters and lack the ability to propagate commands through the entire filterchain, nor do they support directional traversal of the filter graph. Thismakes it difficult to control multiple filters in a chain (e.g., adjustingvolume for all related filters or enabling/disabling a series of filters)with a single command. This patch enhances the command processing logic to address these issues: Add two new flags to control command propagation: AVFILTER_CMD_FLAG_CHAIN: Enables command propagation through the entire filter chain. After processing the current filter, it traverses all associated links (inputs/outputs based on direction) and recursively forwards the command to subsequent filters, covering the full filter topology. AVFILTER_CMD_FLAG_REVERSE: Works with AVFILTER_CMD_FLAG_CHAIN to control traversal direction. Default (forward) follows data flow (source → destination filters), while reverse traversal goes against data flow (destination → source filters). Refactor avfilter_process_command to integrate chain propagation logic: Process the command for the current filter first, then check if chain propagation is enabled. Traverse all relevant links (inputs for reverse, outputs for forward) and recursively forward the command to next-level filters. Track processing status (processed) to determine if any filter in the chain handled the command. Respect AVFILTER_CMD_FLAG_ONE to stop propagation once a filter processes the command, and propagate critical errors. Improve command handling for built-in commands ("ping" and "enable") to workseamlessly with the new propagation logic, ensuring consistent behavioracross the chain. These changes enable flexible command control over entire filter chains,supporting use cases like batch adjustment of filters, topology-wide statuschecks (via "ping"), and coordinated enable/disable operations, whilemaintaining compatibility with existing filter command implementations. Signed-off-by: cenzhanquan1 <cenzhanquan1@xiaomi.com> --- libavfilter/avfilter.c | 75 +++++++++++++++++++++++++++++++++--------- libavfilter/avfilter.h | 10 ++++-- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 169c2baa42..68ec9f6f6a 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -607,25 +607,68 @@ static int set_enable_expr(FFFilterContext *ctxi, const char *expr) return 0; } -int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags) +int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, + char *res, int res_len, int flags) { - if(!strcmp(cmd, "ping")){ - char local_res[256] = {0}; + int direction = flags & AVFILTER_CMD_FLAG_REVERSE; + int ret = AVERROR(ENOSYS); + int processed = 0; - if (!res) { - res = local_res; - res_len = sizeof(local_res); - } - av_strlcatf(res, res_len, "pong from:%s %s\n", filter->filter->name, filter->name); - if (res == local_res) - av_log(filter, AV_LOG_INFO, "%s", res); - return 0; - }else if(!strcmp(cmd, "enable")) { - return set_enable_expr(fffilterctx(filter), arg); - }else if (fffilter(filter->filter)->process_command) { - return fffilter(filter->filter)->process_command(filter, cmd, arg, res, res_len, flags); + int process_flags = flags & ~AVFILTER_CMD_FLAG_CHAIN; + if (!strcmp(cmd, "ping")) { + char local_res[256] = {0}; + char *res_buf = res ? res : local_res; + size_t buf_len = res ? res_len : sizeof(local_res); + av_strlcatf(res_buf, buf_len, "pong from:%s %s\n", + filter->filter->name, filter->name ? filter->name : "unknown"); + if (!res) + av_log(filter, AV_LOG_INFO, "%s", res_buf); + ret = 0; + } else if (!strcmp(cmd, "enable")) { + ret = set_enable_expr(fffilterctx(filter), arg); + } else if (fffilter(filter->filter)->process_command) { + ret = fffilter(filter->filter)->process_command(filter, cmd, arg, res, res_len, process_flags); + } else { + ret = AVERROR(ENOSYS); } - return AVERROR(ENOSYS); + + if (ret != AVERROR(ENOSYS)) { + processed = 1; + if ((flags & AVFILTER_CMD_FLAG_ONE) || ret < 0) { + return ret; + } + } + + if (!(flags & AVFILTER_CMD_FLAG_CHAIN)) { + return processed ? 0 : AVERROR(ENOSYS); + } + + av_log(filter, AV_LOG_DEBUG, + "cmd_chain: [%s] dir:%s -> '%s' '%s' (forwarding)\n", + filter->name ? filter->name : "unknown", + direction ? "reverse" : "forward", + cmd, arg ? arg : ""); + + unsigned nb_links = direction ? filter->nb_inputs : filter->nb_outputs; + for (int i = 0; i < nb_links; i++) { + AVFilterLink *link = direction ? filter->inputs[i] : filter->outputs[i]; + AVFilterContext *next_filter = direction ? (link ? link->src : NULL) : (link ? link->dst : NULL); + + if (!link || !next_filter) { + av_log(filter, AV_LOG_DEBUG, "Invalid %s link at pad %d\n", + direction ? "input" : "output", i); + continue; + } + + ret = avfilter_process_command(next_filter, cmd, arg, res, res_len, flags); + if (ret >= 0) { + processed = 1; + } else if (ret != AVERROR(ENOSYS)) { + return ret; + } + } + + return processed ? 0 : AVERROR(ENOSYS); } unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output) diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 02b58c42c2..fde3811dc3 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -466,8 +466,14 @@ struct AVFilterLink { int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad); -#define AVFILTER_CMD_FLAG_ONE 1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically -#define AVFILTER_CMD_FLAG_FAST 2 ///< Only execute command when its fast (like a video out that supports contrast adjustment in hw) +#define AVFILTER_CMD_FLAG_ONE 1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically +#define AVFILTER_CMD_FLAG_FAST 2 ///< Only execute command when its fast (like a video out that supports contrast adjustment in hw) +#define AVFILTER_CMD_FLAG_CHAIN 4 ///< Propagate the command through the entire filter chain. After processing the current filter, + /// traverse all its associated links (inputs or outputs, based on direction) and recursively + /// forward the command to subsequent filters, covering the full filter topology. +#define AVFILTER_CMD_FLAG_REVERSE 8 ///< Only effective when paired with AVFILTER_CMD_FLAG_CHAIN. Changes the command's traversal + /// direction in the chain: default (forward) follows data flow (source → destination filters), + /// while reverse traversal opposes data flow (destination → source filters). /** * Make the filter instance process a command. -- 2.49.1
cenzhanquan1 via ffmpeg-devel (HE12025-10-21):
PR #20731 opened by cenzhanquan1 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20731 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20731.patch
The existing avfilter_process_command and avfilter_graph_send_command havelimitations in command propagation: they only handle commands for individualfilters and lack the ability to propagate commands through the entire filterchain, nor do they support directional traversal of the filter graph. Thismakes it difficult to control multiple filters in a chain (e.g., adjustingvolume for all related filters or enabling/disabling a series of filters)with a single command.
You are proposing to add an API without adding any code that uses that API, let alone user-oriented examples. That makes it impossible to guess if the feature is useful or if there are better ways to achieve what you want it to do. Regards, -- Nicolas George
On Oct 31, 2025, at 03:12, Nicolas George via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
cenzhanquan1 via ffmpeg-devel (HE12025-10-21):
PR #20731 opened by cenzhanquan1 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20731 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20731.patch
The existing avfilter_process_command and avfilter_graph_send_command havelimitations in command propagation: they only handle commands for individualfilters and lack the ability to propagate commands through the entire filterchain, nor do they support directional traversal of the filter graph. Thismakes it difficult to control multiple filters in a chain (e.g., adjustingvolume for all related filters or enabling/disabling a series of filters)with a single command.
You are proposing to add an API without adding any code that uses that API, let alone user-oriented examples. That makes it impossible to guess if the feature is useful or if there are better ways to achieve what you want it to do.
Current implementation isn’t a new API, but new flags. It extends the ways to traverse a graph. The existing API has the capability to send commands to a specific filter, a certain type of filter, or all filters, but it lacks the ability to send commands to a subgraph, unless the user manually filters out all filters belonging to the subgraph, which is possible but complex. The newly added flags provide subgraph traversal capability. A common use case is when a graph contains multiple sources; I want to send commands, such as volume control, to a subgraph with a specific source as the root node, without affecting other sources. While controlling via volume instance names is also feasible, using the source for control offers additional flexibility.
Regards,
-- Nicolas George _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
Zhao Zhili via ffmpeg-devel (HE12025-10-31):
Current implementation isn’t a new API, but new flags. It extends the ways to traverse a graph.
A new flag is a new API.
The existing API has the capability to send commands to a specific filter, a certain type of filter, or all filters, but it lacks the ability to send commands to a subgraph, unless the user manually filters out all filters belonging to the subgraph, which is possible but complex.
The newly added flags provide subgraph traversal capability.
A common use case is when a graph contains multiple sources; I want to send commands, such as volume control, to a subgraph with a specific source as the root node, without affecting other sources. While controlling via volume instance names is also feasible, using the source for control offers additional flexibility.
Then we need a patch series that really allows to do that, including examples. Regards, -- Nicolas George
Hi Nicolas,
On Oct 31, 2025, at 17:58, Nicolas George via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
Zhao Zhili via ffmpeg-devel (HE12025-10-31):
Current implementation isn’t a new API, but new flags. It extends the ways to traverse a graph.
A new flag is a new API.
The existing API has the capability to send commands to a specific filter, a certain type of filter, or all filters, but it lacks the ability to send commands to a subgraph, unless the user manually filters out all filters belonging to the subgraph, which is possible but complex.
The newly added flags provide subgraph traversal capability.
A common use case is when a graph contains multiple sources; I want to send commands, such as volume control, to a subgraph with a specific source as the root node, without affecting other sources. While controlling via volume instance names is also feasible, using the source for control offers additional flexibility.
Then we need a patch series that really allows to do that, including examples.
Use cases and FATE tests have been added with libavfilter/f_sendcmd.c, it looks fine to me, could you please take a look? https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20731
Regards,
-- Nicolas George _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
Zhao Zhili via ffmpeg-devel (HE12026-02-26):
Use cases and FATE tests have been added with libavfilter/f_sendcmd.c, it looks fine to me, could you please take a look?
Gladly. How can I take a look without a graphical browser? Regards, -- Nicolas George
On 26 Feb 2026, at 9:37, Nicolas George via ffmpeg-devel wrote:
Zhao Zhili via ffmpeg-devel (HE12026-02-26):
Use cases and FATE tests have been added with libavfilter/f_sendcmd.c, it looks fine to me, could you please take a look?
Gladly. How can I take a look without a graphical browser?
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20731.patch or checkout the process_cmd branch of https://code.ffmpeg.org/cenzhanquan1/FFmpeg.git
Regards,
-- Nicolas George _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
Marvin Scholz (HE12026-02-27):
Thanks, but what I am seeing are only the code changes. Not the comments already done and the replies to these comments, all of it necessary to understand why the code is like that and review usefully.
or checkout the process_cmd branch of https://code.ffmpeg.org/cenzhanquan1/FFmpeg.git
As expected (because I know how git works), no more information in there. Only a >180 megaoctets download, good thing my internet access is not metered. Please do not override reply-to settings. Regards, -- Nicolas George
Hi Nicolas, Since the Forgejo web discussion isn't accessible without a browser, here is a summary of the PR review history and key discussion points. PR OVERVIEW This PR adds directional command propagation to FFmpeg's filter graph system, split into two commits: Commit 1 -- avfilter: enhance command processing with subgraph propagation and direction control - Adds AVFILTER_CMD_FLAG_FORWARD (4) and AVFILTER_CMD_FLAG_BACKWARD (8) flags to avfilter.h - Refactors avfilter_process_command() to support recursive chain traversal along/against data flow - Blocks FORWARD/BACKWARD in avfilter_graph_send_command() and avfilter_graph_queue_command() (subgraph traversal only makes sense at filter level) - Adds mutual exclusion check: FORWARD and BACKWARD cannot be set simultaneously - Bumps LIBAVFILTER_VERSION_MINOR to 13 Commit 2 -- avfilter/f_sendcmd: add mode option for command propagation direction - Adds mode option to sendcmd/asendcmd: graph (default, original behavior), forward, backward - In forward/backward modes, locates target filter by instance name (e.g. volume@v1) and calls avfilter_process_command() with the appropriate flag - Adds 5 FATE tests: graph mode, forward, backward, multi-target propagation, and subgraph isolation REVIEW HISTORY 1) michaelni raised a concern about infinite loops in cyclic filter graphs. Resolution: FFmpeg's scheduler performs cycle detection via DFS during initialization (ffmpeg_sched.c:1435-1508). Cyclic graphs are rejected outright at runtime, so infinite recursion cannot occur. As documented in ffmpeg.texi, feedback patterns must use multiple independent filter graphs, not cycles within a single graph. 2) Nicolas George (you) requested a patch series with real examples demonstrating the use case. Resolution: Commit 2 was added, extending sendcmd/asendcmd with the mode option and accompanying FATE tests. 3) Zhao Zhili reviewed the code and provided the following feedback: a) Merge FATE tests from the separate PR #21156 into this PR -- done. b) Several coding style issues -- all fixed. c) Second commit description should focus on the f_sendcmd feature rather than FATE tests -- adjusted. d) Asked why FATE tests use filter_complex_script instead of inline filtergraphs. Resolution: The FATE test framework has a known shell quoting limitation -- in fate-run.sh, the ffmpeg() function uses "for arg in $@" (without quotes around $@), which causes word-splitting on spaces. Since asendcmd parameters contain single quotes and spaces (e.g. commands='0.0 volume volume 0.5'), inline filtergraphs get broken into separate arguments. The tests now use -/filter_complex with static filtergraph files stored in tests/filtergraphs/ (git-tracked, copied to tests/data/filtergraphs/ by the Makefile), avoiding the deprecated filter_complex_script while sidestepping the quoting issue. CURRENT STATUS - Lint check: passed - FATE tests (amd64/aarch64 32/64-bit, wine): passed - All review comments from Zhao Zhili addressed - Zhao Zhili's verdict: LGTM - Awaiting 1 approval to merge The latest patches are at: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20731.patch Happy to provide any additional details or clarifications. Regards, Zhanquan Cen ________________________________ 发件人: Nicolas George via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> 发送时间: 2026年3月1日 19:44 收件人: FFmpeg development discussions and patches 抄送: Nicolas George 主题: [External Mail][FFmpeg-devel] Re: [PATCH] avfilter: enhance command processing with chain propagation and direction control. (PR #20731) [外部邮件] 此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给misec@xiaomi.com进行反馈 Marvin Scholz (HE12026-02-27):
Thanks, but what I am seeing are only the code changes. Not the comments already done and the replies to these comments, all of it necessary to understand why the code is like that and review usefully.
or checkout the process_cmd branch of https://code.ffmpeg.org/cenzhanquan1/FFmpeg.git
As expected (because I know how git works), no more information in there. Only a >180 megaoctets download, good thing my internet access is not metered. Please do not override reply-to settings. Regards, -- Nicolas George _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
Hi. I am not finding the time or courage to address this properly, especially with the unreadable discussion existing in the web monster. So I will only give short comments to this mail. 岑湛权 (HE12026-03-03):
Resolution: FFmpeg's scheduler performs cycle detection via DFS during initialization (ffmpeg_sched.c:1435-1508). Cyclic graphs are rejected outright at runtime, so infinite recursion cannot occur. As documented in ffmpeg.texi, feedback patterns must use multiple independent filter graphs, not cycles within a single graph.
libavfilter is supposed to support cyclic paths. If the new fftools code does broke that… insert the “surprised Pikachu” animated gif here. But that is only the fftools code. OTOH, adding a brand new field in all contexts for this features… this feature better be very important.
2) Nicolas George (you) requested a patch series with real examples demonstrating the use case.
Resolution: Commit 2 was added, extending sendcmd/asendcmd with the mode option and accompanying FATE tests.
That is not enough. To begin with, you are adding options, but I am not seeing the string /doc/ in the whole patchset, that is an immediate reject. Not only does the feature need to be documented, it needs to prove its usefulness: it needs an example that shows something made possible by this feature, something that was not previously possible with different means. Regards, -- Nicolas George
Nicolas George (2026-05-13):
OTOH, adding a brand new field in all contexts for this features… this feature better be very important.
libavfilter supports cyclic filter graphs. Without cmd_visited the BFS traversal loops forever on such graphs. It is a single int per filter context; I do not see a cheaper way to guarantee termination.
I am not seeing the string /doc/ in the whole patchset
You are right, that was missing. Fixed now ― doc/filters.texi and doc/APIchanges are included in the updated series.
it needs an example that shows something made possible by this feature, something that was not previously possible with different means.
Here is a concrete example: ffmpeg -f lavfi -i sine=440:d=3 -filter_complex \ "[0:a]asendcmd=mode=forward:commands='1.0 volume@v1 volume 0.5',\ volume@v1=1.0,volume@v2=1.0,aformat=sample_fmts=s16[out]" \ -map "[out]" -y /tmp/out.wav The chain is: asendcmd → volume@v1 → volume@v2 → aformat → out. At t=1s the command starts at v1 and propagates forward (downstream). Both v1 and v2 receive "volume 0.5", so the output amplitude becomes 0.25 (0.5 × 0.5). Why existing mechanisms cannot do this: 1. avfilter_graph_send_command("volume@v1", "volume", "0.5", FLAG_ONE) ― sets v1 only, does not touch v2. 2. avfilter_graph_send_command("volume", "volume", "0.5", 0) ― sets every volume filter in the graph, including unrelated paths. 3. There is no existing call that means "set this parameter on v1 and propagate to everything downstream of it that understands the command." For the library API the case is even clearer: ffplay's configure_audio_filters() parses the user's -af string and only holds the source/sink pointers. The intermediate filter names are whatever the parser generated. If it wanted to adjust volume at runtime it has no way to target a specific subgraph without manually walking the links ― which is exactly what AVFILTER_CMD_FLAG_FORWARD does internally. Updated patch series attached. Zhanquan ________________________________ 发件人: Nicolas George <george@nsup.org> 发送时间: 2026年5月13日 21:19 收件人: 岑湛权 抄送: FFmpeg development discussions and patches 主题: Re: 答复: [External Mail][FFmpeg-devel] Re: [PATCH] avfilter: enhance command processing with chain propagation and direction control. (PR #20731) [外部邮件] 此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给misec@xiaomi.com进行反馈 Hi. I am not finding the time or courage to address this properly, especially with the unreadable discussion existing in the web monster. So I will only give short comments to this mail. 岑湛权 (HE12026-03-03):
Resolution: FFmpeg's scheduler performs cycle detection via DFS during initialization (ffmpeg_sched.c:1435-1508). Cyclic graphs are rejected outright at runtime, so infinite recursion cannot occur. As documented in ffmpeg.texi, feedback patterns must use multiple independent filter graphs, not cycles within a single graph.
libavfilter is supposed to support cyclic paths. If the new fftools code does broke that… insert the “surprised Pikachu” animated gif here. But that is only the fftools code. OTOH, adding a brand new field in all contexts for this features… this feature better be very important.
2) Nicolas George (you) requested a patch series with real examples demonstrating the use case.
Resolution: Commit 2 was added, extending sendcmd/asendcmd with the mode option and accompanying FATE tests.
That is not enough. To begin with, you are adding options, but I am not seeing the string /doc/ in the whole patchset, that is an immediate reject. Not only does the feature need to be documented, it needs to prove its usefulness: it needs an example that shows something made possible by this feature, something that was not previously possible with different means. Regards, -- Nicolas George
岑湛权 via ffmpeg-devel (HE12026-05-19):
libavfilter supports cyclic filter graphs. Without cmd_visited the BFS traversal loops forever on such graphs. It is a single int per filter context; I do not see a cheaper way to guarantee termination.
You need to allocate something to keep track, but allocating it globally for such a niche feature is no acceptable: you will need to allocate what you need yourself and manage it. I would not object to adding a small integer in AVFilterContext, initialized at graph configuration, to serve as index into an array for features that require storing data about other filters. But before discussing implementations details, let us be sure it is necessary.
ffmpeg -f lavfi -i sine=440:d=3 -filter_complex \ "[0:a]asendcmd=mode=forward:commands='1.0 volume@v1 volume 0.5',\ volume@v1=1.0,volume@v2=1.0,aformat=sample_fmts=s16[out]" \ -map "[out]" -y /tmp/out.wav
The chain is: asendcmd → volume@v1 → volume@v2 → aformat → out. At t=1s the command starts at v1 and propagates forward (downstream). Both v1 and v2 receive "volume 0.5", so the output amplitude becomes 0.25 (0.5 × 0.5).
Why existing mechanisms cannot do this:
1. avfilter_graph_send_command("volume@v1", "volume", "0.5", FLAG_ONE) — sets v1 only, does not touch v2.
2. avfilter_graph_send_command("volume", "volume", "0.5", 0) — sets every volume filter in the graph, including unrelated paths.
3. There is no existing call that means "set this parameter on v1 and propagate to everything downstream of it that understands the command."
But you can just send the command to both filters explicitly: 1.0 volume@v1 volume 0.5, 1.0 volume@v2 volume 0.5 No need for run-time propagation when you can statically analyze the graph. Regards, -- Nicolas George
participants (5)
-
cenzhanquan1 -
Marvin Scholz -
Nicolas George -
Zhao Zhili -
岑湛权