Removed observer from network controller interface.
Moving the responsibility for calling callbacks from implementations of NetworkControllerInterface to SendSideCongestionController. This decreases the coupling and makes the callbacks more explicit. Bug: webrtc:8415 Change-Id: Ie75effbde01533106080bb6c40308b0c20064c45 Reviewed-on: https://webrtc-review.googlesource.com/66882 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22793}
This commit is contained in:
parent
24697ab200
commit
ae9057831f
@ -19,9 +19,8 @@ namespace webrtc {
|
||||
BbrNetworkControllerFactory::BbrNetworkControllerFactory() {}
|
||||
|
||||
std::unique_ptr<NetworkControllerInterface> BbrNetworkControllerFactory::Create(
|
||||
NetworkControllerObserver* observer,
|
||||
NetworkControllerConfig config) {
|
||||
return rtc::MakeUnique<bbr::BbrNetworkController>(observer, config);
|
||||
return rtc::MakeUnique<bbr::BbrNetworkController>(config);
|
||||
}
|
||||
|
||||
TimeDelta BbrNetworkControllerFactory::GetProcessInterval() const {
|
||||
|
||||
@ -21,7 +21,6 @@ class BbrNetworkControllerFactory : public NetworkControllerFactoryInterface {
|
||||
public:
|
||||
BbrNetworkControllerFactory();
|
||||
std::unique_ptr<NetworkControllerInterface> Create(
|
||||
NetworkControllerObserver* observer,
|
||||
NetworkControllerConfig config) override;
|
||||
TimeDelta GetProcessInterval() const override;
|
||||
};
|
||||
|
||||
@ -176,10 +176,8 @@ BbrNetworkController::DebugState::DebugState(const BbrNetworkController& sender)
|
||||
|
||||
BbrNetworkController::DebugState::DebugState(const DebugState& state) = default;
|
||||
|
||||
BbrNetworkController::BbrNetworkController(NetworkControllerObserver* observer,
|
||||
NetworkControllerConfig config)
|
||||
: observer_(observer),
|
||||
random_(10),
|
||||
BbrNetworkController::BbrNetworkController(NetworkControllerConfig config)
|
||||
: random_(10),
|
||||
max_bandwidth_(kBandwidthWindowSize, DataRate::Zero(), 0),
|
||||
default_bandwidth_(kInitialBandwidth),
|
||||
max_ack_height_(kBandwidthWindowSize, DataSize::Zero(), 0),
|
||||
@ -195,7 +193,6 @@ BbrNetworkController::BbrNetworkController(NetworkControllerObserver* observer,
|
||||
constraints_ = config.constraints;
|
||||
Reset();
|
||||
EnterStartupMode();
|
||||
SignalUpdatedRates(config.constraints.at_time);
|
||||
}
|
||||
|
||||
BbrNetworkController::~BbrNetworkController() {}
|
||||
@ -213,7 +210,7 @@ void BbrNetworkController::Reset() {
|
||||
EnterStartupMode();
|
||||
}
|
||||
|
||||
void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) {
|
||||
NetworkControlUpdate BbrNetworkController::CreateRateUpdate(Timestamp at_time) {
|
||||
DataRate bandwidth = BandwidthEstimate();
|
||||
if (bandwidth.IsZero())
|
||||
bandwidth = default_bandwidth_;
|
||||
@ -237,7 +234,7 @@ void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) {
|
||||
last_update_state_.pacing_rate == pacing_rate &&
|
||||
last_update_state_.target_rate == target_rate &&
|
||||
last_update_state_.probing_for_bandwidth == probing_for_bandwidth)
|
||||
return;
|
||||
return NetworkControlUpdate();
|
||||
last_update_state_.mode = mode_;
|
||||
last_update_state_.bandwidth = bandwidth;
|
||||
last_update_state_.rtt = rtt;
|
||||
@ -254,6 +251,8 @@ void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) {
|
||||
<< ", Probing:" << probing_for_bandwidth
|
||||
<< ", pacing_gain: " << pacing_gain_;
|
||||
|
||||
NetworkControlUpdate update;
|
||||
|
||||
TargetTransferRate target_rate_msg;
|
||||
target_rate_msg.network_estimate.at_time = at_time;
|
||||
target_rate_msg.network_estimate.bandwidth = bandwidth;
|
||||
@ -265,7 +264,7 @@ void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) {
|
||||
|
||||
target_rate_msg.target_rate = target_rate;
|
||||
target_rate_msg.at_time = at_time;
|
||||
observer_->OnTargetTransferRate(target_rate_msg);
|
||||
update.target_rate = target_rate_msg;
|
||||
|
||||
PacerConfig pacer_config;
|
||||
// A small time window ensures an even pacing rate.
|
||||
@ -278,46 +277,56 @@ void BbrNetworkController::SignalUpdatedRates(Timestamp at_time) {
|
||||
pacer_config.pad_window = DataSize::Zero();
|
||||
|
||||
pacer_config.at_time = at_time;
|
||||
observer_->OnPacerConfig(pacer_config);
|
||||
update.pacer_config = pacer_config;
|
||||
|
||||
CongestionWindow congestion_window;
|
||||
congestion_window.data_window = GetCongestionWindow();
|
||||
observer_->OnCongestionWindow(congestion_window);
|
||||
update.congestion_window = congestion_window;
|
||||
return update;
|
||||
}
|
||||
|
||||
void BbrNetworkController::OnNetworkAvailability(NetworkAvailability msg) {
|
||||
NetworkControlUpdate BbrNetworkController::OnNetworkAvailability(
|
||||
NetworkAvailability msg) {
|
||||
Reset();
|
||||
rtt_stats_.OnConnectionMigration();
|
||||
SignalUpdatedRates(msg.at_time);
|
||||
return CreateRateUpdate(msg.at_time);
|
||||
}
|
||||
|
||||
void BbrNetworkController::OnNetworkRouteChange(NetworkRouteChange msg) {
|
||||
NetworkControlUpdate BbrNetworkController::OnNetworkRouteChange(
|
||||
NetworkRouteChange msg) {
|
||||
constraints_ = msg.constraints;
|
||||
Reset();
|
||||
if (msg.starting_rate.IsFinite())
|
||||
default_bandwidth_ = msg.starting_rate;
|
||||
rtt_stats_.OnConnectionMigration();
|
||||
SignalUpdatedRates(msg.at_time);
|
||||
return CreateRateUpdate(msg.at_time);
|
||||
}
|
||||
|
||||
void BbrNetworkController::OnProcessInterval(ProcessInterval) {}
|
||||
NetworkControlUpdate BbrNetworkController::OnProcessInterval(
|
||||
ProcessInterval msg) {
|
||||
return CreateRateUpdate(msg.at_time);
|
||||
}
|
||||
|
||||
void BbrNetworkController::OnStreamsConfig(StreamsConfig msg) {}
|
||||
NetworkControlUpdate BbrNetworkController::OnStreamsConfig(StreamsConfig msg) {
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
|
||||
void BbrNetworkController::OnTargetRateConstraints(TargetRateConstraints msg) {
|
||||
NetworkControlUpdate BbrNetworkController::OnTargetRateConstraints(
|
||||
TargetRateConstraints msg) {
|
||||
constraints_ = msg;
|
||||
SignalUpdatedRates(msg.at_time);
|
||||
return CreateRateUpdate(msg.at_time);
|
||||
}
|
||||
|
||||
bool BbrNetworkController::InSlowStart() const {
|
||||
return mode_ == STARTUP;
|
||||
}
|
||||
|
||||
void BbrNetworkController::OnSentPacket(SentPacket msg) {
|
||||
NetworkControlUpdate BbrNetworkController::OnSentPacket(SentPacket msg) {
|
||||
last_send_time_ = msg.send_time;
|
||||
if (!aggregation_epoch_start_time_.IsInitialized()) {
|
||||
aggregation_epoch_start_time_ = msg.send_time;
|
||||
}
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
|
||||
bool BbrNetworkController::CanSend(DataSize bytes_in_flight) {
|
||||
@ -365,7 +374,7 @@ bool BbrNetworkController::IsProbingForMoreBandwidth() const {
|
||||
return (mode_ == PROBE_BW && pacing_gain_ > 1) || mode_ == STARTUP;
|
||||
}
|
||||
|
||||
void BbrNetworkController::OnTransportPacketsFeedback(
|
||||
NetworkControlUpdate BbrNetworkController::OnTransportPacketsFeedback(
|
||||
TransportPacketsFeedback msg) {
|
||||
Timestamp feedback_recv_time = msg.feedback_time;
|
||||
rtc::Optional<SentPacket> last_sent_packet =
|
||||
@ -443,12 +452,21 @@ void BbrNetworkController::OnTransportPacketsFeedback(
|
||||
CalculatePacingRate();
|
||||
CalculateCongestionWindow(total_acked_size);
|
||||
CalculateRecoveryWindow(total_acked_size, bytes_lost, bytes_in_flight);
|
||||
SignalUpdatedRates(msg.feedback_time);
|
||||
return CreateRateUpdate(msg.feedback_time);
|
||||
}
|
||||
|
||||
void BbrNetworkController::OnRemoteBitrateReport(RemoteBitrateReport msg) {}
|
||||
void BbrNetworkController::OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) {}
|
||||
void BbrNetworkController::OnTransportLossReport(TransportLossReport msg) {}
|
||||
NetworkControlUpdate BbrNetworkController::OnRemoteBitrateReport(
|
||||
RemoteBitrateReport msg) {
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
NetworkControlUpdate BbrNetworkController::OnRoundTripTimeUpdate(
|
||||
RoundTripTimeUpdate msg) {
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
NetworkControlUpdate BbrNetworkController::OnTransportLossReport(
|
||||
TransportLossReport msg) {
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
|
||||
TimeDelta BbrNetworkController::GetMinRtt() const {
|
||||
return !min_rtt_.IsZero() ? min_rtt_
|
||||
|
||||
@ -95,23 +95,24 @@ class BbrNetworkController : public NetworkControllerInterface {
|
||||
Timestamp end_of_app_limited_phase;
|
||||
};
|
||||
|
||||
BbrNetworkController(NetworkControllerObserver* observer,
|
||||
NetworkControllerConfig config);
|
||||
explicit BbrNetworkController(NetworkControllerConfig config);
|
||||
~BbrNetworkController() override;
|
||||
|
||||
// NetworkControllerInterface
|
||||
void OnNetworkAvailability(NetworkAvailability msg) override;
|
||||
void OnNetworkRouteChange(NetworkRouteChange msg) override;
|
||||
void OnProcessInterval(ProcessInterval msg) override;
|
||||
void OnSentPacket(SentPacket msg) override;
|
||||
void OnStreamsConfig(StreamsConfig msg) override;
|
||||
void OnTargetRateConstraints(TargetRateConstraints msg) override;
|
||||
void OnTransportPacketsFeedback(TransportPacketsFeedback msg) override;
|
||||
NetworkControlUpdate OnNetworkAvailability(NetworkAvailability msg) override;
|
||||
NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange msg) override;
|
||||
NetworkControlUpdate OnProcessInterval(ProcessInterval msg) override;
|
||||
NetworkControlUpdate OnSentPacket(SentPacket msg) override;
|
||||
NetworkControlUpdate OnStreamsConfig(StreamsConfig msg) override;
|
||||
NetworkControlUpdate OnTargetRateConstraints(
|
||||
TargetRateConstraints msg) override;
|
||||
NetworkControlUpdate OnTransportPacketsFeedback(
|
||||
TransportPacketsFeedback msg) override;
|
||||
|
||||
// Part of remote bitrate estimation api, not implemented for BBR
|
||||
void OnRemoteBitrateReport(RemoteBitrateReport msg) override;
|
||||
void OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override;
|
||||
void OnTransportLossReport(TransportLossReport msg) override;
|
||||
NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport msg) override;
|
||||
NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override;
|
||||
NetworkControlUpdate OnTransportLossReport(TransportLossReport msg) override;
|
||||
|
||||
private:
|
||||
struct BbrControllerConfig {
|
||||
@ -168,7 +169,7 @@ class BbrNetworkController : public NetworkControllerInterface {
|
||||
};
|
||||
|
||||
void Reset();
|
||||
void SignalUpdatedRates(Timestamp at_time);
|
||||
NetworkControlUpdate CreateRateUpdate(Timestamp at_time);
|
||||
|
||||
bool InSlowStart() const;
|
||||
bool InRecovery() const;
|
||||
@ -260,7 +261,6 @@ class BbrNetworkController : public NetworkControllerInterface {
|
||||
void CalculateRecoveryWindow(DataSize bytes_acked,
|
||||
DataSize bytes_lost,
|
||||
DataSize bytes_in_flight);
|
||||
NetworkControllerObserver* observer_;
|
||||
|
||||
RttStats rtt_stats_;
|
||||
webrtc::Random random_;
|
||||
|
||||
@ -13,8 +13,8 @@
|
||||
|
||||
#include "modules/congestion_controller/bbr/bbr_factory.h"
|
||||
#include "modules/congestion_controller/bbr/bbr_network_controller.h"
|
||||
#include "modules/congestion_controller/network_control/test/mock_network_control.h"
|
||||
#include "modules/congestion_controller/network_control/test/network_control_tester.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
using testing::Field;
|
||||
@ -57,6 +57,12 @@ NetworkControllerConfig InitialConfig(
|
||||
return config;
|
||||
}
|
||||
|
||||
ProcessInterval InitialProcessInterval() {
|
||||
ProcessInterval process_interval;
|
||||
process_interval.at_time = kDefaultStartTime;
|
||||
return process_interval;
|
||||
}
|
||||
|
||||
NetworkRouteChange CreateRouteChange(Timestamp at_time,
|
||||
DataRate start_rate,
|
||||
DataRate min_rate = DataRate::Zero(),
|
||||
@ -77,37 +83,37 @@ class BbrNetworkControllerTest : public ::testing::Test {
|
||||
~BbrNetworkControllerTest() override {}
|
||||
};
|
||||
|
||||
TEST_F(BbrNetworkControllerTest, SendsConfigurationOnInitialization) {
|
||||
StrictMock<webrtc::test::MockNetworkControllerObserver> observer;
|
||||
EXPECT_CALL(observer,
|
||||
OnTargetTransferRate(TargetRateCloseTo(kInitialBitrate)));
|
||||
EXPECT_CALL(observer, OnPacerConfig(Property(&PacerConfig::data_rate,
|
||||
Ge(kInitialBitrate))));
|
||||
EXPECT_CALL(observer,
|
||||
OnCongestionWindow(Field(&CongestionWindow::data_window,
|
||||
Property(&DataSize::IsFinite, true))));
|
||||
|
||||
TEST_F(BbrNetworkControllerTest, SendsConfigurationOnFirstProcess) {
|
||||
std::unique_ptr<NetworkControllerInterface> controller_;
|
||||
controller_.reset(new BbrNetworkController(&observer, InitialConfig()));
|
||||
testing::Mock::VerifyAndClearExpectations(&observer);
|
||||
controller_.reset(new BbrNetworkController(InitialConfig()));
|
||||
|
||||
NetworkControlUpdate update =
|
||||
controller_->OnProcessInterval(InitialProcessInterval());
|
||||
EXPECT_THAT(*update.target_rate, TargetRateCloseTo(kInitialBitrate));
|
||||
EXPECT_THAT(*update.pacer_config,
|
||||
Property(&PacerConfig::data_rate, Ge(kInitialBitrate)));
|
||||
EXPECT_THAT(*update.congestion_window,
|
||||
Field(&CongestionWindow::data_window,
|
||||
Property(&DataSize::IsFinite, true)));
|
||||
}
|
||||
|
||||
TEST_F(BbrNetworkControllerTest, SendsConfigurationOnNetworkRouteChanged) {
|
||||
StrictMock<webrtc::test::MockNetworkControllerObserver> observer;
|
||||
EXPECT_CALL(observer, OnTargetTransferRate(_));
|
||||
EXPECT_CALL(observer, OnPacerConfig(_));
|
||||
EXPECT_CALL(observer, OnCongestionWindow(_));
|
||||
std::unique_ptr<NetworkControllerInterface> controller_;
|
||||
controller_.reset(new BbrNetworkController(&observer, InitialConfig()));
|
||||
controller_.reset(new BbrNetworkController(InitialConfig()));
|
||||
|
||||
NetworkControlUpdate update =
|
||||
controller_->OnProcessInterval(InitialProcessInterval());
|
||||
EXPECT_TRUE(update.target_rate.has_value());
|
||||
EXPECT_TRUE(update.pacer_config.has_value());
|
||||
EXPECT_TRUE(update.congestion_window.has_value());
|
||||
|
||||
DataRate new_bitrate = DataRate::bps(200000);
|
||||
EXPECT_CALL(observer, OnTargetTransferRate(TargetRateCloseTo(new_bitrate)));
|
||||
EXPECT_CALL(observer, OnPacerConfig(Property(&PacerConfig::data_rate,
|
||||
Ge(kInitialBitrate))));
|
||||
EXPECT_CALL(observer, OnCongestionWindow(_));
|
||||
controller_->OnNetworkRouteChange(
|
||||
update = controller_->OnNetworkRouteChange(
|
||||
CreateRouteChange(kDefaultStartTime, new_bitrate));
|
||||
testing::Mock::VerifyAndClearExpectations(&observer);
|
||||
EXPECT_THAT(*update.target_rate, TargetRateCloseTo(new_bitrate));
|
||||
EXPECT_THAT(*update.pacer_config,
|
||||
Property(&PacerConfig::data_rate, Ge(kInitialBitrate)));
|
||||
EXPECT_TRUE(update.congestion_window.has_value());
|
||||
}
|
||||
|
||||
// Bandwidth estimation is updated when feedbacks are received.
|
||||
|
||||
@ -18,10 +18,9 @@ GoogCcNetworkControllerFactory::GoogCcNetworkControllerFactory(
|
||||
: event_log_(event_log) {}
|
||||
|
||||
NetworkControllerInterface::uptr GoogCcNetworkControllerFactory::Create(
|
||||
NetworkControllerObserver* observer,
|
||||
NetworkControllerConfig config) {
|
||||
return rtc::MakeUnique<webrtc_cc::GoogCcNetworkController>(event_log_,
|
||||
observer, config);
|
||||
config);
|
||||
}
|
||||
|
||||
TimeDelta GoogCcNetworkControllerFactory::GetProcessInterval() const {
|
||||
|
||||
@ -103,12 +103,9 @@ std::vector<PacketFeedback> ReceivedPacketsFeedbackAsRtp(
|
||||
|
||||
} // namespace
|
||||
|
||||
GoogCcNetworkController::GoogCcNetworkController(
|
||||
RtcEventLog* event_log,
|
||||
NetworkControllerObserver* observer,
|
||||
NetworkControllerConfig config)
|
||||
GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log,
|
||||
NetworkControllerConfig config)
|
||||
: event_log_(event_log),
|
||||
observer_(observer),
|
||||
probe_controller_(new ProbeController()),
|
||||
bandwidth_estimation_(
|
||||
rtc::MakeUnique<SendSideBandwidthEstimation>(event_log_)),
|
||||
@ -134,11 +131,14 @@ GoogCcNetworkController::GoogCcNetworkController(
|
||||
|
||||
GoogCcNetworkController::~GoogCcNetworkController() {}
|
||||
|
||||
void GoogCcNetworkController::OnNetworkAvailability(NetworkAvailability msg) {
|
||||
NetworkControlUpdate GoogCcNetworkController::OnNetworkAvailability(
|
||||
NetworkAvailability msg) {
|
||||
probe_controller_->OnNetworkAvailability(msg);
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnNetworkRouteChange(NetworkRouteChange msg) {
|
||||
NetworkControlUpdate GoogCcNetworkController::OnNetworkRouteChange(
|
||||
NetworkRouteChange msg) {
|
||||
int64_t min_bitrate_bps = msg.constraints.min_data_rate.bps_or(-1);
|
||||
int64_t max_bitrate_bps = msg.constraints.max_data_rate.bps_or(-1);
|
||||
int64_t start_bitrate_bps = msg.starting_rate.bps_or(-1);
|
||||
@ -158,45 +158,53 @@ void GoogCcNetworkController::OnNetworkRouteChange(NetworkRouteChange msg) {
|
||||
probe_controller_->SetBitrates(min_bitrate_bps, start_bitrate_bps,
|
||||
max_bitrate_bps, msg.at_time.ms());
|
||||
|
||||
MaybeTriggerOnNetworkChanged(msg.at_time);
|
||||
return MaybeTriggerOnNetworkChanged(msg.at_time);
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnProcessInterval(ProcessInterval msg) {
|
||||
NetworkControlUpdate GoogCcNetworkController::OnProcessInterval(
|
||||
ProcessInterval msg) {
|
||||
bandwidth_estimation_->UpdateEstimate(msg.at_time.ms());
|
||||
rtc::Optional<int64_t> start_time_ms =
|
||||
alr_detector_->GetApplicationLimitedRegionStartTime();
|
||||
probe_controller_->SetAlrStartTimeMs(start_time_ms);
|
||||
probe_controller_->Process(msg.at_time.ms());
|
||||
|
||||
for (const ProbeClusterConfig& probe :
|
||||
NetworkControlUpdate update = MaybeTriggerOnNetworkChanged(msg.at_time);
|
||||
for (const ProbeClusterConfig& config :
|
||||
probe_controller_->GetAndResetPendingProbes()) {
|
||||
observer_->OnProbeClusterConfig(probe);
|
||||
update.probe_cluster_configs.push_back(config);
|
||||
}
|
||||
MaybeTriggerOnNetworkChanged(msg.at_time);
|
||||
return update;
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnRemoteBitrateReport(RemoteBitrateReport msg) {
|
||||
NetworkControlUpdate GoogCcNetworkController::OnRemoteBitrateReport(
|
||||
RemoteBitrateReport msg) {
|
||||
bandwidth_estimation_->UpdateReceiverEstimate(msg.receive_time.ms(),
|
||||
msg.bandwidth.bps());
|
||||
BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", msg.receive_time.ms(),
|
||||
msg.bandwidth.bps() / 1000);
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) {
|
||||
NetworkControlUpdate GoogCcNetworkController::OnRoundTripTimeUpdate(
|
||||
RoundTripTimeUpdate msg) {
|
||||
if (msg.smoothed) {
|
||||
delay_based_bwe_->OnRttUpdate(msg.round_trip_time.ms());
|
||||
} else {
|
||||
bandwidth_estimation_->UpdateRtt(msg.round_trip_time.ms(),
|
||||
msg.receive_time.ms());
|
||||
}
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnSentPacket(SentPacket sent_packet) {
|
||||
NetworkControlUpdate GoogCcNetworkController::OnSentPacket(
|
||||
SentPacket sent_packet) {
|
||||
alr_detector_->OnBytesSent(sent_packet.size.bytes(),
|
||||
sent_packet.send_time.ms());
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnStreamsConfig(StreamsConfig msg) {
|
||||
NetworkControlUpdate GoogCcNetworkController::OnStreamsConfig(
|
||||
StreamsConfig msg) {
|
||||
probe_controller_->EnablePeriodicAlrProbing(msg.requests_alr_probing);
|
||||
if (msg.max_total_allocated_bitrate &&
|
||||
*msg.max_total_allocated_bitrate != max_total_allocated_bitrate_) {
|
||||
@ -217,13 +225,17 @@ void GoogCcNetworkController::OnStreamsConfig(StreamsConfig msg) {
|
||||
max_padding_rate_ = *msg.max_padding_rate;
|
||||
pacing_changed = true;
|
||||
}
|
||||
NetworkControlUpdate update;
|
||||
if (pacing_changed)
|
||||
UpdatePacingRates(msg.at_time);
|
||||
update.pacer_config = UpdatePacingRates(msg.at_time);
|
||||
return update;
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnTargetRateConstraints(
|
||||
NetworkControlUpdate GoogCcNetworkController::OnTargetRateConstraints(
|
||||
TargetRateConstraints constraints) {
|
||||
NetworkControlUpdate update;
|
||||
UpdateBitrateConstraints(constraints, DataRate());
|
||||
return MaybeTriggerOnNetworkChanged(constraints.at_time);
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::UpdateBitrateConstraints(
|
||||
@ -243,18 +255,18 @@ void GoogCcNetworkController::UpdateBitrateConstraints(
|
||||
if (start_bitrate_bps > 0)
|
||||
delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
|
||||
delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
|
||||
|
||||
MaybeTriggerOnNetworkChanged(constraints.at_time);
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnTransportLossReport(TransportLossReport msg) {
|
||||
NetworkControlUpdate GoogCcNetworkController::OnTransportLossReport(
|
||||
TransportLossReport msg) {
|
||||
int64_t total_packets_delta =
|
||||
msg.packets_received_delta + msg.packets_lost_delta;
|
||||
bandwidth_estimation_->UpdatePacketsLost(
|
||||
msg.packets_lost_delta, total_packets_delta, msg.receive_time.ms());
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnTransportPacketsFeedback(
|
||||
NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback(
|
||||
TransportPacketsFeedback report) {
|
||||
int64_t feedback_rtt = -1;
|
||||
for (const auto& packet_feedback : report.PacketsWithFeedback()) {
|
||||
@ -294,6 +306,7 @@ void GoogCcNetworkController::OnTransportPacketsFeedback(
|
||||
result = delay_based_bwe_->IncomingPacketFeedbackVector(
|
||||
received_feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps(),
|
||||
report.feedback_time.ms());
|
||||
NetworkControlUpdate update;
|
||||
if (result.updated) {
|
||||
if (result.probe) {
|
||||
bandwidth_estimation_->SetSendBitrate(result.target_bitrate_bps);
|
||||
@ -303,24 +316,26 @@ void GoogCcNetworkController::OnTransportPacketsFeedback(
|
||||
bandwidth_estimation_->UpdateDelayBasedEstimate(report.feedback_time.ms(),
|
||||
result.target_bitrate_bps);
|
||||
// Update the estimate in the ProbeController, in case we want to probe.
|
||||
MaybeTriggerOnNetworkChanged(report.feedback_time);
|
||||
update = MaybeTriggerOnNetworkChanged(report.feedback_time);
|
||||
}
|
||||
if (result.recovered_from_overuse) {
|
||||
probe_controller_->SetAlrStartTimeMs(alr_start_time);
|
||||
probe_controller_->RequestProbe(report.feedback_time.ms());
|
||||
}
|
||||
MaybeUpdateCongestionWindow();
|
||||
update.congestion_window = MaybeUpdateCongestionWindow();
|
||||
return update;
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::MaybeUpdateCongestionWindow() {
|
||||
rtc::Optional<CongestionWindow>
|
||||
GoogCcNetworkController::MaybeUpdateCongestionWindow() {
|
||||
if (!in_cwnd_experiment_)
|
||||
return;
|
||||
return rtc::nullopt;
|
||||
// No valid RTT. Could be because send-side BWE isn't used, in which case
|
||||
// we don't try to limit the outstanding packets.
|
||||
if (!min_feedback_rtt_ms_)
|
||||
return;
|
||||
return rtc::nullopt;
|
||||
if (!last_estimate_.has_value())
|
||||
return;
|
||||
return rtc::nullopt;
|
||||
const DataSize kMinCwnd = DataSize::bytes(2 * 1500);
|
||||
TimeDelta time_window =
|
||||
TimeDelta::ms(*min_feedback_rtt_ms_ + accepted_queue_ms_);
|
||||
@ -328,12 +343,13 @@ void GoogCcNetworkController::MaybeUpdateCongestionWindow() {
|
||||
CongestionWindow msg;
|
||||
msg.enabled = true;
|
||||
msg.data_window = std::max(kMinCwnd, data_window);
|
||||
observer_->OnCongestionWindow(msg);
|
||||
RTC_LOG(LS_INFO) << "Feedback rtt: " << *min_feedback_rtt_ms_
|
||||
<< " Bitrate: " << last_estimate_->bandwidth.bps();
|
||||
return msg;
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(Timestamp at_time) {
|
||||
NetworkControlUpdate GoogCcNetworkController::MaybeTriggerOnNetworkChanged(
|
||||
Timestamp at_time) {
|
||||
int32_t estimated_bitrate_bps;
|
||||
uint8_t fraction_loss;
|
||||
int64_t rtt_ms;
|
||||
@ -352,8 +368,9 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(Timestamp at_time) {
|
||||
new_estimate.bwe_period = bwe_period;
|
||||
new_estimate.changed = true;
|
||||
last_estimate_ = new_estimate;
|
||||
OnNetworkEstimate(new_estimate);
|
||||
return OnNetworkEstimate(new_estimate);
|
||||
}
|
||||
return NetworkControlUpdate();
|
||||
}
|
||||
|
||||
bool GoogCcNetworkController::GetNetworkParameters(
|
||||
@ -385,11 +402,13 @@ bool GoogCcNetworkController::GetNetworkParameters(
|
||||
return estimate_changed;
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::OnNetworkEstimate(NetworkEstimate estimate) {
|
||||
NetworkControlUpdate GoogCcNetworkController::OnNetworkEstimate(
|
||||
NetworkEstimate estimate) {
|
||||
NetworkControlUpdate update;
|
||||
if (!estimate.changed)
|
||||
return;
|
||||
return update;
|
||||
|
||||
UpdatePacingRates(estimate.at_time);
|
||||
update.pacer_config = UpdatePacingRates(estimate.at_time);
|
||||
alr_detector_->SetEstimatedBitrate(estimate.bandwidth.bps());
|
||||
probe_controller_->SetEstimatedBitrate(estimate.bandwidth.bps(),
|
||||
estimate.at_time.ms());
|
||||
@ -400,12 +419,12 @@ void GoogCcNetworkController::OnNetworkEstimate(NetworkEstimate estimate) {
|
||||
// for legacy reasons includes target rate constraints.
|
||||
target_rate.target_rate = estimate.bandwidth;
|
||||
target_rate.network_estimate = estimate;
|
||||
observer_->OnTargetTransferRate(target_rate);
|
||||
update.target_rate = target_rate;
|
||||
return update;
|
||||
}
|
||||
|
||||
void GoogCcNetworkController::UpdatePacingRates(Timestamp at_time) {
|
||||
if (!last_estimate_)
|
||||
return;
|
||||
PacerConfig GoogCcNetworkController::UpdatePacingRates(Timestamp at_time) {
|
||||
RTC_DCHECK(last_estimate_);
|
||||
DataRate pacing_rate =
|
||||
std::max(min_pacing_rate_, last_estimate_->bandwidth) * pacing_factor_;
|
||||
DataRate padding_rate =
|
||||
@ -415,8 +434,7 @@ void GoogCcNetworkController::UpdatePacingRates(Timestamp at_time) {
|
||||
msg.time_window = TimeDelta::s(1);
|
||||
msg.data_window = pacing_rate * msg.time_window;
|
||||
msg.pad_window = padding_rate * msg.time_window;
|
||||
observer_->OnPacerConfig(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
} // namespace webrtc_cc
|
||||
} // namespace webrtc
|
||||
|
||||
@ -32,36 +32,36 @@ namespace webrtc_cc {
|
||||
class GoogCcNetworkController : public NetworkControllerInterface {
|
||||
public:
|
||||
GoogCcNetworkController(RtcEventLog* event_log,
|
||||
NetworkControllerObserver* observer,
|
||||
NetworkControllerConfig config);
|
||||
~GoogCcNetworkController() override;
|
||||
|
||||
// NetworkControllerInterface
|
||||
void OnNetworkAvailability(NetworkAvailability msg) override;
|
||||
void OnNetworkRouteChange(NetworkRouteChange msg) override;
|
||||
void OnProcessInterval(ProcessInterval msg) override;
|
||||
void OnRemoteBitrateReport(RemoteBitrateReport msg) override;
|
||||
void OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override;
|
||||
void OnSentPacket(SentPacket msg) override;
|
||||
void OnStreamsConfig(StreamsConfig msg) override;
|
||||
void OnTargetRateConstraints(TargetRateConstraints msg) override;
|
||||
void OnTransportLossReport(TransportLossReport msg) override;
|
||||
void OnTransportPacketsFeedback(TransportPacketsFeedback msg) override;
|
||||
NetworkControlUpdate OnNetworkAvailability(NetworkAvailability msg) override;
|
||||
NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange msg) override;
|
||||
NetworkControlUpdate OnProcessInterval(ProcessInterval msg) override;
|
||||
NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport msg) override;
|
||||
NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override;
|
||||
NetworkControlUpdate OnSentPacket(SentPacket msg) override;
|
||||
NetworkControlUpdate OnStreamsConfig(StreamsConfig msg) override;
|
||||
NetworkControlUpdate OnTargetRateConstraints(
|
||||
TargetRateConstraints msg) override;
|
||||
NetworkControlUpdate OnTransportLossReport(TransportLossReport msg) override;
|
||||
NetworkControlUpdate OnTransportPacketsFeedback(
|
||||
TransportPacketsFeedback msg) override;
|
||||
|
||||
private:
|
||||
void UpdateBitrateConstraints(TargetRateConstraints constraints,
|
||||
DataRate starting_rate);
|
||||
void MaybeUpdateCongestionWindow();
|
||||
void MaybeTriggerOnNetworkChanged(Timestamp at_time);
|
||||
rtc::Optional<CongestionWindow> MaybeUpdateCongestionWindow();
|
||||
NetworkControlUpdate MaybeTriggerOnNetworkChanged(Timestamp at_time);
|
||||
bool GetNetworkParameters(int32_t* estimated_bitrate_bps,
|
||||
uint8_t* fraction_loss,
|
||||
int64_t* rtt_ms,
|
||||
Timestamp at_time);
|
||||
void OnNetworkEstimate(NetworkEstimate msg);
|
||||
void UpdatePacingRates(Timestamp at_time);
|
||||
NetworkControlUpdate OnNetworkEstimate(NetworkEstimate msg);
|
||||
PacerConfig UpdatePacingRates(Timestamp at_time);
|
||||
|
||||
RtcEventLog* const event_log_;
|
||||
NetworkControllerObserver* const observer_;
|
||||
|
||||
const std::unique_ptr<ProbeController> probe_controller_;
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ class GoogCcNetworkControllerFactory
|
||||
public:
|
||||
explicit GoogCcNetworkControllerFactory(RtcEventLog*);
|
||||
NetworkControllerInterface::uptr Create(
|
||||
NetworkControllerObserver* observer,
|
||||
NetworkControllerConfig config) override;
|
||||
TimeDelta GetProcessInterval() const override;
|
||||
|
||||
|
||||
@ -28,19 +28,6 @@ class TargetTransferRateObserver {
|
||||
virtual ~TargetTransferRateObserver() = default;
|
||||
};
|
||||
|
||||
// NetworkControllerObserver is an interface implemented by observers of network
|
||||
// controllers. It contains declarations of the possible configuration messages
|
||||
// that can be sent from a network controller implementation.
|
||||
class NetworkControllerObserver : public TargetTransferRateObserver {
|
||||
public:
|
||||
// Called when congestion window configutation is changed.
|
||||
virtual void OnCongestionWindow(CongestionWindow) = 0;
|
||||
// Called when pacer configuration has changed.
|
||||
virtual void OnPacerConfig(PacerConfig) = 0;
|
||||
// Called to indicate that a new probe should be sent.
|
||||
virtual void OnProbeClusterConfig(ProbeClusterConfig) = 0;
|
||||
};
|
||||
|
||||
// Configuration sent to factory create function. The parameters here are
|
||||
// optional to use for a network controller implementation.
|
||||
struct NetworkControllerConfig {
|
||||
@ -67,26 +54,28 @@ class NetworkControllerInterface {
|
||||
virtual ~NetworkControllerInterface() = default;
|
||||
|
||||
// Called when network availabilty changes.
|
||||
virtual void OnNetworkAvailability(NetworkAvailability) = 0;
|
||||
virtual NetworkControlUpdate OnNetworkAvailability(NetworkAvailability) = 0;
|
||||
// Called when the receiving or sending endpoint changes address.
|
||||
virtual void OnNetworkRouteChange(NetworkRouteChange) = 0;
|
||||
virtual NetworkControlUpdate OnNetworkRouteChange(NetworkRouteChange) = 0;
|
||||
// Called periodically with a periodicy as specified by
|
||||
// NetworkControllerFactoryInterface::GetProcessInterval.
|
||||
virtual void OnProcessInterval(ProcessInterval) = 0;
|
||||
virtual NetworkControlUpdate OnProcessInterval(ProcessInterval) = 0;
|
||||
// Called when remotely calculated bitrate is received.
|
||||
virtual void OnRemoteBitrateReport(RemoteBitrateReport) = 0;
|
||||
virtual NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport) = 0;
|
||||
// Called round trip time has been calculated by protocol specific mechanisms.
|
||||
virtual void OnRoundTripTimeUpdate(RoundTripTimeUpdate) = 0;
|
||||
virtual NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate) = 0;
|
||||
// Called when a packet is sent on the network.
|
||||
virtual void OnSentPacket(SentPacket) = 0;
|
||||
virtual NetworkControlUpdate OnSentPacket(SentPacket) = 0;
|
||||
// Called when the stream specific configuration has been updated.
|
||||
virtual void OnStreamsConfig(StreamsConfig) = 0;
|
||||
virtual NetworkControlUpdate OnStreamsConfig(StreamsConfig) = 0;
|
||||
// Called when target transfer rate constraints has been changed.
|
||||
virtual void OnTargetRateConstraints(TargetRateConstraints) = 0;
|
||||
virtual NetworkControlUpdate OnTargetRateConstraints(
|
||||
TargetRateConstraints) = 0;
|
||||
// Called when a protocol specific calculation of packet loss has been made.
|
||||
virtual void OnTransportLossReport(TransportLossReport) = 0;
|
||||
virtual NetworkControlUpdate OnTransportLossReport(TransportLossReport) = 0;
|
||||
// Called with per packet feedback regarding receive time.
|
||||
virtual void OnTransportPacketsFeedback(TransportPacketsFeedback) = 0;
|
||||
virtual NetworkControlUpdate OnTransportPacketsFeedback(
|
||||
TransportPacketsFeedback) = 0;
|
||||
};
|
||||
|
||||
// NetworkControllerFactoryInterface is an interface for creating a network
|
||||
@ -97,7 +86,6 @@ class NetworkControllerFactoryInterface {
|
||||
// Used to create a new network controller, requires an observer to be
|
||||
// provided to handle callbacks.
|
||||
virtual NetworkControllerInterface::uptr Create(
|
||||
NetworkControllerObserver* observer,
|
||||
NetworkControllerConfig config) = 0;
|
||||
// Returns the interval by which the network controller expects
|
||||
// OnProcessInterval calls.
|
||||
|
||||
@ -63,6 +63,7 @@ struct SentPacket {
|
||||
};
|
||||
|
||||
struct PacerQueueUpdate {
|
||||
Timestamp at_time;
|
||||
TimeDelta expected_queue_time;
|
||||
};
|
||||
|
||||
@ -160,6 +161,19 @@ struct TargetTransferRate {
|
||||
NetworkEstimate network_estimate;
|
||||
};
|
||||
|
||||
// Contains updates of network controller comand state. Using optionals to
|
||||
// indicate whether a member has been updated. The array of probe clusters
|
||||
// should be used to send out probes if not empty.
|
||||
struct NetworkControlUpdate {
|
||||
NetworkControlUpdate();
|
||||
NetworkControlUpdate(const NetworkControlUpdate&);
|
||||
~NetworkControlUpdate();
|
||||
rtc::Optional<CongestionWindow> congestion_window;
|
||||
rtc::Optional<PacerConfig> pacer_config;
|
||||
std::vector<ProbeClusterConfig> probe_cluster_configs;
|
||||
rtc::Optional<TargetTransferRate> target_rate;
|
||||
};
|
||||
|
||||
// Process control
|
||||
struct ProcessInterval {
|
||||
Timestamp at_time;
|
||||
|
||||
@ -51,4 +51,9 @@ std::vector<PacketResult> TransportPacketsFeedback::PacketsWithFeedback()
|
||||
return packet_feedbacks;
|
||||
}
|
||||
|
||||
NetworkControlUpdate::NetworkControlUpdate() = default;
|
||||
NetworkControlUpdate::NetworkControlUpdate(const NetworkControlUpdate&) =
|
||||
default;
|
||||
NetworkControlUpdate::~NetworkControlUpdate() = default;
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -16,11 +16,8 @@
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
class MockNetworkControllerObserver : public NetworkControllerObserver {
|
||||
class MockTargetTransferRateObserver : public TargetTransferRateObserver {
|
||||
public:
|
||||
MOCK_METHOD1(OnCongestionWindow, void(CongestionWindow));
|
||||
MOCK_METHOD1(OnPacerConfig, void(PacerConfig));
|
||||
MOCK_METHOD1(OnProbeClusterConfig, void(ProbeClusterConfig));
|
||||
MOCK_METHOD1(OnTargetTransferRate, void(TargetTransferRate));
|
||||
};
|
||||
} // namespace test
|
||||
|
||||
@ -17,36 +17,33 @@
|
||||
#include "rtc_base/logging.h"
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
NetworkControlState::NetworkControlState() = default;
|
||||
NetworkControlState::~NetworkControlState() = default;
|
||||
NetworkControlState::NetworkControlState(const NetworkControlState&) = default;
|
||||
|
||||
NetworkControlCacher::NetworkControlCacher() = default;
|
||||
NetworkControlCacher::~NetworkControlCacher() = default;
|
||||
|
||||
void NetworkControlCacher::OnCongestionWindow(CongestionWindow msg) {
|
||||
current_state_.congestion_window = msg;
|
||||
RTC_LOG(LS_INFO) << "Received window=" << msg.data_window << "\n";
|
||||
}
|
||||
void NetworkControlCacher::OnPacerConfig(PacerConfig msg) {
|
||||
current_state_.pacer_config = msg;
|
||||
RTC_LOG(LS_INFO) << "Received pacing at:" << msg.at_time
|
||||
<< ": rate=" << msg.data_rate() << "\n";
|
||||
}
|
||||
void NetworkControlCacher::OnProbeClusterConfig(ProbeClusterConfig msg) {
|
||||
current_state_.probe_config = msg;
|
||||
RTC_LOG(LS_INFO) << "Received probe at:" << msg.at_time
|
||||
<< ": target=" << msg.target_data_rate << "\n";
|
||||
}
|
||||
void NetworkControlCacher::OnTargetTransferRate(TargetTransferRate msg) {
|
||||
current_state_.target_rate = msg;
|
||||
RTC_LOG(LS_INFO) << "Received target at:" << msg.at_time
|
||||
<< ": rate=" << msg.target_rate << "\n";
|
||||
namespace {
|
||||
void Update(NetworkControlUpdate* target, const NetworkControlUpdate& update) {
|
||||
if (update.congestion_window) {
|
||||
RTC_LOG(LS_INFO) << "Received window="
|
||||
<< update.congestion_window->data_window << "\n";
|
||||
target->congestion_window = update.congestion_window;
|
||||
}
|
||||
if (update.pacer_config) {
|
||||
RTC_LOG(LS_INFO) << "Received pacing at:" << update.pacer_config->at_time
|
||||
<< ": rate=" << update.pacer_config->data_rate() << "\n";
|
||||
target->pacer_config = update.pacer_config;
|
||||
}
|
||||
if (update.target_rate) {
|
||||
RTC_LOG(LS_INFO) << "Received target at:" << update.target_rate->at_time
|
||||
<< ": rate=" << update.target_rate->target_rate << "\n";
|
||||
target->target_rate = update.target_rate;
|
||||
}
|
||||
for (const auto& probe : update.probe_cluster_configs) {
|
||||
target->probe_cluster_configs.push_back(probe);
|
||||
RTC_LOG(LS_INFO) << "Received probe at:" << probe.at_time
|
||||
<< ": target=" << probe.target_data_rate << "\n";
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
SentPacket SimpleTargetRateProducer::ProduceNext(
|
||||
const NetworkControlState& cache,
|
||||
const NetworkControlUpdate& cache,
|
||||
Timestamp current_time,
|
||||
TimeDelta time_delta) {
|
||||
DataRate actual_send_rate =
|
||||
@ -63,8 +60,11 @@ NetworkControllerTester::NetworkControllerTester(
|
||||
: current_time_(Timestamp::seconds(100000)),
|
||||
accumulated_delay_(TimeDelta::ms(0)) {
|
||||
initial_config.constraints.at_time = current_time_;
|
||||
controller_ = factory->Create(&cacher_, initial_config);
|
||||
controller_ = factory->Create(initial_config);
|
||||
process_interval_ = factory->GetProcessInterval();
|
||||
ProcessInterval interval_msg;
|
||||
interval_msg.at_time = current_time_;
|
||||
state_ = controller_->OnProcessInterval(interval_msg);
|
||||
}
|
||||
|
||||
NetworkControllerTester::~NetworkControllerTester() = default;
|
||||
@ -94,21 +94,18 @@ void NetworkControllerTester::RunSimulation(TimeDelta duration,
|
||||
Timestamp last_process_time = current_time_;
|
||||
while (current_time_ - start_time < duration) {
|
||||
bool send_packet = true;
|
||||
NetworkControlState control_state = cacher_.GetState();
|
||||
|
||||
if (control_state.congestion_window &&
|
||||
control_state.congestion_window->enabled) {
|
||||
if (state_.congestion_window && state_.congestion_window->enabled) {
|
||||
DataSize data_in_flight = DataSize::Zero();
|
||||
for (PacketResult& packet : outstanding_packets_)
|
||||
data_in_flight += packet.sent_packet->size;
|
||||
if (data_in_flight > control_state.congestion_window->data_window)
|
||||
if (data_in_flight > state_.congestion_window->data_window)
|
||||
send_packet = false;
|
||||
}
|
||||
|
||||
if (send_packet) {
|
||||
SentPacket sent_packet =
|
||||
next_packet(cacher_.GetState(), current_time_, packet_interval);
|
||||
controller_->OnSentPacket(sent_packet);
|
||||
next_packet(state_, current_time_, packet_interval);
|
||||
Update(&state_, controller_->OnSentPacket(sent_packet));
|
||||
outstanding_packets_.push_back(SimulateSend(
|
||||
sent_packet, packet_interval, propagation_delay, actual_bandwidth));
|
||||
}
|
||||
@ -131,13 +128,13 @@ void NetworkControllerTester::RunSimulation(TimeDelta duration,
|
||||
feedback.data_in_flight = DataSize::Zero();
|
||||
for (PacketResult& packet : outstanding_packets_)
|
||||
feedback.data_in_flight += packet.sent_packet->size;
|
||||
controller_->OnTransportPacketsFeedback(feedback);
|
||||
Update(&state_, controller_->OnTransportPacketsFeedback(feedback));
|
||||
}
|
||||
current_time_ += packet_interval;
|
||||
if (current_time_ - last_process_time > process_interval_) {
|
||||
ProcessInterval interval_msg;
|
||||
interval_msg.at_time = current_time_;
|
||||
controller_->OnProcessInterval(interval_msg);
|
||||
Update(&state_, controller_->OnProcessInterval(interval_msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,36 +20,14 @@
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
struct NetworkControlState {
|
||||
NetworkControlState();
|
||||
NetworkControlState(const NetworkControlState&);
|
||||
~NetworkControlState();
|
||||
rtc::Optional<CongestionWindow> congestion_window;
|
||||
rtc::Optional<PacerConfig> pacer_config;
|
||||
rtc::Optional<ProbeClusterConfig> probe_config;
|
||||
rtc::Optional<TargetTransferRate> target_rate;
|
||||
};
|
||||
|
||||
// Produces one packet per time delta
|
||||
class SimpleTargetRateProducer {
|
||||
public:
|
||||
static SentPacket ProduceNext(const NetworkControlState& state,
|
||||
static SentPacket ProduceNext(const NetworkControlUpdate& state,
|
||||
Timestamp current_time,
|
||||
TimeDelta time_delta);
|
||||
};
|
||||
class NetworkControlCacher : public NetworkControllerObserver {
|
||||
public:
|
||||
NetworkControlCacher();
|
||||
~NetworkControlCacher() override;
|
||||
void OnCongestionWindow(CongestionWindow msg) override;
|
||||
void OnPacerConfig(PacerConfig msg) override;
|
||||
void OnProbeClusterConfig(ProbeClusterConfig) override;
|
||||
void OnTargetTransferRate(TargetTransferRate msg) override;
|
||||
NetworkControlState GetState() { return current_state_; }
|
||||
|
||||
private:
|
||||
NetworkControlState current_state_;
|
||||
};
|
||||
|
||||
class NetworkControllerTester {
|
||||
public:
|
||||
@ -58,7 +36,7 @@ class NetworkControllerTester {
|
||||
// times (This allows the PacketProducer to be stateless). It returns a
|
||||
// SentPacket struct with actual send time and packet size.
|
||||
using PacketProducer = std::function<
|
||||
SentPacket(const NetworkControlState&, Timestamp, TimeDelta)>;
|
||||
SentPacket(const NetworkControlUpdate&, Timestamp, TimeDelta)>;
|
||||
NetworkControllerTester(NetworkControllerFactoryInterface* factory,
|
||||
NetworkControllerConfig initial_config);
|
||||
~NetworkControllerTester();
|
||||
@ -78,19 +56,19 @@ class NetworkControllerTester {
|
||||
DataRate actual_bandwidth,
|
||||
TimeDelta propagation_delay,
|
||||
PacketProducer next_packet);
|
||||
NetworkControlState GetState() { return cacher_.GetState(); }
|
||||
NetworkControlUpdate GetState() { return state_; }
|
||||
|
||||
private:
|
||||
PacketResult SimulateSend(SentPacket packet,
|
||||
TimeDelta time_delta,
|
||||
TimeDelta propagation_delay,
|
||||
DataRate actual_bandwidth);
|
||||
NetworkControlCacher cacher_;
|
||||
std::unique_ptr<NetworkControllerInterface> controller_;
|
||||
TimeDelta process_interval_;
|
||||
Timestamp current_time_;
|
||||
TimeDelta accumulated_delay_;
|
||||
std::deque<PacketResult> outstanding_packets_;
|
||||
NetworkControlUpdate state_;
|
||||
};
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
@ -163,6 +163,8 @@ class SendSideCongestionController
|
||||
int64_t now_ms)
|
||||
RTC_RUN_ON(task_queue_ptr_);
|
||||
|
||||
void PostUpdates(NetworkControlUpdate update) RTC_RUN_ON(task_queue_ptr_);
|
||||
|
||||
const Clock* const clock_;
|
||||
// PacedSender is thread safe and doesn't need protection here.
|
||||
PacedSender* const pacer_;
|
||||
|
||||
@ -156,17 +156,16 @@ static PeriodicTask* StartPeriodicTask(rtc::TaskQueue* task_queue,
|
||||
} // namespace
|
||||
|
||||
namespace send_side_cc_internal {
|
||||
|
||||
class ControlHandler : public NetworkControllerObserver {
|
||||
class ControlHandler {
|
||||
public:
|
||||
ControlHandler(NetworkChangedObserver* observer,
|
||||
PacerController* pacer_controller,
|
||||
const Clock* clock);
|
||||
|
||||
void OnCongestionWindow(CongestionWindow window) override;
|
||||
void OnPacerConfig(PacerConfig config) override;
|
||||
void OnProbeClusterConfig(ProbeClusterConfig config) override;
|
||||
void OnTargetTransferRate(TargetTransferRate target_rate) override;
|
||||
void OnCongestionWindow(CongestionWindow window);
|
||||
void OnPacerConfig(PacerConfig config);
|
||||
void OnProbeClusterConfig(ProbeClusterConfig config);
|
||||
void OnTargetTransferRate(TargetTransferRate target_rate);
|
||||
|
||||
void OnNetworkAvailability(NetworkAvailability msg);
|
||||
void OnPacerQueueUpdate(PacerQueueUpdate msg);
|
||||
@ -350,7 +349,6 @@ SendSideCongestionController::SendSideCongestionController(
|
||||
task_queue_ptr_ = task_queue_.get();
|
||||
initial_config_.constraints =
|
||||
ConvertConstraints(min_bitrate_bps, max_bitrate_bps, clock_);
|
||||
initial_config_.stream_based_config = StreamsConfig();
|
||||
RTC_DCHECK(start_bitrate_bps > 0);
|
||||
initial_config_.starting_bandwidth = DataRate::bps(start_bitrate_bps);
|
||||
}
|
||||
@ -388,18 +386,15 @@ void SendSideCongestionController::MaybeRecreateControllers() {
|
||||
if (!controller_ || (feedback_only_controller != feedback_only_controller_)) {
|
||||
if (feedback_only_controller) {
|
||||
RTC_LOG(LS_INFO) << "Creating feedback based only controller";
|
||||
controller_ = controller_factory_with_feedback_->Create(
|
||||
control_handler_.get(), initial_config_);
|
||||
controller_ = controller_factory_with_feedback_->Create(initial_config_);
|
||||
process_interval_ =
|
||||
controller_factory_with_feedback_->GetProcessInterval();
|
||||
} else {
|
||||
RTC_LOG(LS_INFO) << "Creating fallback controller";
|
||||
controller_ = controller_factory_fallback_->Create(control_handler_.get(),
|
||||
initial_config_);
|
||||
controller_ = controller_factory_fallback_->Create(initial_config_);
|
||||
process_interval_ = controller_factory_fallback_->GetProcessInterval();
|
||||
}
|
||||
feedback_only_controller_ = feedback_only_controller;
|
||||
UpdateStreamsConfig();
|
||||
UpdateControllerWithTimeInterval();
|
||||
StartProcessPeriodicTasks();
|
||||
}
|
||||
@ -442,7 +437,7 @@ void SendSideCongestionController::SetBweBitrates(int min_bitrate_bps,
|
||||
task_queue_->PostTask([this, constraints, start_bitrate_bps]() {
|
||||
RTC_DCHECK_RUN_ON(task_queue_ptr_);
|
||||
if (controller_) {
|
||||
controller_->OnTargetRateConstraints(constraints);
|
||||
PostUpdates(controller_->OnTargetRateConstraints(constraints));
|
||||
} else {
|
||||
initial_config_.constraints = constraints;
|
||||
if (start_bitrate_bps > 0)
|
||||
@ -485,7 +480,7 @@ void SendSideCongestionController::OnNetworkRouteChanged(
|
||||
start_bitrate_bps > 0 ? DataRate::bps(start_bitrate_bps) : DataRate();
|
||||
task_queue_->PostTask([this, msg]() {
|
||||
RTC_DCHECK_RUN_ON(task_queue_ptr_);
|
||||
controller_->OnNetworkRouteChange(msg);
|
||||
PostUpdates(controller_->OnNetworkRouteChange(msg));
|
||||
pacer_controller_->OnNetworkRouteChange(msg);
|
||||
});
|
||||
}
|
||||
@ -535,7 +530,7 @@ void SendSideCongestionController::EnablePeriodicAlrProbing(bool enable) {
|
||||
void SendSideCongestionController::UpdateStreamsConfig() {
|
||||
streams_config_.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
|
||||
if (controller_)
|
||||
controller_->OnStreamsConfig(streams_config_);
|
||||
PostUpdates(controller_->OnStreamsConfig(streams_config_));
|
||||
}
|
||||
|
||||
TransportFeedbackObserver*
|
||||
@ -553,7 +548,7 @@ void SendSideCongestionController::SignalNetworkState(NetworkState state) {
|
||||
RTC_DCHECK_RUN_ON(task_queue_ptr_);
|
||||
network_available_ = msg.network_available;
|
||||
if (controller_) {
|
||||
controller_->OnNetworkAvailability(msg);
|
||||
PostUpdates(controller_->OnNetworkAvailability(msg));
|
||||
pacer_controller_->OnNetworkAvailability(msg);
|
||||
control_handler_->OnNetworkAvailability(msg);
|
||||
} else {
|
||||
@ -579,7 +574,7 @@ void SendSideCongestionController::OnSentPacket(
|
||||
task_queue_->PostTask([this, msg]() {
|
||||
RTC_DCHECK_RUN_ON(task_queue_ptr_);
|
||||
if (controller_)
|
||||
controller_->OnSentPacket(msg);
|
||||
PostUpdates(controller_->OnSentPacket(msg));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -594,7 +589,7 @@ void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
|
||||
task_queue_->PostTask([this, report]() {
|
||||
RTC_DCHECK_RUN_ON(task_queue_ptr_);
|
||||
if (controller_)
|
||||
controller_->OnRoundTripTimeUpdate(report);
|
||||
PostUpdates(controller_->OnRoundTripTimeUpdate(report));
|
||||
});
|
||||
}
|
||||
|
||||
@ -639,7 +634,7 @@ void SendSideCongestionController::UpdateControllerWithTimeInterval() {
|
||||
if (controller_) {
|
||||
ProcessInterval msg;
|
||||
msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
|
||||
controller_->OnProcessInterval(msg);
|
||||
PostUpdates(controller_->OnProcessInterval(msg));
|
||||
}
|
||||
}
|
||||
|
||||
@ -687,7 +682,7 @@ void SendSideCongestionController::OnTransportFeedback(
|
||||
task_queue_->PostTask([this, msg]() {
|
||||
RTC_DCHECK_RUN_ON(task_queue_ptr_);
|
||||
if (controller_)
|
||||
controller_->OnTransportPacketsFeedback(msg);
|
||||
PostUpdates(controller_->OnTransportPacketsFeedback(msg));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -702,6 +697,17 @@ void SendSideCongestionController::MaybeUpdateOutstandingData() {
|
||||
});
|
||||
}
|
||||
|
||||
void SendSideCongestionController::PostUpdates(NetworkControlUpdate update) {
|
||||
if (update.congestion_window)
|
||||
control_handler_->OnCongestionWindow(*update.congestion_window);
|
||||
if (update.pacer_config)
|
||||
control_handler_->OnPacerConfig(*update.pacer_config);
|
||||
for (const auto& probe : update.probe_cluster_configs)
|
||||
control_handler_->OnProbeClusterConfig(probe);
|
||||
if (update.target_rate)
|
||||
control_handler_->OnTargetTransferRate(*update.target_rate);
|
||||
}
|
||||
|
||||
std::vector<PacketFeedback>
|
||||
SendSideCongestionController::GetTransportFeedbackVector() const {
|
||||
RTC_DCHECK_RUNS_SERIALIZED(&worker_race_);
|
||||
@ -745,7 +751,7 @@ void SendSideCongestionController::OnReceivedEstimatedBitrate(
|
||||
task_queue_->PostTask([this, msg]() {
|
||||
RTC_DCHECK_RUN_ON(task_queue_ptr_);
|
||||
if (controller_)
|
||||
controller_->OnRemoteBitrateReport(msg);
|
||||
PostUpdates(controller_->OnRemoteBitrateReport(msg));
|
||||
});
|
||||
}
|
||||
|
||||
@ -765,7 +771,7 @@ void SendSideCongestionController::OnReceivedRtcpReceiverReport(
|
||||
report.round_trip_time = TimeDelta::ms(rtt_ms);
|
||||
report.smoothed = false;
|
||||
if (controller_)
|
||||
controller_->OnRoundTripTimeUpdate(report);
|
||||
PostUpdates(controller_->OnRoundTripTimeUpdate(report));
|
||||
});
|
||||
}
|
||||
|
||||
@ -809,7 +815,7 @@ void SendSideCongestionController::OnReceivedRtcpReceiverReportBlocks(
|
||||
msg.start_time = last_report_block_time_;
|
||||
msg.end_time = now;
|
||||
if (controller_)
|
||||
controller_->OnTransportLossReport(msg);
|
||||
PostUpdates(controller_->OnTransportLossReport(msg));
|
||||
last_report_block_time_ = now;
|
||||
}
|
||||
} // namespace webrtc_cc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user