Bitrate prober now keep track of probing cluster id.

BUG=webrtc:5859
R=stefan@webrtc.org

Review URL: https://codereview.webrtc.org/1946173002 .

Cr-Commit-Position: refs/heads/master@{#12644}
diff --git a/webrtc/modules/pacing/bitrate_prober.cc b/webrtc/modules/pacing/bitrate_prober.cc
index ca09ee2..db42666 100644
--- a/webrtc/modules/pacing/bitrate_prober.cc
+++ b/webrtc/modules/pacing/bitrate_prober.cc
@@ -15,6 +15,7 @@
 #include <limits>
 #include <sstream>
 
+#include "webrtc/base/checks.h"
 #include "webrtc/base/logging.h"
 #include "webrtc/modules/pacing/paced_sender.h"
 
@@ -33,8 +34,8 @@
 BitrateProber::BitrateProber()
     : probing_state_(kDisabled),
       packet_size_last_send_(0),
-      time_last_send_ms_(-1) {
-}
+      time_last_send_ms_(-1),
+      cluster_id_(0) {}
 
 void BitrateProber::SetEnabled(bool enable) {
   if (enable) {
@@ -61,24 +62,24 @@
     return;
   if (probing_state_ != kAllowedToProbe)
     return;
-  probe_bitrates_.clear();
   // Max number of packets used for probing.
   const int kMaxNumProbes = 2;
   const int kPacketsPerProbe = 5;
   const float kProbeBitrateMultipliers[kMaxNumProbes] = {3, 6};
-  uint32_t bitrates_bps[kMaxNumProbes];
   std::stringstream bitrate_log;
   bitrate_log << "Start probing for bandwidth, bitrates:";
   for (int i = 0; i < kMaxNumProbes; ++i) {
-    bitrates_bps[i] = kProbeBitrateMultipliers[i] * bitrate_bps;
-    bitrate_log << " " << bitrates_bps[i];
-    // We need one extra to get 5 deltas for the first probe.
-    if (i == 0)
-      probe_bitrates_.push_back(bitrates_bps[i]);
-    for (int j = 0; j < kPacketsPerProbe; ++j)
-      probe_bitrates_.push_back(bitrates_bps[i]);
+    ProbeCluster cluster;
+    // We need one extra to get 5 deltas for the first probe, therefore (i == 0)
+    cluster.max_probe_packets = kPacketsPerProbe + (i == 0 ? 1 : 0);
+    cluster.probe_bitrate_bps = kProbeBitrateMultipliers[i] * bitrate_bps;
+    cluster.id = cluster_id_++;
+
+    bitrate_log << " " << cluster.probe_bitrate_bps;
+    bitrate_log << ", num packets: " << cluster.max_probe_packets;
+
+    clusters_.push(cluster);
   }
-  bitrate_log << ", num packets: " << probe_bitrates_.size();
   LOG(LS_INFO) << bitrate_log.str().c_str();
   // Set last send time to current time so TimeUntilNextProbe doesn't short
   // circuit due to inactivity.
@@ -87,10 +88,11 @@
 }
 
 int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
-  if (probing_state_ != kDisabled && probe_bitrates_.empty()) {
+  if (probing_state_ != kDisabled && clusters_.empty()) {
     probing_state_ = kWait;
   }
-  if (probe_bitrates_.empty() || time_last_send_ms_ == -1) {
+
+  if (clusters_.empty() || time_last_send_ms_ == -1) {
     // No probe started, probe finished, or too long since last probe packet.
     return -1;
   }
@@ -107,8 +109,8 @@
   // sent before.
   int time_until_probe_ms = 0;
   if (packet_size_last_send_ != 0 && probing_state_ == kProbing) {
-    int next_delta_ms = ComputeDeltaFromBitrate(packet_size_last_send_,
-                                                probe_bitrates_.front());
+    int next_delta_ms = ComputeDeltaFromBitrate(
+        packet_size_last_send_, clusters_.front().probe_bitrate_bps);
     time_until_probe_ms = next_delta_ms - elapsed_time_ms;
     // There is no point in trying to probe with less than 1 ms between packets
     // as it essentially means trying to probe at infinite bandwidth.
@@ -129,6 +131,12 @@
   return std::max(time_until_probe_ms, 0);
 }
 
+int BitrateProber::CurrentClusterId() const {
+  RTC_DCHECK(!clusters_.empty());
+  RTC_DCHECK_EQ(kProbing, probing_state_);
+  return clusters_.front().id;
+}
+
 size_t BitrateProber::RecommendedPacketSize() const {
   return packet_size_last_send_;
 }
@@ -141,7 +149,11 @@
   time_last_send_ms_ = now_ms;
   if (probing_state_ != kProbing)
     return;
-  if (!probe_bitrates_.empty())
-    probe_bitrates_.pop_front();
+  if (!clusters_.empty()) {
+    ProbeCluster* cluster = &clusters_.front();
+    ++cluster->sent_probe_packets;
+    if (cluster->sent_probe_packets == cluster->max_probe_packets)
+      clusters_.pop();
+  }
 }
 }  // namespace webrtc
diff --git a/webrtc/modules/pacing/bitrate_prober.h b/webrtc/modules/pacing/bitrate_prober.h
index 0749ce4..b0c0986 100644
--- a/webrtc/modules/pacing/bitrate_prober.h
+++ b/webrtc/modules/pacing/bitrate_prober.h
@@ -13,6 +13,7 @@
 
 #include <cstddef>
 #include <list>
+#include <queue>
 
 #include "webrtc/typedefs.h"
 
@@ -42,6 +43,9 @@
   // get accurate probing.
   int TimeUntilNextProbe(int64_t now_ms);
 
+  // Which cluster that is currently being used for probing.
+  int CurrentClusterId() const;
+
   // Returns the number of bytes that the prober recommends for the next probe
   // packet.
   size_t RecommendedPacketSize() const;
@@ -53,13 +57,21 @@
  private:
   enum ProbingState { kDisabled, kAllowedToProbe, kProbing, kWait };
 
+  struct ProbeCluster {
+    int max_probe_packets = 0;
+    int sent_probe_packets = 0;
+    int probe_bitrate_bps = 0;
+    int id = -1;
+  };
+
   ProbingState probing_state_;
   // Probe bitrate per packet. These are used to compute the delta relative to
   // the previous probe packet based on the size and time when that packet was
   // sent.
-  std::list<uint32_t> probe_bitrates_;
+  std::queue<ProbeCluster> clusters_;
   size_t packet_size_last_send_;
   int64_t time_last_send_ms_;
+  int cluster_id_;
 };
 }  // namespace webrtc
 #endif  // WEBRTC_MODULES_PACING_BITRATE_PROBER_H_
diff --git a/webrtc/modules/pacing/bitrate_prober_unittest.cc b/webrtc/modules/pacing/bitrate_prober_unittest.cc
index 59ee479..9e38220 100644
--- a/webrtc/modules/pacing/bitrate_prober_unittest.cc
+++ b/webrtc/modules/pacing/bitrate_prober_unittest.cc
@@ -26,6 +26,7 @@
 
   prober.OnIncomingPacket(300000, 1000, now_ms);
   EXPECT_TRUE(prober.IsProbing());
+  EXPECT_EQ(0, prober.CurrentClusterId());
 
   // First packet should probe as soon as possible.
   EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
@@ -37,12 +38,14 @@
     EXPECT_EQ(4, prober.TimeUntilNextProbe(now_ms));
     now_ms += 4;
     EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
+    EXPECT_EQ(0, prober.CurrentClusterId());
     prober.PacketSent(now_ms, 1000);
   }
   for (int i = 0; i < 5; ++i) {
     EXPECT_EQ(4, prober.TimeUntilNextProbe(now_ms));
     now_ms += 4;
     EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
+    EXPECT_EQ(1, prober.CurrentClusterId());
     prober.PacketSent(now_ms, 1000);
   }