From patchwork Mon Apr 8 12:57:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niklas Haas X-Patchwork-Id: 47914 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:24a8:b0:1a3:b6bb:3029 with SMTP id m40csp2455273pzd; Mon, 8 Apr 2024 06:00:30 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWJHJ2u1K7P4QkVKqT9k/7HJDeMzOiOdYRLd1OWK/FcnbfirgW+aY8YJoMHsr/3sOgkFLNi+AeagUce4G5zA2/2Rks3TMKEZKUE4A== X-Google-Smtp-Source: AGHT+IF7xxcQNTDV2KSbL2GkpuvaZuamaYx7EnbuL83ix6YRGNHL71iko/VtAbb05uCbY94SaBzW X-Received: by 2002:a17:907:7e85:b0:a51:ab81:6062 with SMTP id qb5-20020a1709077e8500b00a51ab816062mr9772598ejc.30.1712581230072; Mon, 08 Apr 2024 06:00:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1712581230; cv=none; d=google.com; s=arc-20160816; b=uxlbYvrtlnxz0bhqlrw+b42AB4tyIJ5tzGd0OjyVlqE4PXG34wWq53CGelvLVSlxgk ZnuPyj7vEnPE/gfBJ88UDTLrYLj79K+Tg57PUyKhszWE/u+u/Y2RJ58QfmQur89jtHjO ETho3xL4pNOJzxURJSWFwivSyRjJrS4du9BlVZhynUQ5FYerJFvHwS+mfIs1rVf+cC93 5DBslD7qXR0RjpA8B1JhfV/luQIjMuquxYzO4THXooScx91U+ts7AbPNIy7v+gQoPK11 UIv3Wwtphorfr1f+zCMKVinjHqlIUehMo+jhPcYbrJJgVFsOeghHiHSGdKC3AfVZ/1j8 EVog== 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=AdKKaWkCK8FnL4NczoP4ZnyGWzeUBbd15QKxI+lnZzc=; fh=xmAeKtysnShNOmkhiJmYkS30uw4Fu2hvBJ7qlIwukxQ=; b=Br12YrBrhHwXKB0/Wxiqg9sQbEatcvZviChnbDKOYR3vFEbJagn+f0ji0ksesE014k xF9Vh5bdRNTeuXYQxufKu8P6Yma76oYlOU0vnE0u6FTC14KawJEiSNbCmiLrRRlBO4k2 OilD8uAyx3tED/I2p8U0SMMgRo34v45bAy+citSL13DY9whLXdXTvjf+XyxYl9K3fKOF oVaFBoLkwUmfvD4OPqXEGlP1qkZrvyhCsny2zFvZ5wZtYSfqntYWm2cI5gs6+AikLoXs jRAFDu5qwpyFf4A27xZchSfnk0rEWs6yVlASpaVP99kOH45U8LCBqjAjv0DoMMSfnK50 V2eA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b=t9WxjURR; 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 du17-20020a17090772d100b00a51da29724bsi707785ejc.15.2024.04.08.06.00.29; Mon, 08 Apr 2024 06:00:30 -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=@haasn.xyz header.s=mail header.b=t9WxjURR; 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 6252368D1C8; Mon, 8 Apr 2024 16:00:02 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from haasn.dev (haasn.dev [78.46.187.166]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2A5EE68D16F for ; Mon, 8 Apr 2024 15:59:53 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=haasn.xyz; s=mail; t=1712581192; bh=GK8qfOa4ZRseTtkfqCkiFkelS3JEGMf7bziw9HD4dJ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=t9WxjURRjRK4oZt93a4hxEbzUZNGUvtyYjp33NKz7uM0DfXDvnFT8IatEd8aGvg/h dyCoRalMWW9ur6/h4g66bOJGdRl9l7SE6I09FqLwniY21cJLOS4BhdxBZvwdVYNDbZ OTmWLYRBTeLCjCp306yaQqRIZ4lLI5Rh9IrsxjYg= Received: from haasn.dev (unknown [10.30.0.2]) by haasn.dev (Postfix) with ESMTP id E0A5D42765; Mon, 8 Apr 2024 14:59:52 +0200 (CEST) From: Niklas Haas To: ffmpeg-devel@ffmpeg.org Date: Mon, 8 Apr 2024 14:57:06 +0200 Message-ID: <20240408125950.53472-3-ffmpeg@haasn.xyz> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240408125950.53472-1-ffmpeg@haasn.xyz> References: <20240408125950.53472-1-ffmpeg@haasn.xyz> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 02/17] avcodec: add avcodec_get_supported_config() 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: Niklas Haas Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 39dj7ylhn/s4 From: Niklas Haas This replaces the myriad of existing lists in AVCodec by a unified API call, allowing us to (ultimately) trim down the sizeof(AVCodec) quite substantially, while also making this more trivially extensible. In addition to the already covered lists, add two new entries for color space and color range, mirroring the newly added negotiable fields in libavfilter. I decided to drop the explicit length field from the API proposed by Andreas Rheinhardt, because having it in place ended up complicating both the codec side and the client side implementations, while also being strictly less flexible (it's trivial to recover a length given a terminator, but requires allocation to add a terminator given a length). Using a terminator also presents less of a porting challenge for existing users of the current API. Once the deprecation period passes for the existing public fields, the rough plan is to move the commonly used fields (such as pix_fmt/sample_fmt) into FFCodec, possibly as a union of audio and video configuration types, and then implement the rarely used fields with custom callbacks. --- doc/APIchanges | 5 +++ libavcodec/avcodec.c | 75 +++++++++++++++++++++++++++++++++++++ libavcodec/avcodec.h | 27 +++++++++++++ libavcodec/codec.h | 19 ++++++++-- libavcodec/codec_internal.h | 24 ++++++++++++ libavcodec/version.h | 4 +- 6 files changed, 148 insertions(+), 6 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 0a39b6d7ab8..fdeae67159d 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,11 @@ The last version increases of all libraries were on 2024-03-07 API changes, most recent first: +2024-04-xx - xxxxxxxxxx - lavc 59.6.100 - avcodec.h + Add avcodec_get_supported_config() and enum AVCodecConfig; deprecate + AVCodec.pix_fmts, AVCodec.sample_fmts, AVCodec.supported_framerates, + AVCodec.supported_samplerates and AVCodec.ch_layouts. + 2024-04-03 - xxxxxxxxxx - lavu 59.13.100 - pixfmt.h Add AVCOL_SPC_IPT_C2, AVCOL_SPC_YCGCO_RE and AVCOL_SPC_YCGCO_RO to map new matrix coefficients defined by H.273 v3. diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 525fe516bd2..96728546d6c 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -700,3 +700,78 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr return ff_decode_receive_frame(avctx, frame); return ff_encode_receive_frame(avctx, frame); } + +#define WRAP_CONFIG(allowed_type, field) \ + do { \ + if (codec->type != (allowed_type)) \ + return AVERROR(EINVAL); \ + *out_configs = (field); \ + return 0; \ + } while (0) + +static const enum AVColorRange color_range_jpeg[] = { + AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED +}; + +static const enum AVColorRange color_range_mpeg[] = { + AVCOL_RANGE_MPEG, AVCOL_RANGE_UNSPECIFIED +}; + +static const enum AVColorRange color_range_all[] = { + AVCOL_RANGE_MPEG, AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED +}; + +static const enum AVColorRange *color_range_table[] = { + [AVCOL_RANGE_MPEG] = color_range_mpeg, + [AVCOL_RANGE_JPEG] = color_range_jpeg, + [AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG] = color_range_all, +}; + +int ff_default_get_supported_config(const AVCodecContext *avctx, + const AVCodec *codec, + enum AVCodecConfig config, + unsigned flags, + const void **out_configs) +{ + switch (config) { +FF_DISABLE_DEPRECATION_WARNINGS + case AV_CODEC_CONFIG_PIX_FORMAT: + WRAP_CONFIG(AVMEDIA_TYPE_VIDEO, codec->pix_fmts); + case AV_CODEC_CONFIG_FRAME_RATE: + WRAP_CONFIG(AVMEDIA_TYPE_VIDEO, codec->supported_framerates); + case AV_CODEC_CONFIG_SAMPLE_RATE: + WRAP_CONFIG(AVMEDIA_TYPE_AUDIO, codec->supported_samplerates); + case AV_CODEC_CONFIG_SAMPLE_FORMAT: + WRAP_CONFIG(AVMEDIA_TYPE_AUDIO, codec->sample_fmts); + case AV_CODEC_CONFIG_CHANNEL_LAYOUT: + WRAP_CONFIG(AVMEDIA_TYPE_AUDIO, codec->ch_layouts); +FF_ENABLE_DEPRECATION_WARNINGS + + case AV_CODEC_CONFIG_COLOR_RANGE: + if (codec->type != AVMEDIA_TYPE_VIDEO) + return AVERROR(EINVAL); + *out_configs = color_range_table[ffcodec(codec)->color_ranges]; + return 0; + + case AV_CODEC_CONFIG_COLOR_SPACE: + *out_configs = NULL; + return 0; + default: + return AVERROR(EINVAL); + } +} + +int avcodec_get_supported_config(const AVCodecContext *avctx, const AVCodec *codec, + enum AVCodecConfig config, unsigned flags, + const void **out) +{ + const FFCodec *codec2; + if (!codec) + codec = avctx->codec; + codec2 = ffcodec(codec); + if (codec2->get_supported_config) { + return codec2->get_supported_config(avctx, codec, config, flags, out); + } else { + return ff_default_get_supported_config(avctx, codec, config, flags, out); + } +} diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 83dc487251c..64f31375fc6 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2690,6 +2690,33 @@ int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, enum AVPixelFormat hw_pix_fmt, AVBufferRef **out_frames_ref); +enum AVCodecConfig { + AV_CODEC_CONFIG_PIX_FORMAT, ///< AVPixelFormat, terminated by AV_PIX_FMT_NONE + AV_CODEC_CONFIG_FRAME_RATE, ///< AVRational, terminated by {0, 0} + AV_CODEC_CONFIG_SAMPLE_RATE, ///< int, terminated by 0 + AV_CODEC_CONFIG_SAMPLE_FORMAT, ///< AVSampleFormat, terminated by AV_SAMPLE_FMT_NONE + AV_CODEC_CONFIG_CHANNEL_LAYOUT, ///< AVChannelLayout, terminated by {0} + AV_CODEC_CONFIG_COLOR_RANGE, ///< AVColorRange, terminated by AVCOL_RANGE_UNSPECIFIED + AV_CODEC_CONFIG_COLOR_SPACE, ///< AVColorSpace, terminated by AVCOL_SPC_UNSPECIFIED +}; + +/** + * Retrieve a list of all supported values for a given configuration type. + * + * @param avctx An optional context to use. Values such as + * `strict_std_compliance` may affect the result. If NULL, + * default values are used. + * @param codec The codec to query, or NULL to use avctx->codec. + * @param config The configuration to query. + * @param flags Currently unused; should be set to zero. + * @param out_configs On success, set to a list of configurations, terminated + * by a config-specific terminator, or NULL if all + * possible values are supported. + */ +int avcodec_get_supported_config(const AVCodecContext *avctx, + const AVCodec *codec, enum AVCodecConfig config, + unsigned flags, const void **out_configs); + /** diff --git a/libavcodec/codec.h b/libavcodec/codec.h index 6f9b42760d7..f7541ffc42b 100644 --- a/libavcodec/codec.h +++ b/libavcodec/codec.h @@ -205,10 +205,19 @@ typedef struct AVCodec { */ int capabilities; uint8_t max_lowres; ///< maximum value for lowres supported by the decoder - const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} - const enum AVPixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 - const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 - const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 + + /** + * Deprecated codec capabilities. + */ + attribute_deprecated + const AVRational *supported_framerates; ///< @deprecated use avcodec_get_supported_config() + attribute_deprecated + const enum AVPixelFormat *pix_fmts; ///< @deprecated use avcodec_get_supported_config() + attribute_deprecated + const int *supported_samplerates; ///< @deprecated use avcodec_get_supported_config() + attribute_deprecated + const enum AVSampleFormat *sample_fmts; ///< @deprecated use avcodec_get_supported_config() + const AVClass *priv_class; ///< AVClass for the private context const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {AV_PROFILE_UNKNOWN} @@ -226,7 +235,9 @@ typedef struct AVCodec { /** * Array of supported channel layouts, terminated with a zeroed layout. + * @deprecated use avcodec_get_supported_config() */ + attribute_deprecated const AVChannelLayout *ch_layouts; } AVCodec; diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h index 2134f184094..bac3e30ba2c 100644 --- a/libavcodec/codec_internal.h +++ b/libavcodec/codec_internal.h @@ -22,6 +22,7 @@ #include #include "libavutil/attributes.h" +#include "avcodec.h" #include "codec.h" #include "config.h" @@ -270,8 +271,31 @@ typedef struct FFCodec { * List of supported codec_tags, terminated by FF_CODEC_TAGS_END. */ const uint32_t *codec_tags; + + /** + * Custom callback for avcodec_get_supported_config(). If absent, + * ff_default_get_supported_config() will be used. + */ + int (*get_supported_config)(const AVCodecContext *avctx, + const AVCodec *codec, + enum AVCodecConfig config, + unsigned flags, + const void **out_configs); } FFCodec; +/** + * Default implementation for avcodec_get_supported_config(). Will return the + * relevant fields from AVCodec if present, or NULL otherwise. + * + * For AVCODEC_CONFIG_COLOR_RANGE, the output will depend on the bitmask in + * FFCodec.color_ranges, with a value of 0 returning NULL. + */ +int ff_default_get_supported_config(const AVCodecContext *avctx, + const AVCodec *codec, + enum AVCodecConfig config, + unsigned flags, + const void **out_configs); + #if CONFIG_SMALL #define CODEC_LONG_NAME(str) .p.long_name = NULL #else diff --git a/libavcodec/version.h b/libavcodec/version.h index 84a1c02ce4a..da54f878874 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,8 +29,8 @@ #include "version_major.h" -#define LIBAVCODEC_VERSION_MINOR 5 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 6 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \