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