diff mbox series

[FFmpeg-devel,1/2] lavfi: regroup formats lists in a single structure.

Message ID 20200813102421.286636-1-george@nsup.org
State Superseded
Headers show
Series [FFmpeg-devel,1/2] lavfi: regroup formats lists in a single structure. | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Nicolas George Aug. 13, 2020, 10:24 a.m. UTC
It will allow to refernce it as a whole without clunky macros.

Most of the changes have been automatically made with sed:

sed -i '
  s/-> *in_formats/->incfg.formats/g;
  s/-> *out_formats/->outcfg.formats/g;
  s/-> *in_channel_layouts/->incfg.channel_layouts/g;
  s/-> *out_channel_layouts/->outcfg.channel_layouts/g;
  s/-> *in_samplerates/->incfg.samplerates/g;
  s/-> *out_samplerates/->outcfg.samplerates/g;
  ' src/libavfilter/*(.)

Signed-off-by: Nicolas George <george@nsup.org>
---


I would appreciate quick feed-back on this one, because I need to build
on it (test the validity of the config), and it is the kind of patch
that is nightmarish to rebase because it can create many conflicts.

Andreas?


 libavfilter/aeval.c                |   4 +-
 libavfilter/af_afir.c              |   8 +-
 libavfilter/af_agate.c             |  10 +-
 libavfilter/af_aiir.c              |   2 +-
 libavfilter/af_amerge.c            |  12 +-
 libavfilter/af_anequalizer.c       |  14 +-
 libavfilter/af_aresample.c         |  12 +-
 libavfilter/af_asetrate.c          |   2 +-
 libavfilter/af_channelmap.c        |   4 +-
 libavfilter/af_channelsplit.c      |   4 +-
 libavfilter/af_hdcd.c              |   4 +-
 libavfilter/af_headphone.c         |   8 +-
 libavfilter/af_join.c              |   4 +-
 libavfilter/af_ladspa.c            |   6 +-
 libavfilter/af_loudnorm.c          |   4 +-
 libavfilter/af_lv2.c               |   6 +-
 libavfilter/af_pan.c               |   4 +-
 libavfilter/af_resample.c          |  12 +-
 libavfilter/af_sidechaincompress.c |  10 +-
 libavfilter/af_sofalizer.c         |   4 +-
 libavfilter/af_surround.c          |   4 +-
 libavfilter/avf_abitscope.c        |   8 +-
 libavfilter/avf_ahistogram.c       |   8 +-
 libavfilter/avf_aphasemeter.c      |  14 +-
 libavfilter/avf_avectorscope.c     |   8 +-
 libavfilter/avf_concat.c           |  12 +-
 libavfilter/avf_showcqt.c          |   8 +-
 libavfilter/avf_showfreqs.c        |   8 +-
 libavfilter/avf_showspatial.c      |   8 +-
 libavfilter/avf_showspectrum.c     |   8 +-
 libavfilter/avf_showvolume.c       |   8 +-
 libavfilter/avf_showwaves.c        |   8 +-
 libavfilter/avfilter.c             |  30 ++---
 libavfilter/avfilter.h             |  59 +++++---
 libavfilter/avfiltergraph.c        | 208 ++++++++++++++---------------
 libavfilter/f_drawgraph.c          |   2 +-
 libavfilter/f_ebur128.c            |  14 +-
 libavfilter/f_graphmonitor.c       |   2 +-
 libavfilter/formats.c              |   6 +-
 libavfilter/src_movie.c            |   8 +-
 libavfilter/tests/filtfmts.c       |   6 +-
 libavfilter/vaapi_vpp.c            |   4 +-
 libavfilter/vaf_spectrumsynth.c    |  10 +-
 libavfilter/vf_alphamerge.c        |   6 +-
 libavfilter/vf_ciescope.c          |   4 +-
 libavfilter/vf_colorspace.c        |   4 +-
 libavfilter/vf_coreimage.m         |   6 +-
 libavfilter/vf_elbg.c              |   4 +-
 libavfilter/vf_extractplanes.c     |  12 +-
 libavfilter/vf_fieldmatch.c        |   6 +-
 libavfilter/vf_fieldorder.c        |   4 +-
 libavfilter/vf_histogram.c         |  12 +-
 libavfilter/vf_hwdownload.c        |   4 +-
 libavfilter/vf_hwmap.c             |   4 +-
 libavfilter/vf_hwupload.c          |   4 +-
 libavfilter/vf_hwupload_cuda.c     |   4 +-
 libavfilter/vf_lut2.c              |   4 +-
 libavfilter/vf_mergeplanes.c       |   4 +-
 libavfilter/vf_overlay.c           |   6 +-
 libavfilter/vf_overlay_qsv.c       |   4 +-
 libavfilter/vf_palettegen.c        |   4 +-
 libavfilter/vf_paletteuse.c        |   6 +-
 libavfilter/vf_remap.c             |   8 +-
 libavfilter/vf_scale.c             |   4 +-
 libavfilter/vf_showpalette.c       |   4 +-
 libavfilter/vf_vectorscope.c       |  12 +-
 libavfilter/vf_vpp_qsv.c           |   4 +-
 libavfilter/vf_waveform.c          |  14 +-
 libavfilter/vf_yadif_cuda.c        |   4 +-
 libavfilter/vf_zscale.c            |   4 +-
 70 files changed, 381 insertions(+), 360 deletions(-)

Comments

Nicolas George Aug. 17, 2020, 3:18 p.m. UTC | #1
Nicolas George (12020-08-13):
> It will allow to refernce it as a whole without clunky macros.
> 
> Most of the changes have been automatically made with sed:
> 
> sed -i '
>   s/-> *in_formats/->incfg.formats/g;
>   s/-> *out_formats/->outcfg.formats/g;
>   s/-> *in_channel_layouts/->incfg.channel_layouts/g;
>   s/-> *out_channel_layouts/->outcfg.channel_layouts/g;
>   s/-> *in_samplerates/->incfg.samplerates/g;
>   s/-> *out_samplerates/->outcfg.samplerates/g;
>   ' src/libavfilter/*(.)
> 
> Signed-off-by: Nicolas George <george@nsup.org>
> ---
> 
> 
> I would appreciate quick feed-back on this one, because I need to build
> on it (test the validity of the config), and it is the kind of patch
> that is nightmarish to rebase because it can create many conflicts.
> 
> Andreas?

Ping?

Regards,
Andreas Rheinhardt Aug. 18, 2020, 7:14 p.m. UTC | #2
Nicolas George:
> It will allow to refernce it as a whole without clunky macros.
> 
> Most of the changes have been automatically made with sed:
> 
> sed -i '
>   s/-> *in_formats/->incfg.formats/g;
>   s/-> *out_formats/->outcfg.formats/g;
>   s/-> *in_channel_layouts/->incfg.channel_layouts/g;
>   s/-> *out_channel_layouts/->outcfg.channel_layouts/g;
>   s/-> *in_samplerates/->incfg.samplerates/g;
>   s/-> *out_samplerates/->outcfg.samplerates/g;
>   ' src/libavfilter/*(.)
> 
> Signed-off-by: Nicolas George <george@nsup.org>
> ---
> 
> 
> I would appreciate quick feed-back on this one, because I need to build
> on it (test the validity of the config), and it is the kind of patch
> that is nightmarish to rebase because it can create many conflicts.
> 
> Andreas?
> 
> 
>  libavfilter/aeval.c                |   4 +-
>  libavfilter/af_afir.c              |   8 +-
>  libavfilter/af_agate.c             |  10 +-
>  libavfilter/af_aiir.c              |   2 +-
>  libavfilter/af_amerge.c            |  12 +-
>  libavfilter/af_anequalizer.c       |  14 +-
>  libavfilter/af_aresample.c         |  12 +-
>  libavfilter/af_asetrate.c          |   2 +-
>  libavfilter/af_channelmap.c        |   4 +-
>  libavfilter/af_channelsplit.c      |   4 +-
>  libavfilter/af_hdcd.c              |   4 +-
>  libavfilter/af_headphone.c         |   8 +-
>  libavfilter/af_join.c              |   4 +-
>  libavfilter/af_ladspa.c            |   6 +-
>  libavfilter/af_loudnorm.c          |   4 +-
>  libavfilter/af_lv2.c               |   6 +-
>  libavfilter/af_pan.c               |   4 +-
>  libavfilter/af_resample.c          |  12 +-
>  libavfilter/af_sidechaincompress.c |  10 +-
>  libavfilter/af_sofalizer.c         |   4 +-
>  libavfilter/af_surround.c          |   4 +-
>  libavfilter/avf_abitscope.c        |   8 +-
>  libavfilter/avf_ahistogram.c       |   8 +-
>  libavfilter/avf_aphasemeter.c      |  14 +-
>  libavfilter/avf_avectorscope.c     |   8 +-
>  libavfilter/avf_concat.c           |  12 +-
>  libavfilter/avf_showcqt.c          |   8 +-
>  libavfilter/avf_showfreqs.c        |   8 +-
>  libavfilter/avf_showspatial.c      |   8 +-
>  libavfilter/avf_showspectrum.c     |   8 +-
>  libavfilter/avf_showvolume.c       |   8 +-
>  libavfilter/avf_showwaves.c        |   8 +-
>  libavfilter/avfilter.c             |  30 ++---
>  libavfilter/avfilter.h             |  59 +++++---
>  libavfilter/avfiltergraph.c        | 208 ++++++++++++++---------------
>  libavfilter/f_drawgraph.c          |   2 +-
>  libavfilter/f_ebur128.c            |  14 +-
>  libavfilter/f_graphmonitor.c       |   2 +-
>  libavfilter/formats.c              |   6 +-
>  libavfilter/src_movie.c            |   8 +-
>  libavfilter/tests/filtfmts.c       |   6 +-
>  libavfilter/vaapi_vpp.c            |   4 +-
>  libavfilter/vaf_spectrumsynth.c    |  10 +-
>  libavfilter/vf_alphamerge.c        |   6 +-
>  libavfilter/vf_ciescope.c          |   4 +-
>  libavfilter/vf_colorspace.c        |   4 +-
>  libavfilter/vf_coreimage.m         |   6 +-
>  libavfilter/vf_elbg.c              |   4 +-
>  libavfilter/vf_extractplanes.c     |  12 +-
>  libavfilter/vf_fieldmatch.c        |   6 +-
>  libavfilter/vf_fieldorder.c        |   4 +-
>  libavfilter/vf_histogram.c         |  12 +-
>  libavfilter/vf_hwdownload.c        |   4 +-
>  libavfilter/vf_hwmap.c             |   4 +-
>  libavfilter/vf_hwupload.c          |   4 +-
>  libavfilter/vf_hwupload_cuda.c     |   4 +-
>  libavfilter/vf_lut2.c              |   4 +-
>  libavfilter/vf_mergeplanes.c       |   4 +-
>  libavfilter/vf_overlay.c           |   6 +-
>  libavfilter/vf_overlay_qsv.c       |   4 +-
>  libavfilter/vf_palettegen.c        |   4 +-
>  libavfilter/vf_paletteuse.c        |   6 +-
>  libavfilter/vf_remap.c             |   8 +-
>  libavfilter/vf_scale.c             |   4 +-
>  libavfilter/vf_showpalette.c       |   4 +-
>  libavfilter/vf_vectorscope.c       |  12 +-
>  libavfilter/vf_vpp_qsv.c           |   4 +-
>  libavfilter/vf_waveform.c          |  14 +-
>  libavfilter/vf_yadif_cuda.c        |   4 +-
>  libavfilter/vf_zscale.c            |   4 +-
>  70 files changed, 381 insertions(+), 360 deletions(-)
> 
> diff --git a/libavfilter/af_asetrate.c b/libavfilter/af_asetrate.c
> index 50a5f43749..71643a36d0 100644
> --- a/libavfilter/af_asetrate.c
> +++ b/libavfilter/af_asetrate.c
> @@ -52,7 +52,7 @@ static av_cold int query_formats(AVFilterContext *ctx)
>      int sample_rates[] = { sr->sample_rate, -1 };
>  
>      return ff_formats_ref(ff_make_format_list(sample_rates),
> -                   &ctx->outputs[0]->in_samplerates);
> +                   &ctx->outputs[0]->incfg.samplerates);

Missed opportunity for proper alignment.

