From: cenzhanquan1 via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> To: ffmpeg-devel@ffmpeg.org Cc: cenzhanquan1 <code@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH] avfilter: add avfilter_forward_command API for recursive command processing. (PR #20621) Date: Sun, 28 Sep 2025 06:42:28 -0000 Message-ID: <175904174886.25.9550971653392209023@bf249f23a2c8> (raw) PR #20621 opened by cenzhanquan1 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20621 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20621.patch This commit introduces a new API that allows commands to be recursively forwarded through filter graphs, enabling dynamic control of filters at runtime. Key changes: 1. Added avfilter_forward_command() function in avfilter.c: - Supports both forward and reverse command propagation via AVFILTER_CMD_FLAG_REVERSE flag - Recursively traverses filter links to find target filters - Falls back to filter-specific forward_command callback when available - Properly handles "all" target for broadcasting commands 2. Extended AVFilter struct in filters.h: - Added forward_command callback for filter-specific implementations - Maintains backward compatibility with existing filters 3. New API documentation in avfilter.h: - Detailed parameter descriptions including pad_idx and flags - Clear explanation of AVFILTER_CMD_FLAG_REVERSE behavior - Usage examples for common scenarios 4. Added AVFILTER_CMD_FLAG_REVERSE flag: - Enables reverse traversal from sink to source filters - Useful for targeting specific filters in complex graphs Signed-off-by: cenzhanquan1 <cenzhanquan1@xiaomi.com> >From d43417d9d3ebfcbbd71905cce648b44b30e458d9 Mon Sep 17 00:00:00 2001 From: cenzhanquan1 <cenzhanquan1@xiaomi.com> Date: Sun, 28 Sep 2025 14:37:21 +0800 Subject: [PATCH] avfilter: add avfilter_forward_command API for recursive command processing. This commit introduces a new API that allows commands to be recursively forwarded through filter graphs, enabling dynamic control of filters at runtime. Key changes: 1. Added avfilter_forward_command() function in avfilter.c: - Supports both forward and reverse command propagation via AVFILTER_CMD_FLAG_REVERSE flag - Recursively traverses filter links to find target filters - Falls back to filter-specific forward_command callback when available - Properly handles "all" target for broadcasting commands 2. Extended AVFilter struct in filters.h: - Added forward_command callback for filter-specific implementations - Maintains backward compatibility with existing filters 3. New API documentation in avfilter.h: - Detailed parameter descriptions including pad_idx and flags - Clear explanation of AVFILTER_CMD_FLAG_REVERSE behavior - Usage examples for common scenarios 4. Added AVFILTER_CMD_FLAG_REVERSE flag: - Enables reverse traversal from sink to source filters - Useful for targeting specific filters in complex graphs Signed-off-by: cenzhanquan1 <cenzhanquan1@xiaomi.com> --- libavfilter/avfilter.c | 53 ++++++++++++++++++++++++++++++++++++++++++ libavfilter/avfilter.h | 15 ++++++++++++ libavfilter/filters.h | 10 ++++++++ 3 files changed, 78 insertions(+) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 169c2baa42..c661556774 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -628,6 +628,59 @@ int avfilter_process_command(AVFilterContext *filter, const char *cmd, const cha return AVERROR(ENOSYS); } +int avfilter_forward_command(AVFilterContext *filter, int pad_idx, const char *target, const char *cmd, + const char *arg, char *res, int res_len, int flags) +{ + AVFilterLink* link; + AVFilterLink** prev_links; + unsigned nb_prev_links; + unsigned nb_next_links; + int i, ret = AVERROR(ENOSYS); + + if (flags & AVFILTER_CMD_FLAG_REVERSE) { + link = filter->inputs[pad_idx]; + filter = link->src; + prev_links = filter->outputs; + nb_prev_links = filter->nb_outputs; + nb_next_links = filter->nb_inputs; + } else { + link = filter->outputs[pad_idx]; + filter = link->dst; + prev_links = filter->inputs; + nb_prev_links = filter->nb_inputs; + nb_next_links = filter->nb_outputs; + } + + if (!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)) { + ret = avfilter_process_command(filter, cmd, arg, res, res_len, flags); + if (ret != AVERROR(ENOSYS)) { + if (ret == AVERROR_OPTION_NOT_FOUND) + ret = AVERROR(ENOSYS); + else if ((flags & AVFILTER_CMD_FLAG_ONE) || ret < 0) + return ret; + } + } + + for (i = 0; i < nb_prev_links; i++) { + if (prev_links[i] == link) { + pad_idx = i; + break; + } + } + + if (fffilter(filter->filter)->forward_command) { + return fffilter(filter->filter)->forward_command(filter, pad_idx, target, cmd, arg, res, res_len, flags); + } + + for (i = 0; i < nb_next_links; i++) { + ret = avfilter_forward_command(filter, i, target, cmd, arg, res, res_len, flags); + if (ret < 0 && ret != AVERROR(ENOSYS)) + return ret; + } + + return ret; +} + unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output) { return is_output ? fffilter(filter)->nb_outputs : fffilter(filter)->nb_inputs; diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 02b58c42c2..0d8a3410ab 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -468,6 +468,7 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad, #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_REVERSE 4 ///< Reverse forward command to source filter (default to sink filter) /** * Make the filter instance process a command. @@ -475,6 +476,20 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad, */ int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags); +/** + * Recursively make the filter instance process a command. + * @see avfilter_process_command + * + * @param filter the filter to forward command. + * @param pad_id the pad index that filter forward command to. + * @param flags @see AVFILTER_CMD_FLAG_REVERSE. + * + * @return the number of filters that successfully processed the command. + */ +int avfilter_forward_command(AVFilterContext *filter, int pad_idx, const char *target, const char *cmd, + const char *arg, char *res, int res_len, int flags); + + /** * Iterate over all registered filters. * diff --git a/libavfilter/filters.h b/libavfilter/filters.h index bc79527b87..fee57fe815 100644 --- a/libavfilter/filters.h +++ b/libavfilter/filters.h @@ -445,6 +445,16 @@ typedef struct FFFilter { */ int (*process_command)(AVFilterContext *, const char *cmd, const char *arg, char *res, int res_len, int flags); + /** + * Forward command to neighbor links. + * + * @param pad_idx indicates the pad index that command is from. + * @return >=0 on successfully forwarding to some filters. + * AVERROR(ENOSYS) on unsupported commands, or didn't forward. + */ + int (*forward_command)(AVFilterContext *, int pad_idx, const char *target, const char *cmd, + const char *arg, char *res, int res_len, int flags); + /** * Filter activation function. * -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
next reply other threads:[~2025-09-28 6:43 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2025-09-28 6:42 cenzhanquan1 via ffmpeg-devel [this message] 2025-09-28 11:18 ` [FFmpeg-devel] " Nicolas George via ffmpeg-devel
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=175904174886.25.9550971653392209023@bf249f23a2c8 \ --to=ffmpeg-devel@ffmpeg.org \ --cc=code@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror http://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ http://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git