From patchwork Sat Aug 31 07:45:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51251 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:4027:b0:48e:c0f8:d0de with SMTP id ky39csp828673vqb; Sat, 31 Aug 2024 01:05:11 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUzS4Iq7QtfMzCdr3osPlpnwl/R68JVULWncCLFVUBmZO6+tMm2MUJsVLPqALicJN5lEo9Y5+c+/f16DHoqZ+mw@gmail.com X-Google-Smtp-Source: AGHT+IGg09w9F8M8P7bi5c30NB5O1eRovg90g1NzvICXDkDGu75REG4kAWa+ZUgKeQbebyo112Ei X-Received: by 2002:a17:907:1c1e:b0:a86:8166:1b0a with SMTP id a640c23a62f3a-a89d8ab4a15mr27997166b.56.1725091510847; Sat, 31 Aug 2024 01:05:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1725091510; cv=none; d=google.com; s=arc-20240605; b=R57+w9wIY5AkHBQ1Z8wC8hrBFTDHMAYnyoR2B1gWN86SIJkozRk5sWrrwi0jcZu8Sn eJBAAphCM68NjyzcBG6f3knhxsVrB8LI/fAVbWeAovhU7GCGnQhoRxk25fNyNjhAq4PO SvsGI7zBTd44A48+MSA9AYz0YY2UtCPCwMNoPhB2dh8yLeZ4icerRR5IzKuKzTl0hIyk hUf0bXk5V9ieyMH2VKMFcGAiCJFIOJ+SJ9Dm4bgZTSeVOO2mNkqJhJXxKMdt1hyIMIjp eGIsJXdeYo/MGKF+UL377ZN/vjP9csNF5GzfaJFpN3kUZK0FOZyo0pTzkc0oc/8V3yvM Wx9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; 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:dkim-signature:delivered-to; bh=0qN+wHqBw9Hfhpv6wUixWyFK0Ncl0B3hnQP/zPpULXU=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=aPYPJct3Lk1RFpQd3/SyFdFKRJA6SemuNagVOib7GbbYu6UwIz5RD46eDLKHect2y4 rsOktXeMt0ziZbFbB2KjtnQVsN40sy3K9El9xaOKqsyqgSbD5dBBKxY5nEi3/nujYpKy LeLkZES44lrwKbKZ4XeQC7EWhraOFIS1/3E0A6A4aH1ePkf9YQHsGvFtoG5nP1n/WLeM lGaNjkYactmYn7L7J+QX3bVixrq1IynKTedfG/W70nMJ++epM1XzQs8QrNVVzVtKPZoa NprDedLUsVRUdgLTJF9gJsOdrhborC4YzwPohvVXZOLpApEz0lI7IwsSlYs3siPPhbFN daLg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=OKmHZyRO; 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 a640c23a62f3a-a898912e06csi402878266b.450.2024.08.31.01.05.09; Sat, 31 Aug 2024 01:05:10 -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=@khirnov.net header.s=mail header.b=OKmHZyRO; 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 58E4D68DD54; Sat, 31 Aug 2024 10:47:16 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4AC9268DD65 for ; Sat, 31 Aug 2024 10:47:09 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=OKmHZyRO; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 698314DE2 for ; Sat, 31 Aug 2024 09:47:08 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id BjgsOGr1HErl for ; Sat, 31 Aug 2024 09:47:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1725090427; bh=2MwvPFIgnYn795lkyJpJq7unjVkFLTpdYBpSCvF4EAA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=OKmHZyROllOpASPxkXLZF5e/AlLdx66TDLkvch2+ShZv36ZZ8L+udMWdQt/3yTE8h jjt0U6TNaLWqvnSvtaBDUktEanbhV3T4fz3o3lCwlZQYNZ+ZCeIkiNb0Vzvv/+0KSE GkGsCfvKly6vh5D296FLfno9DL4D0Kz8BCwDwm7XnIXsCyenH2mqSA+FMtCT7YPOZ3 WHB4+XFrcwnYkJDx2snVaibj5LhbAzwT9Q5VCcOWyvwNHyn/jQqpbhXfji+jZqhhGd 6JCw9tuua9tAKW+uEYTy+zSi73UL6IQMfngdhca677Z584icO953fZhNjko3nEG1ap 0qI8rfBnLAbZw== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 5EFA14DA2 for ; Sat, 31 Aug 2024 09:47:07 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 2E8F03A02CA for ; Sat, 31 Aug 2024 09:47:01 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 31 Aug 2024 09:45:57 +0200 Message-ID: <20240831074659.8909-1-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240829085052.533-1-anton@khirnov.net> References: <20240829085052.533-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 1/8] lavfi: add query_func2() 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: rmKqvQQYxeYI It differs from query_func() in accepting arrays of input/output format configurations to be filled as callback parameters. This allows to mark the filter context as const, ensuring it is not modified by this function, as it is not supposed to have any side effects beyond returning the supported formats. --- Now handling FF_FILTER_FORMATS_QUERY_FUNC2 in the switch in ff_default_query_formats(), avoiding an assertion failure libavfilter/avfilter.h | 85 +++++++++++--------- libavfilter/avfiltergraph.c | 43 ++++++++++ libavfilter/filters.h | 4 + libavfilter/formats.c | 148 +++++++++++++++++++++++++++++++++++ libavfilter/formats.h | 84 ++++++++++++++++++++ libavfilter/tests/filtfmts.c | 19 ++++- 6 files changed, 347 insertions(+), 36 deletions(-) diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 549fe6ce3a..1401577c50 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -98,6 +98,41 @@ const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx); */ enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx); +/** + * Lists of formats / etc. supported by an end of a link. + * + * This structure is directly part of AVFilterLink, in two copies: + * one for the source filter, one for the destination filter. + + * These lists are used for negotiating the format to actually be used, + * which will be loaded into the format and channel_layout members of + * AVFilterLink, when chosen. + */ +typedef struct AVFilterFormatsConfig { + + /** + * List of supported formats (pixel or sample). + */ + AVFilterFormats *formats; + + /** + * Lists of supported sample rates, only for audio. + */ + AVFilterFormats *samplerates; + + /** + * Lists of supported channel layouts, only for audio. + */ + AVFilterChannelLayouts *channel_layouts; + + /** + * Lists of supported YUV color metadata, only for YUV video. + */ + AVFilterFormats *color_spaces; ///< AVColorSpace + AVFilterFormats *color_ranges; ///< AVColorRange + +} AVFilterFormatsConfig; + /** * The number of the filter inputs is not determined just by AVFilter.inputs. * The filter might add additional inputs during initialization depending on the @@ -324,6 +359,21 @@ typedef struct AVFilter { * AVERROR code otherwise */ int (*query_func)(AVFilterContext *); + + /** + * Same as query_func(), except this function writes the results into + * provided arrays. + * + * @param cfg_in array of input format configurations with as many + * members as the filters has inputs (NULL when there are + * no inputs); + * @param cfg_out array of output format configurations with as many + * members as the filters has outputs (NULL when there + * are no outputs); + */ + int (*query_func2)(const AVFilterContext *, + struct AVFilterFormatsConfig **cfg_in, + struct AVFilterFormatsConfig **cfg_out); /** * A pointer to an array of admissible pixel formats delimited * by AV_PIX_FMT_NONE. The generic code will use this list @@ -492,41 +542,6 @@ struct AVFilterContext { int extra_hw_frames; }; -/** - * Lists of formats / etc. supported by an end of a link. - * - * This structure is directly part of AVFilterLink, in two copies: - * one for the source filter, one for the destination filter. - - * These lists are used for negotiating the format to actually be used, - * which will be loaded into the format and channel_layout members of - * AVFilterLink, when chosen. - */ -typedef struct AVFilterFormatsConfig { - - /** - * List of supported formats (pixel or sample). - */ - AVFilterFormats *formats; - - /** - * Lists of supported sample rates, only for audio. - */ - AVFilterFormats *samplerates; - - /** - * Lists of supported channel layouts, only for audio. - */ - AVFilterChannelLayouts *channel_layouts; - - /** - * Lists of supported YUV color metadata, only for YUV video. - */ - AVFilterFormats *color_spaces; ///< AVColorSpace - AVFilterFormats *color_ranges; ///< AVColorRange - -} AVFilterFormatsConfig; - /** * A link between two filters. This contains pointers to the source and * destination filters between which this link exists, and the indexes of diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 68e392b826..215e2e7d6e 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -352,6 +352,49 @@ static int filter_query_formats(AVFilterContext *ctx) ctx->name, av_err2str(ret)); return ret; } + } else if (ctx->filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC2) { + AVFilterFormatsConfig *cfg_in_stack[64], *cfg_out_stack[64]; + AVFilterFormatsConfig **cfg_in_dyn = NULL, **cfg_out_dyn = NULL; + AVFilterFormatsConfig **cfg_in, **cfg_out; + + if (ctx->nb_inputs > FF_ARRAY_ELEMS(cfg_in_stack)) { + cfg_in_dyn = av_malloc_array(ctx->nb_inputs, sizeof(*cfg_in_dyn)); + if (!cfg_in_dyn) + return AVERROR(ENOMEM); + cfg_in = cfg_in_dyn; + } else + cfg_in = ctx->nb_inputs ? cfg_in_stack : NULL; + + for (unsigned i = 0; i < ctx->nb_inputs; i++) { + AVFilterLink *l = ctx->inputs[i]; + cfg_in[i] = &l->outcfg; + } + + if (ctx->nb_outputs > FF_ARRAY_ELEMS(cfg_out_stack)) { + cfg_out_dyn = av_malloc_array(ctx->nb_outputs, sizeof(*cfg_out_dyn)); + if (!cfg_out_dyn) + return AVERROR(ENOMEM); + cfg_out = cfg_out_dyn; + } else + cfg_out = ctx->nb_outputs ? cfg_out_stack : NULL; + + for (unsigned i = 0; i < ctx->nb_outputs; i++) { + AVFilterLink *l = ctx->outputs[i]; + cfg_out[i] = &l->incfg; + } + + ret = ctx->filter->formats.query_func2(ctx, cfg_in, cfg_out); + av_freep(&cfg_in_dyn); + av_freep(&cfg_out_dyn); + if (ret < 0) { + if (ret != AVERROR(EAGAIN)) + av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n", + ctx->name, av_err2str(ret)); + return ret; + } + } + + if (ctx->filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC) { ret = filter_check_formats(ctx); if (ret < 0) diff --git a/libavfilter/filters.h b/libavfilter/filters.h index 0053ad4303..fdc7a95cee 100644 --- a/libavfilter/filters.h +++ b/libavfilter/filters.h @@ -226,6 +226,7 @@ enum FilterFormatsState { */ FF_FILTER_FORMATS_PASSTHROUGH = 0, FF_FILTER_FORMATS_QUERY_FUNC, ///< formats.query active. + FF_FILTER_FORMATS_QUERY_FUNC2, ///< formats.query_func2 active. FF_FILTER_FORMATS_PIXFMT_LIST, ///< formats.pixels_list active. FF_FILTER_FORMATS_SAMPLEFMTS_LIST, ///< formats.samples_list active. FF_FILTER_FORMATS_SINGLE_PIXFMT, ///< formats.pix_fmt active @@ -235,6 +236,9 @@ enum FilterFormatsState { #define FILTER_QUERY_FUNC(func) \ .formats.query_func = func, \ .formats_state = FF_FILTER_FORMATS_QUERY_FUNC +#define FILTER_QUERY_FUNC2(func) \ + .formats.query_func2 = func, \ + .formats_state = FF_FILTER_FORMATS_QUERY_FUNC2 #define FILTER_PIXFMTS_ARRAY(array) \ .formats.pixels_list = array, \ .formats_state = FF_FILTER_FORMATS_PIXFMT_LIST diff --git a/libavfilter/formats.c b/libavfilter/formats.c index eabc3ec946..e22d400ab9 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -876,6 +876,153 @@ int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts) return ff_set_common_formats(ctx, ff_make_format_list(fmts)); } +#define SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, fmts, media_type, \ + ref_fn, unref_fn) \ + if (!fmts) \ + return AVERROR(ENOMEM); \ + \ + for (unsigned i = 0; i < ctx->nb_inputs; i++) { \ + AVFilterLink *const link = ctx->inputs[i]; \ + if (!cfg_in[i]->fmts && \ + (media_type == AVMEDIA_TYPE_UNKNOWN || \ + link->type == media_type)) { \ + int ret = ref_fn(fmts, &cfg_in[i]->fmts); \ + if (ret < 0) { \ + return ret; \ + } \ + } \ + } \ + for (unsigned i = 0; i < ctx->nb_outputs; i++) { \ + AVFilterLink *const link = ctx->outputs[i]; \ + if (!cfg_out[i]->fmts && \ + (media_type == AVMEDIA_TYPE_UNKNOWN || \ + link->type == media_type)) { \ + int ret = ref_fn(fmts, &cfg_out[i]->fmts); \ + if (ret < 0) { \ + return ret; \ + } \ + } \ + } \ + \ + if (!fmts->refcount) \ + unref_fn(&fmts); \ + \ + return 0; + +int ff_set_common_channel_layouts2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterChannelLayouts *channel_layouts) +{ + SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, channel_layouts, AVMEDIA_TYPE_AUDIO, + ff_channel_layouts_ref, ff_channel_layouts_unref); +} + +int ff_set_common_channel_layouts_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const AVChannelLayout *fmts) +{ + return ff_set_common_channel_layouts2(ctx, cfg_in, cfg_out, ff_make_channel_layout_list(fmts)); +} + +int ff_set_common_all_channel_counts2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out) +{ + return ff_set_common_channel_layouts2(ctx, cfg_in, cfg_out, ff_all_channel_counts()); +} + +int ff_set_common_samplerates2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterFormats *samplerates) +{ + SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, samplerates, AVMEDIA_TYPE_AUDIO, + ff_formats_ref, ff_formats_unref); +} + +int ff_set_common_samplerates_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const int *samplerates) +{ + return ff_set_common_samplerates2(ctx, cfg_in, cfg_out, ff_make_format_list(samplerates)); +} + +int ff_set_common_all_samplerates2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out) +{ + return ff_set_common_samplerates2(ctx, cfg_in, cfg_out, ff_all_samplerates()); +} + +int ff_set_common_color_spaces2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterFormats *color_spaces) +{ + SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, color_spaces, AVMEDIA_TYPE_VIDEO, + ff_formats_ref, ff_formats_unref); +} + +int ff_set_common_color_spaces_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const int *color_ranges) +{ + return ff_set_common_color_spaces2(ctx, cfg_in, cfg_out, ff_make_format_list(color_ranges)); +} + +int ff_set_common_all_color_spaces2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out) +{ + return ff_set_common_color_spaces2(ctx, cfg_in, cfg_out, ff_all_color_spaces()); +} + +int ff_set_common_color_ranges2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterFormats *color_ranges) +{ + SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, color_ranges, AVMEDIA_TYPE_VIDEO, + ff_formats_ref, ff_formats_unref); +} + +int ff_set_common_color_ranges_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const int *color_ranges) +{ + return ff_set_common_color_ranges2(ctx, cfg_in, cfg_out, ff_make_format_list(color_ranges)); +} + +int ff_set_common_all_color_ranges2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out) +{ + return ff_set_common_color_ranges2(ctx, cfg_in, cfg_out, ff_all_color_ranges()); +} + +int ff_set_common_formats2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterFormats *formats) +{ + SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, formats, AVMEDIA_TYPE_UNKNOWN, + ff_formats_ref, ff_formats_unref); +} + +int ff_set_common_formats_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const int *fmts) +{ + return ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_make_format_list(fmts)); +} + + int ff_default_query_formats(AVFilterContext *ctx) { const AVFilter *const f = ctx->filter; @@ -905,6 +1052,7 @@ int ff_default_query_formats(AVFilterContext *ctx) /* Intended fallthrough */ case FF_FILTER_FORMATS_PASSTHROUGH: case FF_FILTER_FORMATS_QUERY_FUNC: + case FF_FILTER_FORMATS_QUERY_FUNC2: type = AVMEDIA_TYPE_UNKNOWN; formats = ff_all_formats(ctx->nb_inputs ? ctx->inputs [0]->type : ctx->nb_outputs ? ctx->outputs[0]->type : diff --git a/libavfilter/formats.h b/libavfilter/formats.h index 82b3af4be1..380e9dfd00 100644 --- a/libavfilter/formats.h +++ b/libavfilter/formats.h @@ -225,6 +225,90 @@ int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); av_warn_unused_result int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts); +/** + * Helpers for query_formats2() which set all free audio links to the same list + * of channel layouts/sample rates. If there are no links hooked to this list, + * the list is freed. + */ +av_warn_unused_result +int ff_set_common_channel_layouts2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterChannelLayouts *channel_layouts); + +av_warn_unused_result +int ff_set_common_channel_layouts_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const AVChannelLayout *fmts); +av_warn_unused_result +int ff_set_common_all_channel_counts2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out); + +av_warn_unused_result +int ff_set_common_samplerates2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterFormats *samplerates); + +av_warn_unused_result +int ff_set_common_samplerates_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const int *samplerates); + +av_warn_unused_result +int ff_set_common_all_samplerates2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out); + +av_warn_unused_result +int ff_set_common_color_spaces2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterFormats *color_spaces); + +av_warn_unused_result +int ff_set_common_color_spaces_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const int *color_ranges); + +av_warn_unused_result +int ff_set_common_all_color_spaces2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out); + +av_warn_unused_result +int ff_set_common_color_ranges2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterFormats *color_ranges); + +av_warn_unused_result +int ff_set_common_color_ranges_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const int *color_ranges); + +av_warn_unused_result +int ff_set_common_all_color_ranges2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out); + +av_warn_unused_result +int ff_set_common_formats2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + AVFilterFormats *formats); + +av_warn_unused_result +int ff_set_common_formats_from_list2(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out, + const int *fmts); + av_warn_unused_result int ff_add_channel_layout(AVFilterChannelLayouts **l, const AVChannelLayout *channel_layout); diff --git a/libavfilter/tests/filtfmts.c b/libavfilter/tests/filtfmts.c index bc8c65c0ad..4ef6968826 100644 --- a/libavfilter/tests/filtfmts.c +++ b/libavfilter/tests/filtfmts.c @@ -143,7 +143,24 @@ int main(int argc, char **argv) if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC) ret = filter->formats.query_func(filter_ctx); - else + else if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC2) { + AVFilterFormatsConfig **cfg_in = NULL, **cfg_out = NULL; + + if (filter_ctx->nb_inputs) { + cfg_in = av_malloc_array(filter_ctx->nb_inputs, sizeof(*cfg_in)); + for (unsigned i = 0; i < filter_ctx->nb_inputs; i++) + cfg_in[i] = &filter_ctx->inputs[i]->outcfg; + } + if (filter_ctx->nb_outputs) { + cfg_out = av_malloc_array(filter_ctx->nb_outputs, sizeof(*cfg_out)); + for (unsigned i = 0; i < filter_ctx->nb_outputs; i++) + cfg_out[i] = &filter_ctx->outputs[i]->incfg; + } + + ret = filter->formats.query_func2(filter_ctx, cfg_in, cfg_out); + av_freep(&cfg_in); + av_freep(&cfg_out); + } else ret = ff_default_query_formats(filter_ctx); print_formats(filter_ctx);