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

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Tue Aug 18 22:14:00 EEST 2020


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 at 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


More information about the ffmpeg-devel mailing list