diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc index d65b04c8ab..e8a943f23e 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 @@ void RTCPReceiver::HandleReportBlock( 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 @@ void RTCPReceiver::HandleReportBlock( 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(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(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(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 @@ void RTCPReceiver::HandleXrDlrrReportBlockItem( 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(rtt, 1); + uint32_t rtt_ntp = now - delay_rr - send_time; + uint32_t rtt_ms = CompactNtpIntervalToMs(rtt_ntp); + xr_rr_rtt_ms_ = std::max(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 8ba9fe7c95..c6df905688 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 @@ TEST_F(RtcpReceiverTest, InjectSrPacketFromExpectedPeer) { 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(); + const uint32_t kDelayMs = CompactNtpIntervalToMs(kDelayNtp); + + rtcp_receiver_->SetRemoteSSRC(kSenderSsrc); + std::set 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 @@ TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) { 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 @@ TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) { 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 @@ TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) { 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 @@ TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) { 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(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 @@ TEST_F(RtcpReceiverTest, TestXrRrRttInitiallyFalse) { 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(); + const uint32_t kDelayMs = CompactNtpIntervalToMs(kDelayNtp); + std::set 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, LastReceivedXrReferenceTimeInfoInitiallyFalse) { 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 8ef4f619ff..a3de360cf6 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -195,8 +195,6 @@ RTCPSender::RTCPSender( 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 @@ bool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const { 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::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 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 RTCPSender::BuildBYE(const RtcpContext& ctx) { rtc::scoped_ptr 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( - 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 16ac2df993..977c1ff43a 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.h @@ -106,10 +106,6 @@ class RTCPSender { 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 @@ class RTCPSender { std::map 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. - // . - std::map last_xr_rr_ - GUARDED_BY(critical_section_rtcp_sender_); - // send CSRCs std::vector 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 d7423fa0c8..f440da489d 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 @@ TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) { 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 2c8786b906..07889f9eca 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 @@ int32_t ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection( 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& 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 bc364519ad..88ed61ad58 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 @@ TEST_F(RtpRtcpImplTest, Rtt) { 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 @@ TEST_F(RtpRtcpImplTest, Rtt) { 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 @@ TEST_F(RtpRtcpImplTest, RttForReceiverOnly) { 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 5b544ddf9a..a876b14d56 100644 --- a/webrtc/modules/rtp_rtcp/source/time_util.h +++ b/webrtc/modules/rtp_rtcp/source/time_util.h @@ -41,7 +41,8 @@ inline uint32_t CompactNtp(NtpTime ntp) { // 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(compact_ntp_interval) * 1000 / (1 << 16); + uint64_t value = static_cast(compact_ntp_interval); + return (value * 1000 + (1 << 15)) >> 16; } } // namespace webrtc