>  }
>  
>  static av_cold int config_props(AVFilterLink *outlink)
> diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
> index dd8074e462..c2d3e9b38a 100644
> --- a/libavfilter/avfilter.c
> +++ b/libavfilter/avfilter.c
> @@ -261,15 +261,15 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
>  
>      /* if any information on supported media formats already exists on the
>       * link, we need to preserve that */
> -    if (link->out_formats)
> -        ff_formats_changeref(&link->out_formats,
> -                             &filt->outputs[filt_dstpad_idx]->out_formats);
> -    if (link->out_samplerates)
> -        ff_formats_changeref(&link->out_samplerates,
> -                             &filt->outputs[filt_dstpad_idx]->out_samplerates);
> -    if (link->out_channel_layouts)
> -        ff_channel_layouts_changeref(&link->out_channel_layouts,
> -                                     &filt->outputs[filt_dstpad_idx]->out_channel_layouts);
> +    if (link->outcfg.formats)
> +        ff_formats_changeref(&link->outcfg.formats,
> +                             &filt->outputs[filt_dstpad_idx]->outcfg.formats);
> +    if (link->outcfg.samplerates)
> +        ff_formats_changeref(&link->outcfg.samplerates,
> +                             &filt->outputs[filt_dstpad_idx]->outcfg.samplerates);
> +    if (link->outcfg.channel_layouts)
> +        ff_channel_layouts_changeref(&link->outcfg.channel_layouts,
> +                                     &filt->outputs[filt_dstpad_idx]->outcfg.channel_layouts);
>  
>      return 0;
>  }
> @@ -746,12 +746,12 @@ static void free_link(AVFilterLink *link)
>  
>      av_buffer_unref(&link->hw_frames_ctx);
>  
> -    ff_formats_unref(&link->in_formats);
> -    ff_formats_unref(&link->out_formats);
> -    ff_formats_unref(&link->in_samplerates);
> -    ff_formats_unref(&link->out_samplerates);
> -    ff_channel_layouts_unref(&link->in_channel_layouts);
> -    ff_channel_layouts_unref(&link->out_channel_layouts);
> +    ff_formats_unref(&link->incfg.formats);
> +    ff_formats_unref(&link->outcfg.formats);
> +    ff_formats_unref(&link->incfg.samplerates);
> +    ff_formats_unref(&link->outcfg.samplerates);
> +    ff_channel_layouts_unref(&link->incfg.channel_layouts);
> +    ff_channel_layouts_unref(&link->outcfg.channel_layouts);
>      avfilter_link_free(&link);
>  }
>  
> diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
> index 49b4f7a939..5bcc47df2e 100644
> --- a/libavfilter/avfilter.h
> +++ b/libavfilter/avfilter.h
> @@ -264,13 +264,13 @@ typedef struct AVFilter {
>       * and outputs are fixed), shortly before the format negotiation. This
>       * callback may be called more than once.
>       *
> -     * This callback must set AVFilterLink.out_formats on every input link and
> -     * AVFilterLink.in_formats on every output link to a list of pixel/sample
> +     * This callback must set AVFilterLink.outcfg.formats on every input link and
> +     * AVFilterLink.incfg.formats on every output link to a list of pixel/sample
>       * formats that the filter supports on that link. For audio links, this
> -     * filter must also set @ref AVFilterLink.in_samplerates "in_samplerates" /
> -     * @ref AVFilterLink.out_samplerates "out_samplerates" and
> -     * @ref AVFilterLink.in_channel_layouts "in_channel_layouts" /
> -     * @ref AVFilterLink.out_channel_layouts "out_channel_layouts" analogously.
> +     * filter must also set @ref AVFilterLink.incfg.samplerates "in_samplerates" /
> +     * @ref AVFilterLink.outcfg.samplerates "out_samplerates" and
> +     * @ref AVFilterLink.incfg.channel_layouts "in_channel_layouts" /
> +     * @ref AVFilterLink.outcfg.channel_layouts "out_channel_layouts" analogously.
>       *
>       * This callback may be NULL for filters with one input, in which case
>       * libavfilter assumes that it supports all input formats and preserves
> @@ -424,6 +424,35 @@ struct AVFilterContext {
>      int extra_hw_frames;
>  };
>  
> +/**
> + * Lists of formats / etc. supported by an end of a link.
> + *
> + * This structure is directly part of AVFilterLink, in two copies:
> + * one for the source filter, one for the destination filter.
> +
> + * These lists are used for negotiating the format to actually be used,
> + * which will be loaded into the format and channel_layout members of
> + * AVFilterLink, when chosen.
> + */
> +typedef struct AVFilterFormatsConfig {
> +
> +    /**
> +     * List of supported formats (pixel or sample).
> +     */
> +    AVFilterFormats *formats;
> +
> +    /**
> +     * Lists of supported sample rates, only for audio.
> +     */
> +    AVFilterFormats  *samplerates;
> +
> +    /**
> +     * Lists of supported channel layouts, only for audio.
> +     */
> +    struct AVFilterChannelLayouts  *channel_layouts;

Why is there actually a typedef for AVFilterFormats in this very file,
but none for AVFilterChannelLayouts?

> +
> +} AVFilterFormatsConfig;
> +
>  /**
>   * A link between two filters. This contains pointers to the source and
>   * destination filters between which this link exists, and the indexes of
> @@ -471,24 +500,16 @@ struct AVFilterLink {
>       * New public fields should be added right above.
>       *****************************************************************
>       */
> +
>      /**
> -     * Lists of formats and channel layouts supported by the input and output
> -     * filters respectively. These lists are used for negotiating the format
> -     * to actually be used, which will be loaded into the format and
> -     * channel_layout members, above, when chosen.
> -     *
> +     * Lists of supported formats / etc. supported by the input filter.
>       */
> -    AVFilterFormats *in_formats;
> -    AVFilterFormats *out_formats;
> +    AVFilterFormatsConfig incfg;
>  
>      /**
> -     * Lists of channel layouts and sample rates used for automatic
> -     * negotiation.
> +     * Lists of supported formats / etc. supported by the output filter.
>       */
> -    AVFilterFormats  *in_samplerates;
> -    AVFilterFormats *out_samplerates;
> -    struct AVFilterChannelLayouts  *in_channel_layouts;
> -    struct AVFilterChannelLayouts *out_channel_layouts;
> +    AVFilterFormatsConfig outcfg;
>  
>      /**
>       * Audio only, the destination filter sets this to a non-zero value to
> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
> index a149f8fb6d..c8a52b1f47 100644
> --- a/libavfilter/avfiltergraph.c
> +++ b/libavfilter/avfiltergraph.c
> @@ -331,9 +331,9 @@ static int filter_query_formats(AVFilterContext *ctx)
>      }
>  
>      for (i = 0; i < ctx->nb_inputs; i++)
> -        sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts);
> +        sanitize_channel_layouts(ctx, ctx->inputs[i]->outcfg.channel_layouts);
>      for (i = 0; i < ctx->nb_outputs; i++)
> -        sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts);
> +        sanitize_channel_layouts(ctx, ctx->outputs[i]->incfg.channel_layouts);
>  
>      formats = ff_all_formats(type);
>      if ((ret = ff_set_common_formats(ctx, formats)) < 0)
> @@ -354,19 +354,19 @@ static int formats_declared(AVFilterContext *f)
>      int i;
>  
>      for (i = 0; i < f->nb_inputs; i++) {
> -        if (!f->inputs[i]->out_formats)
> +        if (!f->inputs[i]->outcfg.formats)
>              return 0;
>          if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO &&
> -            !(f->inputs[i]->out_samplerates &&
> -              f->inputs[i]->out_channel_layouts))
> +            !(f->inputs[i]->outcfg.samplerates &&
> +              f->inputs[i]->outcfg.channel_layouts))
>              return 0;
>      }
>      for (i = 0; i < f->nb_outputs; i++) {
> -        if (!f->outputs[i]->in_formats)
> +        if (!f->outputs[i]->incfg.formats)
>              return 0;
>          if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO &&
> -            !(f->outputs[i]->in_samplerates &&
> -              f->outputs[i]->in_channel_layouts))
> +            !(f->outputs[i]->incfg.samplerates &&
> +              f->outputs[i]->incfg.channel_layouts))
>              return 0;
>      }
>      return 1;
> @@ -471,24 +471,24 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
>              if (!link)
>                  continue;
>  
> -            if (link->in_formats != link->out_formats
> -                && link->in_formats && link->out_formats)
> -                if (!can_merge_formats(link->in_formats, link->out_formats,
> +            if (link->incfg.formats != link->outcfg.formats
> +                && link->incfg.formats && link->outcfg.formats)
> +                if (!can_merge_formats(link->incfg.formats, link->outcfg.formats,
>                                        link->type, 0))
>                      convert_needed = 1;
>              if (link->type == AVMEDIA_TYPE_AUDIO) {
> -                if (link->in_samplerates != link->out_samplerates
> -                    && link->in_samplerates && link->out_samplerates)
> -                    if (!can_merge_formats(link->in_samplerates,
> -                                           link->out_samplerates,
> +                if (link->incfg.samplerates != link->outcfg.samplerates
> +                    && link->incfg.samplerates && link->outcfg.samplerates)
> +                    if (!can_merge_formats(link->incfg.samplerates,
> +                                           link->outcfg.samplerates,
>                                             0, 1))
>                          convert_needed = 1;
>              }
>  
>  #define MERGE_DISPATCH(field, statement)                                     \
> -            if (!(link->in_ ## field && link->out_ ## field)) {              \
> +            if (!(link->incfg.field && link->outcfg.field)) {                \
>                  count_delayed++;                                             \
> -            } else if (link->in_ ## field == link->out_ ## field) {          \
> +            } else if (link->incfg.field == link->outcfg.field) {            \
>                  count_already_merged++;                                      \
>              } else if (!convert_needed) {                                    \
>                  count_merged++;                                              \
> @@ -497,18 +497,18 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
>  
>              if (link->type == AVMEDIA_TYPE_AUDIO) {
>                  MERGE_DISPATCH(channel_layouts,
> -                    if (!ff_merge_channel_layouts(link->in_channel_layouts,
> -                                                  link->out_channel_layouts))
> +                    if (!ff_merge_channel_layouts(link->incfg.channel_layouts,
> +                                                  link->outcfg.channel_layouts))
>                          convert_needed = 1;
>                  )
>                  MERGE_DISPATCH(samplerates,
> -                    if (!ff_merge_samplerates(link->in_samplerates,
> -                                              link->out_samplerates))
> +                    if (!ff_merge_samplerates(link->incfg.samplerates,
> +                                              link->outcfg.samplerates))
>                          convert_needed = 1;
>                  )
>              }
>              MERGE_DISPATCH(formats,
> -                if (!ff_merge_formats(link->in_formats, link->out_formats,
> +                if (!ff_merge_formats(link->incfg.formats, link->outcfg.formats,
>                                        link->type))
>                      convert_needed = 1;
>              )
> @@ -571,34 +571,34 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
>  
>                  inlink  = convert->inputs[0];
>                  outlink = convert->outputs[0];
> -                av_assert0( inlink-> in_formats->refcount > 0);
> -                av_assert0( inlink->out_formats->refcount > 0);
> -                av_assert0(outlink-> in_formats->refcount > 0);
> -                av_assert0(outlink->out_formats->refcount > 0);
> +                av_assert0( inlink->incfg.formats->refcount > 0);
> +                av_assert0( inlink->outcfg.formats->refcount > 0);
> +                av_assert0(outlink->incfg.formats->refcount > 0);
> +                av_assert0(outlink->outcfg.formats->refcount > 0);
>                  if (outlink->type == AVMEDIA_TYPE_AUDIO) {
> -                    av_assert0( inlink-> in_samplerates->refcount > 0);
> -                    av_assert0( inlink->out_samplerates->refcount > 0);
> -                    av_assert0(outlink-> in_samplerates->refcount > 0);
> -                    av_assert0(outlink->out_samplerates->refcount > 0);
> -                    av_assert0( inlink-> in_channel_layouts->refcount > 0);
> -                    av_assert0( inlink->out_channel_layouts->refcount > 0);
> -                    av_assert0(outlink-> in_channel_layouts->refcount > 0);
> -                    av_assert0(outlink->out_channel_layouts->refcount > 0);
> +                    av_assert0( inlink->incfg.samplerates->refcount > 0);
> +                    av_assert0( inlink->outcfg.samplerates->refcount > 0);
> +                    av_assert0(outlink->incfg.samplerates->refcount > 0);
> +                    av_assert0(outlink->outcfg.samplerates->refcount > 0);
> +                    av_assert0( inlink->incfg.channel_layouts->refcount > 0);
> +                    av_assert0( inlink->outcfg.channel_layouts->refcount > 0);
> +                    av_assert0(outlink->incfg.channel_layouts->refcount > 0);
> +                    av_assert0(outlink->outcfg.channel_layouts->refcount > 0);

You are breaking the alignment here.

>                  }
> -                if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats,  inlink->type) ||
> -                    !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))
> +                if (!ff_merge_formats( inlink->incfg.formats,  inlink->outcfg.formats,  inlink->type) ||
> +                    !ff_merge_formats(outlink->incfg.formats, outlink->outcfg.formats, outlink->type))
>                      ret = AVERROR(ENOSYS);
>                  if (inlink->type == AVMEDIA_TYPE_AUDIO &&
> -                    (!ff_merge_samplerates(inlink->in_samplerates,
> -                                           inlink->out_samplerates) ||
> -                     !ff_merge_channel_layouts(inlink->in_channel_layouts,
> -                                               inlink->out_channel_layouts)))
> +                    (!ff_merge_samplerates(inlink->incfg.samplerates,
> +                                           inlink->outcfg.samplerates) ||
> +                     !ff_merge_channel_layouts(inlink->incfg.channel_layouts,
> +                                               inlink->outcfg.channel_layouts)))
>                      ret = AVERROR(ENOSYS);
>                  if (outlink->type == AVMEDIA_TYPE_AUDIO &&
> -                    (!ff_merge_samplerates(outlink->in_samplerates,
> -                                           outlink->out_samplerates) ||
> -                     !ff_merge_channel_layouts(outlink->in_channel_layouts,
> -                                               outlink->out_channel_layouts)))
> +                    (!ff_merge_samplerates(outlink->incfg.samplerates,
> +                                           outlink->outcfg.samplerates) ||
> +                     !ff_merge_channel_layouts(outlink->incfg.channel_layouts,
> +                                               outlink->outcfg.channel_layouts)))
>                      ret = AVERROR(ENOSYS);
>  
>                  if (ret < 0) {
> @@ -674,7 +674,7 @@ static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt
>  
>  static int pick_format(AVFilterLink *link, AVFilterLink *ref)
>  {
> -    if (!link || !link->in_formats)
> +    if (!link || !link->incfg.formats)
>          return 0;
>  
>      if (link->type == AVMEDIA_TYPE_VIDEO) {
> @@ -683,67 +683,67 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref)
>              int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0;
>              enum AVPixelFormat best= AV_PIX_FMT_NONE;
>              int i;
> -            for (i=0; i<link->in_formats->nb_formats; i++) {
> -                enum AVPixelFormat p = link->in_formats->formats[i];
> +            for (i=0; i<link->incfg.formats->nb_formats; i++) {

Missed opportunity to add spaces.

> +                enum AVPixelFormat p = link->incfg.formats->formats[i];
>                  best= av_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
>              }
>              av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
> -                   av_get_pix_fmt_name(best), link->in_formats->nb_formats,
> +                   av_get_pix_fmt_name(best), link->incfg.formats->nb_formats,
>                     av_get_pix_fmt_name(ref->format), has_alpha);
> -            link->in_formats->formats[0] = best;
> +            link->incfg.formats->formats[0] = best;
>          }
>      } else if (link->type == AVMEDIA_TYPE_AUDIO) {
>          if(ref && ref->type == AVMEDIA_TYPE_AUDIO){
>              enum AVSampleFormat best= AV_SAMPLE_FMT_NONE;
>              int i;
> -            for (i=0; i<link->in_formats->nb_formats; i++) {
> -                enum AVSampleFormat p = link->in_formats->formats[i];
> +            for (i=0; i<link->incfg.formats->nb_formats; i++) {

Missed opportunity to add spaces.

> +                enum AVSampleFormat p = link->incfg.formats->formats[i];
>                  best = find_best_sample_fmt_of_2(best, p, ref->format);
>              }
>              av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s\n",
> -                   av_get_sample_fmt_name(best), link->in_formats->nb_formats,
> +                   av_get_sample_fmt_name(best), link->incfg.formats->nb_formats,
>                     av_get_sample_fmt_name(ref->format));
> -            link->in_formats->formats[0] = best;
> +            link->incfg.formats->formats[0] = best;
>          }
>      }
>  
> -    link->in_formats->nb_formats = 1;
> -    link->format = link->in_formats->formats[0];
> +    link->incfg.formats->nb_formats = 1;
> +    link->format = link->incfg.formats->formats[0];
>  
>      if (link->type == AVMEDIA_TYPE_AUDIO) {
> -        if (!link->in_samplerates->nb_formats) {
> +        if (!link->incfg.samplerates->nb_formats) {
>              av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
>                     " the link between filters %s and %s.\n", link->src->name,
>                     link->dst->name);
>              return AVERROR(EINVAL);
>          }
> -        link->in_samplerates->nb_formats = 1;
> -        link->sample_rate = link->in_samplerates->formats[0];
> +        link->incfg.samplerates->nb_formats = 1;
> +        link->sample_rate = link->incfg.samplerates->formats[0];
>  
> -        if (link->in_channel_layouts->all_layouts) {
> +        if (link->incfg.channel_layouts->all_layouts) {
>              av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
>                     " the link between filters %s and %s.\n", link->src->name,
>                     link->dst->name);
> -            if (!link->in_channel_layouts->all_counts)
> +            if (!link->incfg.channel_layouts->all_counts)
>                  av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not "
>                         "supported, try specifying a channel layout using "
>                         "'aformat=channel_layouts=something'.\n");
>              return AVERROR(EINVAL);
>          }
> -        link->in_channel_layouts->nb_channel_layouts = 1;
> -        link->channel_layout = link->in_channel_layouts->channel_layouts[0];
> +        link->incfg.channel_layouts->nb_channel_layouts = 1;
> +        link->channel_layout = link->incfg.channel_layouts->channel_layouts[0];
>          if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout)))
>              link->channel_layout = 0;
>          else
>              link->channels = av_get_channel_layout_nb_channels(link->channel_layout);
>      }
>  
> -    ff_formats_unref(&link->in_formats);
> -    ff_formats_unref(&link->out_formats);
> -    ff_formats_unref(&link->in_samplerates);
> -    ff_formats_unref(&link->out_samplerates);
> -    ff_channel_layouts_unref(&link->in_channel_layouts);
> -    ff_channel_layouts_unref(&link->out_channel_layouts);
> +    ff_formats_unref(&link->incfg.formats);
> +    ff_formats_unref(&link->outcfg.formats);
> +    ff_formats_unref(&link->incfg.samplerates);
> +    ff_formats_unref(&link->outcfg.samplerates);
> +    ff_channel_layouts_unref(&link->incfg.channel_layouts);
> +    ff_channel_layouts_unref(&link->outcfg.channel_layouts);
>  
>      return 0;
>  }
> @@ -754,27 +754,27 @@ do {                                                                   \
>          AVFilterLink *link = filter->inputs[i];                        \
>          fmt_type fmt;                                                  \
>                                                                         \
> -        if (!link->out_ ## list || link->out_ ## list->nb != 1)        \
> +        if (!link->outcfg.list || link->outcfg.list->nb != 1)          \
>              continue;                                                  \
> -        fmt = link->out_ ## list->var[0];                              \
> +        fmt = link->outcfg.list->var[0];                               \
>                                                                         \
>          for (j = 0; j < filter->nb_outputs; j++) {                     \
>              AVFilterLink *out_link = filter->outputs[j];               \
>              list_type *fmts;                                           \
>                                                                         \
>              if (link->type != out_link->type ||                        \
> -                out_link->in_ ## list->nb == 1)                        \
> +                out_link->incfg.list->nb == 1)                         \
>                  continue;                                              \
> -            fmts = out_link->in_ ## list;                              \
> +            fmts = out_link->incfg.list;                               \
>                                                                         \
> -            if (!out_link->in_ ## list->nb) {                          \
> -                if ((ret = add_format(&out_link->in_ ##list, fmt)) < 0)\
> +            if (!out_link->incfg.list->nb) {                           \
> +                if ((ret = add_format(&out_link->incfg.list, fmt)) < 0)\
>                      return ret;                                        \
>                  ret = 1;                                               \
>                  break;                                                 \
>              }                                                          \
>                                                                         \
> -            for (k = 0; k < out_link->in_ ## list->nb; k++)            \
> +            for (k = 0; k < out_link->incfg.list->nb; k++)             \
>                  if (fmts->var[k] == fmt) {                             \
>                      fmts->var[0]  = fmt;                               \
>                      fmts->nb = 1;                                      \
> @@ -799,16 +799,16 @@ static int reduce_formats_on_filter(AVFilterContext *filter)
>          AVFilterLink *inlink = filter->inputs[i];
>          uint64_t fmt;
>  
> -        if (!inlink->out_channel_layouts ||
> -            inlink->out_channel_layouts->nb_channel_layouts != 1)
> +        if (!inlink->outcfg.channel_layouts ||
> +            inlink->outcfg.channel_layouts->nb_channel_layouts != 1)
>              continue;
> -        fmt = inlink->out_channel_layouts->channel_layouts[0];
> +        fmt = inlink->outcfg.channel_layouts->channel_layouts[0];
>  
>          for (j = 0; j < filter->nb_outputs; j++) {
>              AVFilterLink *outlink = filter->outputs[j];
>              AVFilterChannelLayouts *fmts;
>  
> -            fmts = outlink->in_channel_layouts;
> +            fmts = outlink->incfg.channel_layouts;
>              if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
>                  continue;
>  
> @@ -816,12 +816,12 @@ static int reduce_formats_on_filter(AVFilterContext *filter)
>                  (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) {
>                  /* Turn the infinite list into a singleton */
>                  fmts->all_layouts = fmts->all_counts  = 0;
> -                if (ff_add_channel_layout(&outlink->in_channel_layouts, fmt) < 0)
> +                if (ff_add_channel_layout(&outlink->incfg.channel_layouts, fmt) < 0)
>                      ret = 1;
>                  break;
>              }
>  
> -            for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) {
> +            for (k = 0; k < outlink->incfg.channel_layouts->nb_channel_layouts; k++) {
>                  if (fmts->channel_layouts[k] == fmt) {
>                      fmts->channel_layouts[0]  = fmt;
>                      fmts->nb_channel_layouts = 1;
> @@ -862,24 +862,24 @@ static void swap_samplerates_on_filter(AVFilterContext *filter)
>          link = filter->inputs[i];
>  
>          if (link->type == AVMEDIA_TYPE_AUDIO &&
> -            link->out_samplerates->nb_formats== 1)
> +            link->outcfg.samplerates->nb_formats== 1)
>              break;
>      }
>      if (i == filter->nb_inputs)
>          return;
>  
> -    sample_rate = link->out_samplerates->formats[0];
> +    sample_rate = link->outcfg.samplerates->formats[0];
>  
>      for (i = 0; i < filter->nb_outputs; i++) {
>          AVFilterLink *outlink = filter->outputs[i];
>          int best_idx, best_diff = INT_MAX;
>  
>          if (outlink->type != AVMEDIA_TYPE_AUDIO ||
> -            outlink->in_samplerates->nb_formats < 2)
> +            outlink->incfg.samplerates->nb_formats < 2)
>              continue;
>  
> -        for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
> -            int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
> +        for (j = 0; j < outlink->incfg.samplerates->nb_formats; j++) {
> +            int diff = abs(sample_rate - outlink->incfg.samplerates->formats[j]);
>  
>              av_assert0(diff < INT_MAX); // This would lead to the use of uninitialized best_diff but is only possible with invalid sample rates
>  
> @@ -888,8 +888,8 @@ static void swap_samplerates_on_filter(AVFilterContext *filter)
>                  best_idx  = j;
>              }
>          }
> -        FFSWAP(int, outlink->in_samplerates->formats[0],
> -               outlink->in_samplerates->formats[best_idx]);
> +        FFSWAP(int, outlink->incfg.samplerates->formats[0],
> +               outlink->incfg.samplerates->formats[best_idx]);
>      }
>  }
>  
> @@ -944,7 +944,7 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter)
>          link = filter->inputs[i];
>  
>          if (link->type == AVMEDIA_TYPE_AUDIO &&
> -            link->out_channel_layouts->nb_channel_layouts == 1)
> +            link->outcfg.channel_layouts->nb_channel_layouts == 1)
>              break;
>      }
>      if (i == filter->nb_inputs)
> @@ -955,12 +955,12 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter)
>          int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
>  
>          if (outlink->type != AVMEDIA_TYPE_AUDIO ||
> -            outlink->in_channel_layouts->nb_channel_layouts < 2)
> +            outlink->incfg.channel_layouts->nb_channel_layouts < 2)
>              continue;
>  
> -        for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
> -            uint64_t  in_chlayout = link->out_channel_layouts->channel_layouts[0];
> -            uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
> +        for (j = 0; j < outlink->incfg.channel_layouts->nb_channel_layouts; j++) {
> +            uint64_t  in_chlayout = link->outcfg.channel_layouts->channel_layouts[0];
> +            uint64_t out_chlayout = outlink->incfg.channel_layouts->channel_layouts[j];
>              int  in_channels      = av_get_channel_layout_nb_channels(in_chlayout);
>              int out_channels      = av_get_channel_layout_nb_channels(out_chlayout);
>              int count_diff        = out_channels - in_channels;
> @@ -1018,8 +1018,8 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter)
>              }
>          }
>          av_assert0(best_idx >= 0);
> -        FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
> -               outlink->in_channel_layouts->channel_layouts[best_idx]);
> +        FFSWAP(uint64_t, outlink->incfg.channel_layouts->channel_layouts[0],
> +               outlink->incfg.channel_layouts->channel_layouts[best_idx]);
>      }
>  
>  }
> @@ -1042,13 +1042,13 @@ static void swap_sample_fmts_on_filter(AVFilterContext *filter)
>          link = filter->inputs[i];
>  
>          if (link->type == AVMEDIA_TYPE_AUDIO &&
> -            link->out_formats->nb_formats == 1)
> +            link->outcfg.formats->nb_formats == 1)
>              break;
>      }
>      if (i == filter->nb_inputs)
>          return;
>  
> -    format = link->out_formats->formats[0];
> +    format = link->outcfg.formats->formats[0];
>      bps    = av_get_bytes_per_sample(format);
>  
>      for (i = 0; i < filter->nb_outputs; i++) {
> @@ -1056,11 +1056,11 @@ static void swap_sample_fmts_on_filter(AVFilterContext *filter)
>          int best_idx = -1, best_score = INT_MIN;
>  
>          if (outlink->type != AVMEDIA_TYPE_AUDIO ||
> -            outlink->in_formats->nb_formats < 2)
> +            outlink->incfg.formats->nb_formats < 2)
>              continue;
>  
> -        for (j = 0; j < outlink->in_formats->nb_formats; j++) {
> -            int out_format = outlink->in_formats->formats[j];
> +        for (j = 0; j < outlink->incfg.formats->nb_formats; j++) {
> +            int out_format = outlink->incfg.formats->formats[j];
>              int out_bps    = av_get_bytes_per_sample(out_format);
>              int score;
>  
> @@ -1087,8 +1087,8 @@ static void swap_sample_fmts_on_filter(AVFilterContext *filter)
>              }
>          }
>          av_assert0(best_idx >= 0);
> -        FFSWAP(int, outlink->in_formats->formats[0],
> -               outlink->in_formats->formats[best_idx]);
> +        FFSWAP(int, outlink->incfg.formats->formats[0],
> +               outlink->incfg.formats->formats[best_idx]);
>      }
>  }
>  
> @@ -1112,7 +1112,7 @@ static int pick_formats(AVFilterGraph *graph)
>              AVFilterContext *filter = graph->filters[i];
>              if (filter->nb_inputs){
>                  for (j = 0; j < filter->nb_inputs; j++){
> -                    if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->nb_formats == 1) {
> +                    if(filter->inputs[j]->incfg.formats && filter->inputs[j]->incfg.formats->nb_formats == 1) {
>                          if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
>                              return ret;
>                          change = 1;
> @@ -1121,7 +1121,7 @@ static int pick_formats(AVFilterGraph *graph)
>              }
>              if (filter->nb_outputs){
>                  for (j = 0; j < filter->nb_outputs; j++){
> -                    if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->nb_formats == 1) {
> +                    if(filter->outputs[j]->incfg.formats && filter->outputs[j]->incfg.formats->nb_formats == 1) {

Missed opportunity to add a space after if here and above.

>                          if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
>                              return ret;
>                          change = 1;

1. Adding this struct has also another benefit besides the ones in your
two other patches: One can simplify the freeing process by adding a new
ff_formatscfg_unref() (I'm not sure on the name). This could also be
used in the uninit function of the aformat filter. If I am not mistaken,
the only place outside of formats.c where one needs to unref an
AVFilterContext/AVFilterChannelLayout is in hwdownload where one only
needs ff_formats_unref() -- ff_channel_layouts_unref() can therefore be
made static. (This presumes that redundant ff_*_unref() have been
removed as is done in [1].)
2. For the ease of backportability the double-frees/memleaks ([2] and
the other patches from that patchset) should be applied before this one.

- Andreas

[1]: https://ffmpeg.org/pipermail/ffmpeg-devel/2020-August/267602.html
[2]: https://ffmpeg.org/pipermail/ffmpeg-devel/2020-August/267595.html
Nicolas George Aug. 20, 2020, 3:05 p.m. UTC | #3
Andreas Rheinhardt (12020-08-18):
> 1. Adding this struct has also another benefit besides the ones in your
> two other patches: One can simplify the freeing process by adding a new
> ff_formatscfg_unref() (I'm not sure on the name). This could also be
> used in the uninit function of the aformat filter. If I am not mistaken,
> the only place outside of formats.c where one needs to unref an
> AVFilterContext/AVFilterChannelLayout is in hwdownload where one only
> needs ff_formats_unref() -- ff_channel_layouts_unref() can therefore be
> made static. (This presumes that redundant ff_*_unref() have been
> removed as is done in [1].)

Actually, I find the use of ff_formats_unref() in filter somewhat
suspicious. The functions are designed to free their arguments if
something fails, so as not to leak anything.

> 2. For the ease of backportability the double-frees/memleaks ([2] and
> the other patches from that patchset) should be applied before this one.

What is missing before applying this?

Anyway, one of the next steps I consider this is to merge
AVFilterChannelLayout into AVFilterFormats. Still with three versions of
the merge functions, but some other functions can be made generic.

That would allow to make the merge / can_merge and other functions part
of a structure of callback, and make the architecture of the negotiation
more nimble, paving the way for other media types and multi-level
negotiation.

Regards,
Andreas Rheinhardt Aug. 21, 2020, 9:18 p.m. UTC | #4
Nicolas George:
> Andreas Rheinhardt (12020-08-18):
>> 1. Adding this struct has also another benefit besides the ones in your
>> two other patches: One can simplify the freeing process by adding a new
>> ff_formatscfg_unref() (I'm not sure on the name). This could also be
>> used in the uninit function of the aformat filter. If I am not mistaken,
>> the only place outside of formats.c where one needs to unref an
>> AVFilterContext/AVFilterChannelLayout is in hwdownload where one only
>> needs ff_formats_unref() -- ff_channel_layouts_unref() can therefore be
>> made static. (This presumes that redundant ff_*_unref() have been
>> removed as is done in [1].)
> 
> Actually, I find the use of ff_formats_unref() in filter somewhat
> suspicious. The functions are designed to free their arguments if
> something fails, so as not to leak anything.
> 

This only works if one only works with one list without owner at a time;
if one has several such lists at the same time and an error happens when
working with one of these lists, one has to free the other lists.

This scenario can of course usually be avoided by making sure that one
only has one list without owner at any given time. I used this method in
my patches a lot. I have also rewritten the hwdownload patch [1] to
avoid explicit ff_formats_unref() in it. This means that
ff_formats_unref() can become static, too.

[1]: https://ffmpeg.org/pipermail/ffmpeg-devel/2020-August/268429.html

>> 2. For the ease of backportability the double-frees/memleaks ([2] and
>> the other patches from that patchset) should be applied before this one.
> 
> What is missing before applying this?
> 

What does "this" refer to here? If it refers to my patches, then nothing
is missing (except a review). They can be applied at once and then they
can also be directly backported and you can then apply your big patch on
top of it; of course, there will be trivial conflicts in the few files
that I touch.

If "this" refers to your patches: Applying them before fixing the
leaks/double-frees will make backporting the fixes much more troublesome.

- Andreas
Nicolas George Aug. 22, 2020, 12:23 p.m. UTC | #5
Andreas Rheinhardt (12020-08-21):
> This only works if one only works with one list without owner at a time;
> if one has several such lists at the same time and an error happens when
> working with one of these lists, one has to free the other lists.
> 
> This scenario can of course usually be avoided by making sure that one
> only has one list without owner at any given time. I used this method in
> my patches a lot. I have also rewritten the hwdownload patch [1] to
> avoid explicit ff_formats_unref() in it. This means that
> ff_formats_unref() can become static, too.
> 
> [1]: https://ffmpeg.org/pipermail/ffmpeg-devel/2020-August/268429.html

Well done.

> What does "this" refer to here? If it refers to my patches, then nothing
> is missing (except a review). They can be applied at once and then they
> can also be directly backported and you can then apply your big patch on
> top of it; of course, there will be trivial conflicts in the few files
> that I touch.
> 
> If "this" refers to your patches: Applying them before fixing the
> leaks/double-frees will make backporting the fixes much more troublesome.

I meant your patch series: I have become lost in the various
submissions. Are there still patches that need review?

Regards,
Andreas Rheinhardt Aug. 22, 2020, 3:24 p.m. UTC | #6
Nicolas George:
> Andreas Rheinhardt (12020-08-21):
>> This only works if one only works with one list without owner at a time;
>> if one has several such lists at the same time and an error happens when
>> working with one of these lists, one has to free the other lists.
>>
>> This scenario can of course usually be avoided by making sure that one
>> only has one list without owner at any given time. I used this method in
>> my patches a lot. I have also rewritten the hwdownload patch [1] to
>> avoid explicit ff_formats_unref() in it. This means that
>> ff_formats_unref() can become static, too.
>>
>> [1]: https://ffmpeg.org/pipermail/ffmpeg-devel/2020-August/268429.html
> 
> Well done.
> 
>> What does "this" refer to here? If it refers to my patches, then nothing
>> is missing (except a review). They can be applied at once and then they
>> can also be directly backported and you can then apply your big patch on
>> top of it; of course, there will be trivial conflicts in the few files
>> that I touch.
>>
>> If "this" refers to your patches: Applying them before fixing the
>> leaks/double-frees will make backporting the fixes much more troublesome.
> 
> I meant your patch series: I have become lost in the various
> submissions. Are there still patches that need review?
> 
Basically patches 8-17 (with the exception of 10 and 13 which Paul
already LGTM'ed) still need review. 17 [1] is the key patch of the whole
series; you should probably look at it first to see what's wrong with
the current API. The other patches are very similar and easy.

- Andreas

[1]: https://ffmpeg.org/pipermail/ffmpeg-devel/2020-August/267595.html
diff mbox series

Patch

diff --git a/libavfilter/aeval.c b/libavfilter/aeval.c
index c7a8cd6550..4c62c98097 100644
--- a/libavfilter/aeval.c
+++ b/libavfilter/aeval.c
@@ -362,7 +362,7 @@  static int aeval_query_formats(AVFilterContext *ctx)
 
     // inlink supports any channel layout
     layouts = ff_all_channel_counts();
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     if (eval->same_chlayout) {
@@ -376,7 +376,7 @@  static int aeval_query_formats(AVFilterContext *ctx)
                               eval->out_channel_layout ? eval->out_channel_layout :
                               FF_COUNT2LAYOUT(eval->nb_channels))) < 0)
             return ret;
-        if ((ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts)) < 0)
+        if ((ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts)) < 0)
             return ret;
     }
 
diff --git a/libavfilter/af_afir.c b/libavfilter/af_afir.c
index 5ba880f10b..43dc691473 100644
--- a/libavfilter/af_afir.c
+++ b/libavfilter/af_afir.c
@@ -727,7 +727,7 @@  static int query_formats(AVFilterContext *ctx)
     if (s->response) {
         AVFilterLink *videolink = ctx->outputs[1];
         formats = ff_make_format_list(pix_fmts);
-        if ((ret = ff_formats_ref(formats, &videolink->in_formats)) < 0)
+        if ((ret = ff_formats_ref(formats, &videolink->incfg.formats)) < 0)
             return ret;
     }
 
@@ -746,12 +746,12 @@  static int query_formats(AVFilterContext *ctx)
         if (ret)
             return ret;
 
-        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts)) < 0)
+        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts)) < 0)
             return ret;
