Fix EncoderBitrateAdjuster to read min bitrates from EncoderInfo

Change-Id: I118817fe9fc4d4e674268743ac7d6d2773d366de
Bug: webrtc:15496
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/320260
Reviewed-by: Michael Horowitz <mhoro@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Dan Tan <dwtan@google.com>
Cr-Commit-Position: refs/heads/main@{#40756}
This commit is contained in:
Dan Tan 2023-09-14 02:59:00 -07:00 committed by WebRTC LUCI CQ
parent 3aa951a7c6
commit 6f34843baa
3 changed files with 44 additions and 0 deletions

View File

@ -48,6 +48,7 @@ EncoderBitrateAdjuster::EncoderBitrateAdjuster(const VideoCodec& codec_settings)
.BitrateAdjusterCanUseNetworkHeadroom()),
frames_since_layout_change_(0),
min_bitrates_bps_{},
frame_size_pixels_{},
codec_(codec_settings.codecType),
codec_mode_(codec_settings.mode) {
// TODO(https://crbug.com/webrtc/14891): If we want to support simulcast of
@ -60,6 +61,8 @@ EncoderBitrateAdjuster::EncoderBitrateAdjuster(const VideoCodec& codec_settings)
min_bitrates_bps_[si] =
std::max(codec_settings.minBitrate * 1000,
codec_settings.spatialLayers[si].minBitrate * 1000);
frame_size_pixels_[si] = codec_settings.spatialLayers[si].width *
codec_settings.spatialLayers[si].height;
}
}
} else {
@ -68,6 +71,8 @@ EncoderBitrateAdjuster::EncoderBitrateAdjuster(const VideoCodec& codec_settings)
min_bitrates_bps_[si] =
std::max(codec_settings.minBitrate * 1000,
codec_settings.simulcastStream[si].minBitrate * 1000);
frame_size_pixels_[si] = codec_settings.spatialLayers[si].width *
codec_settings.spatialLayers[si].height;
}
}
}
@ -314,6 +319,12 @@ void EncoderBitrateAdjuster::OnEncoderInfo(
// Copy allocation into current state and re-allocate.
for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
current_fps_allocation_[si] = encoder_info.fps_allocation[si];
if (frame_size_pixels_[si] > 0) {
if (auto bwlimit = encoder_info.GetEncoderBitrateLimitsForResolution(
frame_size_pixels_[si])) {
min_bitrates_bps_[si] = bwlimit->min_bitrate_bps;
}
}
}
// Trigger re-allocation so that overshoot detectors have correct targets.

View File

@ -74,6 +74,9 @@ class EncoderBitrateAdjuster {
// Minimum bitrates allowed, per spatial layer.
uint32_t min_bitrates_bps_[kMaxSpatialLayers];
// Size in pixels of each spatial layer.
uint32_t frame_size_pixels_[kMaxSpatialLayers];
// Codec type used for encoding.
VideoCodecType codec_;

View File

@ -67,6 +67,8 @@ class EncoderBitrateAdjusterTest : public ::testing::Test {
codec_.simulcastStream[si].maxBitrate = 300 * (1 << si);
codec_.simulcastStream[si].active = true;
codec_.simulcastStream[si].numberOfTemporalLayers = num_temporal_layers;
codec_.spatialLayers[si].width = 320 * (1<<si);
codec_.spatialLayers[si].height = 180 * (1<<si);
}
}
@ -502,5 +504,33 @@ TEST_F(EncoderBitrateAdjusterTest, DontExceedMediaRateEvenWithHeadroom) {
}
}
TEST_F(EncoderBitrateAdjusterTest, HonorMinBitrateSettingFromEncoderInfo) {
// Single layer, well behaved encoder.
const int high_bitrate = 20000;
const int a_lower_min_bitrate = 12000;
current_input_allocation_.SetBitrate(0, 0, high_bitrate);
VideoBitrateAllocation expected_input_allocation;
expected_input_allocation.SetBitrate(0, 0, a_lower_min_bitrate);
target_framerate_fps_ = 30;
SetUpAdjuster(1, 1, false);
auto new_resolution_limit = VideoEncoder::ResolutionBitrateLimits(
codec_.spatialLayers[0].width * codec_.spatialLayers[0].height, 15000,
a_lower_min_bitrate, 2000000);
encoder_info_.resolution_bitrate_limits.push_back(new_resolution_limit);
adjuster_->OnEncoderInfo(encoder_info_);
InsertFrames({{2.0}}, kWindowSizeMs);
current_adjusted_allocation_ =
adjuster_->AdjustRateAllocation(VideoEncoder::RateControlParameters(
current_input_allocation_, target_framerate_fps_));
// Adjusted allocation near input. Allow 1% error margin due to rounding
// errors etc.
ExpectNear(expected_input_allocation, current_adjusted_allocation_, 0.01);
}
} // namespace test
} // namespace webrtc