Add support for multiple report blocks.

Use a weighted average of fraction loss for bandwidth estimation.

TEST=trybots and vie_auto_test --automated
BUG=1811
R=mflodman@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/2198004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4762 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc b/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc
index fcf419e..7abe71b 100644
--- a/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc
+++ b/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc
@@ -20,6 +20,21 @@
 using webrtc::BitrateObserver;
 using webrtc::BitrateController;
 
+uint8_t WeightedLoss(int num_packets1, uint8_t fraction_loss1,
+                     int num_packets2, uint8_t fraction_loss2) {
+  int weighted_sum = num_packets1 * fraction_loss1 +
+      num_packets2 * fraction_loss2;
+  int total_num_packets = num_packets1 + num_packets2;
+  return (weighted_sum + total_num_packets / 2) / total_num_packets;
+}
+
+webrtc::RTCPReportBlock CreateReportBlock(
+    uint32_t remote_ssrc, uint32_t source_ssrc,
+    uint8_t fraction_lost, uint32_t extended_high_sequence_number) {
+  return webrtc::RTCPReportBlock(remote_ssrc, source_ssrc, fraction_lost, 0,
+                                 extended_high_sequence_number, 0, 0, 0);
+}
+
 class TestBitrateObserver: public BitrateObserver {
  public:
   TestBitrateObserver()
@@ -73,33 +88,49 @@
   bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
 
   // Test start bitrate.
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 1, 1);
+  webrtc::ReportBlockList report_blocks;
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1);
   EXPECT_EQ(0u, bitrate_observer.last_bitrate_);
   EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
   EXPECT_EQ(0u, bitrate_observer.last_rtt_);
 
   // Test bitrate increase 8% per second.
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 21, 1001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001);
   EXPECT_EQ(217000u, bitrate_observer.last_bitrate_);
   EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
   EXPECT_EQ(50u, bitrate_observer.last_rtt_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 41, 2001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
   EXPECT_EQ(235360u, bitrate_observer.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 61, 3001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001);
   EXPECT_EQ(255189u, bitrate_observer.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 801, 4001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 801));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 4001);
   EXPECT_EQ(276604u, bitrate_observer.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 101, 5001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 101));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 5001);
   EXPECT_EQ(299732u, bitrate_observer.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 121, 6001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 121));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 6001);
   EXPECT_EQ(300000u, bitrate_observer.last_bitrate_);  // Max cap.
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 141, 7001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 141));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 7001);
   EXPECT_EQ(300000u, bitrate_observer.last_bitrate_);  // Max cap.
 
   // Test that a low REMB trigger immediately.
@@ -124,44 +155,73 @@
   bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
 
   // Test start bitrate.
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 1, 1);
-  second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 1, 1);
+  webrtc::ReportBlockList report_blocks;
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1);
+  second_bandwidth_observer->OnReceivedRtcpReceiverReport(
+      report_blocks, 100, 1);
   EXPECT_EQ(0u, bitrate_observer.last_bitrate_);
   EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
   EXPECT_EQ(0u, bitrate_observer.last_rtt_);
 
   // Test bitrate increase 8% per second.
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 21, 501);
-  second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 21, 1001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 501);
+  second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100,
+                                                          1001);
   EXPECT_EQ(217000u, bitrate_observer.last_bitrate_);
   EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
   EXPECT_EQ(100u, bitrate_observer.last_rtt_);
 
   // Extra report should not change estimate.
-  second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 31, 1501);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 31));
+  second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100,
+                                                          1501);
   EXPECT_EQ(217000u, bitrate_observer.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 41, 2001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
   EXPECT_EQ(235360u, bitrate_observer.last_bitrate_);
 
   // Second report should not change estimate.
-  second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 100, 41, 2001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
+  second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 100,
+                                                          2001);
   EXPECT_EQ(235360u, bitrate_observer.last_bitrate_);
 
   // Reports from only one bandwidth observer is ok.
-  second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 61, 3001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
+  second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
+                                                          3001);
   EXPECT_EQ(255189u, bitrate_observer.last_bitrate_);
 
-  second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 81, 4001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 81));
+  second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
+                                                          4001);
   EXPECT_EQ(276604u, bitrate_observer.last_bitrate_);
 
-  second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 101, 5001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 101));
+  second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
+                                                          5001);
   EXPECT_EQ(299732u, bitrate_observer.last_bitrate_);
 
-  second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 121, 6001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 121));
+  second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
+                                                          6001);
   EXPECT_EQ(300000u, bitrate_observer.last_bitrate_);  // Max cap.
 
-  second_bandwidth_observer->OnReceivedRtcpReceiverReport(1, 0, 50, 141, 7001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 141));
+  second_bandwidth_observer->OnReceivedRtcpReceiverReport(report_blocks, 50,
+                                                          7001);
   EXPECT_EQ(300000u, bitrate_observer.last_bitrate_);  // Max cap.
 
   // Test that a low REMB trigger immediately.
@@ -177,6 +237,78 @@
   delete second_bandwidth_observer;
 }
 
