Account for simulcast hysteresis in padding rate calculation.
Bug: webrtc:10271
Change-Id: If0b0eb7d94fb1c892880ff4745f34c43fcdeee54
Reviewed-on: https://webrtc-review.googlesource.com/c/120661
Commit-Queue: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26527}
diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc
index 5635550..266d27f 100644
--- a/video/video_send_stream_impl.cc
+++ b/video/video_send_stream_impl.cc
@@ -89,6 +89,7 @@
// Calculate max padding bitrate for a multi layer codec.
int CalculateMaxPadBitrateBps(const std::vector<VideoStream>& streams,
+ VideoEncoderConfig::ContentType content_type,
int min_transmit_bitrate_bps,
bool pad_to_min_bitrate,
bool alr_probing) {
@@ -107,12 +108,23 @@
// probing will handle the rest of the rampup.
pad_up_to_bitrate_bps = active_streams[0].min_bitrate_bps;
} else {
- // Pad to min bitrate of the highest layer.
- pad_up_to_bitrate_bps =
- active_streams[active_streams.size() - 1].min_bitrate_bps;
- // Add target_bitrate_bps of the lower layers.
- for (size_t i = 0; i < active_streams.size() - 1; ++i)
+ // Without alr probing, pad up to start bitrate of the
+ // highest active stream.
+ const double hysteresis_factor =
+ RateControlSettings::ParseFromFieldTrials()
+ .GetSimulcastHysteresisFactor(content_type);
+ const size_t top_active_stream_idx = active_streams.size() - 1;
+ pad_up_to_bitrate_bps = std::min(
+ static_cast<int>(
+ hysteresis_factor *
+ active_streams[top_active_stream_idx].min_bitrate_bps +
+ 0.5),
+ active_streams[top_active_stream_idx].target_bitrate_bps);
+
+ // Add target_bitrate_bps of the lower active streams.
+ for (size_t i = 0; i < top_active_stream_idx; ++i) {
pad_up_to_bitrate_bps += active_streams[i].target_bitrate_bps;
+ }
}
} else if (!active_streams.empty() && pad_to_min_bitrate) {
pad_up_to_bitrate_bps = active_streams[0].min_bitrate_bps;
@@ -497,14 +509,17 @@
void VideoSendStreamImpl::OnEncoderConfigurationChanged(
std::vector<VideoStream> streams,
+ VideoEncoderConfig::ContentType content_type,
int min_transmit_bitrate_bps) {
if (!worker_queue_->IsCurrent()) {
rtc::WeakPtr<VideoSendStreamImpl> send_stream = weak_ptr_;
- worker_queue_->PostTask([send_stream, streams, min_transmit_bitrate_bps]() {
- if (send_stream)
- send_stream->OnEncoderConfigurationChanged(std::move(streams),
- min_transmit_bitrate_bps);
- });
+ worker_queue_->PostTask(
+ [send_stream, streams, content_type, min_transmit_bitrate_bps]() {
+ if (send_stream) {
+ send_stream->OnEncoderConfigurationChanged(
+ std::move(streams), content_type, min_transmit_bitrate_bps);
+ }
+ });
return;
}
RTC_DCHECK_GE(config_->rtp.ssrcs.size(), streams.size());
@@ -530,6 +545,7 @@
std::max(static_cast<uint32_t>(encoder_min_bitrate_bps_),
encoder_max_bitrate_bps_);
+ // TODO(bugs.webrtc.org/10266): Query the VideoBitrateAllocator instead.
const VideoCodecType codec_type =
PayloadStringToCodecType(config_->rtp.payload_name);
if (codec_type == kVideoCodecVP9) {
@@ -537,8 +553,8 @@
: streams[0].target_bitrate_bps;
} else {
max_padding_bitrate_ = CalculateMaxPadBitrateBps(
- streams, min_transmit_bitrate_bps, config_->suspend_below_min_bitrate,
- has_alr_probing_);
+ streams, content_type, min_transmit_bitrate_bps,
+ config_->suspend_below_min_bitrate, has_alr_probing_);
}
// Clear stats for disabled layers.