From 7eac6caeeee1ff52fa4c15834e3a86b0fa9258db Mon Sep 17 00:00:00 2001 From: Nico Grunbaum Date: Mon, 24 Jan 2022 13:49:58 -0800 Subject: [PATCH] Don't use wall clock for stats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This uses the local NTP clock for RTCP report block stats. This code exists in the version that Mozilla is shipping, with a review here https://phabricator.services.mozilla.com/D127709 . Bug: webrtc:13484 Change-Id: I2f46ec02acab0bbb09040778b05b248c2d815bd1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/240142 Reviewed-by: Artem Titov Reviewed-by: Harald Alvestrand Commit-Queue: Harald Alvestrand Reviewed-by: Henrik Boström Cr-Commit-Position: refs/heads/main@{#35787} --- audio/channel_receive.cc | 9 +++------ modules/rtp_rtcp/source/receive_statistics_impl.cc | 7 ++----- modules/rtp_rtcp/source/rtcp_receiver.cc | 7 ++++++- modules/rtp_rtcp/source/rtcp_receiver_unittest.cc | 11 ++++------- rtc_base/time_utils.h | 6 ++++++ 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc index 97708dc356..f2fd34ab16 100644 --- a/audio/channel_receive.cc +++ b/audio/channel_receive.cc @@ -846,14 +846,11 @@ CallReceiveStatistics ChannelReceive::GetRTCPStatistics() const { absl::optional rtcp_sr_stats = rtp_rtcp_->GetSenderReportStats(); if (rtcp_sr_stats.has_value()) { - // Number of seconds since 1900 January 1 00:00 GMT (see - // https://tools.ietf.org/html/rfc868). - constexpr int64_t kNtpJan1970Millisecs = - 2208988800 * rtc::kNumMillisecsPerSec; stats.last_sender_report_timestamp_ms = - rtcp_sr_stats->last_arrival_timestamp.ToMs() - kNtpJan1970Millisecs; + rtcp_sr_stats->last_arrival_timestamp.ToMs() - + rtc::kNtpJan1970Millisecs; stats.last_sender_report_remote_timestamp_ms = - rtcp_sr_stats->last_remote_timestamp.ToMs() - kNtpJan1970Millisecs; + rtcp_sr_stats->last_remote_timestamp.ToMs() - rtc::kNtpJan1970Millisecs; stats.sender_reports_packets_sent = rtcp_sr_stats->packets_sent; stats.sender_reports_bytes_sent = rtcp_sr_stats->bytes_sent; stats.sender_reports_reports_count = rtcp_sr_stats->reports_count; diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.cc b/modules/rtp_rtcp/source/receive_statistics_impl.cc index b16f122ee1..d2dba66ec5 100644 --- a/modules/rtp_rtcp/source/receive_statistics_impl.cc +++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc @@ -22,16 +22,13 @@ #include "modules/rtp_rtcp/source/rtp_rtcp_config.h" #include "modules/rtp_rtcp/source/time_util.h" #include "rtc_base/logging.h" +#include "rtc_base/time_utils.h" #include "system_wrappers/include/clock.h" namespace webrtc { namespace { constexpr int64_t kStatisticsTimeoutMs = 8000; constexpr int64_t kStatisticsProcessIntervalMs = 1000; - -// Number of seconds since 1900 January 1 00:00 GMT (see -// https://tools.ietf.org/html/rfc868). -constexpr int64_t kNtpJan1970Millisecs = 2'208'988'800'000; } // namespace StreamStatistician::~StreamStatistician() {} @@ -43,7 +40,7 @@ StreamStatisticianImpl::StreamStatisticianImpl(uint32_t ssrc, clock_(clock), delta_internal_unix_epoch_ms_(clock_->CurrentNtpInMilliseconds() - clock_->TimeInMilliseconds() - - kNtpJan1970Millisecs), + rtc::kNtpJan1970Millisecs), incoming_bitrate_(kStatisticsProcessIntervalMs, RateStatistics::kBpsScale), max_reordering_threshold_(max_reordering_threshold), diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc index 47843be810..d0f9596837 100644 --- a/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -662,7 +662,12 @@ void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block, rtcp_report_block.delay_since_last_sender_report = report_block.delay_since_last_sr(); rtcp_report_block.last_sender_report_timestamp = report_block.last_sr(); - report_block_data->SetReportBlock(rtcp_report_block, rtc::TimeUTCMicros()); + // Number of seconds since 1900 January 1 00:00 GMT (see + // https://tools.ietf.org/html/rfc868). + report_block_data->SetReportBlock( + rtcp_report_block, + (clock_->CurrentNtpInMilliseconds() - rtc::kNtpJan1970Millisecs) * + rtc::kNumMicrosecsPerMillisec); int64_t rtt_ms = 0; uint32_t send_time_ntp = report_block.last_sr(); diff --git a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index fa7d569012..eb5d265c6a 100644 --- a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -1573,12 +1573,8 @@ TEST(RtcpReceiverTest, const uint32_t kCumulativeLoss = 7; const uint32_t kJitter = 9; const uint16_t kSequenceNumber = 1234; - const int64_t kUtcNowUs = 42; - - // The "report_block_timestamp_utc_us" is obtained from the global UTC clock - // (not the simulcated `mocks.clock`) and requires a scoped fake clock. - rtc::ScopedFakeClock fake_clock; - fake_clock.SetTime(Timestamp::Micros(kUtcNowUs)); + const int64_t kNtpNowMs = + mocks.clock.CurrentNtpInMilliseconds() - rtc::kNtpJan1970Millisecs; rtcp::ReportBlock rtcp_block; rtcp_block.SetMediaSsrc(kReceiverMainSsrc); @@ -1601,7 +1597,8 @@ TEST(RtcpReceiverTest, EXPECT_EQ(rtcp_block.extended_high_seq_num(), report_block.extended_highest_sequence_number); EXPECT_EQ(rtcp_block.jitter(), report_block.jitter); - EXPECT_EQ(kUtcNowUs, report_block_data.report_block_timestamp_utc_us()); + EXPECT_EQ(kNtpNowMs * rtc::kNumMicrosecsPerMillisec, + report_block_data.report_block_timestamp_utc_us()); // No RTT is calculated in this test. EXPECT_EQ(0u, report_block_data.num_rtts()); }); diff --git a/rtc_base/time_utils.h b/rtc_base/time_utils.h index de3c58c815..6a3cfda3d1 100644 --- a/rtc_base/time_utils.h +++ b/rtc_base/time_utils.h @@ -31,6 +31,12 @@ static const int64_t kNumNanosecsPerMillisec = static const int64_t kNumNanosecsPerMicrosec = kNumNanosecsPerSec / kNumMicrosecsPerSec; +// Elapsed milliseconds between NTP base, 1900 January 1 00:00 GMT +// (see https://tools.ietf.org/html/rfc868), and January 1 00:00 GMT 1970 +// epoch. This is useful when converting between the NTP time base and the +// time base used in RTCP reports. +constexpr int64_t kNtpJan1970Millisecs = 2'208'988'800 * kNumMillisecsPerSec; + // TODO(honghaiz): Define a type for the time value specifically. class ClockInterface {