RTT intermediate calculation use ntp time instead of milliseconds.
  Compact NTP representation was designed exactly for that purpose: calculate RTT. No need to map to ms before doing arithmetic on this values.
  Because of this change there is no need to keep mapping between compact ntp presentation and milliseconds in the RTCPSender.

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

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

Cr-Commit-Position: refs/heads/master@{#11710}
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
index d65b04c..e8a943f 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -21,6 +21,8 @@
 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
+#include "webrtc/modules/rtp_rtcp/source/time_util.h"
+#include "webrtc/system_wrappers/include/ntp_time.h"
 
 namespace webrtc {
 using RTCPHelp::RTCPPacketInformation;
@@ -487,13 +489,6 @@
     return;
   }
 
-  // To avoid problem with acquiring _criticalSectionRTCPSender while holding
-  // _criticalSectionRTCPReceiver.
-  _criticalSectionRTCPReceiver->Leave();
-  int64_t sendTimeMS =
-      _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
-  _criticalSectionRTCPReceiver->Enter();
-
   RTCPReportBlockInformation* reportBlock =
       CreateOrGetReportBlockInformation(remoteSSRC,
                                         rtcpPacket.ReportBlockItem.SSRC);
@@ -526,60 +521,48 @@
     reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
   }
 
-  uint32_t delaySinceLastSendReport =
-      rtcpPacket.ReportBlockItem.DelayLastSR;
+  uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
+  uint32_t rtt = 0;
 
-  // local NTP time when we received this
-  uint32_t lastReceivedRRNTPsecs = 0;
-  uint32_t lastReceivedRRNTPfrac = 0;
+  if (send_time > 0) {
+    uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
+    // Local NTP time.
+    uint32_t receive_time = CompactNtp(NtpTime(*_clock));
 
-  _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
-
-  // time when we received this in MS
-  int64_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
-                                         lastReceivedRRNTPfrac);
-
-  // Estimate RTT
-  uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
-  d /= 65536;
-  d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
-
-  int64_t RTT = 0;
-
-  if (sendTimeMS > 0) {
-    RTT = receiveTimeMS - d - sendTimeMS;
-    if (RTT <= 0) {
-      RTT = 1;
-    }
-    if (RTT > reportBlock->maxRTT) {
-      // store max RTT
-      reportBlock->maxRTT = RTT;
+    // RTT in 1/(2^16) seconds.
+    uint32_t rtt_ntp = receive_time - delay - send_time;
+    // Convert to 1/1000 seconds (milliseconds).
+    uint32_t rtt_ms = CompactNtpIntervalToMs(rtt_ntp);
+    rtt = std::max<uint32_t>(rtt_ms, 1);
+    if (rtt > reportBlock->maxRTT) {
+      // Store max RTT.
+      reportBlock->maxRTT = rtt;
     }
     if (reportBlock->minRTT == 0) {
-      // first RTT
-      reportBlock->minRTT = RTT;
-    } else if (RTT < reportBlock->minRTT) {
-      // Store min RTT
-      reportBlock->minRTT = RTT;
+      // First RTT.
+      reportBlock->minRTT = rtt;
+    } else if (rtt < reportBlock->minRTT) {
+      // Store min RTT.
+      reportBlock->minRTT = rtt;
     }
-    // store last RTT
-    reportBlock->RTT = RTT;
+    // Store last RTT.
+    reportBlock->RTT = rtt;
 
     // store average RTT
     if (reportBlock->numAverageCalcs != 0) {
       float ac = static_cast<float>(reportBlock->numAverageCalcs);
       float newAverage =
-          ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * RTT);
+          ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
       reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
     } else {
-      // first RTT
-      reportBlock->avgRTT = RTT;
+      // First RTT.
+      reportBlock->avgRTT = rtt;
     }
     reportBlock->numAverageCalcs++;
   }
 
   TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
-                    RTT);
+                    rtt);
 
   rtcpPacketInformation.AddReportInfo(*reportBlock);
 }
@@ -934,28 +917,19 @@
 
   rtcpPacketInformation.xr_dlrr_item = true;
 
