OLD | NEW |
---|---|
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 |
OLD | NEW |