Chromium Code Reviews| Index: webrtc/modules/congestion_controller/send_side_congestion_controller.cc | 
| diff --git a/webrtc/modules/congestion_controller/send_side_congestion_controller.cc b/webrtc/modules/congestion_controller/send_side_congestion_controller.cc | 
| index 60e692ccdfe46c4ea3e04b110a31448af0da7ea0..8ebb7a1a39568e3358f0c3ed66fce0f167296809 100644 | 
| --- a/webrtc/modules/congestion_controller/send_side_congestion_controller.cc | 
| +++ b/webrtc/modules/congestion_controller/send_side_congestion_controller.cc | 
| @@ -23,10 +23,20 @@ | 
| #include "webrtc/rtc_base/ptr_util.h" | 
| #include "webrtc/rtc_base/rate_limiter.h" | 
| #include "webrtc/rtc_base/socket.h" | 
| +#include "webrtc/system_wrappers/include/field_trial.h" | 
| namespace webrtc { | 
| namespace { | 
| +const char kCwndExperiment[] = "WebRTC-CwndExperiment"; | 
| + | 
| +bool CwndExperimentEnabled() { | 
| + std::string experiment_string = | 
| + webrtc::field_trial::FindFullName(kCwndExperiment); | 
| + // The experiment is enabled iff the field trial string begins with "Enabled". | 
| + return experiment_string.find("Enabled") == 0; | 
| +} | 
| + | 
| static const int64_t kRetransmitWindowSizeMs = 500; | 
| // Makes sure that the bitrate and the min, max values are in valid range. | 
| @@ -98,8 +108,11 @@ SendSideCongestionController::SendSideCongestionController( | 
| last_reported_fraction_loss_(0), | 
| last_reported_rtt_(0), | 
| network_state_(kNetworkUp), | 
| + pause_pacer_(false), | 
| 
 
philipel
2017/08/02 15:35:15
I assume you duplicate the paced sender pause stat
 
stefan-webrtc
2017/08/04 09:50:00
Done.
 
 | 
| + pacer_paused_(false), | 
| min_bitrate_bps_(congestion_controller::GetMinBitrateBps()), | 
| - delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)) { | 
| + delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)), | 
| + in_cwnd_experiment_(CwndExperimentEnabled()) { | 
| delay_based_bwe_->SetMinBitrate(min_bitrate_bps_); | 
| } | 
| @@ -216,13 +229,9 @@ SendSideCongestionController::GetTransportFeedbackObserver() { | 
| void SendSideCongestionController::SignalNetworkState(NetworkState state) { | 
| LOG(LS_INFO) << "SignalNetworkState " | 
| << (state == kNetworkUp ? "Up" : "Down"); | 
| - if (state == kNetworkUp) { | 
| - pacer_->Resume(); | 
| - } else { | 
| - pacer_->Pause(); | 
| - } | 
| { | 
| rtc::CritScope cs(&network_state_lock_); | 
| + pause_pacer_ = state == kNetworkDown; | 
| network_state_ = state; | 
| } | 
| probe_controller_->OnNetworkStateChanged(state); | 
| @@ -243,6 +252,7 @@ void SendSideCongestionController::OnSentPacket( | 
| return; | 
| transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id, | 
| sent_packet.send_time_ms); | 
| + LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes()); | 
| } | 
| void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms, | 
| @@ -256,6 +266,20 @@ int64_t SendSideCongestionController::TimeUntilNextProcess() { | 
| } | 
| void SendSideCongestionController::Process() { | 
| + bool pause_pacer; | 
| + // TODO(holmer): Once this class is running on a task queue we should | 
| + // replace this with a task instead. | 
| + { | 
| + rtc::CritScope lock(&network_state_lock_); | 
| + pause_pacer = pause_pacer_; | 
| + } | 
| + if (pause_pacer && !pacer_paused_) { | 
| + pacer_->Pause(); | 
| + pacer_paused_ = true; | 
| + } else if (!pause_pacer && pacer_paused_) { | 
| + pacer_->Resume(); | 
| + pacer_paused_ = false; | 
| + } | 
| bitrate_controller_->Process(); | 
| probe_controller_->Process(); | 
| MaybeTriggerOnNetworkChanged(); | 
| @@ -287,6 +311,32 @@ void SendSideCongestionController::OnTransportFeedback( | 
| } | 
| if (result.updated) | 
| bitrate_controller_->OnDelayBasedBweResult(result); | 
| + LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes()); | 
| +} | 
| + | 
| +void SendSideCongestionController::LimitOutstandingBytes( | 
| + size_t num_outstanding_bytes) { | 
| + if (!in_cwnd_experiment_) | 
| + return; | 
| + { | 
| + rtc::CritScope lock(&network_state_lock_); | 
| + int64_t min_rtt_ms = transport_feedback_adapter_.GetMinFeedbackLoopRtt(); | 
| + // 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_rtt_ms < 0) | 
| + return; | 
| + const int64_t kAcceptedQueueMs = 250; | 
| 
 
philipel
2017/08/02 15:35:15
Just curios, why do we use a hard coded additional
 
stefan-webrtc
2017/08/04 09:50:00
That'd be an option as well. My reasoning is that
 
 | 
| + size_t max_outstanding_bytes = std::max<size_t>( | 
| + (min_rtt_ms + kAcceptedQueueMs) * last_reported_bitrate_bps_ / 1000 / 8, | 
| + 2 * 1500); | 
| 
 
philipel
2017/08/02 15:35:15
kMinCwndBytes = 2*1500
 
stefan-webrtc
2017/08/04 09:50:00
Done.
 
 | 
| + LOG(LS_INFO) << clock_->TimeInMilliseconds() | 
| + << " Outstanding bytes: " << num_outstanding_bytes | 
| + << " pacer queue: " << pacer_->QueueInMs() | 
| + << " max outstanding: " << max_outstanding_bytes; | 
| + LOG(LS_INFO) << "Feedback rtt: " << min_rtt_ms | 
| + << " Bitrate: " << last_reported_bitrate_bps_; | 
| + pause_pacer_ = num_outstanding_bytes > max_outstanding_bytes; | 
| + } | 
| } | 
| std::vector<PacketFeedback> |