-  // To avoid problem with acquiring _criticalSectionRTCPSender while holding
-  // _criticalSectionRTCPReceiver.
-  _criticalSectionRTCPReceiver->Leave();
-
-  int64_t send_time_ms;
-  bool found = _rtpRtcp.SendTimeOfXrRrReport(
-      packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
-
-  _criticalSectionRTCPReceiver->Enter();
-
-  if (!found) {
+  // The send_time and delay_rr fields are in units of 1/2^16 sec.
+  uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
+  // RFC3411, section 4.5, LRR field discription states:
+  // If no such block has been received, the field is set to zero.
+  if (send_time == 0)
     return;
-  }
 
-  // The DelayLastRR field is in units of 1/65536 sec.
-  uint32_t delay_rr_ms =
-      (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
-      (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
+  uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
+  uint32_t now = CompactNtp(NtpTime(*_clock));
 
-  int64_t rtt = _clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
-
-  xr_rr_rtt_ms_ = std::max<int64_t>(rtt, 1);
+  uint32_t rtt_ntp = now - delay_rr - send_time;
+  uint32_t rtt_ms = CompactNtpIntervalToMs(rtt_ntp);
+  xr_rr_rtt_ms_ = std::max<uint32_t>(rtt_ms, 1);
 
   rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
 }
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index 8ba9fe7..c6df905 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -36,7 +36,8 @@
 #include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+#include "webrtc/modules/rtp_rtcp/source/time_util.h"
+#include "webrtc/system_wrappers/include/ntp_time.h"
 
 namespace webrtc {
 
@@ -179,6 +180,42 @@
   EXPECT_EQ(kRtcpSr, rtcp_packet_info_.rtcpPacketTypeFlags);
 }
 
+TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
+  Random r(0x0123456789abcdef);
+  const uint32_t kSenderSsrc = r.Rand(0x00000001u, 0xfffffffeu);
+  const uint32_t kRemoteSsrc = r.Rand(0x00000001u, 0xfffffffeu);
+  const int64_t kRttMs = r.Rand(1, 18 * 3600 * 1000);
+  const uint32_t kDelayNtp = r.Rand<uint32_t>();
+  const uint32_t kDelayMs = CompactNtpIntervalToMs(kDelayNtp);
+
+  rtcp_receiver_->SetRemoteSSRC(kSenderSsrc);
+  std::set<uint32_t> ssrcs;
+  ssrcs.insert(kRemoteSsrc);
+  rtcp_receiver_->SetSsrcs(kRemoteSsrc, ssrcs);
+
+  int64_t rtt_ms = 0;
+  EXPECT_EQ(
+      -1, rtcp_receiver_->RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
+
+  uint32_t sent_ntp = CompactNtp(NtpTime(system_clock_));
+  system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
+
+  rtcp::SenderReport sr;
+  sr.From(kSenderSsrc);
+  rtcp::ReportBlock block;
+  block.To(kRemoteSsrc);
+  block.WithLastSr(sent_ntp);
+  block.WithDelayLastSr(kDelayNtp);
+  sr.WithReportBlock(block);
+
+  rtc::Buffer packet = sr.Build();
+  EXPECT_EQ(0, InjectRtcpPacket(packet.data(), packet.size()));
+
+  EXPECT_EQ(
+      0, rtcp_receiver_->RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
+  EXPECT_NEAR(kRttMs, rtt_ms, 1);
+}
+
 TEST_F(RtcpReceiverTest, InjectRrPacket) {
   const uint32_t kSenderSsrc = 0x10203;
   rtcp::ReceiverReport rr;
@@ -668,8 +705,7 @@
   xr.WithDlrr(dlrr);
   rtc::Buffer packet = xr.Build();
   EXPECT_EQ(0, InjectRtcpPacket(packet.data(), packet.size()));
-  // The parser should note the DLRR report block item, but not flag the packet
-  // since the RTT is not estimated.
+  // The parser should note the DLRR report block item.
   EXPECT_TRUE(rtcp_packet_info_.xr_dlrr_item);
 }
 
@@ -682,14 +718,13 @@
   rtcp::Dlrr dlrr;
   dlrr.WithDlrrItem(kSourceSsrc + 1, 0x12345, 0x67890);
   dlrr.WithDlrrItem(kSourceSsrc + 2, 0x12345, 0x67890);
-  dlrr.WithDlrrItem(kSourceSsrc,     0x12345, 0x67890);
+  dlrr.WithDlrrItem(kSourceSsrc, 0x12345, 0x67890);
   rtcp::ExtendedReports xr;
   xr.From(0x2345);
   xr.WithDlrr(dlrr);
   rtc::Buffer packet = xr.Build();
   EXPECT_EQ(0, InjectRtcpPacket(packet.data(), packet.size()));
-  // The parser should note the DLRR report block item, but not flag the packet
-  // since the RTT is not estimated.
+  // The parser should note the DLRR report block item.
   EXPECT_TRUE(rtcp_packet_info_.xr_dlrr_item);
 }
 
@@ -701,7 +736,7 @@
 
   rtcp::Rrtr rrtr;
   rtcp::Dlrr dlrr;
-  dlrr.WithDlrrItem(kSourceSsrc, 0x12345, 0x67890);
+  dlrr.WithDlrrItem(kSourceSsrc, 0, 0x67890);
   rtcp::VoipMetric metric;
   metric.To(kSourceSsrc);
   rtcp::ExtendedReports xr;
@@ -711,11 +746,11 @@
   xr.WithVoipMetric(metric);
   rtc::Buffer packet = xr.Build();
   EXPECT_EQ(0, InjectRtcpPacket(packet.data(), packet.size()));
+  // The parser should not flag the packet since the RTT is not estimated.
   EXPECT_EQ(static_cast<unsigned int>(kRtcpXrReceiverReferenceTime +
                                       kRtcpXrVoipMetric),
             rtcp_packet_info_.rtcpPacketTypeFlags);
-  // The parser should note the DLRR report block item, but not flag the packet
-  // since the RTT is not estimated.
+  // The parser should note the DLRR report block item.
   EXPECT_TRUE(rtcp_packet_info_.xr_dlrr_item);
 }
 
@@ -755,6 +790,32 @@
   EXPECT_FALSE(rtcp_receiver_->GetAndResetXrRrRtt(&rtt_ms));
 }
 
