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:
Sebastian Jansson 2018-04-09 13:21:35 +02:00 committed by Commit Bot
parent 24697ab200
commit ae9057831f
17 changed files with 264 additions and 239 deletions

View File

@ -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 {

View File

@ -21,7 +21,6 @@ class BbrNetworkControllerFactory : public NetworkControllerFactoryInterface {
public:
BbrNetworkControllerFactory();
std::unique_ptr<NetworkControllerInterface> Create(
NetworkControllerObserver* observer,
NetworkControllerConfig config) override;
TimeDelta GetProcessInterval() const override;
};

View File

@ -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_

View File

@ -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_;

View File

@ -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.

View File

@ -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 {

View File

@ -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

View File

@ -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_;

View File

@ -21,7 +21,6 @@ class GoogCcNetworkControllerFactory
public:
explicit GoogCcNetworkControllerFactory(RtcEventLog*);
NetworkControllerInterface::uptr Create(
NetworkControllerObserver* observer,
NetworkControllerConfig config) override;
TimeDelta GetProcessInterval() const override;

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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));
}
}
}

View File

@ -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

View File

@ -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_;

View File

@ -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