From patchwork Wed Jun 5 21:34:07 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: 49607 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9185:0:b0:460:55fa:d5ed with SMTP id s5csp38563vqg; Wed, 5 Jun 2024 14:34:21 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVali/dUi9j1nCpVqdPsMUhn9cHVmoXK8dpSMYP4X+8B9HtEV6QgkXBBPzFdQKTa9IooGmIT36uvj/L8XYhUG3G5fnMseNfhAJArg== X-Google-Smtp-Source: AGHT+IG8mR6LouL5J1jib7Wwv3NYCcPNVf8V2AMJNrVlmbbU0tGv4LPYkKTMhM4bbQvijOn8nRjJ X-Received: by 2002:a17:906:2bd5:b0:a6b:da7d:8c99 with SMTP id a640c23a62f3a-a6bda7d8dd9mr128507766b.2.1717623261545; Wed, 05 Jun 2024 14:34:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1717623261; cv=none; d=google.com; s=arc-20160816; b=EYLyDAfFiuYXrdSVxZTPdS61kDgzciRCh+CvcF0cVeP6nnYHjd+fyywDTN30pKLMwu OoxbFy1u0xdUK/EjepttldeeFOmGwWAGSpVDU5n8eJ70rEUIOSuq8q16G1U574qUPqYo UCaB5VqTCDkKsgig/7yUoT1J5GcX03nRp89icpysSO0807GCO5yOTR7Yhanfto7xZTlW LOGTq1CepW2ONwtpq9IBAfkkwfPPU7h6AATVnlVkuzNHQcwT0wCBq6MsvHhz/RZ9Fxw7 xrgyRxUTHhJ+QMXJzXipMpayJVJnNM4NzvlcFHh6mhFhGdCQezXcNN417sVPc4oEOrg7 hI6w== 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=hGrWQydbafOyMAv0CmKkNl/fbVISHltv+k9Ir3l0ihpX5yXNm5rLc7DVGFTV7eF/nR kEjYgBaLXLkFXzYzY72Se2bKELVg5GpsKYlHkVwK/ssDkrxbRIPMQSJCkZXyuuKFqXIS ikHPZBwmVbsKfoy2g0PleLB6gOTah21IWrf3Bn1Qhf1QJ9dlAsyQX5+5eSTmKSASdl0r Kx5q+iGfB+giqNrUucbeJVKVHfZsxOab4+Fre5FgUnQzLQh+ytg03D+uG4xY2zu8safy Wbgn3O1pJc+NWhdlANv5N40yW1MyLRJ1phrRh7l71k/2ZP0pZf1pmaBE3HcWnf2/a47l CyHA==; 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=TVsG6C+T; 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 a640c23a62f3a-a690d82a38dsi336059566b.699.2024.06.05.14.34.20; Wed, 05 Jun 2024 14:34:21 -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=TVsG6C+T; 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 7299D68D5D2; Thu, 6 Jun 2024 00:34:17 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f177.google.com (mail-pg1-f177.google.com [209.85.215.177]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A267868D334 for ; Thu, 6 Jun 2024 00:34:10 +0300 (EEST) Received: by mail-pg1-f177.google.com with SMTP id 41be03b00d2f7-6d4bf8eb8e2so185255a12.3 for ; Wed, 05 Jun 2024 14:34:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1717623248; x=1718228048; 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=TVsG6C+TVEXTSwgHCGkfGKuSwpLLBnm0q0PZ5H1kWxO53n1lX3N2KB+vHZBt/DKG0d yImBB3TwP7TIVP0wUHMXDKmwIyDYmpu4En3/obvFyA0p9eZYSumnQnEo09aqewwHHJu4 wH22U9eTjx1nL+TAufeQ7ck+T3bAPDt1hj5yDPbde1Bu39Ls8c5G2bmWcbY+q/xeD2jl I5p0+PYsCjqLEkpyfaVz5f7nDvJijLtyykdVCHxsJCWSrYhSzEyWr/cfnfb6xOFxL80i K7uwFAaXGpIdZZBmpRA1x3S4YqvmMlt5bzEk+truhzcUTceDTpOUy3Qkl7RiUwE01rul nD9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717623248; x=1718228048; 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=REKAGmoc63tyjJcog+0wG5exkLoYKG95uEFhjGym7y6pAxKxch+JTZ7//jaVjYbs70 BbHMj/Fv7vLg+qUR2aQvCFMI42vlQ4QbtZRHS1JrvV/twkdZEghyD1mR/hrYl9ty/PGJ +VwdfN2lsanN2PLP4SK93MJ/UYtrZfq7DwP+VucGM36/1xCKANH6RKY6yt+72V8RwfOG ZIG0gGrr6vOpk4Jm0+7DwCmxlKCF5VTkb7EHkUfMufUQm0RaeyoDsKxt89sC60q0Ql/I 1krpOV1fYolMNksIaDvc7XcLVaPzgD/Jta85In8vjJygapFcJLL1nJe32IejPTJIhlVC hCSQ== X-Gm-Message-State: AOJu0YxFXfma45cVfCr/dLxoZrG1Lw9mtaZh1JJ49PKvJ5j4WJDSKEt9 vSKBCzVojrlRDYybENY0qr5Mfp0Fck+wCfWa3TBXBtcRonUZiJo2nFUn5eNq6D8= X-Received: by 2002:a05:6a20:394c:b0:1af:597f:4970 with SMTP id adf61e73a8af0-1b2b6f8209fmr4068333637.24.1717623248274; Wed, 05 Jun 2024 14:34:08 -0700 (PDT) Received: from ?IPV6:2001:569:7cb3:8e00:bb7e:1736:3480:a6fc? ([2001:569:7cb3:8e00:bb7e:1736:3480:a6fc]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-70242b300ddsm9095588b3a.191.2024.06.05.14.34.07 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 05 Jun 2024 14:34:07 -0700 (PDT) Message-ID: <5e10ed20-f845-41a0-9a9c-91c1cb1972d8@gmail.com> Date: Wed, 5 Jun 2024 14:34:07 -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: NNKikkWYm1lk 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 {