Adding direct congestion window pushback to encoders.
When CongestionWindowPushback experiment is enabled, the pacer is oblivious to the congestion window. The relation between outstanding data and the congestion window affects encoder allocations directly. Bug: None Change-Id: Iaacc1d460d44a4ff2d586934c4f9ceb067109337 Reviewed-on: https://webrtc-review.googlesource.com/74922 Commit-Queue: Ying Wang <yinwa@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23411}
This commit is contained in:
@ -348,7 +348,13 @@ rtc::Optional<DataSize> GoogCcNetworkController::MaybeUpdateCongestionWindow() {
|
||||
TimeDelta time_window =
|
||||
TimeDelta::ms(*min_feedback_rtt_ms_ + accepted_queue_ms_);
|
||||
DataSize data_window = last_bandwidth_ * time_window;
|
||||
data_window = std::max(kMinCwnd, data_window);
|
||||
if (current_data_window_) {
|
||||
data_window =
|
||||
std::max(kMinCwnd, (data_window + current_data_window_.value()) / 2);
|
||||
} else {
|
||||
data_window = std::max(kMinCwnd, data_window);
|
||||
}
|
||||
current_data_window_ = data_window;
|
||||
RTC_LOG(LS_INFO) << "Feedback rtt: " << *min_feedback_rtt_ms_
|
||||
<< " Bitrate: " << last_bandwidth_.bps();
|
||||
return data_window;
|
||||
|
@ -89,6 +89,8 @@ class GoogCcNetworkController : public NetworkControllerInterface {
|
||||
int64_t accepted_queue_ms_;
|
||||
bool previously_in_alr = false;
|
||||
|
||||
rtc::Optional<DataSize> current_data_window_;
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(GoogCcNetworkController);
|
||||
};
|
||||
|
||||
|
@ -38,8 +38,16 @@ namespace webrtc_cc {
|
||||
namespace {
|
||||
using send_side_cc_internal::PeriodicTask;
|
||||
|
||||
// When CongestionWindowPushback is enabled, the pacer is oblivious to
|
||||
// the congestion window. The relation between outstanding data and
|
||||
// the congestion window affects encoder allocations directly.
|
||||
const char kCongestionPushbackExperiment[] = "WebRTC-CongestionWindowPushback";
|
||||
|
||||
// When PacerPushbackExperiment is enabled, build-up in the pacer due to
|
||||
// the congestion window and/or data spikes reduces encoder allocations.
|
||||
const char kPacerPushbackExperiment[] = "WebRTC-PacerPushbackExperiment";
|
||||
const int64_t PacerQueueUpdateIntervalMs = 25;
|
||||
const uint32_t MinPushbackTargetBitrateBps = 30000;
|
||||
|
||||
bool IsPacerPushbackExperimentEnabled() {
|
||||
return webrtc::field_trial::IsEnabled(kPacerPushbackExperiment) ||
|
||||
@ -48,6 +56,10 @@ bool IsPacerPushbackExperimentEnabled() {
|
||||
webrtc::runtime_enabled_features::kDualStreamModeFeatureName));
|
||||
}
|
||||
|
||||
bool IsCongestionWindowExperimentEnabled() {
|
||||
return webrtc::field_trial::IsEnabled(kCongestionPushbackExperiment);
|
||||
}
|
||||
|
||||
void SortPacketFeedbackVector(std::vector<webrtc::PacketFeedback>* input) {
|
||||
std::sort(input->begin(), input->end(), PacketFeedbackComparator());
|
||||
}
|
||||
@ -155,6 +167,7 @@ class ControlHandler {
|
||||
void PostUpdates(NetworkControlUpdate update);
|
||||
|
||||
void OnNetworkAvailability(NetworkAvailability msg);
|
||||
void OnOutstandingData(DataSize in_flight_data);
|
||||
void OnPacerQueueUpdate(TimeDelta expected_queue_time);
|
||||
|
||||
rtc::Optional<TargetTransferRate> last_transfer_rate();
|
||||
@ -172,13 +185,16 @@ class ControlHandler {
|
||||
PacerController* pacer_controller_;
|
||||
|
||||
rtc::Optional<TargetTransferRate> current_target_rate_msg_;
|
||||
rtc::Optional<DataSize> congestion_window_;
|
||||
DataSize outstanding_data_ = DataSize::Zero();
|
||||
bool network_available_ = true;
|
||||
int64_t last_reported_target_bitrate_bps_ = 0;
|
||||
uint8_t last_reported_fraction_loss_ = 0;
|
||||
int64_t last_reported_rtt_ms_ = 0;
|
||||
const bool pacer_pushback_experiment_ = false;
|
||||
const bool congestion_window_pushback_experiment_ = false;
|
||||
int64_t pacer_expected_queue_ms_ = 0;
|
||||
float encoding_rate_ratio_ = 1.0;
|
||||
double encoding_rate_ratio_ = 1.0;
|
||||
|
||||
rtc::SequencedTaskChecker sequenced_checker_;
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ControlHandler);
|
||||
@ -189,14 +205,19 @@ ControlHandler::ControlHandler(NetworkChangedObserver* observer,
|
||||
const Clock* clock)
|
||||
: observer_(observer),
|
||||
pacer_controller_(pacer_controller),
|
||||
pacer_pushback_experiment_(IsPacerPushbackExperimentEnabled()) {
|
||||
pacer_pushback_experiment_(IsPacerPushbackExperimentEnabled()),
|
||||
congestion_window_pushback_experiment_(
|
||||
IsCongestionWindowExperimentEnabled()) {
|
||||
sequenced_checker_.Detach();
|
||||
}
|
||||
|
||||
void ControlHandler::PostUpdates(NetworkControlUpdate update) {
|
||||
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_);
|
||||
if (update.congestion_window) {
|
||||
pacer_controller_->OnCongestionWindow(*update.congestion_window);
|
||||
if (congestion_window_pushback_experiment_) {
|
||||
if (update.congestion_window) {
|
||||
congestion_window_ = update.congestion_window;
|
||||
pacer_controller_->OnCongestionWindow(*update.congestion_window);
|
||||
}
|
||||
}
|
||||
if (update.pacer_config) {
|
||||
pacer_controller_->OnPacerConfig(*update.pacer_config);
|
||||
@ -216,6 +237,12 @@ void ControlHandler::OnNetworkAvailability(NetworkAvailability msg) {
|
||||
OnNetworkInvalidation();
|
||||
}
|
||||
|
||||
void ControlHandler::OnOutstandingData(DataSize in_flight_data) {
|
||||
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_);
|
||||
outstanding_data_ = in_flight_data;
|
||||
OnNetworkInvalidation();
|
||||
}
|
||||
|
||||
void ControlHandler::OnPacerQueueUpdate(TimeDelta expected_queue_time) {
|
||||
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_);
|
||||
pacer_expected_queue_ms_ = expected_queue_time.ms();
|
||||
@ -241,6 +268,29 @@ void ControlHandler::OnNetworkInvalidation() {
|
||||
|
||||
if (!network_available_) {
|
||||
target_bitrate_bps = 0;
|
||||
} else if (congestion_window_pushback_experiment_ && congestion_window_) {
|
||||
double fill_ratio = outstanding_data_.bytes() /
|
||||
static_cast<double>(congestion_window_->bytes());
|
||||
if (fill_ratio > 1.5) {
|
||||
encoding_rate_ratio_ *= 0.9;
|
||||
} else if (fill_ratio > 1) {
|
||||
encoding_rate_ratio_ *= 0.95;
|
||||
} else if (fill_ratio < 0.1) {
|
||||
encoding_rate_ratio_ = 1.0;
|
||||
} else {
|
||||
encoding_rate_ratio_ *= 1.05;
|
||||
encoding_rate_ratio_ = std::min(encoding_rate_ratio_, 1.0);
|
||||
}
|
||||
|
||||
uint32_t adjusted_target_bitrate_bps =
|
||||
static_cast<uint32_t>(target_bitrate_bps * encoding_rate_ratio_);
|
||||
|
||||
// If adjusted target bitrate is lower than minimum target bitrate,
|
||||
// does not reduce target bitrate lower than minimum target bitrate.
|
||||
target_bitrate_bps =
|
||||
adjusted_target_bitrate_bps < MinPushbackTargetBitrateBps
|
||||
? std::min(target_bitrate_bps, MinPushbackTargetBitrateBps)
|
||||
: adjusted_target_bitrate_bps;
|
||||
} else if (!pacer_pushback_experiment_) {
|
||||
target_bitrate_bps = IsSendQueueFull() ? 0 : target_bitrate_bps;
|
||||
} else {
|
||||
@ -249,9 +299,9 @@ void ControlHandler::OnNetworkInvalidation() {
|
||||
if (queue_length_ms == 0) {
|
||||
encoding_rate_ratio_ = 1.0;
|
||||
} else if (queue_length_ms > 50) {
|
||||
float encoding_ratio = 1.0 - queue_length_ms / 1000.0;
|
||||
double encoding_ratio = 1.0 - queue_length_ms / 1000.0;
|
||||
encoding_rate_ratio_ = std::min(encoding_rate_ratio_, encoding_ratio);
|
||||
encoding_rate_ratio_ = std::max(encoding_rate_ratio_, 0.0f);
|
||||
encoding_rate_ratio_ = std::max(encoding_rate_ratio_, 0.0);
|
||||
}
|
||||
|
||||
target_bitrate_bps *= encoding_rate_ratio_;
|
||||
@ -667,6 +717,8 @@ void SendSideCongestionController::MaybeUpdateOutstandingData() {
|
||||
task_queue_->PostTask([this, in_flight_data]() {
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
pacer_controller_->OnOutstandingData(in_flight_data);
|
||||
if (control_handler_)
|
||||
control_handler_->OnOutstandingData(in_flight_data);
|
||||
});
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user