Index: webrtc/modules/pacing/bitrate_prober.cc |
diff --git a/webrtc/modules/pacing/bitrate_prober.cc b/webrtc/modules/pacing/bitrate_prober.cc |
index 4b2a977bbebcdcab302e24c762e679ae0cd87d0e..bb8a059f69a4a1573d9170fdfcddd53cea2959a6 100644 |
--- a/webrtc/modules/pacing/bitrate_prober.cc |
+++ b/webrtc/modules/pacing/bitrate_prober.cc |
@@ -22,6 +22,14 @@ namespace { |
// Inactivity threshold above which probing is restarted. |
constexpr int kInactivityThresholdMs = 5000; |
+// Number of deltas between probes per cluster. On the very first cluster, |
+// we will need kProbeDeltasPerCluster + 1 probes, but on a cluster following |
+// another, we need kProbeDeltasPerCluster probes. |
+constexpr int kProbeDeltasPerCluster = 5; |
+ |
+// Maximum waiting time from the time of sending last probe to getting |
+// the measured results back. |
+const int64_t kMaxWaitingTimeForProbingResultMs = 1000; |
int ComputeDeltaFromBitrate(size_t packet_size, uint32_t bitrate_bps) { |
RTC_CHECK_GT(bitrate_bps, 0u); |
@@ -32,39 +40,94 @@ int ComputeDeltaFromBitrate(size_t packet_size, uint32_t bitrate_bps) { |
} // namespace |
BitrateProber::BitrateProber() |
- : probing_state_(ProbingState::kDisabled), |
+ : probing_state_(State::kInit), |
packet_size_last_sent_(0), |
time_last_probe_sent_ms_(-1), |
- next_cluster_id_(0) { |
- SetEnabled(true); |
+ next_cluster_id_(0), |
+ min_bitrate_to_probe_further_(0), |
+ estimated_bitrate_bps_(0) {} |
+ |
+bool BitrateProber::IsProbing() const { |
+ return probing_state_ == State::kSending; |
} |
void BitrateProber::SetEnabled(bool enable) { |
if (enable) { |
- if (probing_state_ == ProbingState::kDisabled) { |
- probing_state_ = ProbingState::kInactive; |
- LOG(LS_INFO) << "Bandwidth probing enabled, set to inactive"; |
+ if (probing_state_ == State::kDisabled) { |
+ probing_state_ = State::kInit; |
+ LOG(LS_INFO) << "Bandwidth probing enabled"; |
} |
} else { |
- probing_state_ = ProbingState::kDisabled; |
+ probing_state_ = State::kDisabled; |
LOG(LS_INFO) << "Bandwidth probing disabled"; |
} |
} |
-bool BitrateProber::IsProbing() const { |
- return probing_state_ == ProbingState::kActive; |
+bool BitrateProber::IsExpectingProbingResults() const { |
+ // We would like to hear of probe results the moment we start sending |
+ // probes. |
+ return probing_state_ == State::kSending || |
+ probing_state_ == State::kWaitForResult; |
} |
-void BitrateProber::OnIncomingPacket(size_t packet_size) { |
- // Don't initialize probing unless we have something large enough to start |
- // probing. |
- if (probing_state_ == ProbingState::kInactive && |
- packet_size >= PacedSender::kMinProbePacketSize) { |
- probing_state_ = ProbingState::kActive; |
+void BitrateProber::SetEstimatedBitrate(int bitrate_bps) { |
+ switch (probing_state_) { |
+ // We could have a result before we finish sending probe clusters |
+ // completely. |
+ case State::kSending: |
+ 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
|
+ LOG(LS_INFO) << "SetEstimatedBitrate " << bitrate_bps |
+ << " min_bitrate_to_probe_further_ " |
+ << min_bitrate_to_probe_further_; |
+ if (bitrate_bps > min_bitrate_to_probe_further_) { |
+ // Reset before new probe session. |
+ ResetState(); |
+ ProbeAtBitrate(2 * bitrate_bps, kProbeDeltasPerCluster + 1); |
+ // A minimum of 25% gain to continue. |
+ min_bitrate_to_probe_further_ = 1.25 * bitrate_bps; |
+ } |
+ break; |
+ default: |
+ break; |
} |
+ estimated_bitrate_bps_ = bitrate_bps; |
} |
-void BitrateProber::ProbeAtBitrate(uint32_t bitrate_bps, int num_packets) { |
+void BitrateProber::OnIncomingPacket(int64_t now_ms, size_t packet_size) { |
+ switch (probing_state_) { |
+ case State::kInit: |
+ // Don't initialize probing unless we have something large enough to start |
+ // probing. |
+ if (packet_size >= PacedSender::kMinProbePacketSize && |
+ estimated_bitrate_bps_ > 0) { |
+ LOG(LS_INFO) << "kInit: initialize probing"; |
+ // Ensure state is initialized before starting probing. |
+ ResetState(); |
+ ProbeAtBitrate(3 * estimated_bitrate_bps_, kProbeDeltasPerCluster + 1); |
+ ProbeAtBitrate(6 * estimated_bitrate_bps_, kProbeDeltasPerCluster); |
+ // When probing at 1.8 Mbps ( 6x 300), this represents a threshold of |
+ // 1.2 Mbps to continue probing. |
+ min_bitrate_to_probe_further_ = 4 * estimated_bitrate_bps_; |
+ } |
+ break; |
+ case State::kWaitForResult: |
+ if ((now_ms - time_last_probe_sent_ms_) > |
+ kMaxWaitingTimeForProbingResultMs) { |
+ probing_state_ = State::kComplete; |
+ LOG(LS_INFO) << "kWaitForResult: timeout"; |
+ } |
+ break; |
+ case State::kSending: |
+ case State::kComplete: |
+ case State::kDisabled: |
+ break; |
+ default: |
danilchap
2016/08/19 17:19:34
remove default.
Missing state would be noticed at
Irfan
2016/08/23 05:46:57
Done.
|
+ RTC_NOTREACHED(); |
+ } |
+} |
+ |
+void BitrateProber::ProbeAtBitrate(int bitrate_bps, int num_packets) { |
+ 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
|
ProbeCluster cluster; |
cluster.max_probe_packets = num_packets; |
cluster.probe_bitrate_bps = bitrate_bps; |
@@ -73,8 +136,7 @@ void BitrateProber::ProbeAtBitrate(uint32_t bitrate_bps, int num_packets) { |
LOG(LS_INFO) << "Probe cluster (bitrate:packets): (" |
<< cluster.probe_bitrate_bps << ":" << cluster.max_probe_packets |
<< ") "; |
- if (probing_state_ != ProbingState::kActive) |
- probing_state_ = ProbingState::kInactive; |
+ probing_state_ = State::kSending; |
} |
void BitrateProber::ResetState() { |
@@ -89,14 +151,11 @@ void BitrateProber::ResetState() { |
clusters.front().max_probe_packets); |
clusters.pop(); |
} |
- // If its enabled, reset to inactive. |
- if (probing_state_ != ProbingState::kDisabled) |
- probing_state_ = ProbingState::kInactive; |
} |
int BitrateProber::TimeUntilNextProbe(int64_t now_ms) { |
- // Probing is not active or probing is already complete. |
- if (probing_state_ != ProbingState::kActive || clusters_.empty()) |
+ // Proceed only if we are in kSending state. |
+ if (probing_state_ != State::kSending) |
return -1; |
// time_last_probe_sent_ms_ of -1 indicates no probes have yet been sent. |
int64_t elapsed_time_ms; |
@@ -114,7 +173,7 @@ int BitrateProber::TimeUntilNextProbe(int64_t now_ms) { |
// We will send the first probe packet immediately if no packet has been |
// sent before. |
int time_until_probe_ms = 0; |
- if (packet_size_last_sent_ != 0 && probing_state_ == ProbingState::kActive) { |
+ 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.
|
int next_delta_ms = ComputeDeltaFromBitrate( |
packet_size_last_sent_, clusters_.front().probe_bitrate_bps); |
time_until_probe_ms = next_delta_ms - elapsed_time_ms; |
@@ -126,7 +185,7 @@ int BitrateProber::TimeUntilNextProbe(int64_t now_ms) { |
const int kMaxProbeDelayMs = 3; |
if (next_delta_ms < kMinProbeDeltaMs || |
time_until_probe_ms < -kMaxProbeDelayMs) { |
- probing_state_ = ProbingState::kSuspended; |
+ probing_state_ = State::kComplete; |
LOG(LS_INFO) << "Delta too small or missed probing accurately, suspend"; |
time_until_probe_ms = 0; |
} |
@@ -136,7 +195,7 @@ int BitrateProber::TimeUntilNextProbe(int64_t now_ms) { |
int BitrateProber::CurrentClusterId() const { |
RTC_DCHECK(!clusters_.empty()); |
- RTC_DCHECK(ProbingState::kActive == probing_state_); |
+ 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
|
return clusters_.front().id; |
} |
@@ -146,11 +205,11 @@ size_t BitrateProber::RecommendedPacketSize() const { |
void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) { |
assert(packet_size > 0); |
+ 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
|
+ |
if (packet_size < PacedSender::kMinProbePacketSize) |
return; |
packet_size_last_sent_ = packet_size; |
- if (probing_state_ != ProbingState::kActive) |
- return; |
time_last_probe_sent_ms_ = now_ms; |
if (!clusters_.empty()) { |
ProbeCluster* cluster = &clusters_.front(); |
@@ -158,7 +217,7 @@ void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) { |
if (cluster->sent_probe_packets == cluster->max_probe_packets) |
clusters_.pop(); |
if (clusters_.empty()) |
- probing_state_ = ProbingState::kSuspended; |
+ probing_state_ = State::kWaitForResult; |
} |
} |
} // namespace webrtc |