-        if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0)
+        if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0)
             return ret;
         for (int i = 1; i < ctx->nb_inputs; i++) {
-            if ((ret = ff_channel_layouts_ref(mono, &ctx->inputs[i]->out_channel_layouts)) < 0)
+            if ((ret = ff_channel_layouts_ref(mono, &ctx->inputs[i]->outcfg.channel_layouts)) < 0)
                 return ret;
         }
     }
diff --git a/libavfilter/af_agate.c b/libavfilter/af_agate.c
index 936caa0a44..9efc6f9c40 100644
--- a/libavfilter/af_agate.c
+++ b/libavfilter/af_agate.c
@@ -353,20 +353,20 @@  static int scquery_formats(AVFilterContext *ctx)
     };
     int ret, i;
 
-    if (!ctx->inputs[0]->in_channel_layouts ||
-        !ctx->inputs[0]->in_channel_layouts->nb_channel_layouts) {
+    if (!ctx->inputs[0]->incfg.channel_layouts ||
+        !ctx->inputs[0]->incfg.channel_layouts->nb_channel_layouts) {
         av_log(ctx, AV_LOG_WARNING,
                "No channel layout for input 1\n");
             return AVERROR(EAGAIN);
     }
 
-    if ((ret = ff_add_channel_layout(&layouts, ctx->inputs[0]->in_channel_layouts->channel_layouts[0])) < 0 ||
-        (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0)
+    if ((ret = ff_add_channel_layout(&layouts, ctx->inputs[0]->incfg.channel_layouts->channel_layouts[0])) < 0 ||
+        (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0)
         return ret;
 
     for (i = 0; i < 2; i++) {
         layouts = ff_all_channel_counts();
-        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts)) < 0)
+        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0)
             return ret;
     }
 
diff --git a/libavfilter/af_aiir.c b/libavfilter/af_aiir.c
index bc31e5141e..03ab841cee 100644
--- a/libavfilter/af_aiir.c
+++ b/libavfilter/af_aiir.c
@@ -95,7 +95,7 @@  static int query_formats(AVFilterContext *ctx)
         AVFilterLink *videolink = ctx->outputs[1];
 
         formats = ff_make_format_list(pix_fmts);
-        if ((ret = ff_formats_ref(formats, &videolink->in_formats)) < 0)
+        if ((ret = ff_formats_ref(formats, &videolink->incfg.formats)) < 0)
             return ret;
     }
 
diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c
index 567f25982d..a836d09f5a 100644
--- a/libavfilter/af_amerge.c
+++ b/libavfilter/af_amerge.c
@@ -76,14 +76,14 @@  static int query_formats(AVFilterContext *ctx)
     int i, ret, overlap = 0, nb_ch = 0;
 
     for (i = 0; i < s->nb_inputs; i++) {
-        if (!ctx->inputs[i]->in_channel_layouts ||
-            !ctx->inputs[i]->in_channel_layouts->nb_channel_layouts) {
+        if (!ctx->inputs[i]->incfg.channel_layouts ||
+            !ctx->inputs[i]->incfg.channel_layouts->nb_channel_layouts) {
             av_log(ctx, AV_LOG_WARNING,
                    "No channel layout for input %d\n", i + 1);
             return AVERROR(EAGAIN);
         }
-        inlayout[i] = ctx->inputs[i]->in_channel_layouts->channel_layouts[0];
-        if (ctx->inputs[i]->in_channel_layouts->nb_channel_layouts > 1) {
+        inlayout[i] = ctx->inputs[i]->incfg.channel_layouts->channel_layouts[0];
+        if (ctx->inputs[i]->incfg.channel_layouts->nb_channel_layouts > 1) {
             char buf[256];
             av_get_channel_layout_string(buf, sizeof(buf), 0, inlayout[i]);
             av_log(ctx, AV_LOG_INFO, "Using \"%s\" for input %d\n", buf, i + 1);
@@ -131,13 +131,13 @@  static int query_formats(AVFilterContext *ctx)
         layouts = NULL;
         if ((ret = ff_add_channel_layout(&layouts, inlayout[i])) < 0)
             return ret;
-        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts)) < 0)
+        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0)
             return ret;
     }
     layouts = NULL;
     if ((ret = ff_add_channel_layout(&layouts, outlayout)) < 0)
         return ret;
-    if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0)
         return ret;
 
     return ff_set_common_samplerates(ctx, ff_all_samplerates());
diff --git a/libavfilter/af_anequalizer.c b/libavfilter/af_anequalizer.c
index 177e1c7b39..663fd1c1d7 100644
--- a/libavfilter/af_anequalizer.c
+++ b/libavfilter/af_anequalizer.c
@@ -245,23 +245,23 @@  static int query_formats(AVFilterContext *ctx)
     if (s->draw_curves) {
         AVFilterLink *videolink = ctx->outputs[1];
         formats = ff_make_format_list(pix_fmts);
-        if ((ret = ff_formats_ref(formats, &videolink->in_formats)) < 0)
+        if ((ret = ff_formats_ref(formats, &videolink->incfg.formats)) < 0)
             return ret;
     }
 
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0 ||
-        (ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     layouts = ff_all_channel_counts();
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0 ||
-        (ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0 ||
+        (ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0 ||
-        (ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0 ||
+        (ret = ff_formats_ref(formats, &outlink->incfg.samplerates)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c
index b7b1b5ba3c..e54bd3eb41 100644
--- a/libavfilter/af_aresample.c
+++ b/libavfilter/af_aresample.c
@@ -95,15 +95,15 @@  static int query_formats(AVFilterContext *ctx)
     av_opt_get_int(aresample->swr, "ocl", 0, &out_layout);
 
     in_formats      = ff_all_formats(AVMEDIA_TYPE_AUDIO);
-    if ((ret = ff_formats_ref(in_formats, &inlink->out_formats)) < 0)
+    if ((ret = ff_formats_ref(in_formats, &inlink->outcfg.formats)) < 0)
         return ret;
 
     in_samplerates  = ff_all_samplerates();
-    if ((ret = ff_formats_ref(in_samplerates, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(in_samplerates, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     in_layouts      = ff_all_channel_counts();
-    if ((ret = ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(in_layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     if(out_rate > 0) {
@@ -113,7 +113,7 @@  static int query_formats(AVFilterContext *ctx)
         out_samplerates = ff_all_samplerates();
     }
 
-    if ((ret = ff_formats_ref(out_samplerates, &outlink->in_samplerates)) < 0)
+    if ((ret = ff_formats_ref(out_samplerates, &outlink->incfg.samplerates)) < 0)
         return ret;
 
     if(out_format != AV_SAMPLE_FMT_NONE) {
@@ -121,7 +121,7 @@  static int query_formats(AVFilterContext *ctx)
         out_formats = ff_make_format_list(formatlist);
     } else
         out_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO);
-    if ((ret = ff_formats_ref(out_formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(out_formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     if(out_layout) {
@@ -130,7 +130,7 @@  static int query_formats(AVFilterContext *ctx)
     } else
         out_layouts = ff_all_channel_counts();
 
-    return ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts);
+    return ff_channel_layouts_ref(out_layouts, &outlink->incfg.channel_layouts);
 }
 
 
diff --git a/libavfilter/af_asetrate.c b/libavfilter/af_asetrate.c
index 50a5f43749..71643a36d0 100644
--- a/libavfilter/af_asetrate.c
+++ b/libavfilter/af_asetrate.c
@@ -52,7 +52,7 @@  static av_cold int query_formats(AVFilterContext *ctx)
     int sample_rates[] = { sr->sample_rate, -1 };
 
     return ff_formats_ref(ff_make_format_list(sample_rates),
-                   &ctx->outputs[0]->in_samplerates);
+                   &ctx->outputs[0]->incfg.samplerates);
 }
 
 static av_cold int config_props(AVFilterLink *outlink)
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index 285d76a3ef..1314706b5c 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -292,8 +292,8 @@  static int channelmap_query_formats(AVFilterContext *ctx)
     if ((ret = ff_add_channel_layout     (&channel_layouts, s->output_layout                    )) < 0 ||
         (ret = ff_set_common_formats     (ctx             , ff_planar_sample_fmts()             )) < 0 ||
         (ret = ff_set_common_samplerates (ctx             , ff_all_samplerates()                )) < 0 ||
-        (ret = ff_channel_layouts_ref    (layouts         , &ctx->inputs[0]->out_channel_layouts)) < 0 ||
-        (ret = ff_channel_layouts_ref    (channel_layouts , &ctx->outputs[0]->in_channel_layouts)) < 0)
+        (ret = ff_channel_layouts_ref    (layouts         , &ctx->inputs[0]->outcfg.channel_layouts)) < 0 ||
+        (ret = ff_channel_layouts_ref    (channel_layouts , &ctx->outputs[0]->incfg.channel_layouts)) < 0)
             goto fail;
 
     return 0;
diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c
index 821bb73801..ad00fe1ba1 100644
--- a/libavfilter/af_channelsplit.c
+++ b/libavfilter/af_channelsplit.c
@@ -117,7 +117,7 @@  static int query_formats(AVFilterContext *ctx)
         return ret;
 
     if ((ret = ff_add_channel_layout(&in_layouts, s->channel_layout)) < 0 ||
-        (ret = ff_channel_layouts_ref(in_layouts, &ctx->inputs[0]->out_channel_layouts)) < 0)
+        (ret = ff_channel_layouts_ref(in_layouts, &ctx->inputs[0]->outcfg.channel_layouts)) < 0)
         return ret;
 
     for (i = 0; i < ctx->nb_outputs; i++) {
@@ -125,7 +125,7 @@  static int query_formats(AVFilterContext *ctx)
         uint64_t channel = av_channel_layout_extract_channel(s->channel_layout, s->map[i]);
 
         if ((ret = ff_add_channel_layout(&out_layouts, channel)) < 0 ||
-            (ret = ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->in_channel_layouts)) < 0)
+            (ret = ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->incfg.channel_layouts)) < 0)
             return ret;
     }
 
diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c
index fd17646f09..251d03229a 100644
--- a/libavfilter/af_hdcd.c
+++ b/libavfilter/af_hdcd.c
@@ -1638,12 +1638,12 @@  static int query_formats(AVFilterContext *ctx)
         return ret;
 
     in_formats = ff_make_format_list(sample_fmts_in);
-    ret = ff_formats_ref(in_formats, &inlink->out_formats);
+    ret = ff_formats_ref(in_formats, &inlink->outcfg.formats);
     if (ret < 0)
         return ret;
 
     out_formats = ff_make_format_list(sample_fmts_out);
-    ret = ff_formats_ref(out_formats, &outlink->in_formats);
+    ret = ff_formats_ref(out_formats, &outlink->incfg.formats);
     if (ret < 0)
         return ret;
 
diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c
index 552ad84837..de81e51464 100644
--- a/libavfilter/af_headphone.c
+++ b/libavfilter/af_headphone.c
@@ -698,7 +698,7 @@  static int query_formats(AVFilterContext *ctx)
     if (!layouts)
         return AVERROR(ENOMEM);
 
-    ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts);
+    ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts);
     if (ret)
         return ret;
 
@@ -710,18 +710,18 @@  static int query_formats(AVFilterContext *ctx)
         hrir_layouts = ff_all_channel_counts();
         if (!hrir_layouts)
             return AVERROR(ENOMEM);
-        ret = ff_channel_layouts_ref(hrir_layouts, &ctx->inputs[1]->out_channel_layouts);
+        ret = ff_channel_layouts_ref(hrir_layouts, &ctx->inputs[1]->outcfg.channel_layouts);
         if (ret)
             return ret;
     } else {
         for (i = 1; i < s->nb_inputs; i++) {
-            ret = ff_channel_layouts_ref(stereo_layout, &ctx->inputs[i]->out_channel_layouts);
+            ret = ff_channel_layouts_ref(stereo_layout, &ctx->inputs[i]->outcfg.channel_layouts);
             if (ret)
                 return ret;
         }
     }
 
-    ret = ff_channel_layouts_ref(stereo_layout, &ctx->outputs[0]->in_channel_layouts);
+    ret = ff_channel_layouts_ref(stereo_layout, &ctx->outputs[0]->incfg.channel_layouts);
     if (ret)
         return ret;
 
diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c
index ea03b60d67..8f5df267de 100644
--- a/libavfilter/af_join.c
+++ b/libavfilter/af_join.c
@@ -227,12 +227,12 @@  static int join_query_formats(AVFilterContext *ctx)
     int i, ret;
 
     if ((ret = ff_add_channel_layout(&layouts, s->channel_layout)) < 0 ||
-        (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0)
+        (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0)
         return ret;
 
     for (i = 0; i < ctx->nb_inputs; i++) {
         layouts = ff_all_channel_layouts();
-        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts)) < 0)
+        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0)
             return ret;
     }
 
diff --git a/libavfilter/af_ladspa.c b/libavfilter/af_ladspa.c
index ce695db9ff..31adc9c345 100644
--- a/libavfilter/af_ladspa.c
+++ b/libavfilter/af_ladspa.c
@@ -714,12 +714,12 @@  static int query_formats(AVFilterContext *ctx)
             ret = ff_add_channel_layout(&layouts, inlayout);
             if (ret < 0)
                 return ret;
-            ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
+            ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts);
             if (ret < 0)
                 return ret;
 
             if (!s->nb_outputs) {
-                ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
+                ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts);
                 if (ret < 0)
                     return ret;
             }
@@ -732,7 +732,7 @@  static int query_formats(AVFilterContext *ctx)
             ret = ff_add_channel_layout(&layouts, outlayout);
             if (ret < 0)
                 return ret;
-            ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
+            ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts);
             if (ret < 0)
                 return ret;
         }
diff --git a/libavfilter/af_loudnorm.c b/libavfilter/af_loudnorm.c
index 8e3cdc36db..06aca8ef4f 100644
--- a/libavfilter/af_loudnorm.c
+++ b/libavfilter/af_loudnorm.c
@@ -714,10 +714,10 @@  static int query_formats(AVFilterContext *ctx)
         formats = ff_make_format_list(input_srate);
         if (!formats)
             return AVERROR(ENOMEM);
-        ret = ff_formats_ref(formats, &inlink->out_samplerates);
+        ret = ff_formats_ref(formats, &inlink->outcfg.samplerates);
         if (ret < 0)
             return ret;
-        ret = ff_formats_ref(formats, &outlink->in_samplerates);
+        ret = ff_formats_ref(formats, &outlink->incfg.samplerates);
         if (ret < 0)
             return ret;
     }
diff --git a/libavfilter/af_lv2.c b/libavfilter/af_lv2.c
index 8a0a6fd888..3dabe566f5 100644
--- a/libavfilter/af_lv2.c
+++ b/libavfilter/af_lv2.c
@@ -524,12 +524,12 @@  static int query_formats(AVFilterContext *ctx)
             ret = ff_add_channel_layout(&layouts, inlayout);
             if (ret < 0)
                 return ret;
-            ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
+            ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts);
             if (ret < 0)
                 return ret;
 
             if (!s->nb_outputs) {
-                ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
+                ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts);
                 if (ret < 0)
                     return ret;
             }
@@ -542,7 +542,7 @@  static int query_formats(AVFilterContext *ctx)
             ret = ff_add_channel_layout(&layouts, outlayout);
             if (ret < 0)
                 return ret;
-            ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
+            ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts);
             if (ret < 0)
                 return ret;
         }
diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c
index 6924d1c721..b628177071 100644
--- a/libavfilter/af_pan.c
+++ b/libavfilter/af_pan.c
@@ -266,7 +266,7 @@  static int query_formats(AVFilterContext *ctx)
 
     // inlink supports any channel layout
     layouts = ff_all_channel_counts();
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     // outlink supports only requested output channel layout
@@ -275,7 +275,7 @@  static int query_formats(AVFilterContext *ctx)
                           pan->out_channel_layout ? pan->out_channel_layout :
                           FF_COUNT2LAYOUT(pan->nb_output_channels))) < 0)
         return ret;
-    return ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
+    return ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts);
 }
 
 static int config_props(AVFilterLink *link)
diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c
index 785cd0c7f4..caa97d8ab0 100644
--- a/libavfilter/af_resample.c
+++ b/libavfilter/af_resample.c
@@ -102,12 +102,12 @@  static int query_formats(AVFilterContext *ctx)
         !(out_layouts     = ff_all_channel_layouts (                  )))
         return AVERROR(ENOMEM);
 
-    if ((ret = ff_formats_ref         (in_formats,      &inlink->out_formats        )) < 0 ||
-        (ret = ff_formats_ref         (out_formats,     &outlink->in_formats        )) < 0 ||
-        (ret = ff_formats_ref         (in_samplerates,  &inlink->out_samplerates    )) < 0 ||
-        (ret = ff_formats_ref         (out_samplerates, &outlink->in_samplerates    )) < 0 ||
-        (ret = ff_channel_layouts_ref (in_layouts,      &inlink->out_channel_layouts)) < 0 ||
-        (ret = ff_channel_layouts_ref (out_layouts,     &outlink->in_channel_layouts)) < 0)
+    if ((ret = ff_formats_ref         (in_formats,      &inlink->outcfg.formats        )) < 0 ||
+        (ret = ff_formats_ref         (out_formats,     &outlink->incfg.formats        )) < 0 ||
+        (ret = ff_formats_ref         (in_samplerates,  &inlink->outcfg.samplerates    )) < 0 ||
+        (ret = ff_formats_ref         (out_samplerates, &outlink->incfg.samplerates    )) < 0 ||
+        (ret = ff_channel_layouts_ref (in_layouts,      &inlink->outcfg.channel_layouts)) < 0 ||
+        (ret = ff_channel_layouts_ref (out_layouts,     &outlink->incfg.channel_layouts)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/af_sidechaincompress.c b/libavfilter/af_sidechaincompress.c
index e79c04d40e..80d1d8a10b 100644
--- a/libavfilter/af_sidechaincompress.c
+++ b/libavfilter/af_sidechaincompress.c
@@ -306,20 +306,20 @@  static int query_formats(AVFilterContext *ctx)
     };
     int ret, i;
 
-    if (!ctx->inputs[0]->in_channel_layouts ||
-        !ctx->inputs[0]->in_channel_layouts->nb_channel_layouts) {
+    if (!ctx->inputs[0]->incfg.channel_layouts ||
+        !ctx->inputs[0]->incfg.channel_layouts->nb_channel_layouts) {
         av_log(ctx, AV_LOG_WARNING,
                "No channel layout for input 1\n");
             return AVERROR(EAGAIN);
     }
 
-    if ((ret = ff_add_channel_layout(&layouts, ctx->inputs[0]->in_channel_layouts->channel_layouts[0])) < 0 ||
-        (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0)
+    if ((ret = ff_add_channel_layout(&layouts, ctx->inputs[0]->incfg.channel_layouts->channel_layouts[0])) < 0 ||
+        (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0)
         return ret;
 
     for (i = 0; i < 2; i++) {
         layouts = ff_all_channel_counts();
-        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts)) < 0)
+        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0)
             return ret;
     }
 
diff --git a/libavfilter/af_sofalizer.c b/libavfilter/af_sofalizer.c
index ccf3872e77..bfcdfeed05 100644
--- a/libavfilter/af_sofalizer.c
+++ b/libavfilter/af_sofalizer.c
@@ -652,7 +652,7 @@  static int query_formats(AVFilterContext *ctx)
     if (!layouts)
         return AVERROR(ENOMEM);
 
-    ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts);
+    ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts);
     if (ret)
         return ret;
 
@@ -661,7 +661,7 @@  static int query_formats(AVFilterContext *ctx)
     if (ret)
         return ret;
 
-    ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts);
+    ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts);
     if (ret)
         return ret;
 
diff --git a/libavfilter/af_surround.c b/libavfilter/af_surround.c
index 11406786ee..d18b3146e7 100644
--- a/libavfilter/af_surround.c
+++ b/libavfilter/af_surround.c
@@ -175,7 +175,7 @@  static int query_formats(AVFilterContext *ctx)
     if (ret)
         return ret;
 
-    ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts);
+    ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts);
     if (ret)
         return ret;
 
@@ -184,7 +184,7 @@  static int query_formats(AVFilterContext *ctx)
     if (ret)
         return ret;
 
-    ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts);
+    ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts);
     if (ret)
         return ret;
 
