From b43cd86e64db64e83b75e1b8eee1d451ca697f4a Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Mon, 8 Jul 2024 07:42:17 +0200 Subject: [PATCH] Increase frame rate precision in libaom AV1 encoder wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this change the AV1 encoder wrapper converted target frame rate from double to integer with rounding to the middle. That approach resulted in a bitrate mismatch caused by rounding error. The mismatch was especially high at low frame rates. For example, at target frame rate 1.4fps the bitrate mismatch reached 40%: out/debug/video_codec_perf_tests --gtest_also_run_disabled_tests --gtest_filter=*EncodeDecode --framerate_fps=1.4 --width=320 --height=180 --bitrate_kbps=32 --num_frames=600 ... RESULT s0t0_bitrate_mismatch_pct: DISABLED_EncodeDecode= {39.171875,0} n% After the change the mismatch reduced to ~2% in the same scenario: RESULT s0t0_bitrate_mismatch_pct: DISABLED_EncodeDecode= {-2.178125,0} n% Bug: b/337757868 Change-Id: Ia51f92b3dfdce103eed1d04cac0e084b69fa8213 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/356500 Reviewed-by: Erik Språng Commit-Queue: Sergey Silkin Cr-Commit-Position: refs/heads/main@{#42601} --- modules/video_coding/codecs/av1/libaom_av1_encoder.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index 93eeddd8b2..0fbba831fe 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -131,6 +131,7 @@ class LibaomAv1Encoder final : public VideoEncoder { aom_codec_ctx_t ctx_; aom_codec_enc_cfg_t cfg_; EncodedImageCallback* encoded_image_callback_; + double framerate_fps_; // Current target frame rate. int64_t timestamp_; const LibaomAv1EncoderInfoSettings encoder_info_override_; int max_consec_frame_drop_; @@ -179,6 +180,7 @@ LibaomAv1Encoder::LibaomAv1Encoder(const Environment& env, settings_(std::move(settings)), frame_for_encode_(nullptr), encoded_image_callback_(nullptr), + framerate_fps_(0), timestamp_(0), encoder_info_override_(env.field_trials()), max_consec_frame_drop_(GetMaxConsecutiveFrameDrop(env.field_trials())) {} @@ -658,8 +660,7 @@ int32_t LibaomAv1Encoder::Encode( return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE; } - const uint32_t duration = - kRtpTicksPerSecond / static_cast(encoder_settings_.maxFramerate); + const uint32_t duration = kRtpTicksPerSecond / framerate_fps_; timestamp_ += duration; const size_t num_spatial_layers = @@ -836,11 +837,9 @@ void LibaomAv1Encoder::SetRates(const RateControlParameters& parameters) { SetEncoderControlParameters(AV1E_SET_SVC_PARAMS, &*svc_params_); } - rates_configured_ = true; + framerate_fps_ = parameters.framerate_fps; - // Set frame rate to closest integer value. - encoder_settings_.maxFramerate = - static_cast(parameters.framerate_fps + 0.5); + rates_configured_ = true; } VideoEncoder::EncoderInfo LibaomAv1Encoder::GetEncoderInfo() const {