From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 9E27D40665 for ; Tue, 25 Apr 2023 07:30:40 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8EF6168BF4E; Tue, 25 Apr 2023 10:30:29 +0300 (EEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CDEAC68B9FC for ; Tue, 25 Apr 2023 10:30:22 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1682407828; x=1713943828; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gMERouqG1omCEUydY+CPB85v3ZNQme9iuWtebXTaxWA=; b=k/qbt4IgBfeGhiTPDSzLr7JgKJn8R69KvbA9iwxmMdxB4z0v90VFO4Ct WNo3n7hNwdXqxzAcy31ZeL38myQ0vUV1yny/ew3H5MMauQHsxQ3wp5Tl/ 6KiYpBq4ezVq04/zxwZmHuBT/Z3VJPrZbzCud7I3nZqvhyUBrlq6WiBT5 Fljjh9a1vIs5E8XDONDi1/xDaN/PH3MLKkqC8utRIngTQFNWZgbjhY2Tv axv3RpcVAit81VqAZVaZBQdUXCnhW9HEPqc0RhqQ7CKD8Jafw0leFJ0Um t5eHvBkD3tGR8sNamiRXCv5OUukhX1qjBAeSyIM5BbpduCc18ZpVuBLaa g==; X-IronPort-AV: E=McAfee;i="6600,9927,10690"; a="374630986" X-IronPort-AV: E=Sophos;i="5.99,224,1677571200"; d="scan'208";a="374630986" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Apr 2023 00:30:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10690"; a="867798342" X-IronPort-AV: E=Sophos;i="5.99,224,1677571200"; d="scan'208";a="867798342" Received: from desktop-qn7n0nf.sh.intel.com (HELO localhost.localdomain) ([10.239.160.59]) by orsmga005.jf.intel.com with ESMTP; 25 Apr 2023 00:30:00 -0700 From: Tong Wu To: ffmpeg-devel@ffmpeg.org Date: Tue, 25 Apr 2023 15:26:19 +0800 Message-Id: <20230425072620.512-4-tong1.wu@intel.com> X-Mailer: git-send-email 2.39.1.windows.1 In-Reply-To: <20230425072620.512-1-tong1.wu@intel.com> References: <20230425072620.512-1-tong1.wu@intel.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v5 4/5] lavfi/format: wrap auto filters into structures X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Tong Wu Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: 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 --- 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".