[FFmpeg-devel] [PATCH 1/2] avfilter/avfilter: add avfilter_print_config_formats()

Paul B Mahol onemda at gmail.com
Thu Nov 3 11:58:10 EET 2022


On 10/11/22, softworkz <ffmpegagent at gmail.com> wrote:
> From: softworkz <softworkz at hotmail.com>
>
> Prints the following to AVBPrint:
>
> For pass-through filter links:
>
>     "All (passthrough)"
>
> For filters using query_formats:
>
>     "Dynamic"
>
> For filters using query_formats where a call to query_formats
> succeeds (example):
>
>     "Dynamic, Defaults: [yuv420p, yuvj420p, yuva420p, nv12, nv21]"
>
> For all other filters (example):
>
>     "[s16p, s32p, fltp, dblp]"
>
> Except in case when the number of formats equals the number of
> available formats:
>
>     "All"
>
> Signed-off-by: softworkz <softworkz at hotmail.com>
> ---
>  doc/APIchanges              |   3 ++
>  libavfilter/avfilter.c      | 102 +++++++++++++++++++++++++++++++++++-
>  libavfilter/avfilter.h      |  12 +++++
>  libavfilter/avfiltergraph.c |  14 +++--
>  libavfilter/internal.h      |   9 ++++
>  libavfilter/version.h       |   4 +-
>  6 files changed, 136 insertions(+), 8 deletions(-)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index cbb579612e..6e2a528b04 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -14,6 +14,9 @@ libavutil:     2021-04-27
>
>  API changes, most recent first:
>
> +2022-10-11 - xxxxxxxxxx - lavf 59.50.100 - avfilter.h
> +  Add add avfilter_print_config_formats().
> +
>  2022-10-05 - 37d5ddc317 - lavu 57.39.100 - cpu.h
>    Add AV_CPU_FLAG_RVB_BASIC.
>
> diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
> index cc5505e65b..8cc665e19c 100644
> --- a/libavfilter/avfilter.c
> +++ b/libavfilter/avfilter.c
> @@ -196,6 +196,104 @@ void avfilter_link_free(AVFilterLink **link)
>      av_freep(link);
>  }
>
> +static unsigned get_nb_pix_fmts()
> +{
> +    unsigned i = 0;
> +    while (av_pix_fmt_desc_get(i++)) {}
> +    return i - 1;
> +}
> +
> +static unsigned get_nb_sample_fmts()
> +{
> +    unsigned i = 0;
> +    while (av_get_sample_fmt_name(i++)) {}
> +    return i - 1;
> +}
> +
> +int avfilter_print_config_formats(AVBPrint *bp, const struct AVFilter
> *filter, int for_output, unsigned pad_index)
> +{
> +    AVFilterGraph *graph;
> +    AVFilterContext *filter_context;
> +    AVFilterFormatsConfig *config;
> +    enum AVMediaType media_type;
> +    int ret = 0;
> +
> +    if (filter->formats_state == FF_FILTER_FORMATS_PASSTHROUGH) {
> +        av_bprintf(bp, "All (passthrough)");
> +        return 0;
> +    }
> +
> +    graph = avfilter_graph_alloc();
> +    if (!graph) {
> +        av_log(NULL, AV_LOG_ERROR, "Failed to create filtergraph\n");
> +        ret = AVERROR(ENOMEM);
> +        goto cleanup;
> +    }
> +
> +    filter_context = avfilter_graph_alloc_filter(graph, filter, "filter");
> +    if (!filter_context) {
> +        av_log(NULL, AV_LOG_ERROR, "Failed to create filter\n");
> +        ret = AVERROR(ENOMEM);
> +        goto cleanup;
> +    }
> +
> +    avfilter_init_str(filter_context, NULL);
> +
> +    if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC)
> +        av_bprintf(bp, "Dynamic");
> +
> +    if (!for_output && pad_index >= filter_context->nb_inputs
> +        || for_output && pad_index >= filter_context->nb_outputs)
> +        goto cleanup;
> +
> +    avfilter_graph_config(graph, graph);
> +
> +    for (unsigned i = 0; i < filter_context->nb_inputs; i++)
> +        filter_context->inputs[i] = (AVFilterLink
> *)av_mallocz(sizeof(AVFilterLink));
> +
> +    for (unsigned i = 0; i < filter_context->nb_outputs; i++)
> +        filter_context->outputs[i] = (AVFilterLink
> *)av_mallocz(sizeof(AVFilterLink));
> +
> +    ff_filter_query_formats(filter_context);
> +
> +    config = for_output ? &filter_context->outputs[pad_index]->incfg :
> &filter_context->inputs[pad_index]->outcfg;
> +
> +    if (!config || !config->formats)
> +        goto cleanup;
> +
> +    media_type= for_output ? filter->outputs[pad_index].type :
> filter->inputs[pad_index].type;
> +
> +    if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC) {
> +        if (config->formats && config->formats->nb_formats)
> +            av_bprintf(bp, ", Default: ");
> +    }
> +
> +    if (config->formats == NULL)
> +        av_bprintf(bp, "unknown");
> +    else if (media_type == AVMEDIA_TYPE_VIDEO &&
> config->formats->nb_formats == get_nb_pix_fmts() ||
> +             media_type == AVMEDIA_TYPE_AUDIO &&
> config->formats->nb_formats == get_nb_sample_fmts())
> +        av_bprintf(bp, "All");
> +    else {
> +        for (unsigned i = 0; i < config->formats->nb_formats; i++) {
> +            if (i == 0)
> +                av_bprintf(bp, "[");
> +
> +            if (media_type == AVMEDIA_TYPE_VIDEO)
> +                av_bprintf(bp, "%s",
> av_get_pix_fmt_name(config->formats->formats[i]));
> +            else if (media_type == AVMEDIA_TYPE_AUDIO)
> +                av_bprintf(bp, "%s",
> av_get_sample_fmt_name(config->formats->formats[i]));
> +
> +            if (i < config->formats->nb_formats - 1)
> +                av_bprintf(bp, ", ");
> +            else
> +                av_bprintf(bp, "]");        }
> +    }
> +
> +cleanup:
> +    avfilter_graph_free(&graph);
> +    return ret;
> +}
> +
>  void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
>  {
>      filter->ready = FFMAX(filter->ready, priority);
> @@ -759,12 +857,12 @@ void avfilter_free(AVFilterContext *filter)
>
>      for (i = 0; i < filter->nb_inputs; i++) {
>          free_link(filter->inputs[i]);
> -        if (filter->input_pads[i].flags  & AVFILTERPAD_FLAG_FREE_NAME)
> +        if (filter->input_pads && filter->input_pads[i].flags  &
> AVFILTERPAD_FLAG_FREE_NAME)
>              av_freep(&filter->input_pads[i].name);
>      }
>      for (i = 0; i < filter->nb_outputs; i++) {
>          free_link(filter->outputs[i]);
> -        if (filter->output_pads[i].flags & AVFILTERPAD_FLAG_FREE_NAME)
> +        if (filter->output_pads && filter->output_pads[i].flags &
> AVFILTERPAD_FLAG_FREE_NAME)
>              av_freep(&filter->output_pads[i].name);
>      }
>
> diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
> index 2e8197c9a6..705dabe53c 100644
> --- a/libavfilter/avfilter.h
> +++ b/libavfilter/avfilter.h
> @@ -41,6 +41,7 @@
>  #include "libavutil/avutil.h"
>  #include "libavutil/buffer.h"
>  #include "libavutil/dict.h"
> +#include "libavutil/bprint.h"
>  #include "libavutil/frame.h"
>  #include "libavutil/log.h"
>  #include "libavutil/samplefmt.h"
> @@ -738,6 +739,17 @@ int avfilter_link(AVFilterContext *src, unsigned
> srcpad,
>   */
>  void avfilter_link_free(AVFilterLink **link);
>
> +/**
> + * Gets the formats from an AVFilterFormatsConfig.
> + *
> + * @param bp         an instance of AVBPrint
> + * @param filter     the AVFilter
> + * @param for_output set to 1 for filter outputs
> + * @param pad_index  the index of the input or output
> + * @return           zero on success
> + */
> +int avfilter_print_config_formats(AVBPrint *bp, const AVFilter *filter, int
> for_output, unsigned pad_index);
> +
>  /**
>   * Negotiate the media format, dimensions, etc of all inputs to a filter.
>   *
> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
> index 53f468494d..9118a44e1f 100644
> --- a/libavfilter/avfiltergraph.c
> +++ b/libavfilter/avfiltergraph.c
> @@ -416,10 +416,7 @@ static int query_formats(AVFilterGraph *graph, void
> *log_ctx)
>          AVFilterContext *f = graph->filters[i];
>          if (formats_declared(f))
>              continue;
> -        if (f->filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC)
> -            ret = filter_query_formats(f);
> -        else
> -            ret = ff_default_query_formats(f);
> +        ret = ff_filter_query_formats(f);
>          if (ret < 0 && ret != AVERROR(EAGAIN))
>              return ret;
>          /* note: EAGAIN could indicate a partial success, not counted yet
> */
> @@ -1351,3 +1348,12 @@ int ff_filter_graph_run_once(AVFilterGraph *graph)
>          return AVERROR(EAGAIN);
>      return ff_filter_activate(filter);
>  }
> +
> +int ff_filter_query_formats(AVFilterContext *filter)
> +{
> +    if (filter->filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC)
> +        return filter_query_formats(filter);
> +
> +    return ff_default_query_formats(filter);
> +}
> +
> diff --git a/libavfilter/internal.h b/libavfilter/internal.h
> index aaf2c6c584..446d2a45f8 100644
> --- a/libavfilter/internal.h
> +++ b/libavfilter/internal.h
> @@ -374,6 +374,15 @@ void ff_filter_graph_remove_filter(AVFilterGraph
> *graph, AVFilterContext *filter
>   */
>  int ff_filter_graph_run_once(AVFilterGraph *graph);
>
> +/**
> + * Query the formats of a filter.
> + *
> + * @param filter the filter context
> + *
> + * @return 0 on success
> + */
> +int ff_filter_query_formats(AVFilterContext *filter);
> +
>  /**
>   * Get number of threads for current filter instance.
>   * This number is always same or less than graph->nb_threads.
> diff --git a/libavfilter/version.h b/libavfilter/version.h
> index 4ccbf5641c..436c2b8b17 100644
> --- a/libavfilter/version.h
> +++ b/libavfilter/version.h
> @@ -31,8 +31,8 @@
>
>  #include "version_major.h"
>
> -#define LIBAVFILTER_VERSION_MINOR  49
> -#define LIBAVFILTER_VERSION_MICRO 101
> +#define LIBAVFILTER_VERSION_MINOR  50
> +#define LIBAVFILTER_VERSION_MICRO 100
>
>
>  #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR,
> \
> --
> ffmpeg-codebot
>


LGTM

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
>


More information about the ffmpeg-devel mailing list