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

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: Updates Created 4 years, 4 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 36
36 // This ssrc is used to fulfill the current API but will be removed 37 // This ssrc is used to fulfill the current API but will be removed
37 // after the API has been changed. 38 // after the API has been changed.
38 constexpr uint32_t kFixedSsrc = 0; 39 constexpr uint32_t kFixedSsrc = 0;
39 } // namespace 40 } // namespace
40 41
41 namespace webrtc { 42 namespace webrtc {
42 43
43 DelayBasedBwe::DelayBasedBwe(RemoteBitrateObserver* observer, Clock* clock) 44 DelayBasedBwe::DelayBasedBwe(CongestionController* controller, Clock* clock)
44 : clock_(clock), 45 : clock_(clock),
45 observer_(observer), 46 controller_(controller),
46 inter_arrival_(), 47 inter_arrival_(),
47 estimator_(), 48 estimator_(),
48 detector_(OverUseDetectorOptions()), 49 detector_(OverUseDetectorOptions()),
49 incoming_bitrate_(kBitrateWindowMs, 8000), 50 incoming_bitrate_(kBitrateWindowMs, 8000),
50 first_packet_time_ms_(-1),
51 last_update_ms_(-1), 51 last_update_ms_(-1),
52 last_seen_packet_ms_(-1), 52 last_seen_packet_ms_(-1),
53 uma_recorded_(false) { 53 uma_recorded_(false) {
54 RTC_DCHECK(observer_); 54 RTC_DCHECK(controller_);
55 network_thread_.DetachFromThread(); 55 network_thread_.DetachFromThread();
56 } 56 }
57 57
58 void DelayBasedBwe::IncomingPacketFeedbackVector( 58 void DelayBasedBwe::IncomingPacketFeedbackVector(
59 const std::vector<PacketInfo>& packet_feedback_vector) { 59 const std::vector<PacketInfo>& packet_feedback_vector) {
60 RTC_DCHECK(network_thread_.CalledOnValidThread()); 60 RTC_DCHECK(network_thread_.CalledOnValidThread());
61 if (!uma_recorded_) { 61 if (!uma_recorded_) {
62 RTC_LOGGED_HISTOGRAM_ENUMERATION(kBweTypeHistogram, 62 RTC_LOGGED_HISTOGRAM_ENUMERATION(kBweTypeHistogram,
63 BweNames::kSendSideTransportSeqNum, 63 BweNames::kSendSideTransportSeqNum,
64 BweNames::kBweNamesMax); 64 BweNames::kBweNamesMax);
65 uma_recorded_ = true; 65 uma_recorded_ = true;
66 } 66 }
67 for (const auto& packet_info : packet_feedback_vector) { 67 for (const auto& packet_info : packet_feedback_vector) {
68 IncomingPacketInfo(packet_info); 68 IncomingPacketInfo(packet_info);
69 } 69 }
70 } 70 }
71 71
72 void DelayBasedBwe::IncomingPacketInfo(const PacketInfo& info) { 72 void DelayBasedBwe::IncomingPacketInfo(const PacketInfo& info) {
73 int64_t now_ms = clock_->TimeInMilliseconds(); 73 int64_t now_ms = clock_->TimeInMilliseconds();
74 74
75 if (first_packet_time_ms_ == -1)
76 first_packet_time_ms_ = now_ms;
77
78 incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms); 75 incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms);
79 bool update_estimate = false; 76 bool delay_based_bwe_changed = false;
80 uint32_t target_bitrate_bps = 0; 77 int target_bitrate_bps = 0;
81 { 78 {
82 rtc::CritScope lock(&crit_); 79 rtc::CritScope lock(&crit_);
83 80
84 // Reset if the stream has timed out. 81 // Reset if the stream has timed out.
85 if (last_seen_packet_ms_ == -1 || 82 if (last_seen_packet_ms_ == -1 ||
86 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { 83 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) {
87 inter_arrival_.reset(new InterArrival( 84 inter_arrival_.reset(new InterArrival(
88 (kTimestampGroupLengthMs << kInterArrivalShift) / 1000, 85 (kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
89 kTimestampToMs, true)); 86 kTimestampToMs, true));
90 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); 87 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions()));
91 } 88 }
92 last_seen_packet_ms_ = now_ms; 89 last_seen_packet_ms_ = now_ms;
93 90
94 if (info.probe_cluster_id != PacketInfo::kNotAProbe) {
95 ProbingResult probe_result =
96 probe_bitrate_estimator_.PacketFeedback(info);
97 if (probe_result.valid()) {
98 remote_rate_.SetEstimate(probe_result.bps, probe_result.timestamp);
99 update_estimate = true;
100 }
101 }
102
103 uint32_t send_time_24bits = 91 uint32_t send_time_24bits =
104 static_cast<uint32_t>(((static_cast<uint64_t>(info.send_time_ms) 92 static_cast<uint32_t>(((static_cast<uint64_t>(info.send_time_ms)
105 << kAbsSendTimeFraction) + 93 << kAbsSendTimeFraction) +
106 500) / 94 500) /
107 1000) & 95 1000) &
108 0x00FFFFFF; 96 0x00FFFFFF;
109 // Shift up send time to use the full 32 bits that inter_arrival works with, 97 // Shift up send time to use the full 32 bits that inter_arrival works with,
110 // so wrapping works properly. 98 // so wrapping works properly.
111 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; 99 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift;
112 100
113 uint32_t ts_delta = 0; 101 uint32_t ts_delta = 0;
114 int64_t t_delta = 0; 102 int64_t t_delta = 0;
115 int size_delta = 0; 103 int size_delta = 0;
116 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms, 104 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms,
117 info.payload_size, &ts_delta, &t_delta, 105 info.payload_size, &ts_delta, &t_delta,
118 &size_delta)) { 106 &size_delta)) {
119 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); 107 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
120 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State()); 108 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State());
121 detector_.Detect(estimator_->offset(), ts_delta_ms, 109 detector_.Detect(estimator_->offset(), ts_delta_ms,
122 estimator_->num_of_deltas(), info.arrival_time_ms); 110 estimator_->num_of_deltas(), info.arrival_time_ms);
123 } 111 }
124 112
125 if (!update_estimate) { 113 int probing_bps = 0;
126 // Check if it's time for a periodic update or if we should update because 114 if (info.probe_cluster_id != PacketInfo::kNotAProbe &&
127 // of an over-use. 115 controller_->SenderState() ==
128 if (last_update_ms_ == -1 || 116 PacedSender::State::kWaitForProbingResult) {
129 now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval()) { 117 // Without a valid estimate, we wait for two clusters and then later on
130 update_estimate = true; 118 // wait on a single cluster to update probing bitrate.
131 } else if (detector_.State() == kBwOverusing) { 119 if (!remote_rate_.ValidEstimate()) {
132 rtc::Optional<uint32_t> incoming_rate = 120 probing_bps =
133 incoming_bitrate_.Rate(info.arrival_time_ms); 121 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info, 2);
philipel 2016/08/16 14:44:43 Seems like probe_bitrate_estimator.h/.cc haven't b
Irfan 2016/08/16 16:04:17 https://codereview.chromium.org/2239143002/ is the
134 if (incoming_rate && 122 } else {
135 remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) { 123 probing_bps =
136 update_estimate = true; 124 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info, 1);
137 }
138 } 125 }
139 } 126 }
140 127
141 if (update_estimate) { 128 // Overuse
stefan-webrtc 2016/08/16 11:27:04 End the comments with "."
Irfan 2016/08/16 18:12:47 Will make these full sentence comments and add ful
142 // The first overuse should immediately trigger a new estimate. 129 if (detector_.State() == kBwOverusing) {
143 // We also have to update the estimate immediately if we are overusing 130 rtc::Optional<uint32_t> incoming_rate =
144 // and the target bitrate is too high compared to what we are receiving. 131 incoming_bitrate_.Rate(info.arrival_time_ms);
145 const RateControlInput input(detector_.State(), 132 if (incoming_rate &&
146 incoming_bitrate_.Rate(info.arrival_time_ms), 133 remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) {
147 estimator_->var_noise()); 134 delay_based_bwe_changed =
148 remote_rate_.Update(&input, now_ms); 135 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps);
149 target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms); 136 }
150 update_estimate = remote_rate_.ValidEstimate(); 137 // Probe results with overuse
138 if (probing_bps) {
139 // Stop probing
140 controller_->OnProbingBitrateMeasured(0);
stefan-webrtc 2016/08/16 11:27:04 This looks a bit hacky. It's not really that we me
Irfan 2016/08/16 18:12:47 Will make it a well-defined name instead. Works fo
141 }
142 // No overuse, but probing measured a bitrate
143 } else if (probing_bps > 0) {
144 controller_->OnProbingBitrateMeasured(probing_bps);
145 remote_rate_.SetEstimate(probing_bps, info.arrival_time_ms);
146 target_bitrate_bps = probing_bps;
147 delay_based_bwe_changed = true;
148 // Been a while since we updated
stefan-webrtc 2016/08/16 11:27:04 Move this inside the else if below instead to make
Irfan 2016/08/16 18:12:47 Done.
149 } else if (last_update_ms_ == -1 ||
150 now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval()) {
151 delay_based_bwe_changed =
152 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps);
151 } 153 }
152 } 154 }
153 155
154 if (update_estimate) { 156 if (delay_based_bwe_changed) {
155 last_update_ms_ = now_ms; 157 last_update_ms_ = now_ms;
156 observer_->OnReceiveBitrateChanged({kFixedSsrc}, target_bitrate_bps); 158 controller_->OnDelayBasedBweChanged(target_bitrate_bps);
157 } 159 }
158 } 160 }
159 161
162 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms,
163 int64_t now_ms,
164 int* target_bitrate_bps) {
165 rtc::CritScope lock(&crit_);
166 // The first overuse should immediately trigger a new estimate.
167 // We also have to update the estimate immediately if we are overusing
168 // and the target bitrate is too high compared to what we are receiving.
169 const RateControlInput input(detector_.State(),
170 incoming_bitrate_.Rate(arrival_time_ms),
171 estimator_->var_noise());
172 remote_rate_.Update(&input, now_ms);
173 *target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms);
174 return remote_rate_.ValidEstimate();
175 }
176
160 void DelayBasedBwe::Process() {} 177 void DelayBasedBwe::Process() {}
161 178
162 int64_t DelayBasedBwe::TimeUntilNextProcess() { 179 int64_t DelayBasedBwe::TimeUntilNextProcess() {
163 const int64_t kDisabledModuleTime = 1000; 180 const int64_t kDisabledModuleTime = 1000;
164 return kDisabledModuleTime; 181 return kDisabledModuleTime;
165 } 182 }
166 183
167 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { 184 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
168 rtc::CritScope lock(&crit_); 185 rtc::CritScope lock(&crit_);
169 remote_rate_.SetRtt(avg_rtt_ms); 186 remote_rate_.SetRtt(avg_rtt_ms);
(...skipping 18 matching lines...) Expand all
188 return true; 205 return true;
189 } 206 }
190 207
191 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { 208 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) {
192 // Called from both the configuration thread and the network thread. Shouldn't 209 // Called from both the configuration thread and the network thread. Shouldn't
193 // be called from the network thread in the future. 210 // be called from the network thread in the future.
194 rtc::CritScope lock(&crit_); 211 rtc::CritScope lock(&crit_);
195 remote_rate_.SetMinBitrate(min_bitrate_bps); 212 remote_rate_.SetMinBitrate(min_bitrate_bps);
196 } 213 }
197 } // namespace webrtc 214 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698