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_impl.cc b/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc
index 43c6e17..20cc3ac 100644
--- a/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc
+++ b/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc
@@ -30,23 +30,44 @@
   }
   // Received RTCP receiver block.
   virtual void OnReceivedRtcpReceiverReport(
-      const uint32_t ssrc,
-      const uint8_t fraction_loss,
-      const uint32_t rtt,
-      const uint32_t last_received_extended_high_seq_num,
-      const uint32_t now_ms) OVERRIDE {
-    uint32_t number_of_packets = 0;
-    std::map<uint32_t, uint32_t>::iterator it =
-        ssrc_to_last_received_extended_high_seq_num_.find(ssrc);
+      const ReportBlockList& report_blocks,
+      uint16_t rtt,
+      int64_t now_ms) OVERRIDE {
+    if (report_blocks.empty())
+      return;
 
-    if (it != ssrc_to_last_received_extended_high_seq_num_.end()) {
-      number_of_packets = last_received_extended_high_seq_num - it->second;
+    int fraction_lost_aggregate = 0;
+    int total_number_of_packets = 0;
+
+    // Compute the a weighted average of the fraction loss from all report
+    // blocks.
+    for (ReportBlockList::const_iterator it = report_blocks.begin();
+        it != report_blocks.end(); ++it) {
+      std::map<uint32_t, uint32_t>::iterator seq_num_it =
+          ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC);
+
+      int number_of_packets = 0;
+      if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end())
+        number_of_packets = it->extendedHighSeqNum -
+            seq_num_it->second;
+
+      fraction_lost_aggregate += number_of_packets * it->fractionLost;
+      total_number_of_packets += number_of_packets;
+
+      // Update last received for this SSRC.
+      ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] =
+          it->extendedHighSeqNum;
     }
-    // Update last received for this SSRC.
-    ssrc_to_last_received_extended_high_seq_num_[ssrc] =
-        last_received_extended_high_seq_num;
-    owner_->OnReceivedRtcpReceiverReport(fraction_loss, rtt, number_of_packets,
-                                         now_ms);
+    if (total_number_of_packets == 0)
+      fraction_lost_aggregate = 0;
+    else
+      fraction_lost_aggregate  = (fraction_lost_aggregate +
+          total_number_of_packets / 2) / total_number_of_packets;
+    if (fraction_lost_aggregate > 255)
+      return;
+
+    owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
+                                         total_number_of_packets, now_ms);
   }
  private:
   std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;