From 8b27910cbcb121632d3e5fd109b22eb263b57c6e Mon Sep 17 00:00:00 2001 From: Ying Wang Date: Mon, 27 May 2019 17:19:08 +0200 Subject: [PATCH] Include downlink delay into congestion window size. Change-Id: I33db0c8134b6b3181a7b3abcf32a622a89ff3ab4 Bug: webrtc:10688 Change-Id: I33db0c8134b6b3181a7b3abcf32a622a89ff3ab4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138275 Commit-Queue: Ying Wang Reviewed-by: Sebastian Jansson Cr-Commit-Position: refs/heads/master@{#28079} --- api/transport/network_control.h | 2 + api/transport/network_types.h | 5 ++ call/call.cc | 2 + call/rtp_transport_controller_send.cc | 12 ++++ call/rtp_transport_controller_send.h | 1 + .../rtp_transport_controller_send_interface.h | 2 + .../test/mock_rtp_transport_controller_send.h | 1 + .../bbr/bbr_network_controller.cc | 5 ++ .../bbr/bbr_network_controller.h | 1 + .../goog_cc/goog_cc_network_control.cc | 56 ++++++++++++++----- .../goog_cc/goog_cc_network_control.h | 5 ++ .../pcc/pcc_network_controller.cc | 5 ++ .../pcc/pcc_network_controller.h | 1 + 13 files changed, 83 insertions(+), 15 deletions(-) diff --git a/api/transport/network_control.h b/api/transport/network_control.h index 99f1491f25..9c60ccb29f 100644 --- a/api/transport/network_control.h +++ b/api/transport/network_control.h @@ -72,6 +72,8 @@ class NetworkControllerInterface { virtual NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate) = 0; // Called when a packet is sent on the network. virtual NetworkControlUpdate OnSentPacket(SentPacket) = 0; + // Called when a packet is received from the remote client. + virtual NetworkControlUpdate OnReceivedPacket(ReceivedPacket) = 0; // Called when the stream specific configuration has been updated. virtual NetworkControlUpdate OnStreamsConfig(StreamsConfig) = 0; // Called when target transfer rate constraints has been changed. diff --git a/api/transport/network_types.h b/api/transport/network_types.h index a9b9a2cdbe..dfb89d2481 100644 --- a/api/transport/network_types.h +++ b/api/transport/network_types.h @@ -101,6 +101,11 @@ struct SentPacket { DataSize data_in_flight = DataSize::Zero(); }; +struct ReceivedPacket { + Timestamp receive_time = Timestamp::PlusInfinity(); + DataSize size = DataSize::Zero(); +}; + // Transport level feedback struct RemoteBitrateReport { diff --git a/call/call.cc b/call/call.cc index fb60558bf3..af8e5d7407 100644 --- a/call/call.cc +++ b/call/call.cc @@ -1498,6 +1498,8 @@ void Call::NotifyBweOfReceivedPacket(const RtpPacketReceived& packet, RTPHeader header; packet.GetHeader(&header); + transport_send_ptr_->OnReceivedPacket(packet); + if (!use_send_side_bwe && header.extension.hasTransportSequenceNumber) { // Inconsistent configuration of send side BWE. Do nothing. // TODO(nisse): Without this check, we may produce RTCP feedback diff --git a/call/rtp_transport_controller_send.cc b/call/rtp_transport_controller_send.cc index 48a7736f42..a4a5ddaac3 100644 --- a/call/rtp_transport_controller_send.cc +++ b/call/rtp_transport_controller_send.cc @@ -326,6 +326,18 @@ void RtpTransportControllerSend::OnSentPacket( transport_feedback_adapter_.GetOutstandingData().bytes()); } +void RtpTransportControllerSend::OnReceivedPacket( + const RtpPacketReceived& received_packet) { + ReceivedPacket packet_msg; + packet_msg.size = DataSize::bytes(received_packet.payload_size()); + packet_msg.receive_time = Timestamp::ms(received_packet.arrival_time_ms()); + task_queue_.PostTask([this, packet_msg]() { + RTC_DCHECK_RUN_ON(&task_queue_); + if (controller_) + PostUpdates(controller_->OnReceivedPacket(packet_msg)); + }); +} + void RtpTransportControllerSend::SetSdpBitrateParameters( const BitrateConstraints& constraints) { absl::optional updated = diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h index 71608fe55d..2ba566a236 100644 --- a/call/rtp_transport_controller_send.h +++ b/call/rtp_transport_controller_send.h @@ -96,6 +96,7 @@ class RtpTransportControllerSend final int64_t GetFirstPacketTimeMs() const override; void EnablePeriodicAlrProbing(bool enable) override; void OnSentPacket(const rtc::SentPacket& sent_packet) override; + void OnReceivedPacket(const RtpPacketReceived& received_packet) override; void SetSdpBitrateParameters(const BitrateConstraints& constraints) override; void SetClientBitratePreferences(const BitrateSettings& preferences) override; diff --git a/call/rtp_transport_controller_send_interface.h b/call/rtp_transport_controller_send_interface.h index 0db4f80919..611edad607 100644 --- a/call/rtp_transport_controller_send_interface.h +++ b/call/rtp_transport_controller_send_interface.h @@ -28,6 +28,7 @@ #include "modules/rtp_rtcp/include/report_block_data.h" #include "modules/rtp_rtcp/include/rtcp_statistics.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" namespace rtc { struct SentPacket; @@ -149,6 +150,7 @@ class RtpTransportControllerSendInterface { virtual int64_t GetFirstPacketTimeMs() const = 0; virtual void EnablePeriodicAlrProbing(bool enable) = 0; virtual void OnSentPacket(const rtc::SentPacket& sent_packet) = 0; + virtual void OnReceivedPacket(const RtpPacketReceived& received_packet) = 0; virtual void SetSdpBitrateParameters( const BitrateConstraints& constraints) = 0; diff --git a/call/test/mock_rtp_transport_controller_send.h b/call/test/mock_rtp_transport_controller_send.h index b5a0a856a6..625ba64b9f 100644 --- a/call/test/mock_rtp_transport_controller_send.h +++ b/call/test/mock_rtp_transport_controller_send.h @@ -66,6 +66,7 @@ class MockRtpTransportControllerSend MOCK_METHOD1(SetSdpBitrateParameters, void(const BitrateConstraints&)); MOCK_METHOD1(SetClientBitratePreferences, void(const BitrateSettings&)); MOCK_METHOD1(OnTransportOverheadChanged, void(size_t)); + MOCK_METHOD1(OnReceivedPacket, void(const RtpPacketReceived&)); }; } // namespace webrtc #endif // CALL_TEST_MOCK_RTP_TRANSPORT_CONTROLLER_SEND_H_ diff --git a/modules/congestion_controller/bbr/bbr_network_controller.cc b/modules/congestion_controller/bbr/bbr_network_controller.cc index c61a794f97..2e395e9fd0 100644 --- a/modules/congestion_controller/bbr/bbr_network_controller.cc +++ b/modules/congestion_controller/bbr/bbr_network_controller.cc @@ -498,6 +498,11 @@ NetworkControlUpdate BbrNetworkController::OnTransportLossReport( return NetworkControlUpdate(); } +NetworkControlUpdate BbrNetworkController::OnReceivedPacket( + ReceivedPacket msg) { + return NetworkControlUpdate(); +} + TimeDelta BbrNetworkController::GetMinRtt() const { return !min_rtt_.IsZero() ? min_rtt_ : TimeDelta::us(rtt_stats_.initial_rtt_us()); diff --git a/modules/congestion_controller/bbr/bbr_network_controller.h b/modules/congestion_controller/bbr/bbr_network_controller.h index 8535d70d23..8598cadab1 100644 --- a/modules/congestion_controller/bbr/bbr_network_controller.h +++ b/modules/congestion_controller/bbr/bbr_network_controller.h @@ -164,6 +164,7 @@ class BbrNetworkController : public NetworkControllerInterface { NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport msg) override; NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override; NetworkControlUpdate OnTransportLossReport(TransportLossReport msg) override; + NetworkControlUpdate OnReceivedPacket(ReceivedPacket msg) override; NetworkControlUpdate CreateRateUpdate(Timestamp at_time) const; diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc index 540c01a9a0..ea71a982b1 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -88,6 +88,9 @@ GoogCcNetworkController::GoogCcNetworkController(NetworkControllerConfig config, safe_reset_acknowledged_rate_("ack"), use_stable_bandwidth_estimate_( IsEnabled(key_value_config_, "WebRTC-Bwe-StableBandwidthEstimate")), + use_downlink_delay_for_congestion_window_( + IsEnabled(key_value_config_, + "WebRTC-Bwe-CongestionWindowDownlinkDelay")), fall_back_to_probe_rate_( IsEnabled(key_value_config_, "WebRTC-Bwe-ProbeRateFallback")), use_min_allocatable_as_lower_bound_( @@ -221,6 +224,15 @@ NetworkControlUpdate GoogCcNetworkController::OnProcessInterval( update.probe_cluster_configs.insert(update.probe_cluster_configs.end(), probes.begin(), probes.end()); + time_since_last_received_packet_ = + !last_packet_received_time_.IsMinusInfinity() && + use_downlink_delay_for_congestion_window_ + ? msg.at_time - last_packet_received_time_ + : TimeDelta::Zero(); + if (rate_control_settings_.UseCongestionWindow() && + (time_since_last_received_packet_ > TimeDelta::Zero())) { + UpdateCongestionWindowSize(); + } MaybeTriggerOnNetworkChanged(&update, msg.at_time); return update; } @@ -287,6 +299,12 @@ NetworkControlUpdate GoogCcNetworkController::OnSentPacket( } } +NetworkControlUpdate GoogCcNetworkController::OnReceivedPacket( + ReceivedPacket received_packet) { + last_packet_received_time_ = received_packet.receive_time; + return NetworkControlUpdate(); +} + NetworkControlUpdate GoogCcNetworkController::OnStreamsConfig( StreamsConfig msg) { NetworkControlUpdate update; @@ -387,6 +405,28 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportLossReport( return NetworkControlUpdate(); } +void GoogCcNetworkController::UpdateCongestionWindowSize() { + if (feedback_max_rtts_.empty()) + return; + int64_t min_feedback_max_rtt_ms = + *std::min_element(feedback_max_rtts_.begin(), feedback_max_rtts_.end()); + + const DataSize kMinCwnd = DataSize::bytes(2 * 1500); + TimeDelta time_window = + TimeDelta::ms( + min_feedback_max_rtt_ms + + rate_control_settings_.GetCongestionWindowAdditionalTimeMs()) + + time_since_last_received_packet_; + DataSize data_window = last_raw_target_rate_ * time_window; + if (current_data_window_) { + data_window = + std::max(kMinCwnd, (data_window + current_data_window_.value()) / 2); + } else { + data_window = std::max(kMinCwnd, data_window); + } + current_data_window_ = data_window; +} + NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback( TransportPacketsFeedback report) { if (report.packet_feedbacks.empty()) { @@ -537,21 +577,7 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback( // we don't try to limit the outstanding packets. if (rate_control_settings_.UseCongestionWindow() && max_feedback_rtt.IsFinite()) { - int64_t min_feedback_max_rtt_ms = - *std::min_element(feedback_max_rtts_.begin(), feedback_max_rtts_.end()); - - const DataSize kMinCwnd = DataSize::bytes(2 * 1500); - TimeDelta time_window = TimeDelta::ms( - min_feedback_max_rtt_ms + - rate_control_settings_.GetCongestionWindowAdditionalTimeMs()); - DataSize data_window = last_raw_target_rate_ * time_window; - if (current_data_window_) { - data_window = - std::max(kMinCwnd, (data_window + current_data_window_.value()) / 2); - } else { - data_window = std::max(kMinCwnd, data_window); - } - current_data_window_ = data_window; + UpdateCongestionWindowSize(); } if (congestion_window_pushback_controller_ && current_data_window_) { congestion_window_pushback_controller_->SetDataWindow( diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.h b/modules/congestion_controller/goog_cc/goog_cc_network_control.h index 7411c1e399..8ac7341bd0 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h @@ -57,6 +57,7 @@ class GoogCcNetworkController : public NetworkControllerInterface { NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport msg) override; NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override; NetworkControlUpdate OnSentPacket(SentPacket msg) override; + NetworkControlUpdate OnReceivedPacket(ReceivedPacket msg) override; NetworkControlUpdate OnStreamsConfig(StreamsConfig msg) override; NetworkControlUpdate OnTargetRateConstraints( TargetRateConstraints msg) override; @@ -73,6 +74,7 @@ class GoogCcNetworkController : public NetworkControllerInterface { void ClampConstraints(); void MaybeTriggerOnNetworkChanged(NetworkControlUpdate* update, Timestamp at_time); + void UpdateCongestionWindowSize(); PacerConfig GetPacingRates(Timestamp at_time) const; const FieldTrialBasedConfig trial_based_config_; @@ -82,6 +84,7 @@ class GoogCcNetworkController : public NetworkControllerInterface { FieldTrialFlag safe_reset_on_route_change_; FieldTrialFlag safe_reset_acknowledged_rate_; const bool use_stable_bandwidth_estimate_; + const bool use_downlink_delay_for_congestion_window_; const bool fall_back_to_probe_rate_; const bool use_min_allocatable_as_lower_bound_; const RateControlSettings rate_control_settings_; @@ -119,6 +122,8 @@ class GoogCcNetworkController : public NetworkControllerInterface { int32_t last_estimated_bitrate_bps_ = 0; uint8_t last_estimated_fraction_loss_ = 0; int64_t last_estimated_rtt_ms_ = 0; + Timestamp last_packet_received_time_ = Timestamp::MinusInfinity(); + TimeDelta time_since_last_received_packet_ = TimeDelta::Zero(); double pacing_factor_; DataRate min_total_allocated_bitrate_; diff --git a/modules/congestion_controller/pcc/pcc_network_controller.cc b/modules/congestion_controller/pcc/pcc_network_controller.cc index e5385f6f3e..a284710d8f 100644 --- a/modules/congestion_controller/pcc/pcc_network_controller.cc +++ b/modules/congestion_controller/pcc/pcc_network_controller.cc @@ -376,5 +376,10 @@ NetworkControlUpdate PccNetworkController::OnStreamsConfig(StreamsConfig msg) { return NetworkControlUpdate(); } +NetworkControlUpdate PccNetworkController::OnReceivedPacket( + ReceivedPacket msg) { + return NetworkControlUpdate(); +} + } // namespace pcc } // namespace webrtc diff --git a/modules/congestion_controller/pcc/pcc_network_controller.h b/modules/congestion_controller/pcc/pcc_network_controller.h index 90b2bfc916..befabbf91e 100644 --- a/modules/congestion_controller/pcc/pcc_network_controller.h +++ b/modules/congestion_controller/pcc/pcc_network_controller.h @@ -77,6 +77,7 @@ class PccNetworkController : public NetworkControllerInterface { NetworkControlUpdate OnRemoteBitrateReport(RemoteBitrateReport msg) override; NetworkControlUpdate OnRoundTripTimeUpdate(RoundTripTimeUpdate msg) override; NetworkControlUpdate OnTransportLossReport(TransportLossReport msg) override; + NetworkControlUpdate OnReceivedPacket(ReceivedPacket msg) override; private: void UpdateSendingRateAndMode();