From patchwork Tue Jun 11 20:22:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chun-Min Chang X-Patchwork-Id: 49809 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:c504:0:b0:460:55fa:d5ed with SMTP id c4csp62989vqq; Tue, 11 Jun 2024 13:22:33 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCV3mpXVh4vo3/qpH1t3OxCu2WbsoZdXUiZ4Z6vKag7xlE82Frgk3+0KaIrHx/6T3/g1eZ3L4pKzyFIB1G2zsEX9E/d+gqSlkiEGGA== X-Google-Smtp-Source: AGHT+IE2NC8e5bLNpSf/7T8Fl/IqK8nXpfRJ+nZXvq1YsbcR8vBmnHXGhFQQUGhYWRZCOcDWKXm5 X-Received: by 2002:a05:6512:3292:b0:52b:9223:be33 with SMTP id 2adb3069b0e04-52c992c4560mr134692e87.16.1718137352787; Tue, 11 Jun 2024 13:22:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1718137352; cv=none; d=google.com; s=arc-20160816; b=i4Q94FRVUX3Ge1qqPEknR/0zHmiyw20rIVVizhzA0bxpO9UcTVuGBlZilBIJawkqLe xcpWXCgfAGq/eGnP7QyKBoPB+Zm2zrHBaHI1BT6t8s+T2PHnsjPkJP+3YN3xr5Ccfjkp JkaFgA9QroTgYxrcUqvMA0wE1icUdVBjQiPCkNWXM1O8RuAajAKPPxbI2pUcBVzYduzj lWiOsyt7pTOu13Yht3IywdcnNqWSu+07VhJh3Qr+5vdB40C5DmoDUYu6FnfB3IVgvWEp 3nL1XtxTEIus9Vw2Axw0qLGy/zE55D3gUpJwItZAgTBVwaQ21RJg8lZ6MoPP6gnipfOJ ctDw== 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:content-language:to:from:user-agent:mime-version :date:message-id:dkim-signature:delivered-to; bh=beccGwzLvVMbIhzDhRIASQNDa/mmuxJWOWYtlbQf0D8=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=SuVfb15VGoJ1gfoDhsU7WSyWSBFU27fPsafLlOjLGDwfrdmXEQeGnium6g9rU4YBHU d1OJAHEsIcQl7zBbwvC7sJU/v8X7+ASfdZeOZcuhMrUjSTjGQqM26wCyIUXC/VxVzHEE nepluvdYdOmO+Z2MUC1OQWj++RBJyQT1i4IOAMpMd5q4oMRJZJpz5y0kCHQyaWk5GR3f a8YkxtCT6OXsuoYvukCBOPjrz0i1pOAudcnLV/kSiAjga0xN3q55W7zFbji4zpfE/30G 6eEat0EtPq6PuA3xBGz5WDp9uA728vBhnpH5qcQweRIi6pQfW62xuBZN8tTJjT1s/ToN TlpQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=NHiltxq8; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 2adb3069b0e04-52c82bd152asi2051708e87.87.2024.06.11.13.22.32; Tue, 11 Jun 2024 13:22:32 -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=@gmail.com header.s=20230601 header.b=NHiltxq8; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 93F3168D8D0; Tue, 11 Jun 2024 23:22:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8101668A62B for ; Tue, 11 Jun 2024 23:22:21 +0300 (EEST) Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-6f8ec7e054dso1184072b3a.2 for ; Tue, 11 Jun 2024 13:22:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718137339; x=1718742139; darn=ffmpeg.org; h=content-transfer-encoding:content-language:to:subject:from :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=ggBisGVgncQjJfgxcKi1Rzru22xfozOS1xqbQc7cahE=; b=NHiltxq8Ofg4WHml+ZNmOg0Y8upTcOLsyAjKUn+kmBKvWEBzwgIlrjYrRs1cVD+XiR /mTiTHFLVt6jFYmbs0Xau3j+Da0sbHX8A3zVY0ZCjOHSHVnZEiJdGI366eJhZpadKtha A0qgOokfhZzYdVyVWF7qjaS1zgD4zCH9wrTi63vL7QaKeZQjdfgAHEDU5PEt3ORKUagw dtPzM19BqQGgJMf6k+J4z3jsTqdbcRY6c6imgIbvlgoWL5/uqzWRb+l84UaAdN77O4dy q/pVI6GnX1uG/j1xPl03ASMVKr3WWo+SO5RmGLWhc4otTwHzWxYtLfnxBpFCk6KsZKN5 Hkng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718137339; x=1718742139; h=content-transfer-encoding:content-language:to:subject:from :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ggBisGVgncQjJfgxcKi1Rzru22xfozOS1xqbQc7cahE=; b=LFITtx5k5djDbMf1Jx+U6UoPrYJPIUWA/kfcUuMc9mxAeSresyvmr+mrZTCt5faikW HbZWR/l1bduWUYj3OF5zxBEiiHC+3rFMoMSZMOSxJtijoe/K5DyzLWVyCqtg6DuNX7uR jZNo0npP/QXTpQ3TZE8V0ItU9WWf1K0tAbq95MMXhehQdhgf3DqxdpcGiUcmi82ZOpXy /rV3Hlu7HQNtwM7aI2S7svbKugFlvtjESUngkxwK/32gM9DnafRImlNlHwC27VGdnqty NTdE0JTqB4gWPzPFvZtXS2A5cG4LEEBVi9ofAw5Py3WrFvu+NpBiDHCQ7nq323O7APGB yl+g== X-Gm-Message-State: AOJu0YzGuBmqqOed+LS841CV82VeQiMfjVT/9NIP9xuiiaG+/qbMlm2c N0t4iNstKNScOFFyZ3qHzjgV28dgwdJWXWPK3lTCFt2Vt2nd5sbrCOlz5kVV X-Received: by 2002:a05:6a21:6da4:b0:1b5:4c70:d682 with SMTP id adf61e73a8af0-1b8a9b75eb8mr79862637.6.1718137338034; Tue, 11 Jun 2024 13:22:18 -0700 (PDT) Received: from ?IPV6:2001:569:7cb3:8e00:1b9c:c3cc:1f2d:aa24? ([2001:569:7cb3:8e00:1b9c:c3cc:1f2d:aa24]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7042f37f33asm5473904b3a.3.2024.06.11.13.22.17 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 11 Jun 2024 13:22:17 -0700 (PDT) Message-ID: <6f46f156-5a95-4905-8028-bac6b17f872e@gmail.com> Date: Tue, 11 Jun 2024 13:22:16 -0700 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: Chun-Min Chang To: ffmpeg-devel@ffmpeg.org Content-Language: en-US Subject: [FFmpeg-devel] [PATCH] Allow enabling SVC in libaomenc 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: aGd+8MMd6nvU This patch updates libaomenc.c to accept parameters for SVC (Scalable Video Coding) settings via the FFmpeg API `av_opt_set`. The SVC configuration is applied based on the provided parameters. As libaom's SVC functionality only operates with constant bitrate encoding [1], these parameters will only take effect when the bitrate is set to constant. [1] https://aomedia.googlesource.com/aom/+/a7ef80c44bfb34b08254194b1ab72d4e93ff4b07/av1/encoder/svc_layercontext.h#115 Signed-off-by: Chun-Min Chang --- libavcodec/libaomenc.c | 75 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) int enable_diff_wtd_comp; int enable_dist_wtd_comp; int enable_dual_filter; + AVDictionary *svc_parameters; AVDictionary *aom_params; } AOMContext; @@ -201,6 +203,7 @@ static const char *const ctlidstr[] = { [AV1E_GET_TARGET_SEQ_LEVEL_IDX] = "AV1E_GET_TARGET_SEQ_LEVEL_IDX", #endif [AV1_GET_NEW_FRAME_IMAGE] = "AV1_GET_NEW_FRAME_IMAGE", + [AV1E_SET_SVC_PARAMS] = "AV1E_SET_SVC_PARAMS", }; static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc) @@ -382,6 +385,31 @@ static av_cold int codecctl_imgp(AVCodecContext *avctx, return 0; } +static av_cold int codecctl_svcp(AVCodecContext *avctx, +#ifdef UENUM1BYTE + aome_enc_control_id id, +#else + enum aome_enc_control_id id, +#endif + aom_svc_params_t *svc_params) +{ + AOMContext *ctx = avctx->priv_data; + char buf[80]; + int res; + + snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]); + + res = aom_codec_control(&ctx->encoder, id, svc_params); + if (res != AOM_CODEC_OK) { + snprintf(buf, sizeof(buf), "Failed to get %s codec control", + ctlidstr[id]); + log_encoder_error(avctx, buf); + return AVERROR(EINVAL); + } + + return 0; +} + static av_cold int aom_free(AVCodecContext *avctx) { AOMContext *ctx = avctx->priv_data; @@ -673,6 +701,18 @@ static int choose_tiling(AVCodecContext *avctx, return 0; } +static void aom_svc_parse_int_array(int *dest, char *value, int max_entries) +{ + int dest_idx = 0; + char *saveptr = NULL; + char *token = av_strtok(value, ",", &saveptr); + + while (token && dest_idx < max_entries) { + dest[dest_idx++] = strtoul(token, NULL, 10); + token = av_strtok(NULL, ",", &saveptr); + } +} + static av_cold int aom_init(AVCodecContext *avctx, const struct aom_codec_iface *iface) { @@ -968,6 +1008,40 @@ static av_cold int aom_init(AVCodecContext *avctx, if (ctx->enable_intrabc >= 0) codecctl_int(avctx, AV1E_SET_ENABLE_INTRABC, ctx->enable_intrabc); + if (enccfg.rc_end_usage == AOM_CBR) { + aom_svc_params_t svc_params = {}; + svc_params.framerate_factor[0] = 1; + svc_params.number_spatial_layers = 1; + svc_params.number_temporal_layers = 1; + + const AVDictionaryEntry *en = NULL; + while ((en = av_dict_iterate(ctx->svc_parameters, en))) { + if (!strlen(en->value)) + return AVERROR(EINVAL); + + if (!strcmp(en->key, "number_spatial_layers")) + svc_params.number_spatial_layers = strtoul(en->value, NULL, 10); + else if (!strcmp(en->key, "number_temporal_layers")) + svc_params.number_temporal_layers = strtoul(en->value, NULL, 10); + else if (!strcmp(en->key, "max_quantizers")) + aom_svc_parse_int_array(svc_params.max_quantizers, en->value, AOM_MAX_LAYERS); + else if (!strcmp(en->key, "min_quantizers")) + aom_svc_parse_int_array(svc_params.min_quantizers, en->value, AOM_MAX_LAYERS); + else if (!strcmp(en->key, "scaling_factor_num")) + aom_svc_parse_int_array(svc_params.scaling_factor_num, en->value, AOM_MAX_SS_LAYERS); + else if (!strcmp(en->key, "scaling_factor_den")) + aom_svc_parse_int_array(svc_params.scaling_factor_den, en->value, AOM_MAX_SS_LAYERS); + else if (!strcmp(en->key, "layer_target_bitrate")) + aom_svc_parse_int_array(svc_params.layer_target_bitrate, en->value, AOM_MAX_LAYERS); + else if (!strcmp(en->key, "framerate_factor")) + aom_svc_parse_int_array(svc_params.framerate_factor, en->value, AOM_MAX_TS_LAYERS); + } + + res = codecctl_svcp(avctx, AV1E_SET_SVC_PARAMS, &svc_params); + if (res < 0) + return res; + } + #if AOM_ENCODER_ABI_VERSION >= 23 { const AVDictionaryEntry *en = NULL; @@ -1517,6 +1591,7 @@ static const AVOption options[] = { { "enable-masked-comp", "Enable masked compound", OFFSET(enable_masked_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, { "enable-interintra-comp", "Enable interintra compound", OFFSET(enable_interintra_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, { "enable-smooth-interintra", "Enable smooth interintra mode", OFFSET(enable_smooth_interintra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "svc-parameters", "SVC configuration using a :-separated list of key=value parameters (only applied in CBR mode)", OFFSET(svc_parameters), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE}, #if AOM_ENCODER_ABI_VERSION >= 23 { "aom-params", "Set libaom options using a :-separated list of key=value pairs", OFFSET(aom_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE }, #endif diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c index dec74ebecd..a8602a6b56 100644 --- a/libavcodec/libaomenc.c +++ b/libavcodec/libaomenc.c @@ -30,6 +30,7 @@ #include #include "libavutil/avassert.h" +#include "libavutil/avstring.h" #include "libavutil/base64.h" #include "libavutil/common.h" #include "libavutil/cpu.h" @@ -137,6 +138,7 @@ typedef struct AOMEncoderContext {