Add GoogCCScenario test of WebRTC-Bwe-ResetOnAdapterIdChange

The test tests that a route change does not cause BWE do drop unless the adapter is changed.

Bug: webrtc:42221538
Change-Id: I49be55172aff285c55d2564ec3389f3fc7c01d62
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/350820
Reviewed-by: Jonas Oreland <jonaso@webrtc.org>
Reviewed-by: Jonas Oreland <jonaso@google.com>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42347}
This commit is contained in:
Per K 2024-05-16 13:17:46 +00:00 committed by WebRTC LUCI CQ
parent dcfacb4361
commit 819cfb0608
5 changed files with 77 additions and 5 deletions

View File

@ -799,6 +799,44 @@ TEST(GoogCcScenario, MaintainsLowRateInSafeResetTrial) {
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 50);
}
TEST(GoogCcScenario, DoNotResetBweUnlessNetworkAdapterChangeOnRoutChange) {
ScopedFieldTrials trial("WebRTC-Bwe-ResetOnAdapterIdChange/Enabled/");
Scenario s("googcc_unit/do_not_reset_bwe_unless_adapter_change");
const DataRate kLinkCapacity = DataRate::KilobitsPerSec(1000);
const DataRate kStartRate = DataRate::KilobitsPerSec(300);
auto send_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
c->bandwidth = kLinkCapacity;
c->delay = TimeDelta::Millis(50);
});
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
c->transport.rates.start_rate = kStartRate;
});
client->UpdateNetworkAdapterId(0);
auto* route = s.CreateRoutes(
client, {send_net}, s.CreateClient("return", CallClientConfig()),
{s.CreateSimulationNode(NetworkSimulationConfig())});
s.CreateVideoStream(route->forward(), VideoStreamConfig());
// Allow the controller to stabilize.
s.RunFor(TimeDelta::Millis(500));
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 300);
s.ChangeRoute(route->forward(), {send_net});
// Allow new settings to propagate.
s.RunFor(TimeDelta::Millis(50));
// Under the trial, the target should not drop.
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 300);
s.RunFor(TimeDelta::Millis(500));
// But if adapter id change, BWE should reset and start from the beginning if
// the network route changes.
client->UpdateNetworkAdapterId(1);
s.ChangeRoute(route->forward(), {send_net});
// Allow new settings to propagate.
s.RunFor(TimeDelta::Millis(50));
EXPECT_NEAR(client->send_bandwidth().kbps(), kStartRate.kbps(), 30);
}
TEST(GoogCcScenario, CutsHighRateInSafeResetTrial) {
const DataRate kLinkCapacity = DataRate::KilobitsPerSec(1000);
const DataRate kStartRate = DataRate::KilobitsPerSec(300);
@ -819,6 +857,7 @@ TEST(GoogCcScenario, CutsHighRateInSafeResetTrial) {
// Allow the controller to stabilize.
s.RunFor(TimeDelta::Millis(500));
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 300);
client->UpdateNetworkAdapterId(1);
s.ChangeRoute(route->forward(), {send_net});
// Allow new settings to propagate.
s.RunFor(TimeDelta::Millis(50));
@ -851,6 +890,7 @@ TEST(GoogCcScenario, DetectsHighRateInSafeResetTrial) {
// Allow the controller to stabilize.
s.RunFor(TimeDelta::Millis(2000));
EXPECT_NEAR(client->send_bandwidth().kbps(), kInitialLinkCapacity.kbps(), 50);
client->UpdateNetworkAdapterId(1);
s.ChangeRoute(route->forward(), {new_net});
// Allow new settings to propagate, but not probes to be received.
s.RunFor(TimeDelta::Millis(50));

View File

@ -364,6 +364,10 @@ void CallClient::SendTask(std::function<void()> task) {
task_queue_.SendTask(std::move(task));
}
void CallClient::UpdateNetworkAdapterId(int adapter_id) {
transport_->UpdateAdapterId(adapter_id);
}
int16_t CallClient::Bind(EmulatedEndpoint* endpoint) {
uint16_t port = endpoint->BindReceiver(0, this).value();
endpoints_.push_back({endpoint, port});

View File

@ -130,6 +130,9 @@ class CallClient : public EmulatedNetworkReceiverInterface {
void SetVideoReceiveRtpHeaderExtensions(
rtc::ArrayView<RtpExtension> extensions);
// Sets the network adapter id used next time the network route changes.
void UpdateNetworkAdapterId(int adapter_id);
void OnPacketReceived(EmulatedIpPacket packet) override;
std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name);

View File

@ -14,6 +14,7 @@
#include <vector>
#include "absl/cleanup/cleanup.h"
#include "api/sequence_checker.h"
#include "rtc_base/net_helper.h"
#include "rtc_base/numerics/safe_minmax.h"
@ -33,6 +34,12 @@ SimulatedNetwork::Config CreateSimulationConfig(
config.packet_queue_length_limit.value_or(0);
return sim_config;
}
rtc::RouteEndpoint CreateRouteEndpoint(uint16_t network_id,
uint16_t adapter_id) {
return rtc::RouteEndpoint(rtc::ADAPTER_TYPE_UNKNOWN, adapter_id, network_id,
/* uses_turn = */ false);
}
} // namespace
SimulationNode::SimulationNode(NetworkSimulationConfig config,
@ -68,7 +75,9 @@ ColumnPrinter SimulationNode::ConfigPrinter() const {
NetworkNodeTransport::NetworkNodeTransport(Clock* sender_clock,
Call* sender_call)
: sender_clock_(sender_clock), sender_call_(sender_call) {}
: sender_clock_(sender_clock), sender_call_(sender_call) {
sequence_checker_.Detach();
}
NetworkNodeTransport::~NetworkNodeTransport() = default;
@ -103,16 +112,26 @@ bool NetworkNodeTransport::SendRtcp(rtc::ArrayView<const uint8_t> packet) {
return true;
}
void NetworkNodeTransport::UpdateAdapterId(int adapter_id) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
adapter_id_ = adapter_id;
}
void NetworkNodeTransport::Connect(EmulatedEndpoint* endpoint,
const rtc::SocketAddress& receiver_address,
DataSize packet_overhead) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
rtc::NetworkRoute route;
route.connected = true;
// We assume that the address will be unique in the lower bytes.
route.local = rtc::RouteEndpoint::CreateWithNetworkId(static_cast<uint16_t>(
receiver_address.ipaddr().v4AddressAsHostOrderInteger()));
route.remote = rtc::RouteEndpoint::CreateWithNetworkId(static_cast<uint16_t>(
receiver_address.ipaddr().v4AddressAsHostOrderInteger()));
route.local = CreateRouteEndpoint(
static_cast<uint16_t>(
receiver_address.ipaddr().v4AddressAsHostOrderInteger()),
adapter_id_);
route.remote = CreateRouteEndpoint(
static_cast<uint16_t>(
receiver_address.ipaddr().v4AddressAsHostOrderInteger()),
adapter_id_);
route.packet_overhead = packet_overhead.bytes() +
receiver_address.ipaddr().overhead() +
cricket::kUdpHeaderSize;

View File

@ -17,6 +17,7 @@
#include <vector>
#include "api/call/transport.h"
#include "api/sequence_checker.h"
#include "api/units/timestamp.h"
#include "call/call.h"
#include "rtc_base/copy_on_write_buffer.h"
@ -53,6 +54,8 @@ class NetworkNodeTransport : public Transport {
NetworkNodeTransport(Clock* sender_clock, Call* sender_call);
~NetworkNodeTransport() override;
void UpdateAdapterId(int adapter_id);
bool SendRtp(rtc::ArrayView<const uint8_t> packet,
const PacketOptions& options) override;
bool SendRtcp(rtc::ArrayView<const uint8_t> packet) override;
@ -68,6 +71,9 @@ class NetworkNodeTransport : public Transport {
}
private:
SequenceChecker sequence_checker_;
int adapter_id_ RTC_GUARDED_BY(sequence_checker_) = 0;
Mutex mutex_;
Clock* const sender_clock_;
Call* const sender_call_;