From patchwork Mon Jul 4 08:09:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wu, Tong1" X-Patchwork-Id: 36643 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:8b27:b0:88:1bbf:7fd2 with SMTP id l39csp2666403pzh; Mon, 4 Jul 2022 01:11:47 -0700 (PDT) X-Google-Smtp-Source: AGRyM1t7s85yo8MWuh5oigO4kbJ0vqiLlShtt58l2Z2dgVsL3HDb1I0phlLYOvXOoseUmE4osl7M X-Received: by 2002:a05:6402:280b:b0:437:9efc:a065 with SMTP id h11-20020a056402280b00b004379efca065mr37445797ede.3.1656922307804; Mon, 04 Jul 2022 01:11:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656922307; cv=none; d=google.com; s=arc-20160816; b=RvBQDc8pv9tyTN0YVqXywHh0m/aeaw9YjpLadilzjg1iHkeQjq4i1cIeitMTRRHrvN sPWaUNKFP8DDqb0Mne4kusTaMTGMU2/qqm0qlNr3m195FHtSsQyW+ImFnq5GqrKIDeQE TuoflveXedrAg+Vgea19gQbFGX/xhqhGs74O0+jlfhQ9QS+c5fzt4/n9UUw+k+IS9YHk zdtUU7yzL6vWKcJ2pX9kRz8EV28wMYJPMpFyXb42VVzY610oMQhdEJBXr2Z7dyPg2P42 Do/yzajl7qvlccnoWOa5HS19vFxZIseoOHIZ+K07oZGkNI0pO3QJjbrkVvfbMjIoO9xz aUbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=wh2I06Tuz1Hn3PkREOADR8XG2X/tpdF9FPt2DFr4fCQ=; b=Nz3G+GzoL+6LBbqc0jImeKbRC5TkASMucAWNeG+Km1V3P3teYeQLusyrezNTVnLPpP KVI9IRFRDUcyaYmw8T19/V/tZnJTzcQAA8xiryXpWwYKvnZYqjsjT8v4lWGZ6p0Cv+jq HMxyMuqVPzmoW43qIf5MptkUEh4FGlJRbpUJyL5cCX7trm3hXhEx7d33v8JHQqG1pGNz 06qmP0Ji1IiQcWvYv4UxeAmh9W/Uf0R2UIYMBsmAHZrn89k4QkAorrbpaMDfpDZpXUR4 wZyogGwqT88ECXKp1GStxS9xsmfkyu1lUg/n+PDHhnR57QVTwCl0sCM10QrhDqnbZ1i0 aMDg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@intel.com header.s=Intel header.b=Wb+HNs4L; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id hw9-20020a170907a0c900b0072abb81b5f5si4938857ejc.537.2022.07.04.01.11.47; Mon, 04 Jul 2022 01:11:47 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@intel.com header.s=Intel header.b=Wb+HNs4L; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 17F1C68B9F8; Mon, 4 Jul 2022 11:11:19 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4F42768B9FC for ; Mon, 4 Jul 2022 11:11:11 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1656922276; x=1688458276; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=o0E2V7UE8k7IHBeqGT8UrBqVBpqT9Saeivrf2FAsFQk=; b=Wb+HNs4Ll9Wk1oCXMtv2U17OObDD2ZZdEcklQfYg7CV86RJehYsyvBmO lLQecMzjg8ysBIUNEXYlE6ObKj1mpVkIJa+AKCaWN3bASECroEbzOVmKx rHMBs12f3aMoaG4atbK6jYwVxNwzezfXSxxBTwGh0+rXi6Hjq0eVXRSI7 KX63SyCok8HxoiSkqEZp3G17sOMAwYdjO7w+s4riGksDryNTL4qmsNP2u I4Zzw6wRsjIfyvvFRUntF5JH0dvxY5gLrUA2QOrKwjNV2AXcqQX01sjVI Lkz6OYqLrS5Uou9tHERddOnydTGOH9kG/tHp2C+vHPjsV6T9083FXb4O4 Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10397"; a="262861138" X-IronPort-AV: E=Sophos;i="5.92,243,1650956400"; d="scan'208";a="262861138" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 01:11:06 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,243,1650956400"; d="scan'208";a="660122919" Received: from desktop-qn7n0nf.sh.intel.com (HELO localhost.localdomain) ([10.239.160.39]) by fmsmga004.fm.intel.com with ESMTP; 04 Jul 2022 01:11:05 -0700 From: Tong Wu To: ffmpeg-devel@ffmpeg.org Date: Mon, 4 Jul 2022 16:09:56 +0800 Message-Id: <20220704080957.425-4-tong1.wu@intel.com> X-Mailer: git-send-email 2.35.1.windows.2 In-Reply-To: <20220704080957.425-1-tong1.wu@intel.com> References: <20220704080957.425-1-tong1.wu@intel.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v4 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: dlt9gochIHz3 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 2e6938b049..102c1f7693 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);