1 /*
2 * Copyright (c) 2012 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 */
10
11 #include "system_wrappers/include/rtp_to_ntp_estimator.h"
12
13 #include <stddef.h>
14
15 #include "rtc_base/random.h"
16 #include "test/gtest.h"
17
18 namespace webrtc {
19 namespace {
20 const uint32_t kOneMsInNtpFrac = 4294967;
21 const uint32_t kOneHourInNtpSec = 60 * 60;
22 const uint32_t kTimestampTicksPerMs = 90;
23 } // namespace
24
TEST(WrapAroundTests,OldRtcpWrapped_OldRtpTimestamp)25 TEST(WrapAroundTests, OldRtcpWrapped_OldRtpTimestamp) {
26 RtpToNtpEstimator estimator;
27 bool new_sr;
28 uint32_t ntp_sec = 0;
29 uint32_t ntp_frac = 1;
30 uint32_t timestamp = 0;
31 EXPECT_TRUE(
32 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
33 ntp_frac += kOneMsInNtpFrac;
34 timestamp -= kTimestampTicksPerMs;
35 // No wraparound will be detected, since we are not allowed to wrap below 0,
36 // but there will be huge rtp timestamp jump, e.g. old_timestamp = 0,
37 // new_timestamp = 4294967295, which should be detected.
38 EXPECT_FALSE(
39 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
40 }
41
TEST(WrapAroundTests,OldRtcpWrapped_OldRtpTimestamp_Wraparound_Detected)42 TEST(WrapAroundTests, OldRtcpWrapped_OldRtpTimestamp_Wraparound_Detected) {
43 RtpToNtpEstimator estimator;
44 bool new_sr;
45 uint32_t ntp_sec = 0;
46 uint32_t ntp_frac = 1;
47 uint32_t timestamp = 0xFFFFFFFE;
48 EXPECT_TRUE(
49 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
50 ntp_frac += 2 * kOneMsInNtpFrac;
51 timestamp += 2 * kTimestampTicksPerMs;
52 EXPECT_TRUE(
53 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
54 ntp_frac += kOneMsInNtpFrac;
55 timestamp -= kTimestampTicksPerMs;
56 // Expected to fail since the older RTCP has a smaller RTP timestamp than the
57 // newer (old:10, new:4294967206).
58 EXPECT_FALSE(
59 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
60 }
61
TEST(WrapAroundTests,NewRtcpWrapped)62 TEST(WrapAroundTests, NewRtcpWrapped) {
63 RtpToNtpEstimator estimator;
64 bool new_sr;
65 uint32_t ntp_sec = 0;
66 uint32_t ntp_frac = 1;
67 uint32_t timestamp = 0xFFFFFFFF;
68 EXPECT_TRUE(
69 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
70 ntp_frac += kOneMsInNtpFrac;
71 timestamp += kTimestampTicksPerMs;
72 EXPECT_TRUE(
73 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
74 int64_t timestamp_ms = -1;
75 EXPECT_TRUE(estimator.Estimate(0xFFFFFFFF, ×tamp_ms));
76 // Since this RTP packet has the same timestamp as the RTCP packet constructed
77 // at time 0 it should be mapped to 0 as well.
78 EXPECT_EQ(0, timestamp_ms);
79 }
80
TEST(WrapAroundTests,RtpWrapped)81 TEST(WrapAroundTests, RtpWrapped) {
82 RtpToNtpEstimator estimator;
83 bool new_sr;
84 uint32_t ntp_sec = 0;
85 uint32_t ntp_frac = 1;
86 uint32_t timestamp = 0xFFFFFFFF - 2 * kTimestampTicksPerMs;
87 EXPECT_TRUE(
88 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
89 ntp_frac += kOneMsInNtpFrac;
90 timestamp += kTimestampTicksPerMs;
91 EXPECT_TRUE(
92 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
93
94 int64_t timestamp_ms = -1;
95 EXPECT_TRUE(
96 estimator.Estimate(0xFFFFFFFF - 2 * kTimestampTicksPerMs, ×tamp_ms));
97 // Since this RTP packet has the same timestamp as the RTCP packet constructed
98 // at time 0 it should be mapped to 0 as well.
99 EXPECT_EQ(0, timestamp_ms);
100 // Two kTimestampTicksPerMs advanced.
101 timestamp += kTimestampTicksPerMs;
102 EXPECT_TRUE(estimator.Estimate(timestamp, ×tamp_ms));
103 EXPECT_EQ(2, timestamp_ms);
104 // Wrapped rtp.
105 timestamp += kTimestampTicksPerMs;
106 EXPECT_TRUE(estimator.Estimate(timestamp, ×tamp_ms));
107 EXPECT_EQ(3, timestamp_ms);
108 }
109
TEST(WrapAroundTests,OldRtp_RtcpsWrapped)110 TEST(WrapAroundTests, OldRtp_RtcpsWrapped) {
111 RtpToNtpEstimator estimator;
112 bool new_sr;
113 uint32_t ntp_sec = 0;
114 uint32_t ntp_frac = 1;
115 uint32_t timestamp = 0xFFFFFFFF;
116 EXPECT_TRUE(
117 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
118 ntp_frac += kOneMsInNtpFrac;
119 timestamp += kTimestampTicksPerMs;
120 EXPECT_TRUE(
121 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
122 timestamp -= 2 * kTimestampTicksPerMs;
123 int64_t timestamp_ms = 0xFFFFFFFF;
124 EXPECT_FALSE(estimator.Estimate(timestamp, ×tamp_ms));
125 }
126
TEST(WrapAroundTests,OldRtp_NewRtcpWrapped)127 TEST(WrapAroundTests, OldRtp_NewRtcpWrapped) {
128 RtpToNtpEstimator estimator;
129 bool new_sr;
130 uint32_t ntp_sec = 0;
131 uint32_t ntp_frac = 1;
132 uint32_t timestamp = 0xFFFFFFFF;
133 EXPECT_TRUE(
134 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
135 ntp_frac += kOneMsInNtpFrac;
136 timestamp += kTimestampTicksPerMs;
137 EXPECT_TRUE(
138 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
139 timestamp -= kTimestampTicksPerMs;
140 int64_t timestamp_ms = -1;
141 EXPECT_TRUE(estimator.Estimate(timestamp, ×tamp_ms));
142 // Constructed at the same time as the first RTCP and should therefore be
143 // mapped to zero.
144 EXPECT_EQ(0, timestamp_ms);
145 }
146
TEST(WrapAroundTests,GracefullyHandleRtpJump)147 TEST(WrapAroundTests, GracefullyHandleRtpJump) {
148 RtpToNtpEstimator estimator;
149 bool new_sr;
150 uint32_t ntp_sec = 0;
151 uint32_t ntp_frac = 1;
152 uint32_t timestamp = 0;
153 EXPECT_TRUE(
154 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
155 ntp_frac += kOneMsInNtpFrac;
156 timestamp += kTimestampTicksPerMs;
157 EXPECT_TRUE(
158 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
159 ntp_frac += kOneMsInNtpFrac;
160 timestamp -= kTimestampTicksPerMs;
161 int64_t timestamp_ms = -1;
162 EXPECT_TRUE(estimator.Estimate(timestamp, ×tamp_ms));
163 // Constructed at the same time as the first RTCP and should therefore be
164 // mapped to zero.
165 EXPECT_EQ(0, timestamp_ms);
166
167 timestamp -= 0xFFFFF;
168 for (int i = 0; i < RtpToNtpEstimator::kMaxInvalidSamples - 1; ++i) {
169 EXPECT_FALSE(
170 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
171 ntp_frac += kOneMsInNtpFrac;
172 timestamp += kTimestampTicksPerMs;
173 }
174 EXPECT_TRUE(
175 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
176 ntp_frac += kOneMsInNtpFrac;
177 timestamp += kTimestampTicksPerMs;
178 EXPECT_TRUE(
179 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
180 ntp_frac += kOneMsInNtpFrac;
181 timestamp += kTimestampTicksPerMs;
182
183 timestamp_ms = -1;
184 EXPECT_TRUE(estimator.Estimate(timestamp, ×tamp_ms));
185 // 6 milliseconds has passed since the start of the test.
186 EXPECT_EQ(6, timestamp_ms);
187 }
188
TEST(UpdateRtcpMeasurementTests,FailsForZeroNtp)189 TEST(UpdateRtcpMeasurementTests, FailsForZeroNtp) {
190 RtpToNtpEstimator estimator;
191 uint32_t ntp_sec = 0;
192 uint32_t ntp_frac = 0;
193 uint32_t timestamp = 0x12345678;
194 bool new_sr;
195 EXPECT_FALSE(
196 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
197 EXPECT_FALSE(new_sr);
198 }
199
TEST(UpdateRtcpMeasurementTests,FailsForEqualNtp)200 TEST(UpdateRtcpMeasurementTests, FailsForEqualNtp) {
201 RtpToNtpEstimator estimator;
202 uint32_t ntp_sec = 0;
203 uint32_t ntp_frac = 699925050;
204 uint32_t timestamp = 0x12345678;
205 bool new_sr;
206 EXPECT_TRUE(
207 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
208 EXPECT_TRUE(new_sr);
209 // Ntp time already added, list not updated.
210 ++timestamp;
211 EXPECT_TRUE(
212 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
213 EXPECT_FALSE(new_sr);
214 }
215
TEST(UpdateRtcpMeasurementTests,FailsForOldNtp)216 TEST(UpdateRtcpMeasurementTests, FailsForOldNtp) {
217 RtpToNtpEstimator estimator;
218 uint32_t ntp_sec = 1;
219 uint32_t ntp_frac = 699925050;
220 uint32_t timestamp = 0x12345678;
221 bool new_sr;
222 EXPECT_TRUE(
223 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
224 EXPECT_TRUE(new_sr);
225 // Old ntp time, list not updated.
226 ntp_frac -= kOneMsInNtpFrac;
227 timestamp += kTimestampTicksPerMs;
228 EXPECT_FALSE(
229 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
230 }
231
TEST(UpdateRtcpMeasurementTests,FailsForTooNewNtp)232 TEST(UpdateRtcpMeasurementTests, FailsForTooNewNtp) {
233 RtpToNtpEstimator estimator;
234 uint32_t ntp_sec = 1;
235 uint32_t ntp_frac = 699925050;
236 uint32_t timestamp = 0x12345678;
237 bool new_sr;
238 EXPECT_TRUE(
239 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
240 EXPECT_TRUE(new_sr);
241 // Ntp time from far future, list not updated.
242 ntp_sec += kOneHourInNtpSec * 2;
243 timestamp += kTimestampTicksPerMs * 10;
244 EXPECT_FALSE(
245 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
246 }
247
TEST(UpdateRtcpMeasurementTests,FailsForEqualTimestamp)248 TEST(UpdateRtcpMeasurementTests, FailsForEqualTimestamp) {
249 RtpToNtpEstimator estimator;
250 uint32_t ntp_sec = 0;
251 uint32_t ntp_frac = 2;
252 uint32_t timestamp = 0x12345678;
253 bool new_sr;
254 EXPECT_TRUE(
255 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
256 EXPECT_TRUE(new_sr);
257 // Timestamp already added, list not updated.
258 ++ntp_frac;
259 EXPECT_TRUE(
260 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
261 EXPECT_FALSE(new_sr);
262 }
263
TEST(UpdateRtcpMeasurementTests,FailsForOldRtpTimestamp)264 TEST(UpdateRtcpMeasurementTests, FailsForOldRtpTimestamp) {
265 RtpToNtpEstimator estimator;
266 uint32_t ntp_sec = 0;
267 uint32_t ntp_frac = 2;
268 uint32_t timestamp = 0x12345678;
269 bool new_sr;
270 EXPECT_TRUE(
271 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
272 EXPECT_TRUE(new_sr);
273 // Old timestamp, list not updated.
274 ntp_frac += kOneMsInNtpFrac;
275 timestamp -= kTimestampTicksPerMs;
276 EXPECT_FALSE(
277 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
278 EXPECT_FALSE(new_sr);
279 }
280
TEST(UpdateRtcpMeasurementTests,VerifyParameters)281 TEST(UpdateRtcpMeasurementTests, VerifyParameters) {
282 RtpToNtpEstimator estimator;
283 uint32_t ntp_sec = 1;
284 uint32_t ntp_frac = 2;
285 uint32_t timestamp = 0x12345678;
286 bool new_sr;
287 EXPECT_TRUE(
288 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
289 EXPECT_TRUE(new_sr);
290 EXPECT_FALSE(estimator.params());
291 // Add second report, parameters should be calculated.
292 ntp_frac += kOneMsInNtpFrac;
293 timestamp += kTimestampTicksPerMs;
294 EXPECT_TRUE(
295 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
296 EXPECT_TRUE(estimator.params());
297 EXPECT_DOUBLE_EQ(90.0, estimator.params()->frequency_khz);
298 EXPECT_NE(0.0, estimator.params()->offset_ms);
299 }
300
TEST(RtpToNtpTests,FailsForNoParameters)301 TEST(RtpToNtpTests, FailsForNoParameters) {
302 RtpToNtpEstimator estimator;
303 uint32_t ntp_sec = 1;
304 uint32_t ntp_frac = 2;
305 uint32_t timestamp = 0x12345678;
306 bool new_sr;
307 EXPECT_TRUE(
308 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
309 EXPECT_TRUE(new_sr);
310 // Parameters are not calculated, conversion of RTP to NTP time should fail.
311 EXPECT_FALSE(estimator.params());
312 int64_t timestamp_ms = -1;
313 EXPECT_FALSE(estimator.Estimate(timestamp, ×tamp_ms));
314 }
315
TEST(RtpToNtpTests,AveragesErrorOut)316 TEST(RtpToNtpTests, AveragesErrorOut) {
317 RtpToNtpEstimator estimator;
318 uint32_t ntp_sec = 1;
319 uint32_t ntp_frac = 90000000; // More than 1 ms.
320 uint32_t timestamp = 0x12345678;
321 const int kNtpSecStep = 1; // 1 second.
322 const int kRtpTicksPerMs = 90;
323 const int kRtpStep = kRtpTicksPerMs * 1000;
324 bool new_sr;
325 EXPECT_TRUE(
326 estimator.UpdateMeasurements(ntp_sec, ntp_frac, timestamp, &new_sr));
327 EXPECT_TRUE(new_sr);
328
329 Random rand(1123536L);
330 for (size_t i = 0; i < 1000; i++) {
331 // Advance both timestamps by exactly 1 second.
332 ntp_sec += kNtpSecStep;
333 timestamp += kRtpStep;
334 // Add upto 1ms of errors to NTP and RTP timestamps passed to estimator.
335 EXPECT_TRUE(estimator.UpdateMeasurements(
336 ntp_sec,
337 ntp_frac + rand.Rand(-static_cast<int>(kOneMsInNtpFrac),
338 static_cast<int>(kOneMsInNtpFrac)),
339 timestamp + rand.Rand(-kRtpTicksPerMs, kRtpTicksPerMs), &new_sr));
340 EXPECT_TRUE(new_sr);
341
342 int64_t estimated_ntp_ms;
343 EXPECT_TRUE(estimator.Estimate(timestamp, &estimated_ntp_ms));
344 // Allow upto 2 ms of error.
345 EXPECT_NEAR(NtpTime(ntp_sec, ntp_frac).ToMs(), estimated_ntp_ms, 2);
346 }
347 }
348
349 } // namespace webrtc
350