+TEST_F(RtcpReceiverTest, RttCalculatedAfterXrDlrr) {
+  Random rand(0x0123456789abcdef);
+  const uint32_t kSourceSsrc = rand.Rand(0x00000001u, 0xfffffffeu);
+  const uint32_t kRttMs = rand.Rand(1, 18 * 3600 * 1000);
+  const uint32_t kDelayNtp = rand.Rand<uint32_t>();
+  const uint32_t kDelayMs = CompactNtpIntervalToMs(kDelayNtp);
+  std::set<uint32_t> ssrcs;
+  ssrcs.insert(kSourceSsrc);
+  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);
+  NtpTime now(system_clock_);
+  uint32_t sent_ntp = CompactNtp(now);
+  system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
+
+  rtcp::Dlrr dlrr;
+  dlrr.WithDlrrItem(kSourceSsrc, sent_ntp, kDelayNtp);
+  rtcp::ExtendedReports xr;
+  xr.From(0x2345);
+  xr.WithDlrr(dlrr);
+  rtc::Buffer packet = xr.Build();
+  EXPECT_EQ(0, InjectRtcpPacket(packet.data(), packet.size()));
+
+  int64_t rtt_ms = 0;
+  EXPECT_TRUE(rtcp_receiver_->GetAndResetXrRrRtt(&rtt_ms));
+  EXPECT_NEAR(kRttMs, rtt_ms, 1);
+}
+
 TEST_F(RtcpReceiverTest, LastReceivedXrReferenceTimeInfoInitiallyFalse) {
   RtcpReceiveTimeInfo info;
   EXPECT_FALSE(rtcp_receiver_->LastReceivedXrReferenceTimeInfo(&info));
@@ -763,8 +824,7 @@
 TEST_F(RtcpReceiverTest, GetLastReceivedExtendedReportsReferenceTimeInfo) {
   const uint32_t kSenderSsrc = 0x123456;
   const NtpTime kNtp(0x10203, 0x40506);
-  const uint32_t kNtpMid =
-      RTCPUtility::MidNtp(kNtp.seconds(), kNtp.fractions());
+  const uint32_t kNtpMid = CompactNtp(kNtp);
 
   rtcp::Rrtr rrtr;
   rrtr.WithNtp(kNtp);
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
index 8ef4f61..a3de360 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -195,8 +195,6 @@
 
       xr_send_receiver_reference_time_enabled_(false),
       packet_type_counter_observer_(packet_type_counter_observer) {
-  memset(last_send_report_, 0, sizeof(last_send_report_));
-  memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_));
   RTC_DCHECK(transport_ != nullptr);
 
   builders_[kRtcpSr] = &RTCPSender::BuildSR;
@@ -445,46 +443,7 @@
   return false;
 }
 
