From: Tong Wu <tong1.wu-at-intel.com@ffmpeg.org> To: ffmpeg-devel@ffmpeg.org Cc: Tong Wu <tong1.wu@intel.com> Subject: [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures Date: Tue, 25 Apr 2023 15:26:19 +0800 Message-ID: <20230425072620.512-4-tong1.wu@intel.com> (raw) In-Reply-To: <20230425072620.512-1-tong1.wu@intel.com> This patch wraps auto conversion filters into new structures, making it easier to add more auto filters. And it adds a loop to automatically insert every possible conversion filter until merge succeeds. Signed-off-by: Tong Wu <tong1.wu@intel.com> --- libavfilter/avfiltergraph.c | 76 +++++++++++++++++++++++++------------ libavfilter/formats.c | 22 +++++++++-- libavfilter/formats.h | 10 ++++- 3 files changed, 78 insertions(+), 30 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 9e5bb32886..8af0467bc5 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -395,24 +395,22 @@ static int formats_declared(AVFilterContext *f) static int insert_auto_filter(AVFilterContext **convert, AVFilterGraph *graph, AVFilterLink *link, const AVFilterNegotiation *neg, - int *converter_count, void *log_ctx) + unsigned conv_step, int *converter_count, void *log_ctx) { int ret; const AVFilter *filter; AVFilterContext *ctx; AVFilterLink *inlink, *outlink; char inst_name[30]; - const char *opts; + const char *opts = FF_FIELD_AT(char *, neg->conversion_filters[conv_step].conversion_opts_offset, *graph); + const char *name = neg->conversion_filters[conv_step].conversion_filter; - if (!(filter = avfilter_get_by_name(neg->conversion_filter))) { + if (!(filter = avfilter_get_by_name(name))) { av_log(log_ctx, AV_LOG_ERROR, - "'%s' filter not present, cannot convert formats.\n", - neg->conversion_filter); + "'%s' filter not present, cannot convert formats.\n", name); return AVERROR(EINVAL); } - snprintf(inst_name, sizeof(inst_name), "auto_%s_%d", - neg->conversion_filter, (*converter_count)++); - opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph); + snprintf(inst_name, sizeof(inst_name), "auto_%s_%d", name, (*converter_count)++); ret = avfilter_graph_create_filter(&ctx, filter, inst_name, opts, NULL, graph); if (ret < 0) return ret; @@ -501,7 +499,7 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) for (j = 0; j < filter->nb_inputs; j++) { AVFilterLink *link = filter->inputs[j]; const AVFilterNegotiation *neg; - unsigned neg_step; + unsigned neg_step, conv_step; int convert_needed = 0; if (!link) @@ -537,8 +535,6 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) } if (convert_needed) { - AVFilterContext *convert; - if (graph->disable_auto_convert) { av_log(log_ctx, AV_LOG_ERROR, "The filters '%s' and '%s' do not have a common format " @@ -548,20 +544,52 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx) } /* couldn't merge format lists. auto-insert conversion filter */ - ret = insert_auto_filter(&convert, graph, link, neg, &converter_count, log_ctx); - if (ret < 0) { - av_log(log_ctx, AV_LOG_ERROR, "Failed to insert an auto filter.\n"); - return ret; - } + for (conv_step = 0; conv_step < neg->nb_conversion_filters; conv_step++) { + AVFilterContext *convert; + ret = insert_auto_filter(&convert, graph, link, neg, + conv_step, &converter_count, log_ctx); + if (ret < 0) { + av_log(log_ctx, AV_LOG_ERROR, "Failed to insert an auto filter.\n"); + return ret; + } - ret = merge_auto_filter(convert, neg); - if (ret < 0) - return ret; - else if (ret == 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Impossible to convert between the formats supported by the filter " - "'%s' and the filter '%s'\n", link->src->name, link->dst->name); - return AVERROR(ENOSYS); + ret = merge_auto_filter(convert, neg); + if (ret < 0) + return ret; + else if (ret > 0) + break; + else if (conv_step < neg->nb_conversion_filters - 1) { + AVFilterLink *inlink = convert->inputs[0]; + AVFilterLink *outlink = convert->outputs[0]; + av_log(log_ctx, AV_LOG_VERBOSE, + "Impossible to convert between the formats supported by the filter " + "'%s' and the filter '%s', try another conversion filter.\n", + link->src->name, link->dst->name); + unsigned dstpad_idx = outlink->dstpad - outlink->dst->input_pads; + converter_count--; + /* re-hookup the link */ + inlink->dst = outlink->dst; + inlink->dstpad = &outlink->dst->input_pads[dstpad_idx]; + outlink->dst->inputs[dstpad_idx] = inlink; + if (outlink->outcfg.formats) + ff_formats_changeref(&outlink->outcfg.formats, + &inlink->outcfg.formats); + if (outlink->outcfg.samplerates) + ff_formats_changeref(&outlink->outcfg.samplerates, + &inlink->outcfg.samplerates); + if (outlink->outcfg.channel_layouts) + ff_channel_layouts_changeref(&outlink->outcfg.channel_layouts, + &inlink->outcfg.channel_layouts); + /* remove the previous auto filter */ + convert->inputs[0] = NULL; + convert->outputs[0]->dst = NULL; + avfilter_free(convert); + } else { + av_log(log_ctx, AV_LOG_ERROR, + "Impossible to convert between the formats supported by the filter " + "'%s' and the filter '%s'\n", link->src->name, link->dst->name); + return AVERROR(ENOSYS); + } } } } diff --git a/libavfilter/formats.c b/libavfilter/formats.c index e8c2888c0c..c8e20e5b20 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -326,18 +326,32 @@ static const AVFilterFormatsMerger mergers_audio[] = { }, }; +static const AVFilterFormatsFilter filters_video[] = { + { + .conversion_filter = "scale", + .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts), + }, +}; + +static const AVFilterFormatsFilter filters_audio[] = { + { + .conversion_filter = "aresample", + .conversion_opts_offset = offsetof(AVFilterGraph, aresample_swr_opts), + } +}; + static const AVFilterNegotiation negotiate_video = { .nb_mergers = FF_ARRAY_ELEMS(mergers_video), .mergers = mergers_video, - .conversion_filter = "scale", - .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts), + .nb_conversion_filters = FF_ARRAY_ELEMS(filters_video), + .conversion_filters = filters_video, }; static const AVFilterNegotiation negotiate_audio = { .nb_mergers = FF_ARRAY_ELEMS(mergers_audio), .mergers = mergers_audio, - .conversion_filter = "aresample", - .conversion_opts_offset = offsetof(AVFilterGraph, aresample_swr_opts), + .nb_conversion_filters = FF_ARRAY_ELEMS(filters_audio), + .conversion_filters = filters_audio, }; const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link) diff --git a/libavfilter/formats.h b/libavfilter/formats.h index 22224dce2d..868cbe98dd 100644 --- a/libavfilter/formats.h +++ b/libavfilter/formats.h @@ -330,6 +330,12 @@ typedef struct AVFilterFormatMerger { int (*can_merge)(const void *a, const void *b); } AVFilterFormatsMerger; +typedef struct AVFilterFormatFilter { + const char *conversion_filter; + unsigned conversion_opts_offset; +} AVFilterFormatsFilter; + + /** * Callbacks and properties to describe the steps of a format negotiation. * @@ -418,8 +424,8 @@ typedef struct AVFilterFormatMerger { typedef struct AVFilterNegotiation { unsigned nb_mergers; const AVFilterFormatsMerger *mergers; - const char *conversion_filter; - unsigned conversion_opts_offset; + unsigned nb_conversion_filters; + const AVFilterFormatsFilter *conversion_filters; } AVFilterNegotiation; const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link); -- 2.39.1.windows.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2023-04-25 7:30 UTC|newest] Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-04-25 7:26 [FFmpeg-devel] [PATCH v5 1/5] avutil/hwcontext: add a function to get the AVHWDeviceType Tong Wu 2023-04-25 7:26 ` [FFmpeg-devel] [PATCH v5 2/5] avfilter/vf_hwmap: get the AVHWDeviceType from outlink format Tong Wu 2023-04-25 7:26 ` [FFmpeg-devel] [PATCH v5 3/5] lavfi/avfiltergraph: move convert codes into functions Tong Wu 2023-04-25 7:26 ` Tong Wu [this message] 2023-05-13 6:33 ` [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures Paul B Mahol 2023-05-25 7:06 ` Wu, Tong1 2023-06-07 8:42 ` Wu, Tong1 2023-04-25 7:26 ` [FFmpeg-devel] [PATCH v5 5/5] lavfi/format: add a hwmap auto conversion filter Tong Wu 2023-06-07 8:51 ` Marvin Scholz 2023-06-08 8:47 ` Wu, Tong1
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230425072620.512-4-tong1.wu@intel.com \ --to=tong1.wu-at-intel.com@ffmpeg.org \ --cc=ffmpeg-devel@ffmpeg.org \ --cc=tong1.wu@intel.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git