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

Unified 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698