diff --git a/libavfilter/avf_abitscope.c b/libavfilter/avf_abitscope.c
index 759f821e74..5011943888 100644
--- a/libavfilter/avf_abitscope.c
+++ b/libavfilter/avf_abitscope.c
@@ -69,21 +69,21 @@  static int query_formats(AVFilterContext *ctx)
     int ret;
 
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0)
         return ret;
 
     layouts = ff_all_channel_counts();
     if (!layouts)
         return AVERROR(ENOMEM);
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     formats = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/avf_ahistogram.c b/libavfilter/avf_ahistogram.c
index 92cda46756..b37b4a66a2 100644
--- a/libavfilter/avf_ahistogram.c
+++ b/libavfilter/avf_ahistogram.c
@@ -99,17 +99,17 @@  static int query_formats(AVFilterContext *ctx)
     int ret = AVERROR(EINVAL);
 
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref         (formats, &inlink->out_formats        )) < 0 ||
+    if ((ret = ff_formats_ref         (formats, &inlink->outcfg.formats        )) < 0 ||
         (layouts = ff_all_channel_counts()) == NULL ||
-        (ret = ff_channel_layouts_ref (layouts, &inlink->out_channel_layouts)) < 0)
+        (ret = ff_channel_layouts_ref (layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     formats = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/avf_aphasemeter.c b/libavfilter/avf_aphasemeter.c
index be0b2fb70f..ce5085a8e3 100644
--- a/libavfilter/avf_aphasemeter.c
+++ b/libavfilter/avf_aphasemeter.c
@@ -76,23 +76,23 @@  static int query_formats(AVFilterContext *ctx)
     int ret;
 
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref         (formats, &inlink->out_formats        )) < 0 ||
-        (ret = ff_formats_ref         (formats, &outlink->in_formats        )) < 0 ||
+    if ((ret = ff_formats_ref         (formats, &inlink->outcfg.formats        )) < 0 ||
+        (ret = ff_formats_ref         (formats, &outlink->incfg.formats        )) < 0 ||
         (ret = ff_add_channel_layout  (&layout, AV_CH_LAYOUT_STEREO         )) < 0 ||
-        (ret = ff_channel_layouts_ref (layout , &inlink->out_channel_layouts)) < 0 ||
-        (ret = ff_channel_layouts_ref (layout , &outlink->in_channel_layouts)) < 0)
+        (ret = ff_channel_layouts_ref (layout , &inlink->outcfg.channel_layouts)) < 0 ||
+        (ret = ff_channel_layouts_ref (layout , &outlink->incfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0 ||
-        (ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0 ||
+        (ret = ff_formats_ref(formats, &outlink->incfg.samplerates)) < 0)
         return ret;
 
     if (s->do_video) {
         AVFilterLink *outlink = ctx->outputs[1];
 
         formats = ff_make_format_list(pix_fmts);
-        if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+        if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
             return ret;
     }
 
diff --git a/libavfilter/avf_avectorscope.c b/libavfilter/avf_avectorscope.c
index b288ff63ff..c44353c7fd 100644
--- a/libavfilter/avf_avectorscope.c
+++ b/libavfilter/avf_avectorscope.c
@@ -190,17 +190,17 @@  static int query_formats(AVFilterContext *ctx)
     int ret;
 
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref         (formats, &inlink->out_formats        )) < 0 ||
+    if ((ret = ff_formats_ref         (formats, &inlink->outcfg.formats        )) < 0 ||
         (ret = ff_add_channel_layout  (&layout, AV_CH_LAYOUT_STEREO         )) < 0 ||
-        (ret = ff_channel_layouts_ref (layout , &inlink->out_channel_layouts)) < 0)
+        (ret = ff_channel_layouts_ref (layout , &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     formats = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c
index 28bd5407ad..5608ed9ac6 100644
--- a/libavfilter/avf_concat.c
+++ b/libavfilter/avf_concat.c
@@ -87,25 +87,25 @@  static int query_formats(AVFilterContext *ctx)
 
             /* Set the output formats */
             formats = ff_all_formats(type);
-            if ((ret = ff_formats_ref(formats, &ctx->outputs[idx]->in_formats)) < 0)
+            if ((ret = ff_formats_ref(formats, &ctx->outputs[idx]->incfg.formats)) < 0)
                 return ret;
 
             if (type == AVMEDIA_TYPE_AUDIO) {
                 rates = ff_all_samplerates();
-                if ((ret = ff_formats_ref(rates, &ctx->outputs[idx]->in_samplerates)) < 0)
+                if ((ret = ff_formats_ref(rates, &ctx->outputs[idx]->incfg.samplerates)) < 0)
                     return ret;
                 layouts = ff_all_channel_layouts();
-                if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[idx]->in_channel_layouts)) < 0)
+                if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[idx]->incfg.channel_layouts)) < 0)
                     return ret;
             }
 
             /* Set the same formats for each corresponding input */
             for (seg = 0; seg < cat->nb_segments; seg++) {
-                if ((ret = ff_formats_ref(formats, &ctx->inputs[idx]->out_formats)) < 0)
+                if ((ret = ff_formats_ref(formats, &ctx->inputs[idx]->outcfg.formats)) < 0)
                     return ret;
                 if (type == AVMEDIA_TYPE_AUDIO) {
-                    if ((ret = ff_formats_ref(rates, &ctx->inputs[idx]->out_samplerates)) < 0 ||
-                        (ret = ff_channel_layouts_ref(layouts, &ctx->inputs[idx]->out_channel_layouts)) < 0)
+                    if ((ret = ff_formats_ref(rates, &ctx->inputs[idx]->outcfg.samplerates)) < 0 ||
+                        (ret = ff_channel_layouts_ref(layouts, &ctx->inputs[idx]->outcfg.channel_layouts)) < 0)
                         return ret;
                 }
                 idx += ctx->nb_outputs;
diff --git a/libavfilter/avf_showcqt.c b/libavfilter/avf_showcqt.c
index 95efe72628..115174a9b4 100644
--- a/libavfilter/avf_showcqt.c
+++ b/libavfilter/avf_showcqt.c
@@ -1331,20 +1331,20 @@  static int query_formats(AVFilterContext *ctx)
 
     /* set input audio formats */
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0)
         return ret;
 
     layouts = ff_make_format64_list(channel_layouts);
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     /* set output video format */
     formats = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/avf_showfreqs.c b/libavfilter/avf_showfreqs.c
index 645754ded3..5cc1f0b013 100644
--- a/libavfilter/avf_showfreqs.c
+++ b/libavfilter/avf_showfreqs.c
@@ -132,20 +132,20 @@  static int query_formats(AVFilterContext *ctx)
 
     /* set input audio formats */
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0)
         return ret;
 
     layouts = ff_all_channel_layouts();
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     /* set output video format */
     formats = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/avf_showspatial.c b/libavfilter/avf_showspatial.c
index 80109a3055..a2c8ac24ba 100644
--- a/libavfilter/avf_showspatial.c
+++ b/libavfilter/avf_showspatial.c
@@ -114,17 +114,17 @@  static int query_formats(AVFilterContext *ctx)
     int ret;
 
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref         (formats, &inlink->out_formats        )) < 0 ||
+    if ((ret = ff_formats_ref         (formats, &inlink->outcfg.formats        )) < 0 ||
         (ret = ff_add_channel_layout  (&layout, AV_CH_LAYOUT_STEREO         )) < 0 ||
-        (ret = ff_channel_layouts_ref (layout , &inlink->out_channel_layouts)) < 0)
+        (ret = ff_channel_layouts_ref (layout , &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     formats = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
index e99f377fb0..c690665bad 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -355,20 +355,20 @@  static int query_formats(AVFilterContext *ctx)
 
     /* set input audio formats */
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0)
         return ret;
 
     layouts = ff_all_channel_layouts();
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     /* set output video format */
     formats = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/avf_showvolume.c b/libavfilter/avf_showvolume.c
index 7ab2fcfc4c..466283a3eb 100644
--- a/libavfilter/avf_showvolume.c
+++ b/libavfilter/avf_showvolume.c
@@ -125,19 +125,19 @@  static int query_formats(AVFilterContext *ctx)
     int ret;
 
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0)
         return ret;
 
     layouts = ff_all_channel_counts();
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     formats = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
index cf784604d9..aabd79e23b 100644
--- a/libavfilter/avf_showwaves.c
+++ b/libavfilter/avf_showwaves.c
@@ -161,20 +161,20 @@  static int query_formats(AVFilterContext *ctx)
 
     /* set input audio formats */
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0)
         return ret;
 
     layouts = ff_all_channel_layouts();
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_all_samplerates();
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
         return ret;
 
     /* set output video format */
     formats = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index dd8074e462..c2d3e9b38a 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -261,15 +261,15 @@  int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
 
     /* if any information on supported media formats already exists on the
      * link, we need to preserve that */
-    if (link->out_formats)
-        ff_formats_changeref(&link->out_formats,
-                             &filt->outputs[filt_dstpad_idx]->out_formats);
-    if (link->out_samplerates)
-        ff_formats_changeref(&link->out_samplerates,
-                             &filt->outputs[filt_dstpad_idx]->out_samplerates);
-    if (link->out_channel_layouts)
-        ff_channel_layouts_changeref(&link->out_channel_layouts,
-                                     &filt->outputs[filt_dstpad_idx]->out_channel_layouts);
+    if (link->outcfg.formats)
+        ff_formats_changeref(&link->outcfg.formats,
+                             &filt->outputs[filt_dstpad_idx]->outcfg.formats);
+    if (link->outcfg.samplerates)
+        ff_formats_changeref(&link->outcfg.samplerates,
+                             &filt->outputs[filt_dstpad_idx]->outcfg.samplerates);
+    if (link->outcfg.channel_layouts)
+        ff_channel_layouts_changeref(&link->outcfg.channel_layouts,
+                                     &filt->outputs[filt_dstpad_idx]->outcfg.channel_layouts);
 
     return 0;
 }
@@ -746,12 +746,12 @@  static void free_link(AVFilterLink *link)
 
     av_buffer_unref(&link->hw_frames_ctx);
 
-    ff_formats_unref(&link->in_formats);
-    ff_formats_unref(&link->out_formats);
-    ff_formats_unref(&link->in_samplerates);
-    ff_formats_unref(&link->out_samplerates);
-    ff_channel_layouts_unref(&link->in_channel_layouts);
-    ff_channel_layouts_unref(&link->out_channel_layouts);
+    ff_formats_unref(&link->incfg.formats);
+    ff_formats_unref(&link->outcfg.formats);
+    ff_formats_unref(&link->incfg.samplerates);
+    ff_formats_unref(&link->outcfg.samplerates);
+    ff_channel_layouts_unref(&link->incfg.channel_layouts);
+    ff_channel_layouts_unref(&link->outcfg.channel_layouts);
     avfilter_link_free(&link);
 }
 
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 49b4f7a939..5bcc47df2e 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -264,13 +264,13 @@  typedef struct AVFilter {
      * and outputs are fixed), shortly before the format negotiation. This
      * callback may be called more than once.
      *
-     * This callback must set AVFilterLink.out_formats on every input link and
-     * AVFilterLink.in_formats on every output link to a list of pixel/sample
+     * This callback must set AVFilterLink.outcfg.formats on every input link and
+     * AVFilterLink.incfg.formats on every output link to a list of pixel/sample
      * formats that the filter supports on that link. For audio links, this
-     * filter must also set @ref AVFilterLink.in_samplerates "in_samplerates" /
-     * @ref AVFilterLink.out_samplerates "out_samplerates" and
-     * @ref AVFilterLink.in_channel_layouts "in_channel_layouts" /
-     * @ref AVFilterLink.out_channel_layouts "out_channel_layouts" analogously.
+     * filter must also set @ref AVFilterLink.incfg.samplerates "in_samplerates" /
+     * @ref AVFilterLink.outcfg.samplerates "out_samplerates" and
+     * @ref AVFilterLink.incfg.channel_layouts "in_channel_layouts" /
+     * @ref AVFilterLink.outcfg.channel_layouts "out_channel_layouts" analogously.
      *
      * This callback may be NULL for filters with one input, in which case
      * libavfilter assumes that it supports all input formats and preserves
@@ -424,6 +424,35 @@  struct AVFilterContext {
     int extra_hw_frames;
 };
 
+/**
+ * Lists of formats / etc. supported by an end of a link.
+ *
+ * This structure is directly part of AVFilterLink, in two copies:
+ * one for the source filter, one for the destination filter.
+
+ * These lists are used for negotiating the format to actually be used,
+ * which will be loaded into the format and channel_layout members of
+ * AVFilterLink, when chosen.
+ */
+typedef struct AVFilterFormatsConfig {
+
+    /**
+     * List of supported formats (pixel or sample).
+     */
+    AVFilterFormats *formats;
+
+    /**
+     * Lists of supported sample rates, only for audio.
+     */
+    AVFilterFormats  *samplerates;
+
+    /**
+     * Lists of supported channel layouts, only for audio.
+     */
+    struct AVFilterChannelLayouts  *channel_layouts;
+
+} AVFilterFormatsConfig;
+
 /**
  * A link between two filters. This contains pointers to the source and
  * destination filters between which this link exists, and the indexes of
@@ -471,24 +500,16 @@  struct AVFilterLink {
      * New public fields should be added right above.
      *****************************************************************
      */
+
     /**
-     * Lists of formats and channel layouts supported by the input and output
-     * filters respectively. These lists are used for negotiating the format
-     * to actually be used, which will be loaded into the format and
-     * channel_layout members, above, when chosen.
-     *
+     * Lists of supported formats / etc. supported by the input filter.
      */
-    AVFilterFormats *in_formats;
-    AVFilterFormats *out_formats;
+    AVFilterFormatsConfig incfg;
 
     /**
-     * Lists of channel layouts and sample rates used for automatic
-     * negotiation.
+     * Lists of supported formats / etc. supported by the output filter.
      */