-int64_t RTCPSender::SendTimeOfSendReport(uint32_t sendReport) {
-  CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
-
-  // This is only saved when we are the sender
-  if ((last_send_report_[0] == 0) || (sendReport == 0)) {
-    return 0;  // will be ignored
-  } else {
-    for (int i = 0; i < RTCP_NUMBER_OF_SR; ++i) {
-      if (last_send_report_[i] == sendReport)
-        return last_rtcp_time_[i];
-    }
-  }
-  return 0;
-}
-
-bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp,
-                                      int64_t* time_ms) const {
-  CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
-
-  if (last_xr_rr_.empty()) {
-    return false;
-  }
-  std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp);
-  if (it == last_xr_rr_.end()) {
-    return false;
-  }
-  *time_ms = it->second;
-  return true;
-}
-
 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) {
-  for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) {
-    // shift old
-    last_send_report_[i + 1] = last_send_report_[i];
-    last_rtcp_time_[i + 1] = last_rtcp_time_[i];
-  }
-
-  last_rtcp_time_[0] = Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_);
-  last_send_report_[0] = (ctx.ntp_sec_ << 16) + (ctx.ntp_frac_ >> 16);
-
   // The timestamp of this RTCP packet should be estimated as the timestamp of
   // the frame being captured at this moment. We are calculating that
   // timestamp as the last frame's timestamp + the time since the last frame
@@ -752,11 +711,6 @@
 
 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildReceiverReferenceTime(
     const RtcpContext& ctx) {
-  if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR)
-    last_xr_rr_.erase(last_xr_rr_.begin());
-  last_xr_rr_.insert(std::pair<uint32_t, int64_t>(
-      RTCPUtility::MidNtp(ctx.ntp_sec_, ctx.ntp_frac_),
-      Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_)));
 
   rtcp::ExtendedReports* xr = new rtcp::ExtendedReports();
   xr->From(ssrc_);
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
index 16ac2df..977c1ff 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h
@@ -106,10 +106,6 @@
 
   int32_t RemoveMixedCNAME(uint32_t SSRC);
 
-  int64_t SendTimeOfSendReport(uint32_t sendReport);
-
-  bool SendTimeOfXrRrReport(uint32_t mid_ntp, int64_t* time_ms) const;
-
   bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const;
 
   int32_t SendRTCP(const FeedbackState& feedback_state,
@@ -231,17 +227,6 @@
   std::map<uint32_t, std::string> csrc_cnames_
       GUARDED_BY(critical_section_rtcp_sender_);
 
-  // Sent
-  uint32_t last_send_report_[RTCP_NUMBER_OF_SR] GUARDED_BY(
-      critical_section_rtcp_sender_);  // allow packet loss and RTT above 1 sec
-  int64_t last_rtcp_time_[RTCP_NUMBER_OF_SR] GUARDED_BY(
-      critical_section_rtcp_sender_);
-
-  // Sent XR receiver reference time report.
-  // <mid ntp (mid 32 bits of the 64 bits NTP timestamp), send time in ms>.
-  std::map<uint32_t, int64_t> last_xr_rr_
-      GUARDED_BY(critical_section_rtcp_sender_);
-
   // send CSRCs
   std::vector<uint32_t> csrcs_ GUARDED_BY(critical_section_rtcp_sender_);
 
diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index d7423fa..f440da4 100644
--- a/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -643,34 +643,6 @@
   EXPECT_EQ(0, parser()->rrtr()->num_packets());
 }
 
-TEST_F(RtcpSenderTest, TestSendTimeOfXrRrtr) {
-  rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
-  RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
-  EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state, false));
-  rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
-  uint32_t ntp_sec;
-  uint32_t ntp_frac;
-  clock_.CurrentNtp(ntp_sec, ntp_frac);
-  uint32_t initial_mid_ntp = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
-
-  // No packet sent.
-  int64_t time_ms;
-  EXPECT_FALSE(rtcp_sender_->SendTimeOfXrRrReport(initial_mid_ntp, &time_ms));
-
-  // Send XR RR packets.
-  for (int i = 0; i <= RTCP_NUMBER_OF_SR; ++i) {
-    EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
-    EXPECT_EQ(i + 1, test_transport_.parser_.rrtr()->num_packets());
-    clock_.CurrentNtp(ntp_sec, ntp_frac);
-    uint32_t mid_ntp = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
-    EXPECT_TRUE(rtcp_sender_->SendTimeOfXrRrReport(mid_ntp, &time_ms));
-    EXPECT_EQ(clock_.CurrentNtpInMilliseconds(), time_ms);
-    clock_.AdvanceTimeMilliseconds(1000);
-  }
-  // The first report should no longer be stored.
-  EXPECT_FALSE(rtcp_sender_->SendTimeOfXrRrReport(initial_mid_ntp, &time_ms));
-}
-
 TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
   RtcpPacketTypeCounterObserverImpl observer;
   rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 2c8786b..07889f9 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -896,16 +896,6 @@
       GetFeedbackState(), kRtcpRpsi, 0, 0, false, picture_id);
 }
 
