Fix perf issue when timinig out receiver infos in RTCP.

BUG=b/33270241

Review-Url: https://codereview.webrtc.org/2664163002
Cr-Commit-Position: refs/heads/master@{#16414}
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
index 51c4aa8..59049be 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -145,11 +145,7 @@
 
 int64_t RTCPReceiver::LastReceivedReceiverReport() const {
   rtc::CritScope lock(&rtcp_receiver_lock_);
-  int64_t last_received_rr = -1;
-  for (const auto& kv : received_infos_)
-    if (kv.second.last_time_received_ms > last_received_rr)
-      last_received_rr = kv.second.last_time_received_ms;
-  return last_received_rr;
+  return last_received_rr_ms_;
 }
 
 void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
@@ -445,6 +441,8 @@
     return;
   }
 
+  last_received_rr_ms_ = clock_->TimeInMilliseconds();
+
   const uint32_t remote_ssrc = receiver_report.sender_ssrc();
 
   packet_information->remote_ssrc = remote_ssrc;
@@ -478,8 +476,6 @@
 
   ReportBlockWithRtt* report_block_info =
       &received_report_blocks_[report_block.source_ssrc()][remote_ssrc];
-
-  last_received_rr_ms_ = clock_->TimeInMilliseconds();
   report_block_info->report_block.remoteSSRC = remote_ssrc;
   report_block_info->report_block.sourceSSRC = report_block.source_ssrc();
   report_block_info->report_block.fractionLost = report_block.fraction_lost();
@@ -489,7 +485,7 @@
       report_block_info->report_block.extendedHighSeqNum) {
     // We have successfully delivered new RTP packets to the remote side after
     // the last RR was sent from the remote side.
-    last_increased_sequence_number_ms_ = last_received_rr_ms_;
+    last_increased_sequence_number_ms_ = clock_->TimeInMilliseconds();
   }
   report_block_info->report_block.extendedHighSeqNum =
       report_block.extended_high_seq_num();
@@ -579,22 +575,30 @@
 bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
   rtc::CritScope lock(&rtcp_receiver_lock_);
 
-  bool update_bounding_set = false;
   int64_t now_ms = clock_->TimeInMilliseconds();
   // Use audio define since we don't know what interval the remote peer use.
-  int64_t timeouted_ms = now_ms - 5 * RTCP_INTERVAL_AUDIO_MS;
+  int64_t timeout_ms = now_ms - 5 * RTCP_INTERVAL_AUDIO_MS;
 
+  if (oldest_received_info_ms_ >= timeout_ms)
+    return false;
+
+  bool update_bounding_set = false;
+  oldest_received_info_ms_ = -1;
   for (auto receive_info_it = received_infos_.begin();
        receive_info_it != received_infos_.end();) {
     ReceiveInformation* receive_info = &receive_info_it->second;
     if (receive_info->last_time_received_ms > 0) {
-      if (receive_info->last_time_received_ms < timeouted_ms) {
+      if (receive_info->last_time_received_ms < timeout_ms) {
         // No rtcp packet for the last 5 regular intervals, reset limitations.
         receive_info->tmmbr.clear();
         // Prevent that we call this over and over again.
         receive_info->last_time_received_ms = 0;
         // Send new TMMBN to all channels using the default codec.
         update_bounding_set = true;
+      } else if (oldest_received_info_ms_ == -1 ||
+                 receive_info->last_time_received_ms <
+                     oldest_received_info_ms_) {
+        oldest_received_info_ms_ = receive_info->last_time_received_ms;
       }
       ++receive_info_it;
     } else if (receive_info->ready_for_delete) {
@@ -1070,11 +1074,11 @@
 
   int64_t now_ms = clock_->TimeInMilliseconds();
   // Use audio define since we don't know what interval the remote peer use.
-  int64_t timeouted_ms = now_ms - 5 * RTCP_INTERVAL_AUDIO_MS;
+  int64_t timeout_ms = now_ms - 5 * RTCP_INTERVAL_AUDIO_MS;
 
   for (auto& kv : received_infos_) {
     for (auto it = kv.second.tmmbr.begin(); it != kv.second.tmmbr.end();) {
-      if (it->second.last_updated_ms < timeouted_ms) {
+      if (it->second.last_updated_ms < timeout_ms) {
         // Erase timeout entries.
         it = kv.second.tmmbr.erase(it);
       } else {
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
index b67d07f..1e4d88b 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -244,11 +244,12 @@
   // Received report blocks.
   ReportBlockMap received_report_blocks_ GUARDED_BY(rtcp_receiver_lock_);
   ReceivedInfoMap received_infos_ GUARDED_BY(rtcp_receiver_lock_);
+  int64_t oldest_received_info_ms_ GUARDED_BY(rtcp_receiver_lock_);
   std::map<uint32_t, std::string> received_cnames_
       GUARDED_BY(rtcp_receiver_lock_);
 
   // The last time we received an RTCP RR.
-  int64_t last_received_rr_ms_;
+  int64_t last_received_rr_ms_ GUARDED_BY(rtcp_receiver_lock_);
 
   // The time we last received an RTCP RR telling we have successfully
   // delivered RTP packet to the remote side.
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 3c986e9..e0bcebd 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -211,7 +211,7 @@
   if (rtcp_sender_.TimeToSendRTCPReport())
     rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
 
-  if (UpdateRTCPReceiveInformationTimers()) {
+  if (TMMBR() && rtcp_receiver_.UpdateRTCPReceiveInformationTimers()) {
     // A receiver has timed out.
     rtcp_receiver_.UpdateTmmbr();
   }
@@ -867,12 +867,6 @@
   return true;
 }
 
-bool ModuleRtpRtcpImpl::UpdateRTCPReceiveInformationTimers() {
-  // If this returns true this channel has timed out.
-  // Periodically check if this is true and if so call UpdateTMMBR.
-  return rtcp_receiver_.UpdateRTCPReceiveInformationTimers();
-}
-
 // Called from RTCPsender.
 std::vector<rtcp::TmmbItem> ModuleRtpRtcpImpl::BoundingSet(bool* tmmbr_owner) {
   return rtcp_receiver_.BoundingSet(tmmbr_owner);