-    AVFilterFormats  *in_samplerates;
-    AVFilterFormats *out_samplerates;
-    struct AVFilterChannelLayouts  *in_channel_layouts;
-    struct AVFilterChannelLayouts *out_channel_layouts;
+    AVFilterFormatsConfig outcfg;
 
     /**
      * Audio only, the destination filter sets this to a non-zero value to
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index a149f8fb6d..c8a52b1f47 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -331,9 +331,9 @@  static int filter_query_formats(AVFilterContext *ctx)
     }
 
     for (i = 0; i < ctx->nb_inputs; i++)
-        sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts);
+        sanitize_channel_layouts(ctx, ctx->inputs[i]->outcfg.channel_layouts);
     for (i = 0; i < ctx->nb_outputs; i++)
-        sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts);
+        sanitize_channel_layouts(ctx, ctx->outputs[i]->incfg.channel_layouts);
 
     formats = ff_all_formats(type);
     if ((ret = ff_set_common_formats(ctx, formats)) < 0)
@@ -354,19 +354,19 @@  static int formats_declared(AVFilterContext *f)
     int i;
 
     for (i = 0; i < f->nb_inputs; i++) {
-        if (!f->inputs[i]->out_formats)
+        if (!f->inputs[i]->outcfg.formats)
             return 0;
         if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO &&
-            !(f->inputs[i]->out_samplerates &&
-              f->inputs[i]->out_channel_layouts))
+            !(f->inputs[i]->outcfg.samplerates &&
+              f->inputs[i]->outcfg.channel_layouts))
             return 0;
     }
     for (i = 0; i < f->nb_outputs; i++) {
-        if (!f->outputs[i]->in_formats)
+        if (!f->outputs[i]->incfg.formats)
             return 0;
         if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO &&
-            !(f->outputs[i]->in_samplerates &&
-              f->outputs[i]->in_channel_layouts))
+            !(f->outputs[i]->incfg.samplerates &&
+              f->outputs[i]->incfg.channel_layouts))
             return 0;
     }
     return 1;
@@ -471,24 +471,24 @@  static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
             if (!link)
                 continue;
 
-            if (link->in_formats != link->out_formats
-                && link->in_formats && link->out_formats)
-                if (!can_merge_formats(link->in_formats, link->out_formats,
+            if (link->incfg.formats != link->outcfg.formats
+                && link->incfg.formats && link->outcfg.formats)
+                if (!can_merge_formats(link->incfg.formats, link->outcfg.formats,
                                       link->type, 0))
                     convert_needed = 1;
             if (link->type == AVMEDIA_TYPE_AUDIO) {
-                if (link->in_samplerates != link->out_samplerates
-                    && link->in_samplerates && link->out_samplerates)
-                    if (!can_merge_formats(link->in_samplerates,
-                                           link->out_samplerates,
+                if (link->incfg.samplerates != link->outcfg.samplerates
+                    && link->incfg.samplerates && link->outcfg.samplerates)
+                    if (!can_merge_formats(link->incfg.samplerates,
+                                           link->outcfg.samplerates,
                                            0, 1))
                         convert_needed = 1;
             }
 
 #define MERGE_DISPATCH(field, statement)                                     \
-            if (!(link->in_ ## field && link->out_ ## field)) {              \
+            if (!(link->incfg.field && link->outcfg.field)) {                \
                 count_delayed++;                                             \
-            } else if (link->in_ ## field == link->out_ ## field) {          \
+            } else if (link->incfg.field == link->outcfg.field) {            \
                 count_already_merged++;                                      \
             } else if (!convert_needed) {                                    \
                 count_merged++;                                              \
@@ -497,18 +497,18 @@  static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
 
             if (link->type == AVMEDIA_TYPE_AUDIO) {
                 MERGE_DISPATCH(channel_layouts,
-                    if (!ff_merge_channel_layouts(link->in_channel_layouts,
-                                                  link->out_channel_layouts))
+                    if (!ff_merge_channel_layouts(link->incfg.channel_layouts,
+                                                  link->outcfg.channel_layouts))
                         convert_needed = 1;
                 )
                 MERGE_DISPATCH(samplerates,
-                    if (!ff_merge_samplerates(link->in_samplerates,
-                                              link->out_samplerates))
+                    if (!ff_merge_samplerates(link->incfg.samplerates,
+                                              link->outcfg.samplerates))
                         convert_needed = 1;
                 )
             }
             MERGE_DISPATCH(formats,
-                if (!ff_merge_formats(link->in_formats, link->out_formats,
+                if (!ff_merge_formats(link->incfg.formats, link->outcfg.formats,
                                       link->type))
                     convert_needed = 1;
             )
@@ -571,34 +571,34 @@  static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
 
                 inlink  = convert->inputs[0];
                 outlink = convert->outputs[0];
-                av_assert0( inlink-> in_formats->refcount > 0);
-                av_assert0( inlink->out_formats->refcount > 0);
-                av_assert0(outlink-> in_formats->refcount > 0);
-                av_assert0(outlink->out_formats->refcount > 0);
+                av_assert0( inlink->incfg.formats->refcount > 0);
+                av_assert0( inlink->outcfg.formats->refcount > 0);
+                av_assert0(outlink->incfg.formats->refcount > 0);
+                av_assert0(outlink->outcfg.formats->refcount > 0);
                 if (outlink->type == AVMEDIA_TYPE_AUDIO) {
-                    av_assert0( inlink-> in_samplerates->refcount > 0);
-                    av_assert0( inlink->out_samplerates->refcount > 0);
-                    av_assert0(outlink-> in_samplerates->refcount > 0);
-                    av_assert0(outlink->out_samplerates->refcount > 0);
-                    av_assert0( inlink-> in_channel_layouts->refcount > 0);
-                    av_assert0( inlink->out_channel_layouts->refcount > 0);
-                    av_assert0(outlink-> in_channel_layouts->refcount > 0);
-                    av_assert0(outlink->out_channel_layouts->refcount > 0);
+                    av_assert0( inlink->incfg.samplerates->refcount > 0);
+                    av_assert0( inlink->outcfg.samplerates->refcount > 0);
+                    av_assert0(outlink->incfg.samplerates->refcount > 0);
+                    av_assert0(outlink->outcfg.samplerates->refcount > 0);
+                    av_assert0( inlink->incfg.channel_layouts->refcount > 0);
+                    av_assert0( inlink->outcfg.channel_layouts->refcount > 0);
+                    av_assert0(outlink->incfg.channel_layouts->refcount > 0);
+                    av_assert0(outlink->outcfg.channel_layouts->refcount > 0);
                 }
-                if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats,  inlink->type) ||
-                    !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))
+                if (!ff_merge_formats( inlink->incfg.formats,  inlink->outcfg.formats,  inlink->type) ||
+                    !ff_merge_formats(outlink->incfg.formats, outlink->outcfg.formats, outlink->type))
                     ret = AVERROR(ENOSYS);
                 if (inlink->type == AVMEDIA_TYPE_AUDIO &&
-                    (!ff_merge_samplerates(inlink->in_samplerates,
-                                           inlink->out_samplerates) ||
-                     !ff_merge_channel_layouts(inlink->in_channel_layouts,
-                                               inlink->out_channel_layouts)))
+                    (!ff_merge_samplerates(inlink->incfg.samplerates,
+                                           inlink->outcfg.samplerates) ||
+                     !ff_merge_channel_layouts(inlink->incfg.channel_layouts,
+                                               inlink->outcfg.channel_layouts)))
                     ret = AVERROR(ENOSYS);
                 if (outlink->type == AVMEDIA_TYPE_AUDIO &&
-                    (!ff_merge_samplerates(outlink->in_samplerates,
-                                           outlink->out_samplerates) ||
-                     !ff_merge_channel_layouts(outlink->in_channel_layouts,
-                                               outlink->out_channel_layouts)))
+                    (!ff_merge_samplerates(outlink->incfg.samplerates,
+                                           outlink->outcfg.samplerates) ||
+                     !ff_merge_channel_layouts(outlink->incfg.channel_layouts,
+                                               outlink->outcfg.channel_layouts)))
                     ret = AVERROR(ENOSYS);
 
                 if (ret < 0) {
@@ -674,7 +674,7 @@  static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt
 
 static int pick_format(AVFilterLink *link, AVFilterLink *ref)
 {
-    if (!link || !link->in_formats)
+    if (!link || !link->incfg.formats)
         return 0;
 
     if (link->type == AVMEDIA_TYPE_VIDEO) {
@@ -683,67 +683,67 @@  static int pick_format(AVFilterLink *link, AVFilterLink *ref)
             int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0;
             enum AVPixelFormat best= AV_PIX_FMT_NONE;
             int i;
-            for (i=0; i<link->in_formats->nb_formats; i++) {
-                enum AVPixelFormat p = link->in_formats->formats[i];
+            for (i=0; i<link->incfg.formats->nb_formats; i++) {
+                enum AVPixelFormat p = link->incfg.formats->formats[i];
                 best= av_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
             }
             av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
-                   av_get_pix_fmt_name(best), link->in_formats->nb_formats,
+                   av_get_pix_fmt_name(best), link->incfg.formats->nb_formats,
                    av_get_pix_fmt_name(ref->format), has_alpha);
-            link->in_formats->formats[0] = best;
+            link->incfg.formats->formats[0] = best;
         }
     } else if (link->type == AVMEDIA_TYPE_AUDIO) {
         if(ref && ref->type == AVMEDIA_TYPE_AUDIO){
             enum AVSampleFormat best= AV_SAMPLE_FMT_NONE;
             int i;
-            for (i=0; i<link->in_formats->nb_formats; i++) {
-                enum AVSampleFormat p = link->in_formats->formats[i];
+            for (i=0; i<link->incfg.formats->nb_formats; i++) {
+                enum AVSampleFormat p = link->incfg.formats->formats[i];
                 best = find_best_sample_fmt_of_2(best, p, ref->format);
             }
             av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s\n",
-                   av_get_sample_fmt_name(best), link->in_formats->nb_formats,
+                   av_get_sample_fmt_name(best), link->incfg.formats->nb_formats,
                    av_get_sample_fmt_name(ref->format));
-            link->in_formats->formats[0] = best;
+            link->incfg.formats->formats[0] = best;
         }
     }
 
-    link->in_formats->nb_formats = 1;
-    link->format = link->in_formats->formats[0];
+    link->incfg.formats->nb_formats = 1;
+    link->format = link->incfg.formats->formats[0];
 
     if (link->type == AVMEDIA_TYPE_AUDIO) {
-        if (!link->in_samplerates->nb_formats) {
+        if (!link->incfg.samplerates->nb_formats) {
             av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
                    " the link between filters %s and %s.\n", link->src->name,
                    link->dst->name);
             return AVERROR(EINVAL);
         }
-        link->in_samplerates->nb_formats = 1;
-        link->sample_rate = link->in_samplerates->formats[0];
+        link->incfg.samplerates->nb_formats = 1;
+        link->sample_rate = link->incfg.samplerates->formats[0];
 
-        if (link->in_channel_layouts->all_layouts) {
+        if (link->incfg.channel_layouts->all_layouts) {
             av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
                    " the link between filters %s and %s.\n", link->src->name,
                    link->dst->name);
-            if (!link->in_channel_layouts->all_counts)
+            if (!link->incfg.channel_layouts->all_counts)
                 av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not "
                        "supported, try specifying a channel layout using "
                        "'aformat=channel_layouts=something'.\n");
             return AVERROR(EINVAL);
         }
-        link->in_channel_layouts->nb_channel_layouts = 1;
-        link->channel_layout = link->in_channel_layouts->channel_layouts[0];
+        link->incfg.channel_layouts->nb_channel_layouts = 1;
+        link->channel_layout = link->incfg.channel_layouts->channel_layouts[0];
         if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout)))
             link->channel_layout = 0;
         else
             link->channels = av_get_channel_layout_nb_channels(link->channel_layout);
     }
 
-    ff_formats_unref(&link->in_formats);
-    ff_formats_unref(&link->out_formats);
-    ff_formats_unref(&link->in_samplerates);
-    ff_formats_unref(&link->out_samplerates);
-    ff_channel_layouts_unref(&link->in_channel_layouts);
-    ff_channel_layouts_unref(&link->out_channel_layouts);
+    ff_formats_unref(&link->incfg.formats);
+    ff_formats_unref(&link->outcfg.formats);
+    ff_formats_unref(&link->incfg.samplerates);
+    ff_formats_unref(&link->outcfg.samplerates);
+    ff_channel_layouts_unref(&link->incfg.channel_layouts);
+    ff_channel_layouts_unref(&link->outcfg.channel_layouts);
 
     return 0;
 }
@@ -754,27 +754,27 @@  do {                                                                   \
         AVFilterLink *link = filter->inputs[i];                        \
         fmt_type fmt;                                                  \
                                                                        \
-        if (!link->out_ ## list || link->out_ ## list->nb != 1)        \
+        if (!link->outcfg.list || link->outcfg.list->nb != 1)          \
             continue;                                                  \
-        fmt = link->out_ ## list->var[0];                              \
+        fmt = link->outcfg.list->var[0];                               \
                                                                        \
         for (j = 0; j < filter->nb_outputs; j++) {                     \
             AVFilterLink *out_link = filter->outputs[j];               \
             list_type *fmts;                                           \
                                                                        \
             if (link->type != out_link->type ||                        \
-                out_link->in_ ## list->nb == 1)                        \
+                out_link->incfg.list->nb == 1)                         \
                 continue;                                              \
-            fmts = out_link->in_ ## list;                              \
+            fmts = out_link->incfg.list;                               \
                                                                        \
-            if (!out_link->in_ ## list->nb) {                          \
-                if ((ret = add_format(&out_link->in_ ##list, fmt)) < 0)\
+            if (!out_link->incfg.list->nb) {                           \
+                if ((ret = add_format(&out_link->incfg.list, fmt)) < 0)\
                     return ret;                                        \
                 ret = 1;                                               \
                 break;                                                 \
             }                                                          \
                                                                        \
-            for (k = 0; k < out_link->in_ ## list->nb; k++)            \
+            for (k = 0; k < out_link->incfg.list->nb; k++)             \
                 if (fmts->var[k] == fmt) {                             \
                     fmts->var[0]  = fmt;                               \
                     fmts->nb = 1;                                      \
@@ -799,16 +799,16 @@  static int reduce_formats_on_filter(AVFilterContext *filter)
         AVFilterLink *inlink = filter->inputs[i];
         uint64_t fmt;
 
-        if (!inlink->out_channel_layouts ||
-            inlink->out_channel_layouts->nb_channel_layouts != 1)
+        if (!inlink->outcfg.channel_layouts ||
+            inlink->outcfg.channel_layouts->nb_channel_layouts != 1)
             continue;
-        fmt = inlink->out_channel_layouts->channel_layouts[0];
+        fmt = inlink->outcfg.channel_layouts->channel_layouts[0];
 
         for (j = 0; j < filter->nb_outputs; j++) {
             AVFilterLink *outlink = filter->outputs[j];
             AVFilterChannelLayouts *fmts;
 
-            fmts = outlink->in_channel_layouts;
+            fmts = outlink->incfg.channel_layouts;
             if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
                 continue;
 
@@ -816,12 +816,12 @@  static int reduce_formats_on_filter(AVFilterContext *filter)
                 (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) {
                 /* Turn the infinite list into a singleton */
                 fmts->all_layouts = fmts->all_counts  = 0;
-                if (ff_add_channel_layout(&outlink->in_channel_layouts, fmt) < 0)
+                if (ff_add_channel_layout(&outlink->incfg.channel_layouts, fmt) < 0)
                     ret = 1;
                 break;
             }
 
-            for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) {
+            for (k = 0; k < outlink->incfg.channel_layouts->nb_channel_layouts; k++) {
                 if (fmts->channel_layouts[k] == fmt) {
                     fmts->channel_layouts[0]  = fmt;
                     fmts->nb_channel_layouts = 1;
@@ -862,24 +862,24 @@  static void swap_samplerates_on_filter(AVFilterContext *filter)
         link = filter->inputs[i];
 
         if (link->type == AVMEDIA_TYPE_AUDIO &&
-            link->out_samplerates->nb_formats== 1)
+            link->outcfg.samplerates->nb_formats== 1)
             break;
     }
     if (i == filter->nb_inputs)
         return;
 
-    sample_rate = link->out_samplerates->formats[0];
+    sample_rate = link->outcfg.samplerates->formats[0];
 
     for (i = 0; i < filter->nb_outputs; i++) {
         AVFilterLink *outlink = filter->outputs[i];
         int best_idx, best_diff = INT_MAX;
 
         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
-            outlink->in_samplerates->nb_formats < 2)
+            outlink->incfg.samplerates->nb_formats < 2)
             continue;
 
-        for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
-            int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
+        for (j = 0; j < outlink->incfg.samplerates->nb_formats; j++) {
+            int diff = abs(sample_rate - outlink->incfg.samplerates->formats[j]);
 
             av_assert0(diff < INT_MAX); // This would lead to the use of uninitialized best_diff but is only possible with invalid sample rates
 
@@ -888,8 +888,8 @@  static void swap_samplerates_on_filter(AVFilterContext *filter)
                 best_idx  = j;
             }
         }
-        FFSWAP(int, outlink->in_samplerates->formats[0],
-               outlink->in_samplerates->formats[best_idx]);
+        FFSWAP(int, outlink->incfg.samplerates->formats[0],
+               outlink->incfg.samplerates->formats[best_idx]);
     }
 }
 
@@ -944,7 +944,7 @@  static void swap_channel_layouts_on_filter(AVFilterContext *filter)
         link = filter->inputs[i];
 
         if (link->type == AVMEDIA_TYPE_AUDIO &&
-            link->out_channel_layouts->nb_channel_layouts == 1)
+            link->outcfg.channel_layouts->nb_channel_layouts == 1)
             break;
     }
     if (i == filter->nb_inputs)
@@ -955,12 +955,12 @@  static void swap_channel_layouts_on_filter(AVFilterContext *filter)
         int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
 
         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
-            outlink->in_channel_layouts->nb_channel_layouts < 2)
+            outlink->incfg.channel_layouts->nb_channel_layouts < 2)
             continue;
 
-        for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
-            uint64_t  in_chlayout = link->out_channel_layouts->channel_layouts[0];
-            uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
+        for (j = 0; j < outlink->incfg.channel_layouts->nb_channel_layouts; j++) {
+            uint64_t  in_chlayout = link->outcfg.channel_layouts->channel_layouts[0];
+            uint64_t out_chlayout = outlink->incfg.channel_layouts->channel_layouts[j];
             int  in_channels      = av_get_channel_layout_nb_channels(in_chlayout);
             int out_channels      = av_get_channel_layout_nb_channels(out_chlayout);
             int count_diff        = out_channels - in_channels;
@@ -1018,8 +1018,8 @@  static void swap_channel_layouts_on_filter(AVFilterContext *filter)
             }
         }
         av_assert0(best_idx >= 0);
-        FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
-               outlink->in_channel_layouts->channel_layouts[best_idx]);
+        FFSWAP(uint64_t, outlink->incfg.channel_layouts->channel_layouts[0],
+               outlink->incfg.channel_layouts->channel_layouts[best_idx]);
     }
 
 }
@@ -1042,13 +1042,13 @@  static void swap_sample_fmts_on_filter(AVFilterContext *filter)
         link = filter->inputs[i];
 
         if (link->type == AVMEDIA_TYPE_AUDIO &&
-            link->out_formats->nb_formats == 1)
+            link->outcfg.formats->nb_formats == 1)
             break;
     }
     if (i == filter->nb_inputs)
         return;
 
-    format = link->out_formats->formats[0];
+    format = link->outcfg.formats->formats[0];
     bps    = av_get_bytes_per_sample(format);
 
     for (i = 0; i < filter->nb_outputs; i++) {
@@ -1056,11 +1056,11 @@  static void swap_sample_fmts_on_filter(AVFilterContext *filter)
         int best_idx = -1, best_score = INT_MIN;
 
         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
-            outlink->in_formats->nb_formats < 2)
+            outlink->incfg.formats->nb_formats < 2)
             continue;
 
-        for (j = 0; j < outlink->in_formats->nb_formats; j++) {
-            int out_format = outlink->in_formats->formats[j];
+        for (j = 0; j < outlink->incfg.formats->nb_formats; j++) {
+            int out_format = outlink->incfg.formats->formats[j];
             int out_bps    = av_get_bytes_per_sample(out_format);
             int score;
 
@@ -1087,8 +1087,8 @@  static void swap_sample_fmts_on_filter(AVFilterContext *filter)
             }
         }
         av_assert0(best_idx >= 0);
-        FFSWAP(int, outlink->in_formats->formats[0],
-               outlink->in_formats->formats[best_idx]);
+        FFSWAP(int, outlink->incfg.formats->formats[0],
+               outlink->incfg.formats->formats[best_idx]);
     }
 }
 