-int64_t ModuleRtpRtcpImpl::SendTimeOfSendReport(
-    const uint32_t send_report) {
-  return rtcp_sender_.SendTimeOfSendReport(send_report);
-}
-
-bool ModuleRtpRtcpImpl::SendTimeOfXrRrReport(
-    uint32_t mid_ntp, int64_t* time_ms) const {
-  return rtcp_sender_.SendTimeOfXrRrReport(mid_ntp, time_ms);
-}
-
 void ModuleRtpRtcpImpl::OnReceivedNACK(
     const std::list<uint16_t>& nack_sequence_numbers) {
   for (uint16_t nack_sequence_number : nack_sequence_numbers) {
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
index bc36451..88ed61a 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
@@ -309,10 +309,10 @@
   int64_t max_rtt;
   EXPECT_EQ(0,
       sender_.impl_->RTT(kReceiverSsrc, &rtt, &avg_rtt, &min_rtt, &max_rtt));
-  EXPECT_EQ(2 * kOneWayNetworkDelayMs, rtt);
-  EXPECT_EQ(2 * kOneWayNetworkDelayMs, avg_rtt);
-  EXPECT_EQ(2 * kOneWayNetworkDelayMs, min_rtt);
-  EXPECT_EQ(2 * kOneWayNetworkDelayMs, max_rtt);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, rtt, 1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, avg_rtt, 1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, min_rtt, 1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, max_rtt, 1);
 
   // No RTT from other ssrc.
   EXPECT_EQ(-1,
@@ -322,8 +322,9 @@
   EXPECT_EQ(0, sender_.rtt_stats_.LastProcessedRtt());
   EXPECT_EQ(0, sender_.impl_->rtt_ms());
   sender_.impl_->Process();
-  EXPECT_EQ(2 * kOneWayNetworkDelayMs, sender_.rtt_stats_.LastProcessedRtt());
-  EXPECT_EQ(2 * kOneWayNetworkDelayMs, sender_.impl_->rtt_ms());
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, sender_.rtt_stats_.LastProcessedRtt(),
+              1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, sender_.impl_->rtt_ms(), 1);
 }
 
 TEST_F(RtpRtcpImplTest, SetRtcpXrRrtrStatus) {
@@ -346,8 +347,9 @@
   EXPECT_EQ(0, receiver_.rtt_stats_.LastProcessedRtt());
   EXPECT_EQ(0, receiver_.impl_->rtt_ms());
   receiver_.impl_->Process();
-  EXPECT_EQ(2 * kOneWayNetworkDelayMs, receiver_.rtt_stats_.LastProcessedRtt());
-  EXPECT_EQ(2 * kOneWayNetworkDelayMs, receiver_.impl_->rtt_ms());
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs,
+              receiver_.rtt_stats_.LastProcessedRtt(), 1);
+  EXPECT_NEAR(2 * kOneWayNetworkDelayMs, receiver_.impl_->rtt_ms(), 1);
 }
 
 TEST_F(RtpRtcpImplTest, NoSrBeforeMedia) {
diff --git a/webrtc/modules/rtp_rtcp/source/time_util.h b/webrtc/modules/rtp_rtcp/source/time_util.h
index 5b544dd..a876b14 100644
--- a/webrtc/modules/rtp_rtcp/source/time_util.h
+++ b/webrtc/modules/rtp_rtcp/source/time_util.h
@@ -41,7 +41,8 @@
 // Converts interval between compact ntp timestamps to milliseconds.
 // This interval can be upto ~18.2 hours (2^16 seconds).
 inline uint32_t CompactNtpIntervalToMs(uint32_t compact_ntp_interval) {
-  return static_cast<uint64_t>(compact_ntp_interval) * 1000 / (1 << 16);
+  uint64_t value = static_cast<uint64_t>(compact_ntp_interval);
+  return (value * 1000 + (1 << 15)) >> 16;
 }
 
 }  // namespace webrtc