[FFmpeg-devel] [PATCH 09/10] avfilter/formats: Don't set samplerate or channel count on video links

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Sun Aug 15 12:55:37 EEST 2021


This currently happens by accident in a few filters that use
ff_set_common_(samplerates|channel_layouts) like afir (if the response
option is set) or agraphmonitor (due to the default code in
avfiltergraph.c). So change those functions to make sure it does no
longer happen.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
1. Contrary to ff_default_query_formats() the default code in 
avfiltergraph.c still uses ff_all_channel_layouts, not
ff_all_channel_counts. I believe that this doesn't make sense
and intend to change it after having inspected all filters for
compatibility with the change. After it is changed,
ff_default_query_formats() can be used directly.
2. These defaults can be used to e.g. remove lots of
ff_set_common_all_samplerates() and calls. I will also look into this.
3. I don't like the way it is decided whether the audio components
get initialized in ff_default_query_formats() and in the default code
in avfiltergraph.c: In many cases this will lead to an unnecessary
allocation (if the query_formats function has already set everything)
and furthermore I don't think one should only look at the first input
or (lacking that) the first output. Using internal per-filter flags
seems more reasonable for this.
4. Just a quick question: If several links are set to individual
lists that each contain exactly one element that coincides for all of
these lists, then one could just as well use a shared list for all these
links!? After all, in both cases the format negotiation will lead to the
same result: The given format will be choosen for all these links.
(E.g. vf_yadif_cuda.c can be simplified if the answer turns out to be
yes (as I expect).)

 libavfilter/formats.c | 16 ++++++++++------
 libavfilter/formats.h |  6 +++---
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index cc73c5abcb..9ceb32255b 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -622,14 +622,16 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
     FORMATS_CHANGEREF(oldref, newref);
 }
 
-#define SET_COMMON_FORMATS(ctx, fmts, ref_fn, unref_fn)             \
+#define SET_COMMON_FORMATS(ctx, fmts, _type, ref_fn, unref_fn)      \
     int i;                                                          \
                                                                     \
     if (!fmts)                                                      \
         return AVERROR(ENOMEM);                                     \
                                                                     \
     for (i = 0; i < ctx->nb_inputs; i++) {                          \
-        if (ctx->inputs[i] && !ctx->inputs[i]->outcfg.fmts) {       \
+        AVFilterLink *const link = ctx->inputs[i];                  \
+        if (link && !link->outcfg.fmts &&                           \
+            (_type == AVMEDIA_TYPE_UNKNOWN || link->type == _type)) { \
             int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts);   \
             if (ret < 0) {                                          \
                 return ret;                                         \
@@ -637,7 +639,9 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
         }                                                           \
     }                                                               \
     for (i = 0; i < ctx->nb_outputs; i++) {                         \
-        if (ctx->outputs[i] && !ctx->outputs[i]->incfg.fmts) {      \
+        AVFilterLink *const link = ctx->outputs[i];                 \
+        if (link && !link->incfg.fmts &&                            \
+            (_type == AVMEDIA_TYPE_UNKNOWN || link->type == _type)) { \
             int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts);   \
             if (ret < 0) {                                          \
                 return ret;                                         \
@@ -653,7 +657,7 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
 int ff_set_common_channel_layouts(AVFilterContext *ctx,
                                   AVFilterChannelLayouts *channel_layouts)
 {
-    SET_COMMON_FORMATS(ctx, channel_layouts,
+    SET_COMMON_FORMATS(ctx, channel_layouts, AVMEDIA_TYPE_AUDIO,
                        ff_channel_layouts_ref, ff_channel_layouts_unref);
 }
 
@@ -671,7 +675,7 @@ int ff_set_common_all_channel_counts(AVFilterContext *ctx)
 int ff_set_common_samplerates(AVFilterContext *ctx,
                               AVFilterFormats *samplerates)
 {
-    SET_COMMON_FORMATS(ctx, samplerates,
+    SET_COMMON_FORMATS(ctx, samplerates, AVMEDIA_TYPE_AUDIO,
                        ff_formats_ref, ff_formats_unref);
 }
 
@@ -693,7 +697,7 @@ int ff_set_common_all_samplerates(AVFilterContext *ctx)
  */
 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
 {
-    SET_COMMON_FORMATS(ctx, formats,
+    SET_COMMON_FORMATS(ctx, formats, AVMEDIA_TYPE_UNKNOWN,
                        ff_formats_ref, ff_formats_unref);
 }
 
diff --git a/libavfilter/formats.h b/libavfilter/formats.h
index ed513c265a..bef6557578 100644
--- a/libavfilter/formats.h
+++ b/libavfilter/formats.h
@@ -144,9 +144,9 @@ av_warn_unused_result
 AVFilterChannelLayouts *ff_make_format64_list(const int64_t *fmts);
 
 /**
- * A helper for query_formats() which sets all links to the same list of channel
- * layouts/sample rates. If there are no links hooked to this filter, the list
- * is freed.
+ * Helpers for query_formats() which set all free audio links to the same list
+ * of channel layouts/sample rates. If there are no links hooked to this list,
+ * the list is freed.
  */
 av_warn_unused_result
 int ff_set_common_channel_layouts(AVFilterContext *ctx,
-- 
2.30.2



More information about the ffmpeg-devel mailing list