@@ -1112,7 +1112,7 @@  static int pick_formats(AVFilterGraph *graph)
             AVFilterContext *filter = graph->filters[i];
             if (filter->nb_inputs){
                 for (j = 0; j < filter->nb_inputs; j++){
-                    if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->nb_formats == 1) {
+                    if(filter->inputs[j]->incfg.formats && filter->inputs[j]->incfg.formats->nb_formats == 1) {
                         if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
                             return ret;
                         change = 1;
@@ -1121,7 +1121,7 @@  static int pick_formats(AVFilterGraph *graph)
             }
             if (filter->nb_outputs){
                 for (j = 0; j < filter->nb_outputs; j++){
-                    if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->nb_formats == 1) {
+                    if(filter->outputs[j]->incfg.formats && filter->outputs[j]->incfg.formats->nb_formats == 1) {
                         if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
                             return ret;
                         change = 1;
diff --git a/libavfilter/f_drawgraph.c b/libavfilter/f_drawgraph.c
index 030afb9b4e..b9dd26d392 100644
--- a/libavfilter/f_drawgraph.c
+++ b/libavfilter/f_drawgraph.c
@@ -134,7 +134,7 @@  static int query_formats(AVFilterContext *ctx)
     int ret;
 
     AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(fmts_list, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(fmts_list, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c
index 31b75ab097..f6b1f1b6d8 100644
--- a/libavfilter/f_ebur128.c
+++ b/libavfilter/f_ebur128.c
@@ -910,7 +910,7 @@  static int query_formats(AVFilterContext *ctx)
     /* set optional output video format */
     if (ebur128->do_video) {
         formats = ff_make_format_list(pix_fmts);
-        if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+        if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
             return ret;
         outlink = ctx->outputs[1];
     }
@@ -919,18 +919,18 @@  static int query_formats(AVFilterContext *ctx)
      * Note: ff_set_common_* functions are not used because they affect all the
      * links, and thus break the video format negotiation */
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref(formats, &inlink->out_formats)) < 0 ||
-        (ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
         return ret;
 
     layouts = ff_all_channel_layouts();
-    if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0 ||
-        (ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts)) < 0)
+    if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0 ||
+        (ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts)) < 0)
         return ret;
 
     formats = ff_make_format_list(input_srate);
-    if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0 ||
-        (ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0 ||
+        (ret = ff_formats_ref(formats, &outlink->incfg.samplerates)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/f_graphmonitor.c b/libavfilter/f_graphmonitor.c
index a9c4ba42f5..7e3ad1fb8b 100644
--- a/libavfilter/f_graphmonitor.c
+++ b/libavfilter/f_graphmonitor.c
@@ -100,7 +100,7 @@  static int query_formats(AVFilterContext *ctx)
     int ret;
 
     AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
-    if ((ret = ff_formats_ref(fmts_list, &outlink->in_formats)) < 0)
+    if ((ret = ff_formats_ref(fmts_list, &outlink->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index 3c7f099a94..32f41f2c13 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -593,14 +593,14 @@  void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
 int ff_set_common_channel_layouts(AVFilterContext *ctx,
                                   AVFilterChannelLayouts *layouts)
 {
-    SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
+    SET_COMMON_FORMATS(ctx, layouts, incfg.channel_layouts, outcfg.channel_layouts,
                        ff_channel_layouts_ref, ff_channel_layouts_unref, channel_layouts);
 }
 
 int ff_set_common_samplerates(AVFilterContext *ctx,
                               AVFilterFormats *samplerates)
 {
-    SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
+    SET_COMMON_FORMATS(ctx, samplerates, incfg.samplerates, outcfg.samplerates,
                        ff_formats_ref, ff_formats_unref, formats);
 }
 
@@ -611,7 +611,7 @@  int ff_set_common_samplerates(AVFilterContext *ctx,
  */
 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
 {
-    SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
+    SET_COMMON_FORMATS(ctx, formats, incfg.formats, outcfg.formats,
                        ff_formats_ref, ff_formats_unref, formats);
 }
 
diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c
index 64d82e9df1..42ec8572c4 100644
--- a/libavfilter/src_movie.c
+++ b/libavfilter/src_movie.c
@@ -365,19 +365,19 @@  static int movie_query_formats(AVFilterContext *ctx)
         switch (c->codec_type) {
         case AVMEDIA_TYPE_VIDEO:
             list[0] = c->format;
-            if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->in_formats)) < 0)
+            if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->incfg.formats)) < 0)
                 return ret;
             break;
         case AVMEDIA_TYPE_AUDIO:
             list[0] = c->format;
-            if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->in_formats)) < 0)
+            if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->incfg.formats)) < 0)
                 return ret;
             list[0] = c->sample_rate;
-            if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->in_samplerates)) < 0)
+            if ((ret = ff_formats_ref(ff_make_format_list(list), &outlink->incfg.samplerates)) < 0)
                 return ret;
             list64[0] = c->channel_layout;
             if ((ret = ff_channel_layouts_ref(ff_make_format64_list(list64),
-                                   &outlink->in_channel_layouts)) < 0)
+                                   &outlink->incfg.channel_layouts)) < 0)
                 return ret;
             break;
         }
diff --git a/libavfilter/tests/filtfmts.c b/libavfilter/tests/filtfmts.c
index 317df86c55..356f467331 100644
--- a/libavfilter/tests/filtfmts.c
+++ b/libavfilter/tests/filtfmts.c
@@ -40,7 +40,7 @@  static void print_formats(AVFilterContext *filter_ctx)
     for (i = 0; i < filter_ctx->nb_##inout##puts; i++) {                     \
         if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_VIDEO) {   \
             AVFilterFormats *fmts =                                     \
-                filter_ctx->inout##puts[i]->outin##_formats;            \
+                filter_ctx->inout##puts[i]->outin##cfg.formats;            \
             for (j = 0; j < fmts->nb_formats; j++)                    \
                 if(av_get_pix_fmt_name(fmts->formats[j]))               \
                 printf(#INOUT "PUT[%d] %s: fmt:%s\n",                   \
@@ -50,13 +50,13 @@  static void print_formats(AVFilterContext *filter_ctx)
             AVFilterFormats *fmts;                                      \
             AVFilterChannelLayouts *layouts;                            \
                                                                         \
-            fmts = filter_ctx->inout##puts[i]->outin##_formats;         \
+            fmts = filter_ctx->inout##puts[i]->outin##cfg.formats;         \
             for (j = 0; j < fmts->nb_formats; j++)                    \
                 printf(#INOUT "PUT[%d] %s: fmt:%s\n",                   \
                        i, avfilter_pad_get_name(filter_ctx->inout##put_pads, i),      \
                        av_get_sample_fmt_name(fmts->formats[j]));       \
                                                                         \
-            layouts = filter_ctx->inout##puts[i]->outin##_channel_layouts; \
+            layouts = filter_ctx->inout##puts[i]->outin##cfg.channel_layouts; \
             for (j = 0; j < layouts->nb_channel_layouts; j++) {                  \
                 char buf[256];                                          \
                 av_get_channel_layout_string(buf, sizeof(buf), -1,      \
diff --git a/libavfilter/vaapi_vpp.c b/libavfilter/vaapi_vpp.c
index b5b245c8af..1610df4c85 100644
--- a/libavfilter/vaapi_vpp.c
+++ b/libavfilter/vaapi_vpp.c
@@ -32,10 +32,10 @@  int ff_vaapi_vpp_query_formats(AVFilterContext *avctx)
     int err;
 
     if ((err = ff_formats_ref(ff_make_format_list(pix_fmts),
-                              &avctx->inputs[0]->out_formats)) < 0)
+                              &avctx->inputs[0]->outcfg.formats)) < 0)
         return err;
     if ((err = ff_formats_ref(ff_make_format_list(pix_fmts),
-                              &avctx->outputs[0]->in_formats)) < 0)
+                              &avctx->outputs[0]->incfg.formats)) < 0)
         return err;
 
     return 0;
diff --git a/libavfilter/vaf_spectrumsynth.c b/libavfilter/vaf_spectrumsynth.c
index fed2cbba03..67be71a7db 100644
--- a/libavfilter/vaf_spectrumsynth.c
+++ b/libavfilter/vaf_spectrumsynth.c
@@ -114,28 +114,28 @@  static int query_formats(AVFilterContext *ctx)
     int ret, sample_rates[] = { 48000, -1 };
 
     formats = ff_make_format_list(sample_fmts);
-    if ((ret = ff_formats_ref         (formats, &outlink->in_formats        )) < 0 ||
+    if ((ret = ff_formats_ref         (formats, &outlink->incfg.formats        )) < 0 ||
         (ret = ff_add_channel_layout  (&layout, FF_COUNT2LAYOUT(s->channels))) < 0 ||
-        (ret = ff_channel_layouts_ref (layout , &outlink->in_channel_layouts)) < 0)
+        (ret = ff_channel_layouts_ref (layout , &outlink->incfg.channel_layouts)) < 0)
         return ret;
 
     sample_rates[0] = s->sample_rate;
     formats = ff_make_format_list(sample_rates);
     if (!formats)
         return AVERROR(ENOMEM);
-    if ((ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0)
+    if ((ret = ff_formats_ref(formats, &outlink->incfg.samplerates)) < 0)
         return ret;
 
     formats = ff_make_format_list(pix_fmts);
     if (!formats)
         return AVERROR(ENOMEM);
-    if ((ret = ff_formats_ref(formats, &magnitude->out_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &magnitude->outcfg.formats)) < 0)
         return ret;
 
     formats = ff_make_format_list(pix_fmts);
     if (!formats)
         return AVERROR(ENOMEM);
-    if ((ret = ff_formats_ref(formats, &phase->out_formats)) < 0)
+    if ((ret = ff_formats_ref(formats, &phase->outcfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c
index 85b6d9b61a..fadfc76a5d 100644
--- a/libavfilter/vf_alphamerge.c
+++ b/libavfilter/vf_alphamerge.c
@@ -63,9 +63,9 @@  static int query_formats(AVFilterContext *ctx)
             ret = AVERROR(ENOMEM);
             goto fail;
         }
-    if ((ret = ff_formats_ref(main_formats , &ctx->inputs[0]->out_formats)) < 0 ||
-        (ret = ff_formats_ref(alpha_formats, &ctx->inputs[1]->out_formats)) < 0 ||
-        (ret = ff_formats_ref(main_formats , &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(main_formats , &ctx->inputs[0]->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(alpha_formats, &ctx->inputs[1]->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(main_formats , &ctx->outputs[0]->incfg.formats)) < 0)
             goto fail;
     return 0;
 fail:
diff --git a/libavfilter/vf_ciescope.c b/libavfilter/vf_ciescope.c
index d5a2c8c0ad..719e66ad0f 100644
--- a/libavfilter/vf_ciescope.c
+++ b/libavfilter/vf_ciescope.c
@@ -139,10 +139,10 @@  static int query_formats(AVFilterContext *ctx)
 {
     int ret;
 
-    if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0)
+    if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0)
         return ret;
 
-    if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/vf_colorspace.c b/libavfilter/vf_colorspace.c
index 7098dd5bea..34f13d9d3c 100644
--- a/libavfilter/vf_colorspace.c
+++ b/libavfilter/vf_colorspace.c
@@ -896,7 +896,7 @@  static int query_formats(AVFilterContext *ctx)
         return AVERROR(ENOMEM);
     if (s->user_format == AV_PIX_FMT_NONE)
         return ff_set_common_formats(ctx, formats);
-    res = ff_formats_ref(formats, &ctx->inputs[0]->out_formats);
+    res = ff_formats_ref(formats, &ctx->inputs[0]->outcfg.formats);
     if (res < 0)
         return res;
     formats = NULL;
@@ -904,7 +904,7 @@  static int query_formats(AVFilterContext *ctx)
     if (res < 0)
         return res;
 
-    return ff_formats_ref(formats, &ctx->outputs[0]->in_formats);
+    return ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats);
 }
 
 static int config_props(AVFilterLink *outlink)
diff --git a/libavfilter/vf_coreimage.m b/libavfilter/vf_coreimage.m
index 4ed5ba7920..cbd67791bc 100644
--- a/libavfilter/vf_coreimage.m
+++ b/libavfilter/vf_coreimage.m
@@ -149,8 +149,8 @@  static int query_formats(AVFilterContext *fctx)
         return AVERROR(ENOMEM);
     }
 
-    if ((ret = ff_formats_ref(inout_formats, &fctx->inputs[0]->out_formats)) < 0 ||
-        (ret = ff_formats_ref(inout_formats, &fctx->outputs[0]->in_formats)) < 0) {
+    if ((ret = ff_formats_ref(inout_formats, &fctx->inputs[0]->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(inout_formats, &fctx->outputs[0]->incfg.formats)) < 0) {
         return ret;
     }
 
@@ -171,7 +171,7 @@  static int query_formats_src(AVFilterContext *fctx)
         return AVERROR(ENOMEM);
     }
 
-    if ((ret = ff_formats_ref(inout_formats, &fctx->outputs[0]->in_formats)) < 0) {
+    if ((ret = ff_formats_ref(inout_formats, &fctx->outputs[0]->incfg.formats)) < 0) {
         return ret;
     }
 
diff --git a/libavfilter/vf_elbg.c b/libavfilter/vf_elbg.c
index 5bccb5f58d..835b1dfe33 100644
--- a/libavfilter/vf_elbg.c
+++ b/libavfilter/vf_elbg.c
@@ -100,8 +100,8 @@  static int query_formats(AVFilterContext *ctx)
             AV_PIX_FMT_PAL8,
             AV_PIX_FMT_NONE
         };
-        if ((ret = ff_formats_ref(ff_make_format_list(pix_fmts), &ctx->inputs[0]->out_formats)) < 0 ||
-            (ret = ff_formats_ref(ff_make_format_list(pal8_fmt), &ctx->outputs[0]->in_formats)) < 0)
+        if ((ret = ff_formats_ref(ff_make_format_list(pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0 ||
+            (ret = ff_formats_ref(ff_make_format_list(pal8_fmt), &ctx->outputs[0]->incfg.formats)) < 0)
             return ret;
     }
     return 0;
diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c
index 739c2420cb..b10cd13f8f 100644
--- a/libavfilter/vf_extractplanes.c
+++ b/libavfilter/vf_extractplanes.c
@@ -143,12 +143,12 @@  static int query_formats(AVFilterContext *ctx)
     AVFilterFormats *avff;
     int i, ret, depth = 0, be = 0;
 
-    if (!ctx->inputs[0]->in_formats ||
-        !ctx->inputs[0]->in_formats->nb_formats) {
+    if (!ctx->inputs[0]->incfg.formats ||
+        !ctx->inputs[0]->incfg.formats->nb_formats) {
         return AVERROR(EAGAIN);
     }
 
-    avff = ctx->inputs[0]->in_formats;
+    avff = ctx->inputs[0]->incfg.formats;
     desc = av_pix_fmt_desc_get(avff->formats[0]);
     depth = desc->comp[0].depth;
     be = desc->flags & AV_PIX_FMT_FLAG_BE;
@@ -157,8 +157,8 @@  static int query_formats(AVFilterContext *ctx)
     } else {
         in_pixfmts = in_pixfmts_le;
     }
-    if (!ctx->inputs[0]->out_formats)
-        if ((ret = ff_formats_ref(ff_make_format_list(in_pixfmts), &ctx->inputs[0]->out_formats)) < 0)
+    if (!ctx->inputs[0]->outcfg.formats)
+        if ((ret = ff_formats_ref(ff_make_format_list(in_pixfmts), &ctx->inputs[0]->outcfg.formats)) < 0)
             return ret;
 
     for (i = 1; i < avff->nb_formats; i++) {
@@ -193,7 +193,7 @@  static int query_formats(AVFilterContext *ctx)
         out_pixfmts = out16le_pixfmts;
 
     for (i = 0; i < ctx->nb_outputs; i++)
-        if ((ret = ff_formats_ref(ff_make_format_list(out_pixfmts), &ctx->outputs[i]->in_formats)) < 0)
+        if ((ret = ff_formats_ref(ff_make_format_list(out_pixfmts), &ctx->outputs[i]->incfg.formats)) < 0)
             return ret;
     return 0;
 }
diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c
index fa4aa8239c..f613404ec3 100644
--- a/libavfilter/vf_fieldmatch.c
+++ b/libavfilter/vf_fieldmatch.c
@@ -917,14 +917,14 @@  static int query_formats(AVFilterContext *ctx)
         return ff_set_common_formats(ctx, fmts_list);
     }
 
-    if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_MAIN]->out_formats)) < 0)
+    if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_MAIN]->outcfg.formats)) < 0)
         return ret;
     fmts_list = ff_make_format_list(unproc_pix_fmts);
     if (!fmts_list)
         return AVERROR(ENOMEM);
-    if ((ret = ff_formats_ref(fmts_list, &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(fmts_list, &ctx->outputs[0]->incfg.formats)) < 0)
         return ret;
-    if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_CLEANSRC]->out_formats)) < 0)
+    if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_CLEANSRC]->outcfg.formats)) < 0)
         return ret;
     return 0;
 }
diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
index 5707151f1b..5d97dc58df 100644
--- a/libavfilter/vf_fieldorder.c
+++ b/libavfilter/vf_fieldorder.c
@@ -58,8 +58,8 @@  static int query_formats(AVFilterContext *ctx)
                 (ret = ff_add_format(&formats, pix_fmt)) < 0)
                 return ret;
         }
-        if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->out_formats)) < 0 ||
-            (ret = ff_formats_ref(formats, &ctx->outputs[0]->in_formats)) < 0)
+        if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->outcfg.formats)) < 0 ||
+            (ret = ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats)) < 0)
             return ret;
     }
 
diff --git a/libavfilter/vf_histogram.c b/libavfilter/vf_histogram.c
index db1962edc1..4800c06f26 100644
--- a/libavfilter/vf_histogram.c
+++ b/libavfilter/vf_histogram.c
@@ -155,15 +155,15 @@  static int query_formats(AVFilterContext *ctx)
     int rgb, i, bits;
     int ret;
 
