blob: 634775821e74be5de5133338fd253e8367fe1f24 [file] [log] [blame]
wu@webrtc.org88abf112014-05-14 16:53:51 +00001/*
Yves Gerey665174f2018-06-19 15:03:05 +02002 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
wu@webrtc.org88abf112014-05-14 16:53:51 +000010
Mirko Bonadeif6703c42017-11-15 16:14:28 +000011#include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020012#include "system_wrappers/include/clock.h"
13#include "test/gmock.h"
14#include "test/gtest.h"
wu@webrtc.org88abf112014-05-14 16:53:51 +000015
16using ::testing::_;
17using ::testing::DoAll;
18using ::testing::Return;
19using ::testing::SetArgPointee;
20
21namespace webrtc {
22
pkasting@chromium.org16825b12015-01-12 21:51:21 +000023static const int64_t kTestRtt = 10;
wu@webrtc.org88abf112014-05-14 16:53:51 +000024static const int64_t kLocalClockInitialTimeMs = 123;
25static const int64_t kRemoteClockInitialTimeMs = 345;
26static const uint32_t kTimestampOffset = 567;
wu@webrtc.org88abf112014-05-14 16:53:51 +000027
28class RemoteNtpTimeEstimatorTest : public ::testing::Test {
29 protected:
30 RemoteNtpTimeEstimatorTest()
31 : local_clock_(kLocalClockInitialTimeMs * 1000),
32 remote_clock_(kRemoteClockInitialTimeMs * 1000),
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +000033 estimator_(new RemoteNtpTimeEstimator(&local_clock_)) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +000034 ~RemoteNtpTimeEstimatorTest() override = default;
wu@webrtc.org88abf112014-05-14 16:53:51 +000035
36 void AdvanceTimeMilliseconds(int64_t ms) {
37 local_clock_.AdvanceTimeMilliseconds(ms);
38 remote_clock_.AdvanceTimeMilliseconds(ms);
39 }
40
41 uint32_t GetRemoteTimestamp() {
42 return static_cast<uint32_t>(remote_clock_.TimeInMilliseconds()) * 90 +
43 kTimestampOffset;
44 }
45
46 void SendRtcpSr() {
47 uint32_t rtcp_timestamp = GetRemoteTimestamp();
danilchap21dc1892017-03-07 02:51:09 -080048 NtpTime ntp = remote_clock_.CurrentNtpTime();
wu@webrtc.org88abf112014-05-14 16:53:51 +000049
50 AdvanceTimeMilliseconds(kTestRtt / 2);
danilchap21dc1892017-03-07 02:51:09 -080051 ReceiveRtcpSr(kTestRtt, rtcp_timestamp, ntp.seconds(), ntp.fractions());
wu@webrtc.org88abf112014-05-14 16:53:51 +000052 }
53
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +000054 void SendRtcpSrInaccurately(int64_t ntp_error_ms,
55 int64_t networking_delay_ms) {
56 uint32_t rtcp_timestamp = GetRemoteTimestamp();
57 int64_t ntp_error_fractions =
Ilya Nikolaevskiyee45f902018-11-09 10:52:39 +010058 ntp_error_ms * static_cast<int64_t>(NtpTime::kFractionsPerSecond) /
59 1000;
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +000060 NtpTime ntp(static_cast<uint64_t>(remote_clock_.CurrentNtpTime()) +
61 ntp_error_fractions);
62 AdvanceTimeMilliseconds(kTestRtt / 2 + networking_delay_ms);
63 ReceiveRtcpSr(kTestRtt, rtcp_timestamp, ntp.seconds(), ntp.fractions());
64 }
65
Yves Gerey665174f2018-06-19 15:03:05 +020066 void UpdateRtcpTimestamp(int64_t rtt,
67 uint32_t ntp_secs,
68 uint32_t ntp_frac,
69 uint32_t rtp_timestamp,
70 bool expected_result) {
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +000071 EXPECT_EQ(expected_result, estimator_->UpdateRtcpTimestamp(
72 rtt, ntp_secs, ntp_frac, rtp_timestamp));
wu@webrtc.org88abf112014-05-14 16:53:51 +000073 }
74
pkasting@chromium.org16825b12015-01-12 21:51:21 +000075 void ReceiveRtcpSr(int64_t rtt,
minyue@webrtc.org2c0cdbc2014-10-09 10:52:43 +000076 uint32_t rtcp_timestamp,
wu@webrtc.org88abf112014-05-14 16:53:51 +000077 uint32_t ntp_seconds,
78 uint32_t ntp_fractions) {
minyue@webrtc.org2c0cdbc2014-10-09 10:52:43 +000079 UpdateRtcpTimestamp(rtt, ntp_seconds, ntp_fractions, rtcp_timestamp, true);
wu@webrtc.org88abf112014-05-14 16:53:51 +000080 }
81
82 SimulatedClock local_clock_;
83 SimulatedClock remote_clock_;
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +000084 std::unique_ptr<RemoteNtpTimeEstimator> estimator_;
wu@webrtc.org88abf112014-05-14 16:53:51 +000085};
86
87TEST_F(RemoteNtpTimeEstimatorTest, Estimate) {
minyue@webrtc.org2c0cdbc2014-10-09 10:52:43 +000088 // Failed without valid NTP.
89 UpdateRtcpTimestamp(kTestRtt, 0, 0, 0, false);
wu@webrtc.org88abf112014-05-14 16:53:51 +000090
91 AdvanceTimeMilliseconds(1000);
92 // Remote peer sends first RTCP SR.
93 SendRtcpSr();
94
95 // Remote sends a RTP packet.
96 AdvanceTimeMilliseconds(15);
97 uint32_t rtp_timestamp = GetRemoteTimestamp();
98 int64_t capture_ntp_time_ms = local_clock_.CurrentNtpInMilliseconds();
99
100 // Local peer needs at least 2 RTCP SR to calculate the capture time.
101 const int64_t kNotEnoughRtcpSr = -1;
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +0000102 EXPECT_EQ(kNotEnoughRtcpSr, estimator_->Estimate(rtp_timestamp));
wu@webrtc.org88abf112014-05-14 16:53:51 +0000103
104 AdvanceTimeMilliseconds(800);
105 // Remote sends second RTCP SR.
106 SendRtcpSr();
107
108 // Local peer gets enough RTCP SR to calculate the capture time.
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +0000109 EXPECT_EQ(capture_ntp_time_ms, estimator_->Estimate(rtp_timestamp));
110}
111
112TEST_F(RemoteNtpTimeEstimatorTest, AveragesErrorsOut) {
Ilya Nikolaevskiyf1cc3a22018-11-12 15:03:51 +0100113 // Remote peer sends first 10 RTCP SR without errors.
114 AdvanceTimeMilliseconds(1000);
115 SendRtcpSr();
116 AdvanceTimeMilliseconds(1000);
117 SendRtcpSr();
118 AdvanceTimeMilliseconds(1000);
119 SendRtcpSr();
120 AdvanceTimeMilliseconds(1000);
121 SendRtcpSr();
122 AdvanceTimeMilliseconds(1000);
123 SendRtcpSr();
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +0000124 AdvanceTimeMilliseconds(1000);
125 SendRtcpSr();
126 AdvanceTimeMilliseconds(1000);
127 SendRtcpSr();
128 AdvanceTimeMilliseconds(1000);
129 SendRtcpSr();
130 AdvanceTimeMilliseconds(1000);
131 SendRtcpSr();
132 AdvanceTimeMilliseconds(1000);
133 SendRtcpSr();
134
Ilya Nikolaevskiyf1cc3a22018-11-12 15:03:51 +0100135 AdvanceTimeMilliseconds(150);
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +0000136 uint32_t rtp_timestamp = GetRemoteTimestamp();
137 int64_t capture_ntp_time_ms = local_clock_.CurrentNtpInMilliseconds();
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +0000138 // Local peer gets enough RTCP SR to calculate the capture time.
139 EXPECT_EQ(capture_ntp_time_ms, estimator_->Estimate(rtp_timestamp));
140
141 // Remote sends corrupted RTCP SRs
142 AdvanceTimeMilliseconds(1000);
Ilya Nikolaevskiyf1cc3a22018-11-12 15:03:51 +0100143 SendRtcpSrInaccurately(/*ntp_error_ms=*/2, /*networking_delay_ms=*/-1);
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +0000144 AdvanceTimeMilliseconds(1000);
Ilya Nikolaevskiyf1cc3a22018-11-12 15:03:51 +0100145 SendRtcpSrInaccurately(/*ntp_error_ms=*/-2, /*networking_delay_ms=*/1);
Ilya Nikolaevskiy8b64fd82017-11-15 16:48:04 +0000146
147 // New RTP packet to estimate timestamp.
148 AdvanceTimeMilliseconds(150);
149 rtp_timestamp = GetRemoteTimestamp();
150 capture_ntp_time_ms = local_clock_.CurrentNtpInMilliseconds();
151
152 // Errors should be averaged out.
153 EXPECT_EQ(capture_ntp_time_ms, estimator_->Estimate(rtp_timestamp));
wu@webrtc.org88abf112014-05-14 16:53:51 +0000154}
155
156} // namespace webrtc