From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 982844BC34 for ; Wed, 22 Jan 2025 02:55:21 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4190468B870; Wed, 22 Jan 2025 04:54:33 +0200 (EET) Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8464F68B875 for ; Wed, 22 Jan 2025 04:54:26 +0200 (EET) Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-21669fd5c7cso114308955ad.3 for ; Tue, 21 Jan 2025 18:54:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1737514464; x=1738119264; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=pp+VJo8RF+4bOzdZYtWjBT7hv2wRgUsh+8XaNUAZM2A=; b=h7UE1VKH0uC92gr/xPYnufpr7PZdz3IqPD2jl9jjkvAQa0vnpZrTaVTSg4oHJLxN6X Un5awciEo6Ur0l8rsy4pRlHqJwzawzLb95ht0h2t+f9Zmju19OjdXuMxAERBK6qzxgIp d/vSorVcyL89BNihiUW10/BgBihqRRIAlw8/KHnigokvfdhtH/5cPoup4rc6OXFQsKt4 TPJdpF1miT00GgxehJ0+zAKr/1Mygrutd+8/mCVIA5X76ue2BQENl2nugAUwLAKFeMj4 C6QJW4XYxqPdJTyc1xyGnKmr1XEIqChePA31c1xneTz5MSj+DtpZlCh+xxEjnvcuORC8 nFdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737514464; x=1738119264; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pp+VJo8RF+4bOzdZYtWjBT7hv2wRgUsh+8XaNUAZM2A=; b=cmOeaxLXf82ng8xJO/vx4lSmy9RtAmqUzKPcNzhOB4xQs79OsdwIP2+FDwjUpw2CEx RPdU8St/9PFxX5BOYdRtcgzStrLKMcts5g8E06PSOiNqWLqPhk5oB5y3pqj+Nz3vqnnA vuvS5IFvKRFKt3kxYYOXW9g0Mw/kU+EJltSyzUeGht1Bw55D1fNCYp15PSmvsJRo5vLS yV1Jj7Vohb5qn0RRtoHRhPL9yJ6LgBtK5P522NBaag+3VPLxEXPtd/EkewvtDLbqVXRe 8Gu2ZjItv9/uWTKVlmRdRqOM8ttegLtqrQE4w/QnNlvoRiTnZlDcH5pdIxoVGFjwzdJd ccLQ== X-Gm-Message-State: AOJu0YyXYosCwTWDeru/XGIzXDNKTWi8yyNNVVWLY06FKNKQmO8z/1C3 f69pJYmM3M7ZW/O5IGtG0Ujj2+3+6dIPDlYGIIRMQtrLa9Mxt1w1oCyC+Q== X-Gm-Gg: ASbGncuR4ADmp8w8OA7XEbCtyMpPbwDT/mOjYnhR1eOdQF7m98uwA6FyALx+8bOey8d QxVn06ncp7iJgLNzvQWQmfV9rgZ6jsXeHjFHW1aKdqbwqs4vPP3w92TOH5WiweTIHQCSQd1vfSw d5iuHObOr5WEhYuytm3pmjxDIroa+TVBkeH/Z23waL2jsGQS3FU92hzVI8/2c476sqgKiYGFLbe OjPSJh8CWfcuduawWzZ8WEeNaKp4YArO+WTmHVYJFMA5h5/tLMGcOj+m4boH40Gca1pME/rmMpZ wbKZ8CnUNQ== X-Google-Smtp-Source: AGHT+IGOBCElkUeIn5sAzsBYCfN+iTcbybXfV6gSgnaf7CmAACNJvqD+na1+m5dlQvIIZ/oMETkqVw== X-Received: by 2002:a17:902:ea0e:b0:216:6fb5:fd83 with SMTP id d9443c01a7336-21c35563091mr292256905ad.29.1737514463811; Tue, 21 Jan 2025 18:54:23 -0800 (PST) Received: from localhost.localdomain ([2800:2121:b040:c:5b7:a27f:554b:498a]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21c2d3efb4csm84817225ad.201.2025.01.21.18.54.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jan 2025 18:54:23 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Tue, 21 Jan 2025 23:54:02 -0300 Message-ID: <20250122025403.14457-6-jamrial@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250122025403.14457-1-jamrial@gmail.com> References: <20250122025403.14457-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 6/7] avcodec/libaomenc: add support for param change frame side data 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 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Signed-off-by: James Almer --- libavcodec/libaomenc.c | 266 ++++++++++++++++++++++++----------------- 1 file changed, 159 insertions(+), 107 deletions(-) diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c index 0f7571ee7a..45d3fe862a 100644 --- a/libavcodec/libaomenc.c +++ b/libavcodec/libaomenc.c @@ -73,7 +73,10 @@ typedef struct AOMEncoderContext { AVBSFContext *bsf; DOVIContext dovi; struct aom_codec_ctx encoder; + struct aom_codec_enc_cfg enccfg; struct aom_image rawimg; + aom_codec_flags_t flags; + aom_img_fmt_t img_fmt; struct aom_fixed_buf twopass_stats; unsigned twopass_stats_size; struct FrameListData *coded_frame_list; @@ -342,9 +345,6 @@ static av_cold int codecctl_intp(AVCodecContext *avctx, int width = -30; int res; - snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]); - av_log(avctx, AV_LOG_DEBUG, " %*s%d\n", width, buf, *ptr); - res = aom_codec_control(&ctx->encoder, id, ptr); if (res != AOM_CODEC_OK) { snprintf(buf, sizeof(buf), "Failed to set %s codec control", @@ -353,6 +353,9 @@ static av_cold int codecctl_intp(AVCodecContext *avctx, return AVERROR(EINVAL); } + snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]); + av_log(avctx, AV_LOG_DEBUG, " %*s%d\n", width, buf, *ptr); + return 0; } #endif @@ -673,29 +676,22 @@ static int choose_tiling(AVCodecContext *avctx, return 0; } -static av_cold int aom_init(AVCodecContext *avctx, - const struct aom_codec_iface *iface) +static av_cold int aom_config(AVCodecContext *avctx, + const struct aom_codec_iface *iface) { AOMContext *ctx = avctx->priv_data; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); - struct aom_codec_enc_cfg enccfg = { 0 }; - aom_codec_flags_t flags = - (avctx->flags & AV_CODEC_FLAG_PSNR) ? AOM_CODEC_USE_PSNR : 0; - AVCPBProperties *cpb_props; int res; - aom_img_fmt_t img_fmt; aom_codec_caps_t codec_caps = aom_codec_get_caps(iface); - av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str()); - av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config()); + ctx->flags = (avctx->flags & AV_CODEC_FLAG_PSNR) ? AOM_CODEC_USE_PSNR : 0; - if ((res = aom_codec_enc_config_default(iface, &enccfg, ctx->usage)) != AOM_CODEC_OK) { + if ((res = aom_codec_enc_config_default(iface, &ctx->enccfg, ctx->usage)) != AOM_CODEC_OK) { av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n", aom_codec_err_to_string(res)); return AVERROR(EINVAL); } - if (set_pix_fmt(avctx, codec_caps, &enccfg, &flags, &img_fmt)) + if (set_pix_fmt(avctx, codec_caps, &ctx->enccfg, &ctx->flags, &ctx->img_fmt)) return AVERROR(EINVAL); if(!avctx->bit_rate) @@ -704,39 +700,30 @@ static av_cold int aom_init(AVCodecContext *avctx, return AVERROR(EINVAL); } - dump_enc_cfg(avctx, &enccfg, AV_LOG_DEBUG); - - enccfg.g_w = avctx->width; - enccfg.g_h = avctx->height; - enccfg.g_timebase.num = avctx->time_base.num; - enccfg.g_timebase.den = avctx->time_base.den; - enccfg.g_threads = + ctx->enccfg.g_w = avctx->width; + ctx->enccfg.g_h = avctx->height; + ctx->enccfg.g_timebase.num = avctx->time_base.num; + ctx->enccfg.g_timebase.den = avctx->time_base.den; + ctx->enccfg.g_threads = FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 64); if (ctx->lag_in_frames >= 0) - enccfg.g_lag_in_frames = ctx->lag_in_frames; - - if (avctx->flags & AV_CODEC_FLAG_PASS1) - enccfg.g_pass = AOM_RC_FIRST_PASS; - else if (avctx->flags & AV_CODEC_FLAG_PASS2) - enccfg.g_pass = AOM_RC_LAST_PASS; - else - enccfg.g_pass = AOM_RC_ONE_PASS; + ctx->enccfg.g_lag_in_frames = ctx->lag_in_frames; if (avctx->rc_min_rate == avctx->rc_max_rate && avctx->rc_min_rate == avctx->bit_rate && avctx->bit_rate) { - enccfg.rc_end_usage = AOM_CBR; + ctx->enccfg.rc_end_usage = AOM_CBR; } else if (ctx->crf >= 0) { - enccfg.rc_end_usage = AOM_CQ; + ctx->enccfg.rc_end_usage = AOM_CQ; if (!avctx->bit_rate) - enccfg.rc_end_usage = AOM_Q; + ctx->enccfg.rc_end_usage = AOM_Q; } if (avctx->bit_rate) { - enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000, + ctx->enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000, AV_ROUND_NEAR_INF); - } else if (enccfg.rc_end_usage != AOM_Q) { - enccfg.rc_end_usage = AOM_Q; + } else if (ctx->enccfg.rc_end_usage != AOM_Q) { + ctx->enccfg.rc_end_usage = AOM_Q; ctx->crf = 32; av_log(avctx, AV_LOG_WARNING, "Neither bitrate nor constrained quality specified, using default CRF of %d\n", @@ -744,95 +731,65 @@ static av_cold int aom_init(AVCodecContext *avctx, } if (avctx->qmin >= 0) - enccfg.rc_min_quantizer = avctx->qmin; + ctx->enccfg.rc_min_quantizer = avctx->qmin; if (avctx->qmax >= 0) { - enccfg.rc_max_quantizer = avctx->qmax; + ctx->enccfg.rc_max_quantizer = avctx->qmax; } else if (!ctx->crf) { - enccfg.rc_max_quantizer = 0; + ctx->enccfg.rc_max_quantizer = 0; } - if (enccfg.rc_end_usage == AOM_CQ || enccfg.rc_end_usage == AOM_Q) { - if (ctx->crf < enccfg.rc_min_quantizer || ctx->crf > enccfg.rc_max_quantizer) { + if (ctx->enccfg.rc_end_usage == AOM_CQ || ctx->enccfg.rc_end_usage == AOM_Q) { + if (ctx->crf < ctx->enccfg.rc_min_quantizer || ctx->crf > ctx->enccfg.rc_max_quantizer) { av_log(avctx, AV_LOG_ERROR, "CQ level %d must be between minimum and maximum quantizer value (%d-%d)\n", - ctx->crf, enccfg.rc_min_quantizer, enccfg.rc_max_quantizer); + ctx->crf, ctx->enccfg.rc_min_quantizer, ctx->enccfg.rc_max_quantizer); return AVERROR(EINVAL); } } - enccfg.rc_dropframe_thresh = ctx->drop_threshold; + ctx->enccfg.rc_dropframe_thresh = ctx->drop_threshold; // 0-100 (0 => CBR, 100 => VBR) - enccfg.rc_2pass_vbr_bias_pct = round(avctx->qcompress * 100); + ctx->enccfg.rc_2pass_vbr_bias_pct = round(avctx->qcompress * 100); if (ctx->minsection_pct >= 0) - enccfg.rc_2pass_vbr_minsection_pct = ctx->minsection_pct; + ctx->enccfg.rc_2pass_vbr_minsection_pct = ctx->minsection_pct; else if (avctx->bit_rate) - enccfg.rc_2pass_vbr_minsection_pct = + ctx->enccfg.rc_2pass_vbr_minsection_pct = avctx->rc_min_rate * 100LL / avctx->bit_rate; if (ctx->maxsection_pct >= 0) - enccfg.rc_2pass_vbr_maxsection_pct = ctx->maxsection_pct; + ctx->enccfg.rc_2pass_vbr_maxsection_pct = ctx->maxsection_pct; else if (avctx->rc_max_rate) - enccfg.rc_2pass_vbr_maxsection_pct = + ctx->enccfg.rc_2pass_vbr_maxsection_pct = avctx->rc_max_rate * 100LL / avctx->bit_rate; if (avctx->rc_buffer_size) - enccfg.rc_buf_sz = + ctx->enccfg.rc_buf_sz = avctx->rc_buffer_size * 1000LL / avctx->bit_rate; if (avctx->rc_initial_buffer_occupancy) - enccfg.rc_buf_initial_sz = + ctx->enccfg.rc_buf_initial_sz = avctx->rc_initial_buffer_occupancy * 1000LL / avctx->bit_rate; - enccfg.rc_buf_optimal_sz = enccfg.rc_buf_sz * 5 / 6; + ctx->enccfg.rc_buf_optimal_sz = ctx->enccfg.rc_buf_sz * 5 / 6; if (ctx->rc_undershoot_pct >= 0) - enccfg.rc_undershoot_pct = ctx->rc_undershoot_pct; + ctx->enccfg.rc_undershoot_pct = ctx->rc_undershoot_pct; if (ctx->rc_overshoot_pct >= 0) - enccfg.rc_overshoot_pct = ctx->rc_overshoot_pct; + ctx->enccfg.rc_overshoot_pct = ctx->rc_overshoot_pct; // _enc_init() will balk if kf_min_dist differs from max w/AOM_KF_AUTO if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size) - enccfg.kf_min_dist = avctx->keyint_min; + ctx->enccfg.kf_min_dist = avctx->keyint_min; if (avctx->gop_size >= 0) - enccfg.kf_max_dist = avctx->gop_size; - - if (enccfg.g_pass == AOM_RC_FIRST_PASS) - enccfg.g_lag_in_frames = 0; - else if (enccfg.g_pass == AOM_RC_LAST_PASS) { - int decode_size, ret; - - if (!avctx->stats_in) { - av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n"); - return AVERROR_INVALIDDATA; - } - - ctx->twopass_stats.sz = strlen(avctx->stats_in) * 3 / 4; - ret = av_reallocp(&ctx->twopass_stats.buf, ctx->twopass_stats.sz); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, - "Stat buffer alloc (%"SIZE_SPECIFIER" bytes) failed\n", - ctx->twopass_stats.sz); - ctx->twopass_stats.sz = 0; - return ret; - } - decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in, - ctx->twopass_stats.sz); - if (decode_size < 0) { - av_log(avctx, AV_LOG_ERROR, "Stat buffer decode failed\n"); - return AVERROR_INVALIDDATA; - } - - ctx->twopass_stats.sz = decode_size; - enccfg.rc_twopass_stats_in = ctx->twopass_stats; - } + ctx->enccfg.kf_max_dist = avctx->gop_size; /* 0-3: For non-zero values the encoder increasingly optimizes for reduced * complexity playback on low powered devices at the expense of encode * quality. */ if (avctx->profile != AV_PROFILE_UNKNOWN) - enccfg.g_profile = avctx->profile; + ctx->enccfg.g_profile = avctx->profile; - enccfg.g_error_resilient = ctx->error_resilient; + ctx->enccfg.g_error_resilient = ctx->error_resilient; - res = choose_tiling(avctx, &enccfg); + res = choose_tiling(avctx, &ctx->enccfg); if (res < 0) return res; @@ -840,22 +797,22 @@ static av_cold int aom_init(AVCodecContext *avctx, // Set the maximum number of frames to 1. This will let libaom set // still_picture and reduced_still_picture_header to 1 in the Sequence // Header as required by AVIF still images. - enccfg.g_limit = 1; + ctx->enccfg.g_limit = 1; // Reduce memory usage for still images. - enccfg.g_lag_in_frames = 0; + ctx->enccfg.g_lag_in_frames = 0; // All frames will be key frames. - enccfg.kf_max_dist = 0; - enccfg.kf_mode = AOM_KF_DISABLED; + ctx->enccfg.kf_max_dist = 0; + ctx->enccfg.kf_mode = AOM_KF_DISABLED; } - /* Construct Encoder Context */ - res = aom_codec_enc_init(&ctx->encoder, iface, &enccfg, flags); - if (res != AOM_CODEC_OK) { - dump_enc_cfg(avctx, &enccfg, AV_LOG_WARNING); - log_encoder_error(avctx, "Failed to initialize encoder"); - return AVERROR(EINVAL); - } - dump_enc_cfg(avctx, &enccfg, AV_LOG_DEBUG); + return 0; +} + +static av_cold int aom_codecctl(AVCodecContext *avctx) +{ + AOMContext *ctx = avctx->priv_data; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + aom_codec_caps_t codec_caps = aom_codec_get_caps(ctx->encoder.iface); // codec control failures are currently treated only as warnings av_log(avctx, AV_LOG_DEBUG, "aom_codec_control\n"); @@ -983,20 +940,87 @@ static av_cold int aom_init(AVCodecContext *avctx, #endif // provide dummy value to initialize wrapper, values will be updated each _encode() - aom_img_wrap(&ctx->rawimg, img_fmt, avctx->width, avctx->height, 1, + aom_img_wrap(&ctx->rawimg, ctx->img_fmt, avctx->width, avctx->height, 1, (unsigned char*)1); if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) - ctx->rawimg.bit_depth = enccfg.g_bit_depth; + ctx->rawimg.bit_depth = ctx->enccfg.g_bit_depth; - cpb_props = ff_encode_add_cpb_side_data(avctx); - if (!cpb_props) - return AVERROR(ENOMEM); + return 0; +} + +static av_cold int aom_init(AVCodecContext *avctx, + const struct aom_codec_iface *iface) +{ + AOMContext *ctx = avctx->priv_data; + AVCPBProperties *cpb_props; + int res; + + av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str()); + av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config()); + + res = aom_config(avctx, iface); + if (res < 0) + return res; + + if (avctx->flags & AV_CODEC_FLAG_PASS1) + ctx->enccfg.g_pass = AOM_RC_FIRST_PASS; + else if (avctx->flags & AV_CODEC_FLAG_PASS2) + ctx->enccfg.g_pass = AOM_RC_LAST_PASS; + else + ctx->enccfg.g_pass = AOM_RC_ONE_PASS; + + if (ctx->enccfg.g_pass == AOM_RC_FIRST_PASS) + ctx->enccfg.g_lag_in_frames = 0; + else if (ctx->enccfg.g_pass == AOM_RC_LAST_PASS) { + int decode_size, ret; + + if (!avctx->stats_in) { + av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n"); + return AVERROR_INVALIDDATA; + } + + ctx->twopass_stats.sz = strlen(avctx->stats_in) * 3 / 4; + ret = av_reallocp(&ctx->twopass_stats.buf, ctx->twopass_stats.sz); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, + "Stat buffer alloc (%"SIZE_SPECIFIER" bytes) failed\n", + ctx->twopass_stats.sz); + ctx->twopass_stats.sz = 0; + return ret; + } + decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in, + ctx->twopass_stats.sz); + if (decode_size < 0) { + av_log(avctx, AV_LOG_ERROR, "Stat buffer decode failed\n"); + return AVERROR_INVALIDDATA; + } + + ctx->twopass_stats.sz = decode_size; + ctx->enccfg.rc_twopass_stats_in = ctx->twopass_stats; + } + + /* Construct Encoder Context */ + res = aom_codec_enc_init(&ctx->encoder, iface, &ctx->enccfg, ctx->flags); + if (res != AOM_CODEC_OK) { + dump_enc_cfg(avctx, &ctx->enccfg, AV_LOG_WARNING); + log_encoder_error(avctx, "Failed to initialize encoder"); + return AVERROR(EINVAL); + } + dump_enc_cfg(avctx, &ctx->enccfg, AV_LOG_DEBUG); + + res = aom_codecctl(avctx); + if (res < 0) + return res; ctx->dovi.logctx = avctx; if ((res = ff_dovi_configure(&ctx->dovi, avctx)) < 0) return res; + cpb_props = ff_encode_add_cpb_side_data(avctx); + if (!cpb_props) + return AVERROR(ENOMEM); + if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { const AVBitStreamFilter *filter = av_bsf_get_by_name("extract_extradata"); int ret; @@ -1019,8 +1043,8 @@ static av_cold int aom_init(AVCodecContext *avctx, return ret; } - if (enccfg.rc_end_usage == AOM_CBR || - enccfg.g_pass != AOM_RC_ONE_PASS) { + if (ctx->enccfg.rc_end_usage == AOM_CBR || + ctx->enccfg.g_pass != AOM_RC_ONE_PASS) { cpb_props->max_bitrate = avctx->rc_max_rate; cpb_props->min_bitrate = avctx->rc_min_rate; cpb_props->avg_bitrate = avctx->bit_rate; @@ -1464,6 +1488,32 @@ static av_cold int av1_init(AVCodecContext *avctx) return aom_init(avctx, aom_codec_av1_cx()); } +static av_cold int av1_reconf(AVCodecContext *avctx) +{ + AOMContext *ctx = avctx->priv_data; + int loglevel; + int res; + + res = aom_config(avctx, ctx->encoder.iface); + if (res < 0) + return res; + + res = aom_codec_enc_config_set(&ctx->encoder, &ctx->enccfg); + loglevel = res != AOM_CODEC_OK ? AV_LOG_WARNING : AV_LOG_DEBUG; + av_log(avctx, loglevel, "Reconfigure options:\n"); + dump_enc_cfg(avctx, &ctx->enccfg, loglevel); + if (res != AOM_CODEC_OK) { + log_encoder_error(avctx, "Failed to reconfigure encoder"); + return AVERROR(EINVAL); + } + + res = aom_codecctl(avctx); + if (res < 0) + return res; + + return 0; +} + #define OFFSET(x) offsetof(AOMContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { @@ -1567,6 +1617,7 @@ FFCodec ff_libaom_av1_encoder = { .p.id = AV_CODEC_ID_AV1, .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_ENCODER_RECON_FRAME | + AV_CODEC_CAP_PARAM_CHANGE | AV_CODEC_CAP_OTHER_THREADS, .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG, .p.profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), @@ -1574,6 +1625,7 @@ FFCodec ff_libaom_av1_encoder = { .p.wrapper_name = "libaom", .priv_data_size = sizeof(AOMContext), .init = av1_init, + .reconf = av1_reconf, FF_CODEC_ENCODE_CB(aom_encode), .close = aom_free, .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | -- 2.48.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".