Enable congestion window pushback to reduce bitrate by only drop video frames.

With current congestion window pushback, when congestion window is filling up, it will reduce bitrate directly and encoder may reduce encode quality, resolution, or framerate to adapt to the allocated bitrate, the behavior is depending on the degradation preference.
This change enable congestion window to only drop frames to reduce bitrate (when needed) instead of reduce general bitrate allocation.

Bug: webrtc:11334
Change-Id: I9cf5c20a0858c4d07d006942abe72aa5e1f7cb38
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168059
Commit-Queue: Ying Wang <yinwa@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30483}
This commit is contained in:
Ying Wang
2020-02-07 14:29:32 +01:00
committed by Commit Bot
parent 8d94dc23a6
commit 9b881abea9
18 changed files with 300 additions and 133 deletions

View File

@ -89,5 +89,17 @@ TEST_F(CongestionWindowPushbackControllerTest, PushbackOnInititialDataWindow) {
EXPECT_GT(80000u, bitrate_bps);
}
TEST_F(CongestionWindowPushbackControllerTest, PushbackDropFrame) {
test::ScopedFieldTrials trials("WebRTC-CongestionWindow/DropFrame:true/");
cwnd_controller_.reset(
new CongestionWindowPushbackController(&field_trial_config_));
cwnd_controller_->UpdateOutstandingData(1e8); // Large number
cwnd_controller_->SetDataWindow(DataSize::bytes(50000));
uint32_t bitrate_bps = 80000;
bitrate_bps = cwnd_controller_->UpdateTargetBitrate(bitrate_bps);
EXPECT_GT(80000u, bitrate_bps);
}
} // namespace test
} // namespace webrtc

View File

@ -600,6 +600,7 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(
BWE_TEST_LOGGING_PLOT(1, "Target_bitrate_kbps", at_time.ms(),
loss_based_target_rate.kbps());
double cwnd_reduce_ratio = 0.0;
if (congestion_window_pushback_controller_) {
int64_t pushback_rate =
congestion_window_pushback_controller_->UpdateTargetBitrate(
@ -607,6 +608,11 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(
pushback_rate = std::max<int64_t>(bandwidth_estimation_->GetMinBitrate(),
pushback_rate);
pushback_target_rate = DataRate::bps(pushback_rate);
if (rate_control_settings_.UseCongestionWindowDropFrameOnly()) {
cwnd_reduce_ratio = static_cast<double>(loss_based_target_rate.bps() -
pushback_target_rate.bps()) /
loss_based_target_rate.bps();
}
}
if ((loss_based_target_rate != last_loss_based_target_rate_) ||
@ -624,7 +630,12 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(
TargetTransferRate target_rate_msg;
target_rate_msg.at_time = at_time;
target_rate_msg.target_rate = pushback_target_rate;
if (rate_control_settings_.UseCongestionWindowDropFrameOnly()) {
target_rate_msg.target_rate = loss_based_target_rate;
target_rate_msg.cwnd_reduce_ratio = cwnd_reduce_ratio;
} else {
target_rate_msg.target_rate = pushback_target_rate;
}
if (loss_based_stable_rate_) {
target_rate_msg.stable_target_rate =
std::min(bandwidth_estimation_->GetEstimatedLinkCapacity(),

View File

@ -289,6 +289,40 @@ TEST_F(GoogCcNetworkControllerTest, CongestionWindowPushbackOnNetworkDelay) {
EXPECT_LT(client->target_rate().kbps(), 40);
}
// Test congestion window pushback on network delay happens.
TEST_F(GoogCcNetworkControllerTest,
CongestionWindowPushbackDropFrameOnNetworkDelay) {
auto factory = CreateFeedbackOnlyFactory();
ScopedFieldTrials trial(
"WebRTC-CongestionWindow/QueueSize:800,MinBitrate:30000,DropFrame:true/");
Scenario s("googcc_unit/cwnd_on_delay", false);
auto send_net =
s.CreateMutableSimulationNode([=](NetworkSimulationConfig* c) {
c->bandwidth = DataRate::kbps(1000);
c->delay = TimeDelta::ms(100);
});
auto ret_net = s.CreateSimulationNode(
[](NetworkSimulationConfig* c) { c->delay = TimeDelta::ms(100); });
CallClientConfig config;
config.transport.cc_factory = &factory;
// Start high so bandwidth drop has max effect.
config.transport.rates.start_rate = DataRate::kbps(300);
config.transport.rates.max_rate = DataRate::kbps(2000);
config.transport.rates.min_rate = DataRate::kbps(10);
auto* client = CreateVideoSendingClient(&s, std::move(config),
{send_net->node()}, {ret_net});
s.RunFor(TimeDelta::seconds(10));
send_net->PauseTransmissionUntil(s.Now() + TimeDelta::seconds(10));
s.RunFor(TimeDelta::seconds(3));
// As the dropframe is set, after 3 seconds without feedback from any sent
// packets, we expect that the target rate is not reduced by congestion
// window.
EXPECT_GT(client->target_rate().kbps(), 300);
}
TEST_F(GoogCcNetworkControllerTest, OnNetworkRouteChanged) {
NetworkControlUpdate update;
DataRate new_bitrate = DataRate::bps(200000);