mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-20 09:07:52 +01:00
Unittests for loss based bandwidth estimation.
Bug: none Change-Id: I204071683c1c6e28040ea3bce900c4b04108cba7 Reviewed-on: https://webrtc-review.googlesource.com/c/112380 Commit-Queue: Christoffer Rodbro <crodbro@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25844}
This commit is contained in:
parent
b535c13e25
commit
5976bde2e6
3 changed files with 120 additions and 51 deletions
|
@ -156,9 +156,9 @@ void LossBasedBandwidthEstimation::UpdateAcknowledgedBitrate(
|
|||
if (acknowledged_bitrate > acknowledged_bitrate_max_) {
|
||||
acknowledged_bitrate_max_ = acknowledged_bitrate;
|
||||
} else {
|
||||
acknowledged_bitrate_max_ +=
|
||||
acknowledged_bitrate_max_ -=
|
||||
ExponentialUpdate(config_.acknowledged_rate_max_window, time_passed) *
|
||||
(acknowledged_bitrate - acknowledged_bitrate_max_);
|
||||
(acknowledged_bitrate_max_ - acknowledged_bitrate);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,58 @@ namespace {
|
|||
const uint32_t kInitialBitrateKbps = 60;
|
||||
const DataRate kInitialBitrate = DataRate::kbps(kInitialBitrateKbps);
|
||||
const float kDefaultPacingRate = 2.5f;
|
||||
|
||||
void UpdatesTargetRateBasedOnLinkCapacity(double loss_rate = 0.0) {
|
||||
Scenario s("googcc_unit/target_capacity", false);
|
||||
SimulatedTimeClientConfig config;
|
||||
config.transport.cc =
|
||||
TransportControllerConfig::CongestionController::kGoogCcFeedback;
|
||||
config.transport.rates.min_rate = DataRate::kbps(10);
|
||||
config.transport.rates.max_rate = DataRate::kbps(1500);
|
||||
config.transport.rates.start_rate = DataRate::kbps(300);
|
||||
NetworkNodeConfig net_conf;
|
||||
auto send_net = s.CreateSimulationNode([loss_rate](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(500);
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
c->simulation.loss_rate = loss_rate;
|
||||
c->update_frequency = TimeDelta::ms(5);
|
||||
});
|
||||
auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
c->update_frequency = TimeDelta::ms(5);
|
||||
});
|
||||
StatesPrinter* truth = s.CreatePrinter(
|
||||
"send.truth.txt", TimeDelta::PlusInfinity(), {send_net->ConfigPrinter()});
|
||||
SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
|
||||
"send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
|
||||
|
||||
truth->PrintRow();
|
||||
s.RunFor(TimeDelta::seconds(25));
|
||||
truth->PrintRow();
|
||||
EXPECT_NEAR(client->target_rate_kbps(), 450, 100);
|
||||
|
||||
send_net->UpdateConfig([](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(800);
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
});
|
||||
|
||||
truth->PrintRow();
|
||||
s.RunFor(TimeDelta::seconds(20));
|
||||
truth->PrintRow();
|
||||
EXPECT_NEAR(client->target_rate_kbps(), 750, 150);
|
||||
|
||||
send_net->UpdateConfig([](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(100);
|
||||
c->simulation.delay = TimeDelta::ms(200);
|
||||
});
|
||||
ret_net->UpdateConfig(
|
||||
[](NetworkNodeConfig* c) { c->simulation.delay = TimeDelta::ms(200); });
|
||||
|
||||
truth->PrintRow();
|
||||
s.RunFor(TimeDelta::seconds(30));
|
||||
truth->PrintRow();
|
||||
EXPECT_NEAR(client->target_rate_kbps(), 90, 20);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class GoogCcNetworkControllerTest : public ::testing::Test {
|
||||
|
@ -349,54 +401,7 @@ TEST_F(GoogCcNetworkControllerTest, LimitsToMinRateIfRttIsHighInTrial) {
|
|||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest, UpdatesTargetRateBasedOnLinkCapacity) {
|
||||
Scenario s("googcc_unit/target_capacity", false);
|
||||
SimulatedTimeClientConfig config;
|
||||
config.transport.cc =
|
||||
TransportControllerConfig::CongestionController::kGoogCcFeedback;
|
||||
config.transport.rates.min_rate = DataRate::kbps(10);
|
||||
config.transport.rates.max_rate = DataRate::kbps(1500);
|
||||
config.transport.rates.start_rate = DataRate::kbps(300);
|
||||
NetworkNodeConfig net_conf;
|
||||
auto send_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(500);
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
c->update_frequency = TimeDelta::ms(5);
|
||||
});
|
||||
auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
c->update_frequency = TimeDelta::ms(5);
|
||||
});
|
||||
StatesPrinter* truth = s.CreatePrinter(
|
||||
"send.truth.txt", TimeDelta::PlusInfinity(), {send_net->ConfigPrinter()});
|
||||
SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
|
||||
"send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
|
||||
|
||||
truth->PrintRow();
|
||||
s.RunFor(TimeDelta::seconds(25));
|
||||
truth->PrintRow();
|
||||
EXPECT_NEAR(client->target_rate_kbps(), 450, 100);
|
||||
|
||||
send_net->UpdateConfig([](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(800);
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
});
|
||||
|
||||
truth->PrintRow();
|
||||
s.RunFor(TimeDelta::seconds(20));
|
||||
truth->PrintRow();
|
||||
EXPECT_NEAR(client->target_rate_kbps(), 750, 150);
|
||||
|
||||
send_net->UpdateConfig([](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(100);
|
||||
c->simulation.delay = TimeDelta::ms(200);
|
||||
});
|
||||
ret_net->UpdateConfig(
|
||||
[](NetworkNodeConfig* c) { c->simulation.delay = TimeDelta::ms(200); });
|
||||
|
||||
truth->PrintRow();
|
||||
s.RunFor(TimeDelta::seconds(30));
|
||||
truth->PrintRow();
|
||||
EXPECT_NEAR(client->target_rate_kbps(), 90, 20);
|
||||
UpdatesTargetRateBasedOnLinkCapacity();
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest, DefaultEstimateVariesInSteadyState) {
|
||||
|
@ -455,5 +460,68 @@ TEST_F(GoogCcNetworkControllerTest, StableEstimateDoesNotVaryInSteadyState) {
|
|||
EXPECT_GT(min_estimate / max_estimate, 0.95);
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest,
|
||||
LossBasedControlUpdatesTargetRateBasedOnLinkCapacity) {
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
|
||||
UpdatesTargetRateBasedOnLinkCapacity(/*loss_rate*/ 0.01);
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest,
|
||||
LossBasedControlDoesModestBackoffToHighLoss) {
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
|
||||
Scenario s("googcc_unit/high_loss_channel", false);
|
||||
SimulatedTimeClientConfig config;
|
||||
config.transport.cc =
|
||||
TransportControllerConfig::CongestionController::kGoogCcFeedback;
|
||||
config.transport.rates.min_rate = DataRate::kbps(10);
|
||||
config.transport.rates.max_rate = DataRate::kbps(1500);
|
||||
config.transport.rates.start_rate = DataRate::kbps(300);
|
||||
NetworkNodeConfig net_conf;
|
||||
auto send_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(2000);
|
||||
c->simulation.delay = TimeDelta::ms(200);
|
||||
c->simulation.loss_rate = 0.1;
|
||||
c->update_frequency = TimeDelta::ms(5);
|
||||
});
|
||||
auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
|
||||
c->simulation.delay = TimeDelta::ms(200);
|
||||
c->update_frequency = TimeDelta::ms(5);
|
||||
});
|
||||
SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
|
||||
"send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
|
||||
|
||||
s.RunFor(TimeDelta::seconds(120));
|
||||
// Without LossBasedControl trial, bandwidth drops to ~10 kbps.
|
||||
EXPECT_GT(client->target_rate_kbps(), 100);
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest, LossBasedEstimatorCapsRateAtModerateLoss) {
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
|
||||
Scenario s("googcc_unit/moderate_loss_channel", false);
|
||||
SimulatedTimeClientConfig config;
|
||||
config.transport.cc =
|
||||
TransportControllerConfig::CongestionController::kGoogCcFeedback;
|
||||
config.transport.rates.min_rate = DataRate::kbps(10);
|
||||
config.transport.rates.max_rate = DataRate::kbps(5000);
|
||||
config.transport.rates.start_rate = DataRate::kbps(300);
|
||||
NetworkNodeConfig net_conf;
|
||||
auto send_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(5000);
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
c->simulation.loss_rate = 0.02;
|
||||
c->update_frequency = TimeDelta::ms(5);
|
||||
});
|
||||
auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
c->update_frequency = TimeDelta::ms(5);
|
||||
});
|
||||
SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
|
||||
"send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
|
||||
|
||||
s.RunFor(TimeDelta::seconds(60));
|
||||
// Without LossBasedControl trial, bitrate reaches above 4 mbps.
|
||||
EXPECT_NEAR(client->target_rate_kbps(), 2000, 500);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -229,7 +229,8 @@ bool SimulatedFeedback::TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
|
|||
it->second});
|
||||
receive_times_.erase(it);
|
||||
}
|
||||
if (receive_times_.size() >= RawFeedbackReportPacket::MAX_FEEDBACKS) {
|
||||
if (report.receive_times.size() >=
|
||||
RawFeedbackReportPacket::MAX_FEEDBACKS) {
|
||||
return_node_->TryDeliverPacket(FeedbackToBuffer(report),
|
||||
return_receiver_id_, at_time);
|
||||
report = SimpleFeedbackReportPacket();
|
||||
|
|
Loading…
Reference in a new issue