Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: webrtc/modules/congestion_controller/delay_based_bwe.cc

Issue 2235373004: Probing: Add support for exponential startup probing (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@fix_probing2
Patch Set: lint fix Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/congestion_controller/delay_based_bwe.h" 11 #include "webrtc/modules/congestion_controller/delay_based_bwe.h"
12 12
13 #include <math.h> 13 #include <math.h>
14 14
15 #include <algorithm> 15 #include <algorithm>
16 16
17 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
18 #include "webrtc/base/constructormagic.h" 18 #include "webrtc/base/constructormagic.h"
19 #include "webrtc/base/logging.h" 19 #include "webrtc/base/logging.h"
20 #include "webrtc/base/thread_annotations.h" 20 #include "webrtc/base/thread_annotations.h"
21 #include "webrtc/modules/congestion_controller/include/congestion_controller.h"
21 #include "webrtc/modules/pacing/paced_sender.h" 22 #include "webrtc/modules/pacing/paced_sender.h"
22 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h" 23 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h"
23 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 24 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
24 #include "webrtc/system_wrappers/include/metrics.h" 25 #include "webrtc/system_wrappers/include/metrics.h"
25 #include "webrtc/typedefs.h" 26 #include "webrtc/typedefs.h"
26 27
27 namespace { 28 namespace {
28 constexpr int kTimestampGroupLengthMs = 5; 29 constexpr int kTimestampGroupLengthMs = 5;
29 constexpr int kAbsSendTimeFraction = 18; 30 constexpr int kAbsSendTimeFraction = 18;
30 constexpr int kAbsSendTimeInterArrivalUpshift = 8; 31 constexpr int kAbsSendTimeInterArrivalUpshift = 8;
31 constexpr int kInterArrivalShift = 32 constexpr int kInterArrivalShift =
32 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; 33 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift;
33 constexpr double kTimestampToMs = 34 constexpr double kTimestampToMs =
34 1000.0 / static_cast<double>(1 << kInterArrivalShift); 35 1000.0 / static_cast<double>(1 << kInterArrivalShift);
35 // This ssrc is used to fulfill the current API but will be removed 36 // This ssrc is used to fulfill the current API but will be removed
36 // after the API has been changed. 37 // after the API has been changed.
37 constexpr uint32_t kFixedSsrc = 0; 38 constexpr uint32_t kFixedSsrc = 0;
38 } // namespace 39 } // namespace
39 40
40 namespace webrtc { 41 namespace webrtc {
41 42
42 DelayBasedBwe::DelayBasedBwe(RemoteBitrateObserver* observer, Clock* clock) 43 DelayBasedBwe::DelayBasedBwe(RemoteBitrateObserver* observer, Clock* clock)
43 : clock_(clock), 44 : clock_(clock),
44 observer_(observer), 45 observer_(observer),
45 inter_arrival_(), 46 inter_arrival_(),
46 estimator_(), 47 estimator_(),
47 detector_(OverUseDetectorOptions()), 48 detector_(OverUseDetectorOptions()),
48 incoming_bitrate_(kBitrateWindowMs, 8000), 49 incoming_bitrate_(kBitrateWindowMs, 8000),
49 first_packet_time_ms_(-1),
50 last_update_ms_(-1), 50 last_update_ms_(-1),
51 last_seen_packet_ms_(-1), 51 last_seen_packet_ms_(-1),
52 uma_recorded_(false) { 52 uma_recorded_(false) {
53 RTC_DCHECK(observer_); 53 RTC_DCHECK(observer_);
54 network_thread_.DetachFromThread(); 54 network_thread_.DetachFromThread();
55 } 55 }
56 56
57 void DelayBasedBwe::IncomingPacketFeedbackVector( 57 void DelayBasedBwe::IncomingPacketFeedbackVector(
58 const std::vector<PacketInfo>& packet_feedback_vector) { 58 const std::vector<PacketInfo>& packet_feedback_vector) {
59 RTC_DCHECK(network_thread_.CalledOnValidThread()); 59 RTC_DCHECK(network_thread_.CalledOnValidThread());
60 if (!uma_recorded_) { 60 if (!uma_recorded_) {
61 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, 61 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram,
62 BweNames::kSendSideTransportSeqNum, 62 BweNames::kSendSideTransportSeqNum,
63 BweNames::kBweNamesMax); 63 BweNames::kBweNamesMax);
64 uma_recorded_ = true; 64 uma_recorded_ = true;
65 } 65 }
66 for (const auto& packet_info : packet_feedback_vector) { 66 for (const auto& packet_info : packet_feedback_vector) {
67 IncomingPacketInfo(packet_info); 67 IncomingPacketInfo(packet_info);
68 } 68 }
69 } 69 }
70 70
71 void DelayBasedBwe::IncomingPacketInfo(const PacketInfo& info) { 71 void DelayBasedBwe::IncomingPacketInfo(const PacketInfo& info) {
72 int64_t now_ms = clock_->TimeInMilliseconds(); 72 int64_t now_ms = clock_->TimeInMilliseconds();
73 73
74 if (first_packet_time_ms_ == -1)
75 first_packet_time_ms_ = now_ms;
76
77 incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms); 74 incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms);
78 bool update_estimate = false; 75 bool delay_based_bwe_changed = false;
79 uint32_t target_bitrate_bps = 0; 76 uint32_t target_bitrate_bps = 0;
80 { 77 {
81 rtc::CritScope lock(&crit_); 78 rtc::CritScope lock(&crit_);
82 79
83 // Reset if the stream has timed out. 80 // Reset if the stream has timed out.
84 if (last_seen_packet_ms_ == -1 || 81 if (last_seen_packet_ms_ == -1 ||
85 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { 82 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) {
86 inter_arrival_.reset(new InterArrival( 83 inter_arrival_.reset(new InterArrival(
87 (kTimestampGroupLengthMs << kInterArrivalShift) / 1000, 84 (kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
88 kTimestampToMs, true)); 85 kTimestampToMs, true));
89 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); 86 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions()));
90 } 87 }
91 last_seen_packet_ms_ = now_ms; 88 last_seen_packet_ms_ = now_ms;
92 89
93 if (info.probe_cluster_id != PacketInfo::kNotAProbe) {
94 int bps = probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info);
95 if (bps > 0) {
96 remote_rate_.SetEstimate(bps, info.arrival_time_ms);
97 observer_->OnProbeBitrate(bps);
98 update_estimate = true;
99 }
100 }
101
102 uint32_t send_time_24bits = 90 uint32_t send_time_24bits =
103 static_cast<uint32_t>(((static_cast<uint64_t>(info.send_time_ms) 91 static_cast<uint32_t>(((static_cast<uint64_t>(info.send_time_ms)
104 << kAbsSendTimeFraction) + 92 << kAbsSendTimeFraction) +
105 500) / 93 500) /
106 1000) & 94 1000) &
107 0x00FFFFFF; 95 0x00FFFFFF;
108 // Shift up send time to use the full 32 bits that inter_arrival works with, 96 // Shift up send time to use the full 32 bits that inter_arrival works with,
109 // so wrapping works properly. 97 // so wrapping works properly.
110 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; 98 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift;
111 99
112 uint32_t ts_delta = 0; 100 uint32_t ts_delta = 0;
113 int64_t t_delta = 0; 101 int64_t t_delta = 0;
114 int size_delta = 0; 102 int size_delta = 0;
115 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms, 103 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms,
116 info.payload_size, &ts_delta, &t_delta, 104 info.payload_size, &ts_delta, &t_delta,
117 &size_delta)) { 105 &size_delta)) {
118 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); 106 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
119 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State()); 107 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State());
120 detector_.Detect(estimator_->offset(), ts_delta_ms, 108 detector_.Detect(estimator_->offset(), ts_delta_ms,
121 estimator_->num_of_deltas(), info.arrival_time_ms); 109 estimator_->num_of_deltas(), info.arrival_time_ms);
122 } 110 }
123 111
124 if (!update_estimate) { 112 int probing_bps = 0;
125 // Check if it's time for a periodic update or if we should update because 113 if (info.probe_cluster_id != PacketInfo::kNotAProbe) {
126 // of an over-use. 114 probing_bps =
127 if (last_update_ms_ == -1 || 115 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info);
128 now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval()) {
129 update_estimate = true;
130 } else if (detector_.State() == kBwOverusing) {
131 rtc::Optional<uint32_t> incoming_rate =
132 incoming_bitrate_.Rate(info.arrival_time_ms);
133 if (incoming_rate &&
134 remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) {
135 update_estimate = true;
136 }
137 }
138 } 116 }
139 117
140 if (update_estimate) { 118 // Currently overusing the bandwidth.
141 // The first overuse should immediately trigger a new estimate. 119 if (detector_.State() == kBwOverusing) {
142 // We also have to update the estimate immediately if we are overusing 120 rtc::Optional<uint32_t> incoming_rate =
143 // and the target bitrate is too high compared to what we are receiving. 121 incoming_bitrate_.Rate(info.arrival_time_ms);
144 const RateControlInput input(detector_.State(), 122 if (incoming_rate &&
145 incoming_bitrate_.Rate(info.arrival_time_ms), 123 remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) {
146 estimator_->var_noise()); 124 delay_based_bwe_changed =
147 remote_rate_.Update(&input, now_ms); 125 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps);
148 target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms); 126 }
149 update_estimate = remote_rate_.ValidEstimate(); 127 } else if (probing_bps > 0) {
128 // No overuse, but probing measured a bitrate.
129 remote_rate_.SetEstimate(probing_bps, info.arrival_time_ms);
130 observer_->OnProbeBitrate(probing_bps);
131 delay_based_bwe_changed =
132 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps);
133 }
134 if (!delay_based_bwe_changed &&
135 (last_update_ms_ == -1 ||
136 now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval())) {
137 delay_based_bwe_changed =
138 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps);
150 } 139 }
151 } 140 }
152 141
153 if (update_estimate) { 142 if (delay_based_bwe_changed) {
154 last_update_ms_ = now_ms; 143 last_update_ms_ = now_ms;
155 observer_->OnReceiveBitrateChanged({kFixedSsrc}, target_bitrate_bps); 144 observer_->OnReceiveBitrateChanged({kFixedSsrc}, target_bitrate_bps);
156 } 145 }
157 } 146 }
158 147
148 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms,
149 int64_t now_ms,
150 uint32_t* target_bitrate_bps) {
151 // The first overuse should immediately trigger a new estimate.
152 // We also have to update the estimate immediately if we are overusing
153 // and the target bitrate is too high compared to what we are receiving.
154 const RateControlInput input(detector_.State(),
155 incoming_bitrate_.Rate(arrival_time_ms),
156 estimator_->var_noise());
157 remote_rate_.Update(&input, now_ms);
158 *target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms);
159 return remote_rate_.ValidEstimate();
160 }
161
159 void DelayBasedBwe::Process() {} 162 void DelayBasedBwe::Process() {}
160 163
161 int64_t DelayBasedBwe::TimeUntilNextProcess() { 164 int64_t DelayBasedBwe::TimeUntilNextProcess() {
162 const int64_t kDisabledModuleTime = 1000; 165 const int64_t kDisabledModuleTime = 1000;
163 return kDisabledModuleTime; 166 return kDisabledModuleTime;
164 } 167 }
165 168
166 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { 169 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
167 rtc::CritScope lock(&crit_); 170 rtc::CritScope lock(&crit_);
168 remote_rate_.SetRtt(avg_rtt_ms); 171 remote_rate_.SetRtt(avg_rtt_ms);
(...skipping 18 matching lines...) Expand all
187 return true; 190 return true;
188 } 191 }
189 192
190 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { 193 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) {
191 // Called from both the configuration thread and the network thread. Shouldn't 194 // Called from both the configuration thread and the network thread. Shouldn't
192 // be called from the network thread in the future. 195 // be called from the network thread in the future.
193 rtc::CritScope lock(&crit_); 196 rtc::CritScope lock(&crit_);
194 remote_rate_.SetMinBitrate(min_bitrate_bps); 197 remote_rate_.SetMinBitrate(min_bitrate_bps);
195 } 198 }
196 } // namespace webrtc 199 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698