From patchwork Sat Jul 24 15:29:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas George X-Patchwork-Id: 29042 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a5d:965a:0:0:0:0:0 with SMTP id d26csp2320741ios; Sat, 24 Jul 2021 08:30:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwM1XTVprbijgNlB6bImcKvvyZvh3eHlWewlRg9N4FMI+VUGF1rfzxXroeX9PsycH5Fs9HL X-Received: by 2002:a17:906:2541:: with SMTP id j1mr9763790ejb.128.1627140601776; Sat, 24 Jul 2021 08:30:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627140601; cv=none; d=google.com; s=arc-20160816; b=lDptkIDqs1Ygi1lNLLJkfP9r4rfRlPB96kFjn6+rlCQlOMrvD5VHVFWQkVeWwLJ8dI 3qldBF2VyRqDo0cjjU0RD1T+x8CGJWBuzEOTGMQ0u0a20+WlN+i7MM51UVpT4coa75n1 V6F4U4MyzY6iMvzws4ieUjXuPO9D8sS5REo2VdhBL+vG1U9NNqFff+H41xUB0i2A2S04 kibMQDgmF57scP77g4YCirObgfdLxbe3LWP8navrvzzQ7cjbURT6EdqBhnn7m1zpo/Wm l6hj34RQ57ISUQ8AcrGuZW0u/s/oE7wV14Qtdjf/EPBk9VopVYVPUx9N6XSlXozZXdS4 F4eg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :delivered-to; bh=KC9pqJGZyKIq3pd9gsoYJyIsaXE+JlbsZbMEcdRbwHs=; b=BzTlVWOpRus9VZtgVZsI6ObLJVt6sPTL7yDNBcHY2ujzAbib7BSx4CQeWsNsom+0xP OyDsw605AI45Uzwxhlsc5ytDxR9Vs/B18u42gGd7Z5aPJEMw2gncYXFjPiibHNFfNtLI VoGHhrpEPPSi00LjFm+jJpFt5ru4HyIS8DBj6cDXfMmhYcXg5MmN1A+5VFRHYjR7TNiJ ZHo8Jvtguzn00EMXsTDXrJBEEXHYInA7CB2eP7mEjYwI+vkZBETRsT69rLqknUILnnEp 6FlXuunnMdfoHYeTcRmBurfBIOrQTOG4HOq+rroQuQreKlZ1Mdf7gAINcRDNh2nO3tQ4 4yKQ== ARC-Authentication-Results: i=1; mx.google.com; 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 b18si2919555edw.290.2021.07.24.08.30.01; Sat, 24 Jul 2021 08:30:01 -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; 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 6BA1C68AA07; Sat, 24 Jul 2021 18:29:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from nef.ens.fr (nef2.ens.fr [129.199.96.40]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 639E768A5A8 for ; Sat, 24 Jul 2021 18:29:51 +0300 (EEST) X-ENS-nef-client: 129.199.129.80 ( name = phare.normalesup.org ) Received: from phare.normalesup.org (phare.normalesup.org [129.199.129.80]) by nef.ens.fr (8.14.4/1.01.28121999) with ESMTP id 16OFToEF004860 for ; Sat, 24 Jul 2021 17:29:50 +0200 Received: by phare.normalesup.org (Postfix, from userid 1001) id 499CCE0027; Sat, 24 Jul 2021 17:29:50 +0200 (CEST) From: Nicolas George To: ffmpeg-devel@ffmpeg.org Date: Sat, 24 Jul 2021 17:29:46 +0200 Message-Id: <20210724152947.258052-1-george@nsup.org> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.4.3 (nef.ens.fr [129.199.96.32]); Sat, 24 Jul 2021 17:29:50 +0200 (CEST) Subject: [FFmpeg-devel] [PATCH 1/2] lavu/internal: add FF_FIELD_AT(). 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: B8SQrvvzr5rR Signed-off-by: Nicolas George --- libavutil/internal.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavutil/internal.h b/libavutil/internal.h index a33e8700c3..2011813932 100644 --- a/libavutil/internal.h +++ b/libavutil/internal.h @@ -103,6 +103,11 @@ #define FF_PTR_ADD(ptr, off) ((off) ? (ptr) + (off) : (ptr)) +/** + * Access a field in a structure by its offset. + */ +#define FF_FIELD_AT(type, off, obj) (*(type *)((char *)&(obj) + (off))) + #include "libm.h" /** From patchwork Sat Jul 24 15:29:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas George X-Patchwork-Id: 29043 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a5d:965a:0:0:0:0:0 with SMTP id d26csp2320886ios; Sat, 24 Jul 2021 08:30:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz8jsSaeXSH4zrdOLaCKkGpX8nq/dG2zGe+T/L+W/X0lICj7STuGW+V5FQlBQGIz0709bwK X-Received: by 2002:a17:906:7fcd:: with SMTP id r13mr9414096ejs.547.1627140611073; Sat, 24 Jul 2021 08:30:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627140611; cv=none; d=google.com; s=arc-20160816; b=Jon3qc/bR+LyeeZ5hV9nLgZYTuccGzwpRq1baa63ZKSX5MXQXjCTzoF7ivd/IaMejs 2SfsHD62wNl0Fvf5SikQPctkqAmJ39diBG0mG2zQ7kqsE0HOU2x6j2GkF9iuSOV1UqnV /NEDehPcTmNOb61qD/khNg+eaUM29QVhErCCYaVgjPQGYulFtYCbPKTTDYvTcSg86rqc ur0Cu7cGR9WgM7qvnwTmoFZy5ppCpv8BNL+Ga2oo5XMsxZvcbtjrbfe0ENx+LChp4SHz n2/wmgxr1QMRfUW/woPmXj7a+btVlwvWjj3LufYVr8sUVg51p/I1QA19hyTaYQ+IEOWF ZEvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding: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:delivered-to; bh=4PXnfSYJ84x4Juy6OlTa/ZI1V1VzWE0ewFNHVHeByEo=; b=xDAozu0nwNwYy6e8BawpC4B2LfpSEtXBJpl1meyJacC+ppbkExq0oRlYuZmcGYQjPq o3GMWVDmqIYQifCS0xhrIN0HbC4DajmXIgxHA2LBG8kXROGY8HYoKs6s0Sv+CEkhVtKT GjnXGqQTb5LwQ7IKtPhbY/rx+/qO6HkzqSUH64z1jr0yTp2QvNxzq2XIiSf9srbStNrJ YzoLX5YaG8p1UkztNi2kX/bJqPeK0c4YKz3ruGAaTElZjMAO8gzm1oDx+AMtzoZDT0rI oNOrxNFqyBo82XNX83KctnkF+621iRWU8JgFKwRaczrWYypqKKTitaKKr6rli25hws2U MSnQ== ARC-Authentication-Results: i=1; mx.google.com; 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 b5si2273348ejx.649.2021.07.24.08.30.10; Sat, 24 Jul 2021 08:30:11 -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; 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 72E9168AA83; Sat, 24 Jul 2021 18:30:00 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from nef.ens.fr (nef2.ens.fr [129.199.96.40]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 158B668AA07 for ; Sat, 24 Jul 2021 18:29:53 +0300 (EEST) X-ENS-nef-client: 129.199.129.80 ( name = phare.normalesup.org ) Received: from phare.normalesup.org (phare.normalesup.org [129.199.129.80]) by nef.ens.fr (8.14.4/1.01.28121999) with ESMTP id 16OFTqqv004865 for ; Sat, 24 Jul 2021 17:29:52 +0200 Received: by phare.normalesup.org (Postfix, from userid 1001) id 47FFEE0027; Sat, 24 Jul 2021 17:29:52 +0200 (CEST) From: Nicolas George To: ffmpeg-devel@ffmpeg.org Date: Sat, 24 Jul 2021 17:29:47 +0200 Message-Id: <20210724152947.258052-2-george@nsup.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210724152947.258052-1-george@nsup.org> References: <20210724152947.258052-1-george@nsup.org> MIME-Version: 1.0 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.4.3 (nef.ens.fr [129.199.96.32]); Sat, 24 Jul 2021 17:29:52 +0200 (CEST) Subject: [FFmpeg-devel] [PATCH 2/2] lavfi/formats: put merge functions in 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: sUXfLkS6ejdn It makes the code clearer and will allow adding new stages of negotiation easier. Signed-off-by: Nicolas George --- libavfilter/avfiltergraph.c | 96 +++++++++++++----------------- libavfilter/formats.c | 114 ++++++++++++++++++++++++++++++++---- libavfilter/formats.h | 41 ++++--------- 3 files changed, 157 insertions(+), 94 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 5389d82d9f..37f09cb686 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -458,48 +458,41 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) for (j = 0; j < filter->nb_inputs; j++) { AVFilterLink *link = filter->inputs[j]; + const AVFilterNegotiation *neg; + unsigned neg_step; int convert_needed = 0; if (!link) continue; - if (link->incfg.formats != link->outcfg.formats - && link->incfg.formats && link->outcfg.formats) - if (!ff_can_merge_formats(link->incfg.formats, link->outcfg.formats, - link->type)) + neg = ff_filter_get_negotiation(link); + av_assert0(neg); + for (neg_step = 1; neg_step < neg->nb; neg_step++) { + const AVFilterFormatsMerger *m = &neg->mergers[neg_step]; + void *a = FF_FIELD_AT(void *, m->offset, link->incfg); + void *b = FF_FIELD_AT(void *, m->offset, link->outcfg); + if (a && b && a != b && !m->can_merge(a, b)) { convert_needed = 1; - if (link->type == AVMEDIA_TYPE_AUDIO) { - if (link->incfg.samplerates != link->outcfg.samplerates - && link->incfg.samplerates && link->outcfg.samplerates) - if (!ff_can_merge_samplerates(link->incfg.samplerates, - link->outcfg.samplerates)) - convert_needed = 1; - } - -#define CHECKED_MERGE(field, ...) ((ret = ff_merge_ ## field(__VA_ARGS__)) <= 0) -#define MERGE_DISPATCH(field, ...) \ - if (!(link->incfg.field && link->outcfg.field)) { \ - count_delayed++; \ - } else if (link->incfg.field == link->outcfg.field) { \ - count_already_merged++; \ - } else if (!convert_needed) { \ - count_merged++; \ - if (CHECKED_MERGE(field, __VA_ARGS__)) { \ - if (ret < 0) \ - return ret; \ - convert_needed = 1; \ - } \ + break; + } } - - if (link->type == AVMEDIA_TYPE_AUDIO) { - MERGE_DISPATCH(channel_layouts, link->incfg.channel_layouts, - link->outcfg.channel_layouts) - MERGE_DISPATCH(samplerates, link->incfg.samplerates, - link->outcfg.samplerates) + for (neg_step = 0; neg_step < neg->nb; neg_step++) { + const AVFilterFormatsMerger *m = &neg->mergers[neg_step]; + void *a = FF_FIELD_AT(void *, m->offset, link->incfg); + void *b = FF_FIELD_AT(void *, m->offset, link->outcfg); + if (!(a && b)) { + count_delayed++; + } else if (a == b) { + count_already_merged++; + } else if (!convert_needed) { + count_merged++; + ret = m->merge(a, b); + if (ret < 0) + return ret; + if (!ret) + convert_needed = 1; + } } - MERGE_DISPATCH(formats, link->incfg.formats, - link->outcfg.formats, link->type) -#undef MERGE_DISPATCH if (convert_needed) { AVFilterContext *convert; @@ -572,26 +565,21 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) av_assert0(outlink-> incfg.channel_layouts->refcount > 0); av_assert0(outlink->outcfg.channel_layouts->refcount > 0); } - if (CHECKED_MERGE(formats, inlink->incfg.formats, - inlink->outcfg.formats, inlink->type) || - CHECKED_MERGE(formats, outlink->incfg.formats, - outlink->outcfg.formats, outlink->type) || - inlink->type == AVMEDIA_TYPE_AUDIO && - (CHECKED_MERGE(samplerates, inlink->incfg.samplerates, - inlink->outcfg.samplerates) || - CHECKED_MERGE(channel_layouts, inlink->incfg.channel_layouts, - inlink->outcfg.channel_layouts)) || - outlink->type == AVMEDIA_TYPE_AUDIO && - (CHECKED_MERGE(samplerates, outlink->incfg.samplerates, - outlink->outcfg.samplerates) || - CHECKED_MERGE(channel_layouts, outlink->incfg.channel_layouts, - outlink->outcfg.channel_layouts))) { - if (ret < 0) - return ret; - 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); + for (neg_step = 0; neg_step < neg->nb; neg_step++) { + const AVFilterFormatsMerger *m = &neg->mergers[neg_step]; + void *ia = FF_FIELD_AT(void *, m->offset, inlink->incfg); + void *ib = FF_FIELD_AT(void *, m->offset, inlink->outcfg); + void *oa = FF_FIELD_AT(void *, m->offset, outlink->incfg); + void *ob = FF_FIELD_AT(void *, m->offset, outlink->outcfg); + if ((ret = m->merge(ia, ib)) <= 0 || + (ret = m->merge(oa, ob)) <= 0) { + if (ret < 0) + return ret; + 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 6c05b118c9..eceae8ba9c 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -100,6 +100,8 @@ static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b, int alpha1=0, alpha2=0; int chroma1=0, chroma2=0; + av_assert2(check || (a->refcount && b->refcount)); + if (a == b) return 1; @@ -132,43 +134,86 @@ static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b, return 1; } -int ff_can_merge_formats(const AVFilterFormats *a, const AVFilterFormats *b, - enum AVMediaType type) + +/** + * Check the formats lists for compatibility for merging without actually + * merging. + * + * @return 1 if they are compatible, 0 if not. + */ +static int can_merge_pix_fmts(const void *a, const void *b) { return merge_formats_internal((AVFilterFormats *)a, - (AVFilterFormats *)b, type, 1); + (AVFilterFormats *)b, AVMEDIA_TYPE_VIDEO, 1); +} + +/** + * Merge the formats lists if they are compatible and update all the + * references of a and b to point to the combined list and free the old + * lists as needed. The combined list usually contains the intersection of + * the lists of a and b. + * + * Both a and b must have owners (i.e. refcount > 0) for these functions. + * + * @return 1 if merging succeeded, 0 if a and b are incompatible + * and negative AVERROR code on failure. + * a and b are unmodified if 0 is returned. + */ +static int merge_pix_fmts(void *a, void *b) +{ + return merge_formats_internal(a, b, AVMEDIA_TYPE_VIDEO, 0); } -int ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, - enum AVMediaType type) +/** + * See can_merge_pix_fmts(). + */ +static int can_merge_sample_fmts(const void *a, const void *b) { - av_assert2(a->refcount && b->refcount); - return merge_formats_internal(a, b, type, 0); + return merge_formats_internal((AVFilterFormats *)a, + (AVFilterFormats *)b, AVMEDIA_TYPE_AUDIO, 1); +} + +/** + * See merge_pix_fmts(). + */ +static int merge_sample_fmts(void *a, void *b) +{ + return merge_formats_internal(a, b, AVMEDIA_TYPE_AUDIO, 0); } static int merge_samplerates_internal(AVFilterFormats *a, AVFilterFormats *b, int check) { + av_assert2(check || (a->refcount && b->refcount)); if (a == b) return 1; MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 1); return 1; } -int ff_can_merge_samplerates(const AVFilterFormats *a, const AVFilterFormats *b) +/** + * See can_merge_pix_fmts(). + */ +static int can_merge_samplerates(const void *a, const void *b) { return merge_samplerates_internal((AVFilterFormats *)a, (AVFilterFormats *)b, 1); } -int ff_merge_samplerates(AVFilterFormats *a, AVFilterFormats *b) +/** + * See merge_pix_fmts(). + */ +static int merge_samplerates(void *a, void *b) { - av_assert2(a->refcount && b->refcount); return merge_samplerates_internal(a, b, 0); } -int ff_merge_channel_layouts(AVFilterChannelLayouts *a, - AVFilterChannelLayouts *b) +/** + * See merge_pix_fmts(). + */ +static int merge_channel_layouts(void *va, void *vb) { + AVFilterChannelLayouts *a = va; + AVFilterChannelLayouts *b = vb; uint64_t *channel_layouts; unsigned a_all = a->all_layouts + a->all_counts; unsigned b_all = b->all_layouts + b->all_counts; @@ -255,6 +300,51 @@ int ff_merge_channel_layouts(AVFilterChannelLayouts *a, return 1; } +static const AVFilterFormatsMerger mergers_video[] = { + { + .offset = offsetof(AVFilterFormatsConfig, formats), + .merge = merge_pix_fmts, + .can_merge = can_merge_pix_fmts, + }, +}; + +static const AVFilterFormatsMerger mergers_audio[] = { + { + .offset = offsetof(AVFilterFormatsConfig, channel_layouts), + .merge = merge_channel_layouts, + .can_merge = NULL, + }, + { + .offset = offsetof(AVFilterFormatsConfig, samplerates), + .merge = merge_samplerates, + .can_merge = can_merge_samplerates, + }, + { + .offset = offsetof(AVFilterFormatsConfig, formats), + .merge = merge_sample_fmts, + .can_merge = can_merge_sample_fmts, + }, +}; + +static const AVFilterNegotiation negotiate_video = { + .nb = FF_ARRAY_ELEMS(mergers_video), + .mergers = mergers_video, +}; + +static const AVFilterNegotiation negotiate_audio = { + .nb = FF_ARRAY_ELEMS(mergers_audio), + .mergers = mergers_audio, +}; + +const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link) +{ + switch (link->type) { + case AVMEDIA_TYPE_VIDEO: return &negotiate_video; + case AVMEDIA_TYPE_AUDIO: return &negotiate_audio; + default: return NULL; + } +} + int ff_fmt_is_in(int fmt, const int *fmts) { const int *p; diff --git a/libavfilter/formats.h b/libavfilter/formats.h index 65acc939e3..7a1f8408ac 100644 --- a/libavfilter/formats.h +++ b/libavfilter/formats.h @@ -69,6 +69,19 @@ struct AVFilterFormats { struct AVFilterFormats ***refs; ///< references to this list }; +typedef struct AVFilterFormatMerger { + unsigned offset; + int (*merge)(void *a, void *b); + int (*can_merge)(const void *a, const void *b); +} AVFilterFormatsMerger; + +typedef struct AVFilterNegotiation { + unsigned nb; + const AVFilterFormatsMerger *mergers; +} AVFilterNegotiation; + +const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link); + /** * A list of supported channel layouts. * @@ -108,34 +121,6 @@ struct AVFilterChannelLayouts { #define FF_LAYOUT2COUNT(l) (((l) & 0x8000000000000000ULL) ? \ (int)((l) & 0x7FFFFFFF) : 0) -/** - * Check the formats/samplerates lists for compatibility for merging - * without actually merging. - * - * @return 1 if they are compatible, 0 if not. - */ -int ff_can_merge_formats(const AVFilterFormats *a, const AVFilterFormats *b, - enum AVMediaType type); -int ff_can_merge_samplerates(const AVFilterFormats *a, const AVFilterFormats *b); - -/** - * Merge the formats/channel layouts/samplerates lists if they are compatible - * and update all the references of a and b to point to the combined list and - * free the old lists as needed. The combined list usually contains the - * intersection of the lists of a and b. - * - * Both a and b must have owners (i.e. refcount > 0) for these functions. - * - * @return 1 if merging succeeded, 0 if a and b are incompatible - * and negative AVERROR code on failure. - * a and b are unmodified if 0 is returned. - */ -int ff_merge_channel_layouts(AVFilterChannelLayouts *a, - AVFilterChannelLayouts *b); -int ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, - enum AVMediaType type); -int ff_merge_samplerates(AVFilterFormats *a, AVFilterFormats *b); - /** * Construct an empty AVFilterChannelLayouts/AVFilterFormats struct -- * representing any channel layout (with known disposition)/sample rate.