-    if (!ctx->inputs[0]->in_formats ||
-        !ctx->inputs[0]->in_formats->nb_formats) {
+    if (!ctx->inputs[0]->incfg.formats ||
+        !ctx->inputs[0]->incfg.formats->nb_formats) {
         return AVERROR(EAGAIN);
     }
 
-    if (!ctx->inputs[0]->out_formats)
-        if ((ret = ff_formats_ref(ff_make_format_list(levels_in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0)
+    if (!ctx->inputs[0]->outcfg.formats)
+        if ((ret = ff_formats_ref(ff_make_format_list(levels_in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0)
             return ret;
-    avff = ctx->inputs[0]->in_formats;
+    avff = ctx->inputs[0]->incfg.formats;
     desc = av_pix_fmt_desc_get(avff->formats[0]);
     rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
     bits = desc->comp[0].depth;
@@ -192,7 +192,7 @@  static int query_formats(AVFilterContext *ctx)
         out_pix_fmts = levels_out_yuv12_pix_fmts;
     else
         return AVERROR(EAGAIN);
-    if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/vf_hwdownload.c b/libavfilter/vf_hwdownload.c
index 33af30cf40..979b0aed54 100644
--- a/libavfilter/vf_hwdownload.c
+++ b/libavfilter/vf_hwdownload.c
@@ -55,8 +55,8 @@  static int hwdownload_query_formats(AVFilterContext *avctx)
         }
     }
 
-    if ((err = ff_formats_ref(infmts,  &avctx->inputs[0]->out_formats)) < 0 ||
-        (err = ff_formats_ref(outfmts, &avctx->outputs[0]->in_formats)) < 0)
+    if ((err = ff_formats_ref(infmts,  &avctx->inputs[0]->outcfg.formats)) < 0 ||
+        (err = ff_formats_ref(outfmts, &avctx->outputs[0]->incfg.formats)) < 0)
         return err;
 
     return 0;
diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c
index 290559a06a..a89f69cbec 100644
--- a/libavfilter/vf_hwmap.c
+++ b/libavfilter/vf_hwmap.c
@@ -42,9 +42,9 @@  static int hwmap_query_formats(AVFilterContext *avctx)
     int ret;
 
     if ((ret = ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_VIDEO),
-                              &avctx->inputs[0]->out_formats)) < 0 ||
+                              &avctx->inputs[0]->outcfg.formats)) < 0 ||
         (ret = ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_VIDEO),
-                              &avctx->outputs[0]->in_formats)) < 0)
+                              &avctx->outputs[0]->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/vf_hwupload.c b/libavfilter/vf_hwupload.c
index 7c5dd497b0..7f2aa90af3 100644
--- a/libavfilter/vf_hwupload.c
+++ b/libavfilter/vf_hwupload.c
@@ -90,9 +90,9 @@  static int hwupload_query_formats(AVFilterContext *avctx)
         }
     }
 
-    if ((err = ff_formats_ref(input_formats, &avctx->inputs[0]->out_formats)) < 0 ||
+    if ((err = ff_formats_ref(input_formats, &avctx->inputs[0]->outcfg.formats)) < 0 ||
         (err = ff_formats_ref(ff_make_format_list(output_pix_fmts),
-                              &avctx->outputs[0]->in_formats)) < 0)
+                              &avctx->outputs[0]->incfg.formats)) < 0)
         goto fail;
 
     av_hwframe_constraints_free(&constraints);
diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c
index 8ee0825859..33906f2515 100644
--- a/libavfilter/vf_hwupload_cuda.c
+++ b/libavfilter/vf_hwupload_cuda.c
@@ -71,13 +71,13 @@  static int cudaupload_query_formats(AVFilterContext *ctx)
     AVFilterFormats *in_fmts  = ff_make_format_list(input_pix_fmts);
     AVFilterFormats *out_fmts;
 
-    ret = ff_formats_ref(in_fmts, &ctx->inputs[0]->out_formats);
+    ret = ff_formats_ref(in_fmts, &ctx->inputs[0]->outcfg.formats);
     if (ret < 0)
         return ret;
 
     out_fmts = ff_make_format_list(output_pix_fmts);
 
-    ret = ff_formats_ref(out_fmts, &ctx->outputs[0]->in_formats);
+    ret = ff_formats_ref(out_fmts, &ctx->outputs[0]->incfg.formats);
     if (ret < 0)
         return ret;
 
diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c
index 7a204f5f1d..1f8bc5d75c 100644
--- a/libavfilter/vf_lut2.c
+++ b/libavfilter/vf_lut2.c
@@ -177,7 +177,7 @@  static int query_formats(AVFilterContext *ctx)
     if (s->tlut2 || !s->odepth)
         return ff_set_common_formats(ctx, ff_make_format_list(all_pix_fmts));
 
-    ret = ff_formats_ref(ff_make_format_list(all_pix_fmts), &ctx->inputs[0]->out_formats);
+    ret = ff_formats_ref(ff_make_format_list(all_pix_fmts), &ctx->inputs[0]->outcfg.formats);
     if (ret < 0)
         return ret;
 
@@ -192,7 +192,7 @@  static int query_formats(AVFilterContext *ctx)
              return AVERROR(EINVAL);
     }
 
-    return ff_formats_ref(ff_make_format_list(pix_fmts), &ctx->outputs[0]->in_formats);
+    return ff_formats_ref(ff_make_format_list(pix_fmts), &ctx->outputs[0]->incfg.formats);
 }
 
 static int config_inputx(AVFilterLink *inlink)
diff --git a/libavfilter/vf_mergeplanes.c b/libavfilter/vf_mergeplanes.c
index 4b4f91be5d..22eb36a2e1 100644
--- a/libavfilter/vf_mergeplanes.c
+++ b/libavfilter/vf_mergeplanes.c
@@ -122,12 +122,12 @@  static int query_formats(AVFilterContext *ctx)
     }
 
     for (i = 0; i < s->nb_inputs; i++)
-        if ((ret = ff_formats_ref(formats, &ctx->inputs[i]->out_formats)) < 0)
+        if ((ret = ff_formats_ref(formats, &ctx->inputs[i]->outcfg.formats)) < 0)
             return ret;
 
     formats = NULL;
     if ((ret = ff_add_format(&formats, s->out_fmt)) < 0 ||
-        (ret = ff_formats_ref(formats, &ctx->outputs[0]->in_formats)) < 0)
+        (ret = ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index b3a1ac1a09..c2f656473c 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -290,9 +290,9 @@  static int query_formats(AVFilterContext *ctx)
         if (ret < 0)
             goto fail;
     } else {
-        if ((ret = ff_formats_ref(main_formats   , &ctx->inputs[MAIN]->out_formats   )) < 0 ||
-            (ret = ff_formats_ref(overlay_formats, &ctx->inputs[OVERLAY]->out_formats)) < 0 ||
-            (ret = ff_formats_ref(main_formats   , &ctx->outputs[MAIN]->in_formats   )) < 0)
+        if ((ret = ff_formats_ref(main_formats   , &ctx->inputs[MAIN]->outcfg.formats   )) < 0 ||
+            (ret = ff_formats_ref(overlay_formats, &ctx->inputs[OVERLAY]->outcfg.formats)) < 0 ||
+            (ret = ff_formats_ref(main_formats   , &ctx->outputs[MAIN]->incfg.formats   )) < 0)
                 goto fail;
     }
 
diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c
index 2a4dc5cb58..3fc887c716 100644
--- a/libavfilter/vf_overlay_qsv.c
+++ b/libavfilter/vf_overlay_qsv.c
@@ -381,12 +381,12 @@  static int overlay_qsv_query_formats(AVFilterContext *ctx)
     };
 
     for (i = 0; i < ctx->nb_inputs; i++) {
-        ret = ff_formats_ref(ff_make_format_list(main_in_fmts), &ctx->inputs[i]->out_formats);
+        ret = ff_formats_ref(ff_make_format_list(main_in_fmts), &ctx->inputs[i]->outcfg.formats);
         if (ret < 0)
             return ret;
     }
 
-    ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats);
+    ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats);
     if (ret < 0)
         return ret;
 
diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c
index 9b0a0e1b80..c49a6f1168 100644
--- a/libavfilter/vf_palettegen.c
+++ b/libavfilter/vf_palettegen.c
@@ -99,9 +99,9 @@  static int query_formats(AVFilterContext *ctx)
     static const enum AVPixelFormat out_fmts[] = {AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE};
     int ret;
 
-    if ((ret = ff_formats_ref(ff_make_format_list(in_fmts) , &ctx->inputs[0]->out_formats)) < 0)
+    if ((ret = ff_formats_ref(ff_make_format_list(in_fmts) , &ctx->inputs[0]->outcfg.formats)) < 0)
         return ret;
-    if ((ret = ff_formats_ref(ff_make_format_list(out_fmts), &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(ff_make_format_list(out_fmts), &ctx->outputs[0]->incfg.formats)) < 0)
         return ret;
     return 0;
 }
diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c
index b32ff817d0..ce2a880a33 100644
--- a/libavfilter/vf_paletteuse.c
+++ b/libavfilter/vf_paletteuse.c
@@ -151,9 +151,9 @@  static int query_formats(AVFilterContext *ctx)
         av_freep(&out);
         return AVERROR(ENOMEM);
     }
-    if ((ret = ff_formats_ref(in   , &ctx->inputs[0]->out_formats)) < 0 ||
-        (ret = ff_formats_ref(inpal, &ctx->inputs[1]->out_formats)) < 0 ||
-        (ret = ff_formats_ref(out  , &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(in   , &ctx->inputs[0]->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(inpal, &ctx->inputs[1]->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(out  , &ctx->outputs[0]->incfg.formats)) < 0)
         return ret;
     return 0;
 }
diff --git a/libavfilter/vf_remap.c b/libavfilter/vf_remap.c
index 6d5d75225b..9075297b1e 100644
--- a/libavfilter/vf_remap.c
+++ b/libavfilter/vf_remap.c
@@ -120,10 +120,10 @@  static int query_formats(AVFilterContext *ctx)
         ret = AVERROR(ENOMEM);
         goto fail;
     }
-    if ((ret = ff_formats_ref(pix_formats, &ctx->inputs[0]->out_formats)) < 0 ||
-        (ret = ff_formats_ref(map_formats, &ctx->inputs[1]->out_formats)) < 0 ||
-        (ret = ff_formats_ref(map_formats, &ctx->inputs[2]->out_formats)) < 0 ||
-        (ret = ff_formats_ref(pix_formats, &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(pix_formats, &ctx->inputs[0]->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(map_formats, &ctx->inputs[1]->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(map_formats, &ctx->inputs[2]->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(pix_formats, &ctx->outputs[0]->incfg.formats)) < 0)
         goto fail;
     return 0;
 fail:
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index ff69bb138f..58eee96744 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -358,7 +358,7 @@  static int query_formats(AVFilterContext *ctx)
                 return ret;
             }
         }
-        if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->out_formats)) < 0)
+        if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->outcfg.formats)) < 0)
             return ret;
     }
     if (ctx->outputs[0]) {
@@ -372,7 +372,7 @@  static int query_formats(AVFilterContext *ctx)
                 return ret;
             }
         }
-        if ((ret = ff_formats_ref(formats, &ctx->outputs[0]->in_formats)) < 0)
+        if ((ret = ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats)) < 0)
             return ret;
     }
 
diff --git a/libavfilter/vf_showpalette.c b/libavfilter/vf_showpalette.c
index f715d6bc2c..a592ab5497 100644
--- a/libavfilter/vf_showpalette.c
+++ b/libavfilter/vf_showpalette.c
@@ -54,8 +54,8 @@  static int query_formats(AVFilterContext *ctx)
         goto fail;
     }
 
-    if ((ret = ff_formats_ref(in , &ctx->inputs[0]->out_formats)) < 0 ||
-        (ret = ff_formats_ref(out, &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(in , &ctx->inputs[0]->outcfg.formats)) < 0 ||
+        (ret = ff_formats_ref(out, &ctx->outputs[0]->incfg.formats)) < 0)
         goto fail;
     return 0;
 fail:
diff --git a/libavfilter/vf_vectorscope.c b/libavfilter/vf_vectorscope.c
index 38af878042..e51f8191fd 100644
--- a/libavfilter/vf_vectorscope.c
+++ b/libavfilter/vf_vectorscope.c
@@ -216,23 +216,23 @@  static int query_formats(AVFilterContext *ctx)
     AVFilterFormats *avff;
     int depth, rgb, i, ret;
 
-    if (!ctx->inputs[0]->in_formats ||
-        !ctx->inputs[0]->in_formats->nb_formats) {
+    if (!ctx->inputs[0]->incfg.formats ||
+        !ctx->inputs[0]->incfg.formats->nb_formats) {
         return AVERROR(EAGAIN);
     }
 
-    if (!ctx->inputs[0]->out_formats) {
+    if (!ctx->inputs[0]->outcfg.formats) {
         const enum AVPixelFormat *in_pix_fmts;
 
         if ((s->x == 1 && s->y == 2) || (s->x == 2 && s->y == 1))
             in_pix_fmts = in2_pix_fmts;
         else
             in_pix_fmts = in1_pix_fmts;
-        if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0)
+        if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0)
             return ret;
     }
 
-    avff = ctx->inputs[0]->in_formats;
+    avff = ctx->inputs[0]->incfg.formats;
     desc = av_pix_fmt_desc_get(avff->formats[0]);
     rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
     depth = desc->comp[0].depth;
@@ -261,7 +261,7 @@  static int query_formats(AVFilterContext *ctx)
         out_pix_fmts = out_yuv12_pix_fmts;
     else
         return AVERROR(EAGAIN);
-    if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
index 3194295f5f..6d4b245175 100644
--- a/libavfilter/vf_vpp_qsv.c
+++ b/libavfilter/vf_vpp_qsv.c
@@ -507,10 +507,10 @@  static int query_formats(AVFilterContext *ctx)
 
     in_fmts  = ff_make_format_list(in_pix_fmts);
     out_fmts = ff_make_format_list(out_pix_fmts);
-    ret = ff_formats_ref(in_fmts, &ctx->inputs[0]->out_formats);
+    ret = ff_formats_ref(in_fmts, &ctx->inputs[0]->outcfg.formats);
     if (ret < 0)
         return ret;
-    ret = ff_formats_ref(out_fmts, &ctx->outputs[0]->in_formats);
+    ret = ff_formats_ref(out_fmts, &ctx->outputs[0]->incfg.formats);
     if (ret < 0)
         return ret;
 
diff --git a/libavfilter/vf_waveform.c b/libavfilter/vf_waveform.c
index b2c5b46d80..11f8c0016e 100644
--- a/libavfilter/vf_waveform.c
+++ b/libavfilter/vf_waveform.c
@@ -319,8 +319,8 @@  static int query_formats(AVFilterContext *ctx)
     AVFilterFormats *avff, *avff2;
     int depth, depth2, rgb, i, ret, ncomp, ncomp2;
 
-    if (!ctx->inputs[0]->in_formats ||
-        !ctx->inputs[0]->in_formats->nb_formats) {
+    if (!ctx->inputs[0]->incfg.formats ||
+        !ctx->inputs[0]->incfg.formats->nb_formats) {
         return AVERROR(EAGAIN);
     }
 
@@ -336,13 +336,13 @@  static int query_formats(AVFilterContext *ctx)
     default: return AVERROR_BUG;
     }
 
-    if (!ctx->inputs[0]->out_formats) {
-        if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0)
+    if (!ctx->inputs[0]->outcfg.formats) {
+        if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0)
             return ret;
     }
 
-    avff = ctx->inputs[0]->in_formats;
-    avff2 = ctx->inputs[0]->out_formats;
+    avff = ctx->inputs[0]->incfg.formats;
+    avff2 = ctx->inputs[0]->outcfg.formats;
     desc = av_pix_fmt_desc_get(avff->formats[0]);
     desc2 = av_pix_fmt_desc_get(avff2->formats[0]);
     ncomp = desc->nb_components;
@@ -385,7 +385,7 @@  static int query_formats(AVFilterContext *ctx)
         out_pix_fmts = out_yuv12_lowpass_pix_fmts;
     else
         return AVERROR(EAGAIN);
-    if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0)
+    if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/vf_yadif_cuda.c b/libavfilter/vf_yadif_cuda.c
index c9eb1a229d..3841c5f0d4 100644
--- a/libavfilter/vf_yadif_cuda.c
+++ b/libavfilter/vf_yadif_cuda.c
@@ -216,10 +216,10 @@  static int deint_cuda_query_formats(AVFilterContext *ctx)
     int ret;
 
     if ((ret = ff_formats_ref(ff_make_format_list(pix_fmts),
-                              &ctx->inputs[0]->out_formats)) < 0)
+                              &ctx->inputs[0]->outcfg.formats)) < 0)
         return ret;
     if ((ret = ff_formats_ref(ff_make_format_list(pix_fmts),
-                              &ctx->outputs[0]->in_formats)) < 0)
+                              &ctx->outputs[0]->incfg.formats)) < 0)
         return ret;
 
     return 0;
diff --git a/libavfilter/vf_zscale.c b/libavfilter/vf_zscale.c
index 023a5d10e9..8059061827 100644
--- a/libavfilter/vf_zscale.c
+++ b/libavfilter/vf_zscale.c
@@ -187,10 +187,10 @@  static int query_formats(AVFilterContext *ctx)
     };
     int ret;
 
-    ret = ff_formats_ref(ff_make_format_list(pixel_fmts), &ctx->inputs[0]->out_formats);
+    ret = ff_formats_ref(ff_make_format_list(pixel_fmts), &ctx->inputs[0]->outcfg.formats);
     if (ret < 0)
         return ret;
-    return ff_formats_ref(ff_make_format_list(pixel_fmts), &ctx->outputs[0]->in_formats);
+    return ff_formats_ref(ff_make_format_list(pixel_fmts), &ctx->outputs[0]->incfg.formats);
 }
 
 static int config_props(AVFilterLink *outlink)