Break out RemoteBitrateEstimator from RtpRtcp module and make RemoteBitrateEstimator::Process trigger new REMB messages.

Also make sure RTT is computed independently of whether it's time to send RTCP messages or not.

BUG=1298

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3455 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
index 0438510..5340ed2 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
@@ -60,11 +60,13 @@
  protected:
   RtcpFormatRembTest()
       : over_use_detector_options_(),
+        system_clock_(Clock::GetRealTimeClock()),
         remote_bitrate_observer_(),
         remote_bitrate_estimator_(RemoteBitrateEstimator::Create(
-            &remote_bitrate_observer_,
             over_use_detector_options_,
-            RemoteBitrateEstimator::kMultiStreamEstimation)) {}
+            RemoteBitrateEstimator::kMultiStreamEstimation,
+            &remote_bitrate_observer_,
+            system_clock_)) {}
   virtual void SetUp();
   virtual void TearDown();
 
@@ -79,7 +81,6 @@
 };
 
 void RtcpFormatRembTest::SetUp() {
-  system_clock_ = Clock::GetRealTimeClock();
   RtpRtcp::Configuration configuration;
   configuration.id = 0;
   configuration.audio = false;
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
index e300439..d05dd2d 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -113,6 +113,19 @@
     return _lastReceived;
 }
 
+WebRtc_Word64
+RTCPReceiver::LastReceivedReceiverReport() const {
+    CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
+    WebRtc_Word64 last_received_rr = -1;
+    for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
+         it != _receivedInfoMap.end(); ++it) {
+      if (it->second->lastTimeReceived > last_received_rr) {
+        last_received_rr = it->second->lastTimeReceived;
+      }
+    }
+    return last_received_rr;
+}
+
 WebRtc_Word32
 RTCPReceiver::SetRemoteSSRC( const WebRtc_UWord32 ssrc)
 {
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
index 08ff37b..befe2df 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -37,6 +37,7 @@
     WebRtc_Word32 SetRTCPStatus(const RTCPMethod method);
 
     WebRtc_Word64 LastReceived();
+    WebRtc_Word64 LastReceivedReceiverReport() const;
 
     void SetSSRC( const WebRtc_UWord32 ssrc);
     void SetRelaySSRC( const WebRtc_UWord32 ssrc);
@@ -197,6 +198,8 @@
                        RTCPHelp::RTCPPacketInformation& rtcpPacketInformation);
 
  private:
+  typedef std::map<WebRtc_UWord32, RTCPHelp::RTCPReceiveInformation*>
+      ReceivedInfoMap;
   WebRtc_Word32           _id;
   Clock*                  _clock;
   RTCPMethod              _method;
@@ -221,8 +224,7 @@
   // Received report blocks.
   std::map<WebRtc_UWord32, RTCPHelp::RTCPReportBlockInformation*>
       _receivedReportBlockMap;
