From 216cce5f49fb33a26aba6ddfbad24697d91973dc Mon Sep 17 00:00:00 2001 From: Johannes Kron Date: Wed, 26 Jun 2024 19:22:19 +0200 Subject: [PATCH] Add minimum_qp to VideoEncoder::EncoderInfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The minimum QP field will be used to signal what the QP value will be once the encoder reach its target video quality. This will be used in the generalized QP convergence detection. Bug: chromium:328598314 Change-Id: I82299cd921e3c091e651218d1e3f337875176567 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/355701 Reviewed-by: Erik Språng Commit-Queue: Johannes Kron Reviewed-by: Markus Handell Cr-Commit-Position: refs/heads/main@{#42559} --- api/video_codecs/video_encoder.h | 5 +++++ modules/video_coding/codecs/av1/libaom_av1_encoder.cc | 4 ++++ modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc | 5 +++++ modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/api/video_codecs/video_encoder.h b/api/video_codecs/video_encoder.h index 49ea6e1c0e..1fcde28fdc 100644 --- a/api/video_codecs/video_encoder.h +++ b/api/video_codecs/video_encoder.h @@ -259,6 +259,11 @@ class RTC_EXPORT VideoEncoder { // Indicates whether or not QP value encoder writes into frame/slice/tile // header can be interpreted as average frame/slice/tile QP. absl::optional is_qp_trusted; + + // The minimum QP that the encoder is expected to use with the current + // configuration. This may be used to determine if the encoder has reached + // its target video quality for static screenshare content. + absl::optional minimum_qp; }; struct RTC_EXPORT RateControlParameters { diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index a42c08e520..93eeddd8b2 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -59,6 +59,8 @@ namespace { // Encoder configuration parameters constexpr int kQpMin = 10; +constexpr int kAv1ScreenshareMinimumQindex = + 40; // Min qindex corresponding to kQpMin. constexpr int kUsageProfile = AOM_USAGE_REALTIME; constexpr int kMinQindex = 145; // Min qindex threshold for QP scaling. constexpr int kMaxQindex = 205; // Max qindex threshold for QP scaling. @@ -866,6 +868,8 @@ VideoEncoder::EncoderInfo LibaomAv1Encoder::GetEncoderInfo() const { info.resolution_bitrate_limits = encoder_info_override_.resolution_bitrate_limits(); } + + info.minimum_qp = kAv1ScreenshareMinimumQindex; return info; } diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index 6dcdbfd2c8..3d2d4821b2 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -68,6 +68,7 @@ constexpr char kVp8ForcePartitionResilience[] = // bitstream range of [0, 127] and not the user-level range of [0,63]. constexpr int kLowVp8QpThreshold = 29; constexpr int kHighVp8QpThreshold = 95; +constexpr int kVp8ScreenshareMinimumQp = 15; constexpr int kTokenPartitions = VP8_ONE_TOKENPARTITION; constexpr uint32_t kVp832ByteAlign = 32u; @@ -1348,6 +1349,10 @@ VideoEncoder::EncoderInfo LibvpxVp8Encoder::GetEncoderInfo() const { } } } + + if (codec_.mode == VideoCodecMode::kScreensharing) { + info.minimum_qp = kVp8ScreenshareMinimumQp; + } } return info; diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc index cef37a9300..b9a9ffe9a9 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc @@ -1825,6 +1825,10 @@ VideoEncoder::EncoderInfo LibvpxVp9Encoder::GetEncoderInfo() const { info.preferred_pixel_formats = {VideoFrameBuffer::Type::kI420, VideoFrameBuffer::Type::kNV12}; } + + if (codec_.mode == VideoCodecMode::kScreensharing) { + info.minimum_qp = variable_framerate_screenshare::kMinQP; + } } if (!encoder_info_override_.resolution_bitrate_limits().empty()) { info.resolution_bitrate_limits =