From 05666b4db76acd5c9363e62cb3e0e2bbddaa0ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olov=20Br=C3=A4ndstr=C3=B6m?= Date: Wed, 23 Oct 2024 12:45:27 +0200 Subject: [PATCH] Function that Converts NtpTime to a Timestamp with UTC epoch in Clock. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit danilchap@webrtc.org suggested to add a converter for NtpTime <-> UTC Timestamp for in https://webrtc-review.googlesource.com/c/src/+/365641. This CL add a NtpTime -> UTC Timestamp in Clock, and change code to start to use the new function. Bug: None Change-Id: If4af6cb8e31c1731692edfb8358e67b7a43226a0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366001 Commit-Queue: Olov Brändström Reviewed-by: Henrik Boström Reviewed-by: Danil Chapovalov Reviewed-by: Henrik Andreassson Cr-Commit-Position: refs/heads/main@{#43293} --- audio/channel_receive.cc | 6 ++---- modules/rtp_rtcp/source/rtcp_receiver.cc | 5 ++--- .../rtp_rtcp/source/rtcp_receiver_unittest.cc | 6 ++---- .../rtp_rtcp/source/rtcp_transceiver_impl.cc | 3 +-- system_wrappers/BUILD.gn | 1 + system_wrappers/include/clock.h | 17 +++++++++++++++++ system_wrappers/source/clock_unittest.cc | 10 ++++++++++ video/video_receive_stream2.cc | 6 ++---- 8 files changed, 37 insertions(+), 17 deletions(-) diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc index 9fc2882258..ea4c912d28 100644 --- a/audio/channel_receive.cc +++ b/audio/channel_receive.cc @@ -874,11 +874,9 @@ CallReceiveStatistics ChannelReceive::GetRTCPStatistics() const { if (rtcp_sr_stats.has_value()) { stats.last_sender_report_timestamp = rtcp_sr_stats->last_arrival_timestamp; stats.last_sender_report_utc_timestamp = - Timestamp::Millis(rtcp_sr_stats->last_arrival_ntp_timestamp.ToMs() - - rtc::kNtpJan1970Millisecs); + Clock::NtpToUtc(rtcp_sr_stats->last_arrival_ntp_timestamp); stats.last_sender_report_remote_utc_timestamp = - Timestamp::Millis(rtcp_sr_stats->last_remote_ntp_timestamp.ToMs() - - rtc::kNtpJan1970Millisecs); + Clock::NtpToUtc(rtcp_sr_stats->last_remote_ntp_timestamp); 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/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc index 10f9d87730..672ee98d29 100644 --- a/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -621,9 +621,8 @@ void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block, NtpTime now_ntp = env_.clock().ConvertTimestampToNtpTime(now); // Number of seconds since 1900 January 1 00:00 GMT (see // https://tools.ietf.org/html/rfc868). - report_block_data->SetReportBlock( - remote_ssrc, report_block, - Timestamp::Millis(now_ntp.ToMs() - rtc::kNtpJan1970Millisecs), now); + report_block_data->SetReportBlock(remote_ssrc, report_block, + Clock::NtpToUtc(now_ntp), now); uint32_t send_time_ntp = report_block.last_sr(); // RFC3550, section 6.4.1, LSR field discription states: diff --git a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index b01c23c310..f8789edcc9 100644 --- a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -1544,8 +1544,7 @@ TEST(RtcpReceiverTest, const uint32_t kCumulativeLoss = 7; const uint32_t kJitter = 9; const uint16_t kSequenceNumber = 1234; - const int64_t kNtpNowMs = - mocks.clock.CurrentNtpInMilliseconds() - rtc::kNtpJan1970Millisecs; + const Timestamp kUtcNow = Clock::NtpToUtc(mocks.clock.CurrentNtpTime()); rtcp::ReportBlock rtcp_block; rtcp_block.SetMediaSsrc(kReceiverMainSsrc); @@ -1566,8 +1565,7 @@ 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(report_block.report_block_timestamp_utc(), - Timestamp::Millis(kNtpNowMs)); + EXPECT_EQ(report_block.report_block_timestamp_utc(), kUtcNow); // No RTT is calculated in this test. EXPECT_EQ(0u, report_block.num_rtts()); }); diff --git a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc index 858b580795..e1d316d497 100644 --- a/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc +++ b/modules/rtp_rtcp/source/rtcp_transceiver_impl.cc @@ -362,8 +362,7 @@ void RtcpTransceiverImpl::HandleReportBlocks( } NtpTime now_ntp = config_.clock->ConvertTimestampToNtpTime(now); uint32_t receive_time_ntp = CompactNtp(now_ntp); - Timestamp now_utc = - Timestamp::Millis(now_ntp.ToMs() - rtc::kNtpJan1970Millisecs); + Timestamp now_utc = Clock::NtpToUtc(now_ntp); for (const rtcp::ReportBlock& block : rtcp_report_blocks) { std::optional rtt; diff --git a/system_wrappers/BUILD.gn b/system_wrappers/BUILD.gn index 5e66d4b0ef..1afd20a7e6 100644 --- a/system_wrappers/BUILD.gn +++ b/system_wrappers/BUILD.gn @@ -142,6 +142,7 @@ if (rtc_include_tests && !build_with_chromium) { ":field_trial", ":metrics", ":system_wrappers", + "../api/units:time_delta", "../rtc_base:checks", "../rtc_base:random", "../rtc_base:stringutils", diff --git a/system_wrappers/include/clock.h b/system_wrappers/include/clock.h index 60296070cc..ec4bae0aed 100644 --- a/system_wrappers/include/clock.h +++ b/system_wrappers/include/clock.h @@ -48,6 +48,23 @@ class RTC_EXPORT Clock { return ConvertTimestampToNtpTime(Timestamp::Millis(timestamp_ms)).ToMs(); } + // Converts NtpTime to a Timestamp with UTC epoch. + // A `Minus Infinity` Timestamp is returned if the NtpTime is invalid. + static Timestamp NtpToUtc(NtpTime ntp_time) { + if (!ntp_time.Valid()) { + return Timestamp::MinusInfinity(); + } + // Seconds since UTC epoch. + int64_t time = ntp_time.seconds() - kNtpJan1970; + // Microseconds since UTC epoch (not including NTP fraction) + time = time * 1'000'000; + // Fractions part of the NTP time, in microseconds. + int64_t time_fraction = + DivideRoundToNearest(int64_t{ntp_time.fractions()} * 1'000'000, + NtpTime::kFractionsPerSecond); + return Timestamp::Micros(time + time_fraction); + } + // Returns an instance of the real-time system clock implementation. static Clock* GetRealTimeClock(); }; diff --git a/system_wrappers/source/clock_unittest.cc b/system_wrappers/source/clock_unittest.cc index f7b0ed7a47..e50b789e53 100644 --- a/system_wrappers/source/clock_unittest.cc +++ b/system_wrappers/source/clock_unittest.cc @@ -10,6 +10,7 @@ #include "system_wrappers/include/clock.h" +#include "api/units/time_delta.h" #include "test/gtest.h" namespace webrtc { @@ -31,4 +32,13 @@ TEST(ClockTest, NtpTime) { EXPECT_GE(milliseconds_upper_bound + 1, ntp_time.ToMs()); } +TEST(ClockTest, NtpToUtc) { + Clock* clock = Clock::GetRealTimeClock(); + NtpTime ntp = clock->CurrentNtpTime(); + Timestamp a = Clock::NtpToUtc(ntp); + Timestamp b = Timestamp::Millis(ntp.ToMs() - int64_t{kNtpJan1970} * 1000); + TimeDelta d = a - b; + EXPECT_LT(d.Abs(), TimeDelta::Millis(1)); +} + } // namespace webrtc diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc index aa3ff4a6af..610ef141db 100644 --- a/video/video_receive_stream2.cc +++ b/video/video_receive_stream2.cc @@ -573,11 +573,9 @@ VideoReceiveStreamInterface::Stats VideoReceiveStream2::GetStats() const { rtp_video_stream_receiver_.GetSenderReportStats(); if (rtcp_sr_stats) { stats.last_sender_report_utc_timestamp = - Timestamp::Millis(rtcp_sr_stats->last_arrival_ntp_timestamp.ToMs() - - rtc::kNtpJan1970Millisecs); + Clock::NtpToUtc(rtcp_sr_stats->last_arrival_ntp_timestamp); stats.last_sender_report_remote_utc_timestamp = - Timestamp::Millis(rtcp_sr_stats->last_remote_ntp_timestamp.ToMs() - - rtc::kNtpJan1970Millisecs); + Clock::NtpToUtc(rtcp_sr_stats->last_remote_ntp_timestamp); 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;