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

Side by Side Diff: webrtc/modules/pacing/bitrate_prober.cc

Issue 2235373004: Probing: Add support for exponential startup probing (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@fix_probing2
Patch Set: Addressed comments 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) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 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/pacing/bitrate_prober.h" 11 #include "webrtc/modules/pacing/bitrate_prober.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 14
15 #include "webrtc/base/checks.h" 15 #include "webrtc/base/checks.h"
16 #include "webrtc/base/logging.h" 16 #include "webrtc/base/logging.h"
17 #include "webrtc/modules/pacing/paced_sender.h" 17 #include "webrtc/modules/pacing/paced_sender.h"
18 18
19 namespace webrtc { 19 namespace webrtc {
20 20
21 namespace { 21 namespace {
22 22
23 // Inactivity threshold above which probing is restarted. 23 // Inactivity threshold above which probing is restarted.
24 constexpr int kInactivityThresholdMs = 5000; 24 constexpr int kInactivityThresholdMs = 5000;
25 25
26 // Number of deltas between probes per cluster. On the very first cluster,
27 // we will need kProbeDeltasPerCluster + 1 probes, but on a cluster following
28 // another, we need kProbeDeltasPerCluster probes.
29 constexpr int kProbeDeltasPerCluster = 5;
30
31 // Maximum waiting time from the time of sending last probe to getting
32 // the measured results back.
33 constexpr int64_t kMaxWaitingTimeForProbingResultMs = 1000;
34
35 // Value of |min_bitrate_to_probe_further_| that indicates
36 // further probing is disabled.
37 constexpr int kDisableExponentialProbing = 0;
38
26 int ComputeDeltaFromBitrate(size_t packet_size, int bitrate_bps) { 39 int ComputeDeltaFromBitrate(size_t packet_size, int bitrate_bps) {
27 RTC_CHECK_GT(bitrate_bps, 0); 40 RTC_CHECK_GT(bitrate_bps, 0);
28 // Compute the time delta needed to send packet_size bytes at bitrate_bps 41 // Compute the time delta needed to send packet_size bytes at bitrate_bps
29 // bps. Result is in milliseconds. 42 // bps. Result is in milliseconds.
30 return static_cast<int>((1000ll * packet_size * 8) / bitrate_bps); 43 return static_cast<int>((1000ll * packet_size * 8) / bitrate_bps);
31 } 44 }
32 } // namespace 45 } // namespace
33 46
34 BitrateProber::BitrateProber() 47 BitrateProber::BitrateProber()
35 : probing_state_(ProbingState::kDisabled), 48 : probing_state_(State::kInit),
36 packet_size_last_sent_(0), 49 packet_size_last_sent_(0),
37 time_last_probe_sent_ms_(-1), 50 time_last_probe_sent_ms_(-1),
38 next_cluster_id_(0) { 51 next_cluster_id_(0),
39 SetEnabled(true); 52 min_bitrate_to_probe_further_(kDisableExponentialProbing),
53 estimated_bitrate_bps_(0) {}
54
55 bool BitrateProber::IsProbing() const {
56 return probing_state_ == State::kSending;
40 } 57 }
41 58
42 void BitrateProber::SetEnabled(bool enable) { 59 void BitrateProber::SetEnabled(bool enable) {
43 if (enable) { 60 if (enable) {
44 if (probing_state_ == ProbingState::kDisabled) { 61 if (probing_state_ == State::kDisabled) {
45 probing_state_ = ProbingState::kInactive; 62 probing_state_ = State::kInit;
46 LOG(LS_INFO) << "Bandwidth probing enabled, set to inactive"; 63 LOG(LS_INFO) << "Bandwidth probing enabled";
47 } 64 }
48 } else { 65 } else {
49 probing_state_ = ProbingState::kDisabled; 66 probing_state_ = State::kDisabled;
50 LOG(LS_INFO) << "Bandwidth probing disabled"; 67 LOG(LS_INFO) << "Bandwidth probing disabled";
51 } 68 }
52 } 69 }
53 70
54 bool BitrateProber::IsProbing() const { 71 bool BitrateProber::IsExpectingProbingResults() const {
55 return probing_state_ == ProbingState::kActive; 72 // We would like to hear of probe results the moment we start sending
73 // probes.
74 return probing_state_ == State::kSending ||
75 probing_state_ == State::kWaitForResult;
56 } 76 }
57 77
58 void BitrateProber::OnIncomingPacket(size_t packet_size) { 78 void BitrateProber::SetEstimatedBitrate(int bitrate_bps) {
philipel 2016/08/25 10:39:56 In order to make the bitrate prober more general I
stefan-webrtc 2016/09/02 13:10:22 Do you mean that the CongestionController should b
philipel 2016/09/02 13:32:50 To me it looks like this could be implemented eith
59 // Don't initialize probing unless we have something large enough to start 79 switch (probing_state_) {
60 // probing. 80 // We could have a result before we finish sending probe clusters
61 if (probing_state_ == ProbingState::kInactive && 81 // completely.
62 !clusters_.empty() && 82 case State::kSending:
63 packet_size >= PacedSender::kMinProbePacketSize) { 83 case State::kWaitForResult:
64 probing_state_ = ProbingState::kActive; 84 LOG(LS_INFO) << "SetEstimatedBitrate " << bitrate_bps;
85 if (min_bitrate_to_probe_further_ &&
philipel 2016/08/25 10:39:56 min_bitrate_to_probe_further != kDisableExponentia
86 bitrate_bps > min_bitrate_to_probe_further_) {
87 // Reset before new probe session.
88 ResetState();
89 CreateProbeCluster(2 * bitrate_bps, kProbeDeltasPerCluster + 1);
90 // A minimum of 25% gain to continue.
91 min_bitrate_to_probe_further_ = 1.25 * bitrate_bps;
92 LOG(LS_INFO) << " min_bitrate_to_probe_further_ "
93 << min_bitrate_to_probe_further_;
94 }
95 break;
96 default:
97 break;
98 }
99 estimated_bitrate_bps_ = bitrate_bps;
100 }
101
102 void BitrateProber::OnIncomingPacket(int64_t now_ms, size_t packet_size) {
103 switch (probing_state_) {
104 case State::kInit:
105 // Don't initialize probing unless we have something large enough to start
106 // probing.
107 if (packet_size >= PacedSender::kMinProbePacketSize &&
108 estimated_bitrate_bps_ > 0) {
109 LOG(LS_INFO) << "kInit: initialize probing";
110 // Ensure state is initialized before starting probing.
111 ResetState();
112 CreateProbeCluster(900000, kProbeDeltasPerCluster + 1);
philipel 2016/08/25 10:39:56 Why move the creation of initial probe clusters he
113 CreateProbeCluster(1800000, kProbeDeltasPerCluster);
114 // When probing at 1.8 Mbps ( 6x 300), this represents a threshold of
115 // 1.2 Mbps to continue probing.
116 min_bitrate_to_probe_further_ = 4 * estimated_bitrate_bps_;
danilchap 2016/08/23 17:59:29 it probably make more sense to derive this value f
117 LOG(LS_INFO) << " min_bitrate_to_probe_further_ "
118 << min_bitrate_to_probe_further_;
119 }
120 break;
121 case State::kWaitForResult:
122 if ((now_ms - time_last_probe_sent_ms_) >
danilchap 2016/08/23 17:59:29 this check has nothing to do with IncomingPacket (
philipel 2016/08/25 10:39:56 I don't think this will ever occur. If we don't ha
123 kMaxWaitingTimeForProbingResultMs) {
124 probing_state_ = State::kComplete;
125 LOG(LS_INFO) << "kWaitForResult: timeout";
126 }
127 break;
128 case State::kSending:
129 case State::kComplete:
130 case State::kDisabled:
131 break;
65 } 132 }
66 } 133 }
67 134
68 void BitrateProber::CreateProbeCluster(int bitrate_bps, int num_packets) { 135 void BitrateProber::CreateProbeCluster(int bitrate_bps, int num_packets) {
136 RTC_DCHECK(probing_state_ != State::kDisabled);
69 ProbeCluster cluster; 137 ProbeCluster cluster;
70 cluster.max_probe_packets = num_packets; 138 cluster.max_probe_packets = num_packets;
71 cluster.probe_bitrate_bps = bitrate_bps; 139 cluster.probe_bitrate_bps = bitrate_bps;
72 cluster.id = next_cluster_id_++; 140 cluster.id = next_cluster_id_++;
73 clusters_.push(cluster); 141 clusters_.push(cluster);
74 LOG(LS_INFO) << "Probe cluster (bitrate:packets): (" 142 LOG(LS_INFO) << "Probe cluster (bitrate:packets): ("
75 << cluster.probe_bitrate_bps << ":" << cluster.max_probe_packets 143 << cluster.probe_bitrate_bps << ":" << cluster.max_probe_packets
76 << ") "; 144 << ") ";
77 if (probing_state_ != ProbingState::kActive) 145 probing_state_ = State::kSending;
78 probing_state_ = ProbingState::kInactive; 146 min_bitrate_to_probe_further_ = kDisableExponentialProbing;
79 } 147 }
80 148
81 void BitrateProber::ResetState() { 149 void BitrateProber::ResetState() {
82 time_last_probe_sent_ms_ = -1; 150 time_last_probe_sent_ms_ = -1;
83 packet_size_last_sent_ = 0; 151 packet_size_last_sent_ = 0;
84 152
85 // Recreate all probing clusters. 153 // Recreate all probing clusters.
86 std::queue<ProbeCluster> clusters; 154 std::queue<ProbeCluster> clusters;
87 clusters.swap(clusters_); 155 clusters.swap(clusters_);
88 while (!clusters.empty()) { 156 while (!clusters.empty()) {
89 CreateProbeCluster(clusters.front().probe_bitrate_bps, 157 CreateProbeCluster(clusters.front().probe_bitrate_bps,
90 clusters.front().max_probe_packets); 158 clusters.front().max_probe_packets);
91 clusters.pop(); 159 clusters.pop();
92 } 160 }
93 // If its enabled, reset to inactive.
94 if (probing_state_ != ProbingState::kDisabled)
95 probing_state_ = ProbingState::kInactive;
96 } 161 }
97 162
98 int BitrateProber::TimeUntilNextProbe(int64_t now_ms) { 163 int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
99 // Probing is not active or probing is already complete. 164 // Proceed only if we are in kSending state.
100 if (probing_state_ != ProbingState::kActive || clusters_.empty()) 165 if (probing_state_ != State::kSending)
101 return -1; 166 return -1;
102 // time_last_probe_sent_ms_ of -1 indicates no probes have yet been sent. 167 // time_last_probe_sent_ms_ of -1 indicates no probes have yet been sent.
103 int64_t elapsed_time_ms; 168 int64_t elapsed_time_ms;
104 if (time_last_probe_sent_ms_ == -1) { 169 if (time_last_probe_sent_ms_ == -1) {
105 elapsed_time_ms = 0; 170 elapsed_time_ms = 0;
106 } else { 171 } else {
107 elapsed_time_ms = now_ms - time_last_probe_sent_ms_; 172 elapsed_time_ms = now_ms - time_last_probe_sent_ms_;
108 } 173 }
109 // If no probes have been sent for a while, abort current probing and 174 // If no probes have been sent for a while, abort current probing and
110 // reset. 175 // reset.
111 if (elapsed_time_ms > kInactivityThresholdMs) { 176 if (elapsed_time_ms > kInactivityThresholdMs) {
112 ResetState(); 177 ResetState();
113 return -1; 178 return -1;
114 } 179 }
115 // We will send the first probe packet immediately if no packet has been 180 // We will send the first probe packet immediately if no packet has been
116 // sent before. 181 // sent before.
117 int time_until_probe_ms = 0; 182 int time_until_probe_ms = 0;
118 if (packet_size_last_sent_ != 0 && probing_state_ == ProbingState::kActive) { 183 if (packet_size_last_sent_ != 0) {
119 int next_delta_ms = ComputeDeltaFromBitrate( 184 int next_delta_ms = ComputeDeltaFromBitrate(
120 packet_size_last_sent_, clusters_.front().probe_bitrate_bps); 185 packet_size_last_sent_, clusters_.front().probe_bitrate_bps);
121 time_until_probe_ms = next_delta_ms - elapsed_time_ms; 186 time_until_probe_ms = next_delta_ms - elapsed_time_ms;
122 // There is no point in trying to probe with less than 1 ms between packets 187 // There is no point in trying to probe with less than 1 ms between packets
123 // as it essentially means trying to probe at infinite bandwidth. 188 // as it essentially means trying to probe at infinite bandwidth.
124 const int kMinProbeDeltaMs = 1; 189 const int kMinProbeDeltaMs = 1;
125 // If we have waited more than 3 ms for a new packet to probe with we will 190 // If we have waited more than 3 ms for a new packet to probe with we will
126 // consider this probing session over. 191 // consider this probing session over.
127 const int kMaxProbeDelayMs = 3; 192 const int kMaxProbeDelayMs = 3;
128 if (next_delta_ms < kMinProbeDeltaMs || 193 if (next_delta_ms < kMinProbeDeltaMs ||
129 time_until_probe_ms < -kMaxProbeDelayMs) { 194 time_until_probe_ms < -kMaxProbeDelayMs) {
130 probing_state_ = ProbingState::kSuspended; 195 probing_state_ = State::kComplete;
131 LOG(LS_INFO) << "Delta too small or missed probing accurately, suspend"; 196 LOG(LS_INFO) << "Delta too small or missed probing accurately, suspend";
132 time_until_probe_ms = 0; 197 time_until_probe_ms = 0;
133 } 198 }
134 } 199 }
135 return std::max(time_until_probe_ms, 0); 200 return std::max(time_until_probe_ms, 0);
136 } 201 }
137 202
138 int BitrateProber::CurrentClusterId() const { 203 int BitrateProber::CurrentClusterId() const {
139 RTC_DCHECK(!clusters_.empty()); 204 RTC_DCHECK(!clusters_.empty());
140 RTC_DCHECK(ProbingState::kActive == probing_state_); 205 RTC_DCHECK(probing_state_ == State::kSending);
141 return clusters_.front().id; 206 return clusters_.front().id;
142 } 207 }
143 208
144 size_t BitrateProber::RecommendedPacketSize() const { 209 size_t BitrateProber::RecommendedPacketSize() const {
145 return packet_size_last_sent_; 210 return packet_size_last_sent_;
146 } 211 }
147 212
148 void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) { 213 void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) {
149 assert(packet_size > 0); 214 assert(packet_size > 0);
215 RTC_DCHECK(probing_state_ == State::kSending);
216
150 if (packet_size < PacedSender::kMinProbePacketSize) 217 if (packet_size < PacedSender::kMinProbePacketSize)
151 return; 218 return;
152 packet_size_last_sent_ = packet_size; 219 packet_size_last_sent_ = packet_size;
153 if (probing_state_ != ProbingState::kActive)
154 return;
155 time_last_probe_sent_ms_ = now_ms; 220 time_last_probe_sent_ms_ = now_ms;
156 if (!clusters_.empty()) { 221 if (!clusters_.empty()) {
157 ProbeCluster* cluster = &clusters_.front(); 222 ProbeCluster* cluster = &clusters_.front();
158 ++cluster->sent_probe_packets; 223 ++cluster->sent_probe_packets;
159 if (cluster->sent_probe_packets == cluster->max_probe_packets) 224 if (cluster->sent_probe_packets == cluster->max_probe_packets)
160 clusters_.pop(); 225 clusters_.pop();
161 if (clusters_.empty()) 226 if (clusters_.empty())
162 probing_state_ = ProbingState::kSuspended; 227 probing_state_ = State::kWaitForResult;
163 } 228 }
164 } 229 }
165 } // namespace webrtc 230 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698