-  std::map<WebRtc_UWord32, RTCPHelp::RTCPReceiveInformation*>
-      _receivedInfoMap;
+  ReceivedInfoMap _receivedInfoMap;
   std::map<WebRtc_UWord32, RTCPUtility::RTCPCnameInformation*>
       _receivedCnameMap;
 
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index 783b13a..11d158a 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -172,9 +172,10 @@
         remote_bitrate_observer_(),
         remote_bitrate_estimator_(
             RemoteBitrateEstimator::Create(
-                &remote_bitrate_observer_,
                 over_use_detector_options_,
-                RemoteBitrateEstimator::kMultiStreamEstimation)) {
+                RemoteBitrateEstimator::kMultiStreamEstimation,
+                &remote_bitrate_observer_,
+                &system_clock_)) {
     test_transport_ = new TestTransport();
 
     RtpRtcp::Configuration configuration;
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index 7bd2931..e3cadbd 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -99,13 +99,14 @@
  protected:
   RtcpSenderTest()
       : over_use_detector_options_(),
+        system_clock_(Clock::GetRealTimeClock()),
         remote_bitrate_observer_(),
         remote_bitrate_estimator_(
             RemoteBitrateEstimator::Create(
-                &remote_bitrate_observer_,
                 over_use_detector_options_,
-                RemoteBitrateEstimator::kMultiStreamEstimation)) {
-    system_clock_ = Clock::GetRealTimeClock();
+                RemoteBitrateEstimator::kMultiStreamEstimation,
+                &remote_bitrate_observer_,
+                system_clock_)) {
     test_transport_ = new TestTransport();
 
     RtpRtcp::Configuration configuration;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h
index 066b3c2..e128a10 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h
@@ -15,7 +15,8 @@
 namespace webrtc {
 enum { kRtpRtcpMaxIdleTimeProcess = 5,
        kRtpRtcpBitrateProcessTimeMs = 10,
-       kRtpRtcpPacketTimeoutProcessTimeMs = 100 };
+       kRtpRtcpPacketTimeoutProcessTimeMs = 100,
+       kRtpRtcpRttProcessTimeMs = 1000 };
 
 enum { NACK_PACKETS_MAX_SIZE    = 256 }; // in packets
 enum { NACK_BYTECOUNT_SIZE      = 60};   // size of our NACK history
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 2cc17a3..3cb7994 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -11,7 +11,6 @@
 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
 
 #include <string.h>
-
 #include <cassert>
 
 #include "webrtc/common_types.h"
@@ -39,8 +38,6 @@
 
 namespace webrtc {
 
-const WebRtc_UWord16 kDefaultRtt = 200;
-
 static RtpData* NullObjectRtpData() {
   static NullRtpData null_rtp_data;
   return &null_rtp_data;
@@ -107,6 +104,7 @@
       last_bitrate_process_time_(configuration.clock->TimeInMilliseconds()),
       last_packet_timeout_process_time_(
           configuration.clock->TimeInMilliseconds()),
+      last_rtt_process_time_(configuration.clock->TimeInMilliseconds()),
       packet_overhead_(28),  // IPV4 UDP.
       critical_section_module_ptrs_(
           CriticalSectionWrapper::CreateCriticalSection()),
@@ -258,33 +256,30 @@
   ProcessDeadOrAliveTimer();
 
   const bool default_instance(child_modules_.empty() ? false : true);
-  if (!default_instance && rtcp_sender_.TimeToSendRTCPReport()) {
-    WebRtc_UWord16 max_rtt = 0;
+  if (!default_instance) {
     if (rtcp_sender_.Sending()) {
-      std::vector<RTCPReportBlock> receive_blocks;
-      rtcp_receiver_.StatisticsReceived(&receive_blocks);
-      for (std::vector<RTCPReportBlock>::iterator it = receive_blocks.begin();
-           it != receive_blocks.end(); ++it) {
-        WebRtc_UWord16 rtt = 0;
-        rtcp_receiver_.RTT(it->remoteSSRC, &rtt, NULL, NULL, NULL);
-        max_rtt = (rtt > max_rtt) ? rtt : max_rtt;
+      // Process RTT if we have received a receiver report and we haven't
+      // processed RTT for at least |kRtpRtcpRttProcessTimeMs| milliseconds.
+      if (rtcp_receiver_.LastReceivedReceiverReport() >
+          last_rtt_process_time_ && now >= last_rtt_process_time_ +
+          kRtpRtcpRttProcessTimeMs) {
+        last_rtt_process_time_ = now;
+        std::vector<RTCPReportBlock> receive_blocks;
+        rtcp_receiver_.StatisticsReceived(&receive_blocks);
+        uint16_t max_rtt = 0;
+        for (std::vector<RTCPReportBlock>::iterator it = receive_blocks.begin();
+             it != receive_blocks.end(); ++it) {
+          uint16_t rtt = 0;
+          rtcp_receiver_.RTT(it->remoteSSRC, &rtt, NULL, NULL, NULL);
+          max_rtt = (rtt > max_rtt) ? rtt : max_rtt;
+        }
+        // Report the rtt.
+        if (rtt_observer_ && max_rtt != 0)
+          rtt_observer_->OnRttUpdate(max_rtt);
       }
-      // Report the rtt.
-      if (rtt_observer_ && max_rtt != 0)
-        rtt_observer_->OnRttUpdate(max_rtt);
-    } else {
-      // No valid RTT estimate, probably since this is a receive only channel.
-      // Use an estimate set by a send module.
-      max_rtt = rtcp_receiver_.RTT();
-    }
-    if (max_rtt == 0) {
-      // No own rtt calculation or set rtt, use default value.
-      max_rtt = kDefaultRtt;
-    }
 
-    // Verify receiver reports are delivered and the reported sequence number is
-    // increasing.
-    if (rtcp_sender_.Sending()) {
+      // Verify receiver reports are delivered and the reported sequence number
+      // is increasing.
       int64_t rtcp_interval = RtcpReportInterval();
       if (rtcp_receiver_.RtcpRrTimeout(rtcp_interval)) {
         LOG_F(LS_WARNING) << "Timeout: No RTCP RR received.";
@@ -292,13 +287,8 @@
         LOG_F(LS_WARNING) <<
             "Timeout: No increase in RTCP RR extended highest sequence number.";
       }
-    }
 
-    if (remote_bitrate_) {
-      // TODO(mflodman) Remove this and let this be propagated by CallStats.
-      remote_bitrate_->SetRtt(max_rtt);
-      remote_bitrate_->UpdateEstimate(rtp_receiver_->SSRC(), now);
-      if (TMMBR()) {
+      if (remote_bitrate_ && TMMBR()) {
         unsigned int target_bitrate = 0;
         std::vector<unsigned int> ssrcs;
         if (remote_bitrate_->LatestEstimate(&ssrcs, &target_bitrate)) {
@@ -309,7 +299,8 @@
         }
       }
     }
-    rtcp_sender_.SendRTCP(kRtcpReport);
+    if (rtcp_sender_.TimeToSendRTCPReport())
+      rtcp_sender_.SendRTCP(kRtcpReport);
   }
 
   if (UpdateRTCPReceiveInformationTimers()) {
@@ -1995,22 +1986,6 @@
     *nack_rate = rtp_sender_.NackOverheadRate();
 }
 
-int ModuleRtpRtcpImpl::EstimatedReceiveBandwidth(
-    WebRtc_UWord32* available_bandwidth) const {
-  if (remote_bitrate_) {
-    std::vector<unsigned int> ssrcs;
-    if (!remote_bitrate_->LatestEstimate(&ssrcs, available_bandwidth)) {
-      return -1;
-    }
-    if (!ssrcs.empty()) {
-      *available_bandwidth /= ssrcs.size();
-    }
-    return 0;
-  }
-  // No bandwidth receive-side bandwidth estimation is connected to this module.
-  return -1;
-}
-
 // Bad state of RTP receiver request a keyframe.
 void ModuleRtpRtcpImpl::OnRequestIntraFrame() {
   RequestKeyFrame();
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index 5883a11..666612b 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -427,9 +427,6 @@
                            WebRtc_UWord32* fec_rate,
                            WebRtc_UWord32* nackRate) const;
 
-  virtual int EstimatedReceiveBandwidth(
-      WebRtc_UWord32* available_bandwidth) const;
-
   virtual void SetRemoteSSRC(const WebRtc_UWord32 ssrc);
 
   virtual WebRtc_UWord32 SendTimeOfSendReport(const WebRtc_UWord32 send_report);
@@ -493,6 +490,7 @@
   WebRtc_Word64             last_process_time_;
   WebRtc_Word64             last_bitrate_process_time_;
   WebRtc_Word64             last_packet_timeout_process_time_;
+  WebRtc_Word64             last_rtt_process_time_;
   WebRtc_UWord16            packet_overhead_;
 
   scoped_ptr<CriticalSectionWrapper> critical_section_module_ptrs_;