+TEST_F(BitrateControllerTest, OneBitrateObserverMultipleReportBlocks) {
+  TestBitrateObserver bitrate_observer;
+  uint32_t sequence_number[2] = {0, 0xFF00};
+  const uint32_t kStartBitrate = 200000;
+  const uint32_t kMinBitrate = 100000;
+  const uint32_t kMaxBitrate = 300000;
+  controller_->SetBitrateObserver(&bitrate_observer, kStartBitrate, kMinBitrate,
+                                  kMaxBitrate);
+
+  // Receive a high REMB, test bitrate increase.
+  bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
+
+  webrtc::ReportBlockList report_blocks;
+  int64_t time_ms = 1001;
+  uint32_t last_bitrate = 0;
+  // Ramp up to max bitrate.
+  for (int i = 0; i < 6; ++i) {
+    report_blocks.push_back(CreateReportBlock(1, 2, 0, sequence_number[0]));
+    report_blocks.push_back(CreateReportBlock(1, 3, 0, sequence_number[1]));
+    bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50,
+                                                      time_ms);
+    EXPECT_GT(bitrate_observer.last_bitrate_, last_bitrate);
+    EXPECT_EQ(0, bitrate_observer.last_fraction_loss_);
+    EXPECT_EQ(50u, bitrate_observer.last_rtt_);
+    last_bitrate = bitrate_observer.last_bitrate_;
+    time_ms += 1000;
+    sequence_number[0] += 20;
+    sequence_number[1] += 1;
+    report_blocks.clear();
+  }
+
+  EXPECT_EQ(kMaxBitrate, bitrate_observer.last_bitrate_);
+
+  // Packet loss on the first stream. Verify that bitrate decreases.
+  report_blocks.push_back(CreateReportBlock(1, 2, 50, sequence_number[0]));
+  report_blocks.push_back(CreateReportBlock(1, 3, 0, sequence_number[1]));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
+  EXPECT_LT(bitrate_observer.last_bitrate_, last_bitrate);
+  EXPECT_EQ(WeightedLoss(20, 50, 1, 0), bitrate_observer.last_fraction_loss_);
+  EXPECT_EQ(50u, bitrate_observer.last_rtt_);
+  last_bitrate = bitrate_observer.last_bitrate_;
+  sequence_number[0] += 20;
+  sequence_number[1] += 20;
+  time_ms += 1000;
+  report_blocks.clear();
+
+  // Packet loss on the second stream. Verify that bitrate decreases.
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, sequence_number[0]));
+  report_blocks.push_back(CreateReportBlock(1, 3, 75, sequence_number[1]));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
+  EXPECT_LT(bitrate_observer.last_bitrate_, last_bitrate);
+  EXPECT_EQ(WeightedLoss(20, 0, 20, 75), bitrate_observer.last_fraction_loss_);
+  EXPECT_EQ(50u, bitrate_observer.last_rtt_);
+  last_bitrate = bitrate_observer.last_bitrate_;
+  sequence_number[0] += 20;
+  sequence_number[1] += 1;
+  time_ms += 1000;
+  report_blocks.clear();
+
+  // All packets lost on stream with few packets, no back-off.
+  report_blocks.push_back(CreateReportBlock(1, 2, 1, sequence_number[0]));
+  report_blocks.push_back(CreateReportBlock(1, 3, 255, sequence_number[1]));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
+  EXPECT_EQ(bitrate_observer.last_bitrate_, last_bitrate);
+  EXPECT_EQ(WeightedLoss(20, 1, 1, 255), bitrate_observer.last_fraction_loss_);
+  EXPECT_EQ(50u, bitrate_observer.last_rtt_);
+  last_bitrate = bitrate_observer.last_bitrate_;
+  sequence_number[0] += 20;
+  sequence_number[1] += 1;
+  report_blocks.clear();
+}
+
 TEST_F(BitrateControllerTest, TwoBitrateObserversOneRtcpObserver) {
   TestBitrateObserver bitrate_observer_1;
   TestBitrateObserver bitrate_observer_2;
@@ -187,10 +319,14 @@
   bandwidth_observer_->OnReceivedEstimatedBitrate(400000);
 
   // Test too low start bitrate, hence lower than sum of min.
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 1, 1);
+  webrtc::ReportBlockList report_blocks;
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 1));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1);
 
   // Test bitrate increase 8% per second, distributed equally.
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 21, 1001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 21));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001);
   EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_);
   EXPECT_EQ(50u, bitrate_observer_1.last_rtt_);
@@ -199,47 +335,67 @@
   EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_);
   EXPECT_EQ(50u, bitrate_observer_2.last_rtt_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 41, 2001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 41));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001);
   EXPECT_EQ(112500u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(212500u, bitrate_observer_2.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 61, 3001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 61));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001);
   EXPECT_EQ(126000u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(226000u, bitrate_observer_2.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 81, 4001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 81));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 4001);
   EXPECT_EQ(140580u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(240580u, bitrate_observer_2.last_bitrate_);
 
   // Check that the bitrate sum honor our REMB.
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 101, 5001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 101));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 5001);
   EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(250000u, bitrate_observer_2.last_bitrate_);
 
   // Remove REMB cap, higher than sum of max.
   bandwidth_observer_->OnReceivedEstimatedBitrate(700000);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 121, 6001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 121));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 6001);
   EXPECT_EQ(166500u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(266500u, bitrate_observer_2.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 141, 7001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 141));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 7001);
   EXPECT_EQ(184320u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(284320u, bitrate_observer_2.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 161, 8001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 161));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 8001);
   EXPECT_EQ(207130u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);  // Max cap.
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 181, 9001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 181));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 9001);
   EXPECT_EQ(248700u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 201, 10001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 201));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 10001);
   EXPECT_EQ(293596u, bitrate_observer_1.last_bitrate_);
   EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);
 
-  bandwidth_observer_->OnReceivedRtcpReceiverReport(1, 0, 50, 221, 11001);
+  report_blocks.clear();
+  report_blocks.push_back(CreateReportBlock(1, 2, 0, 221));
+  bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 11001);
   EXPECT_EQ(300000u, bitrate_observer_1.last_bitrate_);  // Max cap.
   EXPECT_EQ(300000u, bitrate_observer_2.last_bitrate_);