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

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, 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) 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 // Number of deltas between probes per cluster. On the very first cluster,
26 // we will need kProbeDeltasPerCluster + 1 probes, but on a cluster following
27 // another, we need kProbeDeltasPerCluster probes.
28 constexpr int kProbeDeltasPerCluster = 5;
29
30 // Maximum waiting time from the time of sending last probe to getting
31 // the measured results back.
32 const int64_t kMaxWaitingTimeForProbingResultMs = 1000;
25 33
26 int ComputeDeltaFromBitrate(size_t packet_size, uint32_t bitrate_bps) { 34 int ComputeDeltaFromBitrate(size_t packet_size, uint32_t bitrate_bps) {
27 RTC_CHECK_GT(bitrate_bps, 0u); 35 RTC_CHECK_GT(bitrate_bps, 0u);
28 // Compute the time delta needed to send packet_size bytes at bitrate_bps 36 // Compute the time delta needed to send packet_size bytes at bitrate_bps
29 // bps. Result is in milliseconds. 37 // bps. Result is in milliseconds.
30 return static_cast<int>((1000ll * packet_size * 8) / bitrate_bps); 38 return static_cast<int>((1000ll * packet_size * 8) / bitrate_bps);
31 } 39 }
32 } // namespace 40 } // namespace
33 41
34 BitrateProber::BitrateProber() 42 BitrateProber::BitrateProber()
35 : probing_state_(ProbingState::kDisabled), 43 : probing_state_(State::kInit),
36 packet_size_last_sent_(0), 44 packet_size_last_sent_(0),
37 time_last_probe_sent_ms_(-1), 45 time_last_probe_sent_ms_(-1),
38 next_cluster_id_(0) { 46 next_cluster_id_(0),
39 SetEnabled(true); 47 min_bitrate_to_probe_further_(0),
48 estimated_bitrate_bps_(0) {}
49
50 bool BitrateProber::IsProbing() const {
51 return probing_state_ == State::kSending;
40 } 52 }
41 53
42 void BitrateProber::SetEnabled(bool enable) { 54 void BitrateProber::SetEnabled(bool enable) {
43 if (enable) { 55 if (enable) {
44 if (probing_state_ == ProbingState::kDisabled) { 56 if (probing_state_ == State::kDisabled) {
45 probing_state_ = ProbingState::kInactive; 57 probing_state_ = State::kInit;
46 LOG(LS_INFO) << "Bandwidth probing enabled, set to inactive"; 58 LOG(LS_INFO) << "Bandwidth probing enabled";
47 } 59 }
48 } else { 60 } else {
49 probing_state_ = ProbingState::kDisabled; 61 probing_state_ = State::kDisabled;
50 LOG(LS_INFO) << "Bandwidth probing disabled"; 62 LOG(LS_INFO) << "Bandwidth probing disabled";
51 } 63 }
52 } 64 }
53 65
54 bool BitrateProber::IsProbing() const { 66 bool BitrateProber::IsExpectingProbingResults() const {
55 return probing_state_ == ProbingState::kActive; 67 // We would like to hear of probe results the moment we start sending
68 // probes.
69 return probing_state_ == State::kSending ||
70 probing_state_ == State::kWaitForResult;
56 } 71 }
57 72
58 void BitrateProber::OnIncomingPacket(size_t packet_size) { 73 void BitrateProber::SetEstimatedBitrate(int bitrate_bps) {
59 // Don't initialize probing unless we have something large enough to start 74 switch (probing_state_) {
60 // probing. 75 // We could have a result before we finish sending probe clusters
61 if (probing_state_ == ProbingState::kInactive && 76 // completely.
62 packet_size >= PacedSender::kMinProbePacketSize) { 77 case State::kSending:
63 probing_state_ = ProbingState::kActive; 78 case State::kWaitForResult:
danilchap 2016/08/19 17:19:34 shouldn't you start probing from State::kComplete
Irfan 2016/08/23 05:46:57 kComplete indicates we do not expect any results f
danilchap 2016/08/23 17:59:29 So it is not a coincidence it is same states as in
79 LOG(LS_INFO) << "SetEstimatedBitrate " << bitrate_bps
80 << " min_bitrate_to_probe_further_ "
81 << min_bitrate_to_probe_further_;
82 if (bitrate_bps > min_bitrate_to_probe_further_) {
83 // Reset before new probe session.
84 ResetState();
85 ProbeAtBitrate(2 * bitrate_bps, kProbeDeltasPerCluster + 1);
86 // A minimum of 25% gain to continue.
87 min_bitrate_to_probe_further_ = 1.25 * bitrate_bps;
88 }
89 break;
90 default:
91 break;
92 }
93 estimated_bitrate_bps_ = bitrate_bps;
94 }
95
96 void BitrateProber::OnIncomingPacket(int64_t now_ms, size_t packet_size) {
97 switch (probing_state_) {
98 case State::kInit:
99 // Don't initialize probing unless we have something large enough to start
100 // probing.
101 if (packet_size >= PacedSender::kMinProbePacketSize &&
102 estimated_bitrate_bps_ > 0) {
103 LOG(LS_INFO) << "kInit: initialize probing";
104 // Ensure state is initialized before starting probing.
105 ResetState();
106 ProbeAtBitrate(3 * estimated_bitrate_bps_, kProbeDeltasPerCluster + 1);
107 ProbeAtBitrate(6 * estimated_bitrate_bps_, kProbeDeltasPerCluster);
108 // When probing at 1.8 Mbps ( 6x 300), this represents a threshold of
109 // 1.2 Mbps to continue probing.
110 min_bitrate_to_probe_further_ = 4 * estimated_bitrate_bps_;
111 }
112 break;
113 case State::kWaitForResult:
114 if ((now_ms - time_last_probe_sent_ms_) >
115 kMaxWaitingTimeForProbingResultMs) {
116 probing_state_ = State::kComplete;
117 LOG(LS_INFO) << "kWaitForResult: timeout";
118 }
119 break;
120 case State::kSending:
121 case State::kComplete:
122 case State::kDisabled:
123 break;
124 default:
danilchap 2016/08/19 17:19:34 remove default. Missing state would be noticed at
Irfan 2016/08/23 05:46:57 Done.
125 RTC_NOTREACHED();
64 } 126 }
65 } 127 }
66 128
67 void BitrateProber::ProbeAtBitrate(uint32_t bitrate_bps, int num_packets) { 129 void BitrateProber::ProbeAtBitrate(int bitrate_bps, int num_packets) {
130 RTC_DCHECK(probing_state_ != State::kDisabled);
danilchap 2016/08/19 17:19:34 RTC_DCHECK_NE
Irfan 2016/08/23 05:46:57 RTC_DCHECK_NE does not handle scoped enums properl
68 ProbeCluster cluster; 131 ProbeCluster cluster;
69 cluster.max_probe_packets = num_packets; 132 cluster.max_probe_packets = num_packets;
70 cluster.probe_bitrate_bps = bitrate_bps; 133 cluster.probe_bitrate_bps = bitrate_bps;
71 cluster.id = next_cluster_id_++; 134 cluster.id = next_cluster_id_++;
72 clusters_.push(cluster); 135 clusters_.push(cluster);
73 LOG(LS_INFO) << "Probe cluster (bitrate:packets): (" 136 LOG(LS_INFO) << "Probe cluster (bitrate:packets): ("
74 << cluster.probe_bitrate_bps << ":" << cluster.max_probe_packets 137 << cluster.probe_bitrate_bps << ":" << cluster.max_probe_packets
75 << ") "; 138 << ") ";
76 if (probing_state_ != ProbingState::kActive) 139 probing_state_ = State::kSending;
77 probing_state_ = ProbingState::kInactive;
78 } 140 }
79 141
80 void BitrateProber::ResetState() { 142 void BitrateProber::ResetState() {
81 time_last_probe_sent_ms_ = -1; 143 time_last_probe_sent_ms_ = -1;
82 packet_size_last_sent_ = 0; 144 packet_size_last_sent_ = 0;
83 145
84 // Recreate all probing clusters. 146 // Recreate all probing clusters.
85 std::queue<ProbeCluster> clusters; 147 std::queue<ProbeCluster> clusters;
86 clusters.swap(clusters_); 148 clusters.swap(clusters_);
87 while (!clusters.empty()) { 149 while (!clusters.empty()) {
88 ProbeAtBitrate(clusters.front().probe_bitrate_bps, 150 ProbeAtBitrate(clusters.front().probe_bitrate_bps,
89 clusters.front().max_probe_packets); 151 clusters.front().max_probe_packets);
90 clusters.pop(); 152 clusters.pop();
91 } 153 }
92 // If its enabled, reset to inactive.
93 if (probing_state_ != ProbingState::kDisabled)
94 probing_state_ = ProbingState::kInactive;
95 } 154 }
96 155
97 int BitrateProber::TimeUntilNextProbe(int64_t now_ms) { 156 int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
98 // Probing is not active or probing is already complete. 157 // Proceed only if we are in kSending state.
99 if (probing_state_ != ProbingState::kActive || clusters_.empty()) 158 if (probing_state_ != State::kSending)
100 return -1; 159 return -1;
101 // time_last_probe_sent_ms_ of -1 indicates no probes have yet been sent. 160 // time_last_probe_sent_ms_ of -1 indicates no probes have yet been sent.
102 int64_t elapsed_time_ms; 161 int64_t elapsed_time_ms;
103 if (time_last_probe_sent_ms_ == -1) { 162 if (time_last_probe_sent_ms_ == -1) {
104 elapsed_time_ms = 0; 163 elapsed_time_ms = 0;
105 } else { 164 } else {
106 elapsed_time_ms = now_ms - time_last_probe_sent_ms_; 165 elapsed_time_ms = now_ms - time_last_probe_sent_ms_;
107 } 166 }
108 // If no probes have been sent for a while, abort current probing and 167 // If no probes have been sent for a while, abort current probing and
109 // reset. 168 // reset.
110 if (elapsed_time_ms > kInactivityThresholdMs) { 169 if (elapsed_time_ms > kInactivityThresholdMs) {
111 ResetState(); 170 ResetState();
112 return -1; 171 return -1;
113 } 172 }
114 // We will send the first probe packet immediately if no packet has been 173 // We will send the first probe packet immediately if no packet has been
115 // sent before. 174 // sent before.
116 int time_until_probe_ms = 0; 175 int time_until_probe_ms = 0;
117 if (packet_size_last_sent_ != 0 && probing_state_ == ProbingState::kActive) { 176 if (packet_size_last_sent_ != 0 && probing_state_ == State::kSending) {
danilchap 2016/08/19 17:19:34 probing_state == State::kSending seems no longer n
Irfan 2016/08/23 05:46:57 Done.
118 int next_delta_ms = ComputeDeltaFromBitrate( 177 int next_delta_ms = ComputeDeltaFromBitrate(
119 packet_size_last_sent_, clusters_.front().probe_bitrate_bps); 178 packet_size_last_sent_, clusters_.front().probe_bitrate_bps);
120 time_until_probe_ms = next_delta_ms - elapsed_time_ms; 179 time_until_probe_ms = next_delta_ms - elapsed_time_ms;
121 // There is no point in trying to probe with less than 1 ms between packets 180 // There is no point in trying to probe with less than 1 ms between packets
122 // as it essentially means trying to probe at infinite bandwidth. 181 // as it essentially means trying to probe at infinite bandwidth.
123 const int kMinProbeDeltaMs = 1; 182 const int kMinProbeDeltaMs = 1;
124 // If we have waited more than 3 ms for a new packet to probe with we will 183 // If we have waited more than 3 ms for a new packet to probe with we will
125 // consider this probing session over. 184 // consider this probing session over.
126 const int kMaxProbeDelayMs = 3; 185 const int kMaxProbeDelayMs = 3;
127 if (next_delta_ms < kMinProbeDeltaMs || 186 if (next_delta_ms < kMinProbeDeltaMs ||
128 time_until_probe_ms < -kMaxProbeDelayMs) { 187 time_until_probe_ms < -kMaxProbeDelayMs) {
129 probing_state_ = ProbingState::kSuspended; 188 probing_state_ = State::kComplete;
130 LOG(LS_INFO) << "Delta too small or missed probing accurately, suspend"; 189 LOG(LS_INFO) << "Delta too small or missed probing accurately, suspend";
131 time_until_probe_ms = 0; 190 time_until_probe_ms = 0;
132 } 191 }
133 } 192 }
134 return std::max(time_until_probe_ms, 0); 193 return std::max(time_until_probe_ms, 0);
135 } 194 }
136 195
137 int BitrateProber::CurrentClusterId() const { 196 int BitrateProber::CurrentClusterId() const {
138 RTC_DCHECK(!clusters_.empty()); 197 RTC_DCHECK(!clusters_.empty());
139 RTC_DCHECK(ProbingState::kActive == probing_state_); 198 RTC_DCHECK(probing_state_ == State::kSending);
danilchap 2016/08/19 17:19:34 RTC_DCHECK_EQ
Irfan 2016/08/23 05:46:57 see above
140 return clusters_.front().id; 199 return clusters_.front().id;
141 } 200 }
142 201
143 size_t BitrateProber::RecommendedPacketSize() const { 202 size_t BitrateProber::RecommendedPacketSize() const {
144 return packet_size_last_sent_; 203 return packet_size_last_sent_;
145 } 204 }
146 205
147 void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) { 206 void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) {
148 assert(packet_size > 0); 207 assert(packet_size > 0);
208 RTC_DCHECK(probing_state_ == State::kSending);
danilchap 2016/08/19 17:19:34 RTC_DCHECK_EQ
Irfan 2016/08/23 05:46:57 see above
209
149 if (packet_size < PacedSender::kMinProbePacketSize) 210 if (packet_size < PacedSender::kMinProbePacketSize)
150 return; 211 return;
151 packet_size_last_sent_ = packet_size; 212 packet_size_last_sent_ = packet_size;
152 if (probing_state_ != ProbingState::kActive)
153 return;
154 time_last_probe_sent_ms_ = now_ms; 213 time_last_probe_sent_ms_ = now_ms;
155 if (!clusters_.empty()) { 214 if (!clusters_.empty()) {
156 ProbeCluster* cluster = &clusters_.front(); 215 ProbeCluster* cluster = &clusters_.front();
157 ++cluster->sent_probe_packets; 216 ++cluster->sent_probe_packets;
158 if (cluster->sent_probe_packets == cluster->max_probe_packets) 217 if (cluster->sent_probe_packets == cluster->max_probe_packets)
159 clusters_.pop(); 218 clusters_.pop();
160 if (clusters_.empty()) 219 if (clusters_.empty())
161 probing_state_ = ProbingState::kSuspended; 220 probing_state_ = State::kWaitForResult;
162 } 221 }
163 } 222 }
164 } // namespace webrtc 223 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698