diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc new file mode 100644 index 0000000000..3737d66f07 --- /dev/null +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/remote_ntp_time_estimator_unittest.cc @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h" + +#include "absl/types/optional.h" +#include "modules/rtp_rtcp/source/time_util.h" +#include "system_wrappers/include/clock.h" +#include "system_wrappers/include/ntp_time.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { + +constexpr TimeDelta kTestRtt = TimeDelta::Millis(10); +constexpr Timestamp kLocalClockInitialTime = Timestamp::Millis(123); +constexpr Timestamp kRemoteClockInitialTime = Timestamp::Millis(373); +constexpr uint32_t kTimestampOffset = 567; +constexpr int64_t kRemoteToLocalClockOffsetNtp = + ToNtpUnits(kLocalClockInitialTime - kRemoteClockInitialTime); + +class RemoteNtpTimeEstimatorTest : public ::testing::Test { + protected: + void AdvanceTime(TimeDelta delta) { + local_clock_.AdvanceTime(delta); + remote_clock_.AdvanceTime(delta); + } + + uint32_t GetRemoteTimestamp() { + return static_cast<uint32_t>(remote_clock_.TimeInMilliseconds()) * 90 + + kTimestampOffset; + } + + void SendRtcpSr() { + uint32_t rtcp_timestamp = GetRemoteTimestamp(); + NtpTime ntp = remote_clock_.CurrentNtpTime(); + + AdvanceTime(kTestRtt / 2); + EXPECT_TRUE(estimator_.UpdateRtcpTimestamp(kTestRtt, ntp, rtcp_timestamp)); + } + + void SendRtcpSrInaccurately(TimeDelta ntp_error, TimeDelta networking_delay) { + uint32_t rtcp_timestamp = GetRemoteTimestamp(); + int64_t ntp_error_fractions = ToNtpUnits(ntp_error); + NtpTime ntp(static_cast<uint64_t>(remote_clock_.CurrentNtpTime()) + + ntp_error_fractions); + AdvanceTime(kTestRtt / 2 + networking_delay); + EXPECT_TRUE(estimator_.UpdateRtcpTimestamp(kTestRtt, ntp, rtcp_timestamp)); + } + + SimulatedClock local_clock_{kLocalClockInitialTime}; + SimulatedClock remote_clock_{kRemoteClockInitialTime}; + RemoteNtpTimeEstimator estimator_{&local_clock_}; +}; + +TEST_F(RemoteNtpTimeEstimatorTest, FailsWithoutValidNtpTime) { + EXPECT_FALSE( + estimator_.UpdateRtcpTimestamp(kTestRtt, NtpTime(), /*rtp_timestamp=*/0)); +} + +TEST_F(RemoteNtpTimeEstimatorTest, Estimate) { + // Remote peer sends first RTCP SR. + SendRtcpSr(); + + // Remote sends a RTP packet. + AdvanceTime(TimeDelta::Millis(15)); + uint32_t rtp_timestamp = GetRemoteTimestamp(); + int64_t capture_ntp_time_ms = local_clock_.CurrentNtpInMilliseconds(); + + // Local peer needs at least 2 RTCP SR to calculate the capture time. + const int64_t kNotEnoughRtcpSr = -1; + EXPECT_EQ(kNotEnoughRtcpSr, estimator_.Estimate(rtp_timestamp)); + EXPECT_EQ(estimator_.EstimateRemoteToLocalClockOffset(), absl::nullopt); + + AdvanceTime(TimeDelta::Millis(800)); + // Remote sends second RTCP SR. + SendRtcpSr(); + + // Local peer gets enough RTCP SR to calculate the capture time. + EXPECT_EQ(capture_ntp_time_ms, estimator_.Estimate(rtp_timestamp)); + EXPECT_EQ(estimator_.EstimateRemoteToLocalClockOffset(), + kRemoteToLocalClockOffsetNtp); +} + +TEST_F(RemoteNtpTimeEstimatorTest, AveragesErrorsOut) { + // Remote peer sends first 10 RTCP SR without errors. + for (int i = 0; i < 10; ++i) { + AdvanceTime(TimeDelta::Seconds(1)); + SendRtcpSr(); + } + + AdvanceTime(TimeDelta::Millis(150)); + uint32_t rtp_timestamp = GetRemoteTimestamp(); + int64_t capture_ntp_time_ms = local_clock_.CurrentNtpInMilliseconds(); + // Local peer gets enough RTCP SR to calculate the capture time. + EXPECT_EQ(capture_ntp_time_ms, estimator_.Estimate(rtp_timestamp)); + EXPECT_EQ(kRemoteToLocalClockOffsetNtp, + estimator_.EstimateRemoteToLocalClockOffset()); + + // Remote sends corrupted RTCP SRs + AdvanceTime(TimeDelta::Seconds(1)); + SendRtcpSrInaccurately(/*ntp_error=*/TimeDelta::Millis(2), + /*networking_delay=*/TimeDelta::Millis(-1)); + AdvanceTime(TimeDelta::Seconds(1)); + SendRtcpSrInaccurately(/*ntp_error=*/TimeDelta::Millis(-2), + /*networking_delay=*/TimeDelta::Millis(1)); + + // New RTP packet to estimate timestamp. + AdvanceTime(TimeDelta::Millis(150)); + rtp_timestamp = GetRemoteTimestamp(); + capture_ntp_time_ms = local_clock_.CurrentNtpInMilliseconds(); + + // Errors should be averaged out. + EXPECT_EQ(capture_ntp_time_ms, estimator_.Estimate(rtp_timestamp)); + EXPECT_EQ(kRemoteToLocalClockOffsetNtp, + estimator_.EstimateRemoteToLocalClockOffset()); +} + +} // namespace +} // namespace webrtc |