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:
parent
dcfacb4361
commit
819cfb0608
@ -799,6 +799,44 @@ TEST(GoogCcScenario, MaintainsLowRateInSafeResetTrial) {
|
|||||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 50);
|
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) {
|
TEST(GoogCcScenario, CutsHighRateInSafeResetTrial) {
|
||||||
const DataRate kLinkCapacity = DataRate::KilobitsPerSec(1000);
|
const DataRate kLinkCapacity = DataRate::KilobitsPerSec(1000);
|
||||||
const DataRate kStartRate = DataRate::KilobitsPerSec(300);
|
const DataRate kStartRate = DataRate::KilobitsPerSec(300);
|
||||||
@ -819,6 +857,7 @@ TEST(GoogCcScenario, CutsHighRateInSafeResetTrial) {
|
|||||||
// Allow the controller to stabilize.
|
// Allow the controller to stabilize.
|
||||||
s.RunFor(TimeDelta::Millis(500));
|
s.RunFor(TimeDelta::Millis(500));
|
||||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 300);
|
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 300);
|
||||||
|
client->UpdateNetworkAdapterId(1);
|
||||||
s.ChangeRoute(route->forward(), {send_net});
|
s.ChangeRoute(route->forward(), {send_net});
|
||||||
// Allow new settings to propagate.
|
// Allow new settings to propagate.
|
||||||
s.RunFor(TimeDelta::Millis(50));
|
s.RunFor(TimeDelta::Millis(50));
|
||||||
@ -851,6 +890,7 @@ TEST(GoogCcScenario, DetectsHighRateInSafeResetTrial) {
|
|||||||
// Allow the controller to stabilize.
|
// Allow the controller to stabilize.
|
||||||
s.RunFor(TimeDelta::Millis(2000));
|
s.RunFor(TimeDelta::Millis(2000));
|
||||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kInitialLinkCapacity.kbps(), 50);
|
EXPECT_NEAR(client->send_bandwidth().kbps(), kInitialLinkCapacity.kbps(), 50);
|
||||||
|
client->UpdateNetworkAdapterId(1);
|
||||||
s.ChangeRoute(route->forward(), {new_net});
|
s.ChangeRoute(route->forward(), {new_net});
|
||||||
// Allow new settings to propagate, but not probes to be received.
|
// Allow new settings to propagate, but not probes to be received.
|
||||||
s.RunFor(TimeDelta::Millis(50));
|
s.RunFor(TimeDelta::Millis(50));
|
||||||
|
|||||||
@ -364,6 +364,10 @@ void CallClient::SendTask(std::function<void()> task) {
|
|||||||
task_queue_.SendTask(std::move(task));
|
task_queue_.SendTask(std::move(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CallClient::UpdateNetworkAdapterId(int adapter_id) {
|
||||||
|
transport_->UpdateAdapterId(adapter_id);
|
||||||
|
}
|
||||||
|
|
||||||
int16_t CallClient::Bind(EmulatedEndpoint* endpoint) {
|
int16_t CallClient::Bind(EmulatedEndpoint* endpoint) {
|
||||||
uint16_t port = endpoint->BindReceiver(0, this).value();
|
uint16_t port = endpoint->BindReceiver(0, this).value();
|
||||||
endpoints_.push_back({endpoint, port});
|
endpoints_.push_back({endpoint, port});
|
||||||
|
|||||||
@ -130,6 +130,9 @@ class CallClient : public EmulatedNetworkReceiverInterface {
|
|||||||
void SetVideoReceiveRtpHeaderExtensions(
|
void SetVideoReceiveRtpHeaderExtensions(
|
||||||
rtc::ArrayView<RtpExtension> extensions);
|
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;
|
void OnPacketReceived(EmulatedIpPacket packet) override;
|
||||||
std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name);
|
std::unique_ptr<RtcEventLogOutput> GetLogWriter(std::string name);
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/cleanup/cleanup.h"
|
#include "absl/cleanup/cleanup.h"
|
||||||
|
#include "api/sequence_checker.h"
|
||||||
#include "rtc_base/net_helper.h"
|
#include "rtc_base/net_helper.h"
|
||||||
#include "rtc_base/numerics/safe_minmax.h"
|
#include "rtc_base/numerics/safe_minmax.h"
|
||||||
|
|
||||||
@ -33,6 +34,12 @@ SimulatedNetwork::Config CreateSimulationConfig(
|
|||||||
config.packet_queue_length_limit.value_or(0);
|
config.packet_queue_length_limit.value_or(0);
|
||||||
return sim_config;
|
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
|
} // namespace
|
||||||
|
|
||||||
SimulationNode::SimulationNode(NetworkSimulationConfig config,
|
SimulationNode::SimulationNode(NetworkSimulationConfig config,
|
||||||
@ -68,7 +75,9 @@ ColumnPrinter SimulationNode::ConfigPrinter() const {
|
|||||||
|
|
||||||
NetworkNodeTransport::NetworkNodeTransport(Clock* sender_clock,
|
NetworkNodeTransport::NetworkNodeTransport(Clock* sender_clock,
|
||||||
Call* sender_call)
|
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;
|
NetworkNodeTransport::~NetworkNodeTransport() = default;
|
||||||
|
|
||||||
@ -103,16 +112,26 @@ bool NetworkNodeTransport::SendRtcp(rtc::ArrayView<const uint8_t> packet) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkNodeTransport::UpdateAdapterId(int adapter_id) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
adapter_id_ = adapter_id;
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkNodeTransport::Connect(EmulatedEndpoint* endpoint,
|
void NetworkNodeTransport::Connect(EmulatedEndpoint* endpoint,
|
||||||
const rtc::SocketAddress& receiver_address,
|
const rtc::SocketAddress& receiver_address,
|
||||||
DataSize packet_overhead) {
|
DataSize packet_overhead) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
rtc::NetworkRoute route;
|
rtc::NetworkRoute route;
|
||||||
route.connected = true;
|
route.connected = true;
|
||||||
// We assume that the address will be unique in the lower bytes.
|
// We assume that the address will be unique in the lower bytes.
|
||||||
route.local = rtc::RouteEndpoint::CreateWithNetworkId(static_cast<uint16_t>(
|
route.local = CreateRouteEndpoint(
|
||||||
receiver_address.ipaddr().v4AddressAsHostOrderInteger()));
|
static_cast<uint16_t>(
|
||||||
route.remote = rtc::RouteEndpoint::CreateWithNetworkId(static_cast<uint16_t>(
|
receiver_address.ipaddr().v4AddressAsHostOrderInteger()),
|
||||||
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() +
|
route.packet_overhead = packet_overhead.bytes() +
|
||||||
receiver_address.ipaddr().overhead() +
|
receiver_address.ipaddr().overhead() +
|
||||||
cricket::kUdpHeaderSize;
|
cricket::kUdpHeaderSize;
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/call/transport.h"
|
#include "api/call/transport.h"
|
||||||
|
#include "api/sequence_checker.h"
|
||||||
#include "api/units/timestamp.h"
|
#include "api/units/timestamp.h"
|
||||||
#include "call/call.h"
|
#include "call/call.h"
|
||||||
#include "rtc_base/copy_on_write_buffer.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(Clock* sender_clock, Call* sender_call);
|
||||||
~NetworkNodeTransport() override;
|
~NetworkNodeTransport() override;
|
||||||
|
|
||||||
|
void UpdateAdapterId(int adapter_id);
|
||||||
|
|
||||||
bool SendRtp(rtc::ArrayView<const uint8_t> packet,
|
bool SendRtp(rtc::ArrayView<const uint8_t> packet,
|
||||||
const PacketOptions& options) override;
|
const PacketOptions& options) override;
|
||||||
bool SendRtcp(rtc::ArrayView<const uint8_t> packet) override;
|
bool SendRtcp(rtc::ArrayView<const uint8_t> packet) override;
|
||||||
@ -68,6 +71,9 @@ class NetworkNodeTransport : public Transport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
SequenceChecker sequence_checker_;
|
||||||
|
int adapter_id_ RTC_GUARDED_BY(sequence_checker_) = 0;
|
||||||
|
|
||||||
Mutex mutex_;
|
Mutex mutex_;
|
||||||
Clock* const sender_clock_;
|
Clock* const sender_clock_;
|
||||||
Call* const sender_call_;
|
Call* const sender_call_;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user