1 /*
2 * Copyright (c) 2017 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 <memory>
12
13 #include "common_types.h" // NOLINT(build/include)
14 #include "modules/rtp_rtcp/include/rtp_header_parser.h"
15 #include "modules/rtp_rtcp/include/rtp_payload_registry.h"
16 #include "modules/rtp_rtcp/include/rtp_receiver.h"
17 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
18 #include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
19 #include "modules/rtp_rtcp/source/rtp_receiver_impl.h"
20 #include "test/gmock.h"
21 #include "test/gtest.h"
22
23 namespace webrtc {
24 namespace {
25
26 using ::testing::NiceMock;
27 using ::testing::UnorderedElementsAre;
28
29 const uint32_t kTestRate = 64000u;
30 const uint8_t kTestPayload[] = {'t', 'e', 's', 't'};
31 const uint8_t kPcmuPayloadType = 96;
32 const int64_t kGetSourcesTimeoutMs = 10000;
33 const uint32_t kSsrc1 = 123;
34 const uint32_t kSsrc2 = 124;
35 const uint32_t kCsrc1 = 111;
36 const uint32_t kCsrc2 = 222;
37
rtp_timestamp(int64_t time_ms)38 static uint32_t rtp_timestamp(int64_t time_ms) {
39 return static_cast<uint32_t>(time_ms * kTestRate / 1000);
40 }
41
42 } // namespace
43
44 class RtpReceiverTest : public ::testing::Test {
45 protected:
RtpReceiverTest()46 RtpReceiverTest()
47 : fake_clock_(123456),
48 rtp_receiver_(
49 RtpReceiver::CreateAudioReceiver(&fake_clock_,
50 &mock_rtp_data_,
51 nullptr,
52 &rtp_payload_registry_)) {
53 rtp_receiver_->RegisterReceivePayload(kPcmuPayloadType,
54 SdpAudioFormat("PCMU", 8000, 1));
55 }
~RtpReceiverTest()56 ~RtpReceiverTest() {}
57
FindSourceByIdAndType(const std::vector<RtpSource> & sources,uint32_t source_id,RtpSourceType type,RtpSource * source)58 bool FindSourceByIdAndType(const std::vector<RtpSource>& sources,
59 uint32_t source_id,
60 RtpSourceType type,
61 RtpSource* source) {
62 for (size_t i = 0; i < sources.size(); ++i) {
63 if (sources[i].source_id() == source_id &&
64 sources[i].source_type() == type) {
65 (*source) = sources[i];
66 return true;
67 }
68 }
69 return false;
70 }
71
72 SimulatedClock fake_clock_;
73 NiceMock<MockRtpData> mock_rtp_data_;
74 RTPPayloadRegistry rtp_payload_registry_;
75 std::unique_ptr<RtpReceiver> rtp_receiver_;
76 };
77
TEST_F(RtpReceiverTest,GetSources)78 TEST_F(RtpReceiverTest, GetSources) {
79 int64_t now_ms = fake_clock_.TimeInMilliseconds();
80
81 RTPHeader header;
82 header.payloadType = kPcmuPayloadType;
83 header.ssrc = kSsrc1;
84 header.timestamp = rtp_timestamp(now_ms);
85 header.numCSRCs = 2;
86 header.arrOfCSRCs[0] = kCsrc1;
87 header.arrOfCSRCs[1] = kCsrc2;
88 const PayloadUnion payload_specific{
89 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
90
91 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
92 header, kTestPayload, sizeof(kTestPayload), payload_specific));
93 auto sources = rtp_receiver_->GetSources();
94 // One SSRC source and two CSRC sources.
95 EXPECT_THAT(sources, UnorderedElementsAre(
96 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC),
97 RtpSource(now_ms, kCsrc1, RtpSourceType::CSRC),
98 RtpSource(now_ms, kCsrc2, RtpSourceType::CSRC)));
99
100 // Advance the fake clock and the method is expected to return the
101 // contributing source object with same source id and updated timestamp.
102 fake_clock_.AdvanceTimeMilliseconds(1);
103 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
104 header, kTestPayload, sizeof(kTestPayload), payload_specific));
105 sources = rtp_receiver_->GetSources();
106 now_ms = fake_clock_.TimeInMilliseconds();
107 EXPECT_THAT(sources, UnorderedElementsAre(
108 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC),
109 RtpSource(now_ms, kCsrc1, RtpSourceType::CSRC),
110 RtpSource(now_ms, kCsrc2, RtpSourceType::CSRC)));
111
112 // Test the edge case that the sources are still there just before the
113 // timeout.
114 int64_t prev_time_ms = fake_clock_.TimeInMilliseconds();
115 fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs);
116 sources = rtp_receiver_->GetSources();
117 EXPECT_THAT(sources,
118 UnorderedElementsAre(
119 RtpSource(prev_time_ms, kSsrc1, RtpSourceType::SSRC),
120 RtpSource(prev_time_ms, kCsrc1, RtpSourceType::CSRC),
121 RtpSource(prev_time_ms, kCsrc2, RtpSourceType::CSRC)));
122
123 // Time out.
124 fake_clock_.AdvanceTimeMilliseconds(1);
125 sources = rtp_receiver_->GetSources();
126 // All the sources should be out of date.
127 ASSERT_EQ(0u, sources.size());
128 }
129
130 // Test the case that the SSRC is changed.
TEST_F(RtpReceiverTest,GetSourcesChangeSSRC)131 TEST_F(RtpReceiverTest, GetSourcesChangeSSRC) {
132 int64_t prev_time_ms = -1;
133 int64_t now_ms = fake_clock_.TimeInMilliseconds();
134
135 RTPHeader header;
136 header.payloadType = kPcmuPayloadType;
137 header.ssrc = kSsrc1;
138 header.timestamp = rtp_timestamp(now_ms);
139 const PayloadUnion payload_specific{
140 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
141
142 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
143 header, kTestPayload, sizeof(kTestPayload), payload_specific));
144 auto sources = rtp_receiver_->GetSources();
145 EXPECT_THAT(sources, UnorderedElementsAre(
146 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC)));
147
148 // The SSRC is changed and the old SSRC is expected to be returned.
149 fake_clock_.AdvanceTimeMilliseconds(100);
150 prev_time_ms = now_ms;
151 now_ms = fake_clock_.TimeInMilliseconds();
152 header.ssrc = kSsrc2;
153 header.timestamp = rtp_timestamp(now_ms);
154 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
155 header, kTestPayload, sizeof(kTestPayload), payload_specific));
156 sources = rtp_receiver_->GetSources();
157 EXPECT_THAT(sources, UnorderedElementsAre(
158 RtpSource(prev_time_ms, kSsrc1, RtpSourceType::SSRC),
159 RtpSource(now_ms, kSsrc2, RtpSourceType::SSRC)));
160
161 // The SSRC is changed again and happen to be changed back to 1. No
162 // duplication is expected.
163 fake_clock_.AdvanceTimeMilliseconds(100);
164 header.ssrc = kSsrc1;
165 header.timestamp = rtp_timestamp(now_ms);
166 prev_time_ms = now_ms;
167 now_ms = fake_clock_.TimeInMilliseconds();
168 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
169 header, kTestPayload, sizeof(kTestPayload), payload_specific));
170 sources = rtp_receiver_->GetSources();
171 EXPECT_THAT(sources, UnorderedElementsAre(
172 RtpSource(prev_time_ms, kSsrc2, RtpSourceType::SSRC),
173 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC)));
174
175 // Old SSRC source timeout.
176 fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs);
177 now_ms = fake_clock_.TimeInMilliseconds();
178 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
179 header, kTestPayload, sizeof(kTestPayload), payload_specific));
180 sources = rtp_receiver_->GetSources();
181 EXPECT_THAT(sources, UnorderedElementsAre(
182 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC)));
183 }
184
TEST_F(RtpReceiverTest,GetSourcesRemoveOutdatedSource)185 TEST_F(RtpReceiverTest, GetSourcesRemoveOutdatedSource) {
186 int64_t now_ms = fake_clock_.TimeInMilliseconds();
187
188 RTPHeader header;
189 header.payloadType = kPcmuPayloadType;
190 header.timestamp = rtp_timestamp(now_ms);
191 const PayloadUnion payload_specific{
192 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
193 header.numCSRCs = 1;
194 size_t kSourceListSize = 20;
195
196 for (size_t i = 0; i < kSourceListSize; ++i) {
197 header.ssrc = i;
198 header.arrOfCSRCs[0] = (i + 1);
199 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
200 header, kTestPayload, sizeof(kTestPayload), payload_specific));
201 }
202
203 RtpSource source(0, 0, RtpSourceType::SSRC);
204 auto sources = rtp_receiver_->GetSources();
205 // Expect |kSourceListSize| SSRC sources and |kSourceListSize| CSRC sources.
206 ASSERT_EQ(2 * kSourceListSize, sources.size());
207 for (size_t i = 0; i < kSourceListSize; ++i) {
208 // The SSRC source IDs are expected to be 19, 18, 17 ... 0
209 ASSERT_TRUE(
210 FindSourceByIdAndType(sources, i, RtpSourceType::SSRC, &source));
211 EXPECT_EQ(now_ms, source.timestamp_ms());
212
213 // The CSRC source IDs are expected to be 20, 19, 18 ... 1
214 ASSERT_TRUE(
215 FindSourceByIdAndType(sources, (i + 1), RtpSourceType::CSRC, &source));
216 EXPECT_EQ(now_ms, source.timestamp_ms());
217 }
218
219 fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs);
220 for (size_t i = 0; i < kSourceListSize; ++i) {
221 // The SSRC source IDs are expected to be 19, 18, 17 ... 0
222 ASSERT_TRUE(
223 FindSourceByIdAndType(sources, i, RtpSourceType::SSRC, &source));
224 EXPECT_EQ(now_ms, source.timestamp_ms());
225
226 // The CSRC source IDs are expected to be 20, 19, 18 ... 1
227 ASSERT_TRUE(
228 FindSourceByIdAndType(sources, (i + 1), RtpSourceType::CSRC, &source));
229 EXPECT_EQ(now_ms, source.timestamp_ms());
230 }
231
232 // Timeout. All the existing objects are out of date and are expected to be
233 // removed.
234 fake_clock_.AdvanceTimeMilliseconds(1);
235 header.ssrc = kSsrc1;
236 header.arrOfCSRCs[0] = kCsrc1;
237 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
238 header, kTestPayload, sizeof(kTestPayload), payload_specific));
239 auto rtp_receiver_impl = static_cast<RtpReceiverImpl*>(rtp_receiver_.get());
240 auto ssrc_sources = rtp_receiver_impl->ssrc_sources_for_testing();
241 ASSERT_EQ(1u, ssrc_sources.size());
242 EXPECT_EQ(kSsrc1, ssrc_sources.begin()->source_id());
243 EXPECT_EQ(RtpSourceType::SSRC, ssrc_sources.begin()->source_type());
244 EXPECT_EQ(fake_clock_.TimeInMilliseconds(),
245 ssrc_sources.begin()->timestamp_ms());
246
247 auto csrc_sources = rtp_receiver_impl->csrc_sources_for_testing();
248 ASSERT_EQ(1u, csrc_sources.size());
249 EXPECT_EQ(kCsrc1, csrc_sources.begin()->source_id());
250 EXPECT_EQ(RtpSourceType::CSRC, csrc_sources.begin()->source_type());
251 EXPECT_EQ(fake_clock_.TimeInMilliseconds(),
252 csrc_sources.begin()->timestamp_ms());
253 }
254
255 // The audio level from the RTPHeader extension should be stored in the
256 // RtpSource with the matching SSRC.
TEST_F(RtpReceiverTest,GetSourcesContainsAudioLevelExtension)257 TEST_F(RtpReceiverTest, GetSourcesContainsAudioLevelExtension) {
258 RTPHeader header;
259 int64_t time1_ms = fake_clock_.TimeInMilliseconds();
260 header.payloadType = kPcmuPayloadType;
261 header.ssrc = kSsrc1;
262 header.timestamp = rtp_timestamp(time1_ms);
263 header.extension.hasAudioLevel = true;
264 header.extension.audioLevel = 10;
265 const PayloadUnion payload_specific{
266 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
267
268 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
269 header, kTestPayload, sizeof(kTestPayload), payload_specific));
270 auto sources = rtp_receiver_->GetSources();
271 EXPECT_THAT(sources, UnorderedElementsAre(RtpSource(
272 time1_ms, kSsrc1, RtpSourceType::SSRC, 10)));
273
274 // Receive a packet from a different SSRC with a different level and check
275 // that they are both remembered.
276 fake_clock_.AdvanceTimeMilliseconds(1);
277 int64_t time2_ms = fake_clock_.TimeInMilliseconds();
278 header.ssrc = kSsrc2;
279 header.timestamp = rtp_timestamp(time2_ms);
280 header.extension.hasAudioLevel = true;
281 header.extension.audioLevel = 20;
282
283 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
284 header, kTestPayload, sizeof(kTestPayload), payload_specific));
285 sources = rtp_receiver_->GetSources();
286 EXPECT_THAT(sources,
287 UnorderedElementsAre(
288 RtpSource(time1_ms, kSsrc1, RtpSourceType::SSRC, 10),
289 RtpSource(time2_ms, kSsrc2, RtpSourceType::SSRC, 20)));
290
291 // Receive a packet from the first SSRC again and check that the level is
292 // updated.
293 fake_clock_.AdvanceTimeMilliseconds(1);
294 int64_t time3_ms = fake_clock_.TimeInMilliseconds();
295 header.ssrc = kSsrc1;
296 header.timestamp = rtp_timestamp(time3_ms);
297 header.extension.hasAudioLevel = true;
298 header.extension.audioLevel = 30;
299
300 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
301 header, kTestPayload, sizeof(kTestPayload), payload_specific));
302 sources = rtp_receiver_->GetSources();
303 EXPECT_THAT(sources,
304 UnorderedElementsAre(
305 RtpSource(time3_ms, kSsrc1, RtpSourceType::SSRC, 30),
306 RtpSource(time2_ms, kSsrc2, RtpSourceType::SSRC, 20)));
307 }
308
TEST_F(RtpReceiverTest,MissingAudioLevelHeaderExtensionClearsRtpSourceAudioLevel)309 TEST_F(RtpReceiverTest,
310 MissingAudioLevelHeaderExtensionClearsRtpSourceAudioLevel) {
311 RTPHeader header;
312 int64_t time1_ms = fake_clock_.TimeInMilliseconds();
313 header.payloadType = kPcmuPayloadType;
314 header.ssrc = kSsrc1;
315 header.timestamp = rtp_timestamp(time1_ms);
316 header.extension.hasAudioLevel = true;
317 header.extension.audioLevel = 10;
318 const PayloadUnion payload_specific{
319 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
320
321 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
322 header, kTestPayload, sizeof(kTestPayload), payload_specific));
323 auto sources = rtp_receiver_->GetSources();
324 EXPECT_THAT(sources, UnorderedElementsAre(RtpSource(
325 time1_ms, kSsrc1, RtpSourceType::SSRC, 10)));
326
327 // Receive a second packet without the audio level header extension and check
328 // that the audio level is cleared.
329 fake_clock_.AdvanceTimeMilliseconds(1);
330 int64_t time2_ms = fake_clock_.TimeInMilliseconds();
331 header.timestamp = rtp_timestamp(time2_ms);
332 header.extension.hasAudioLevel = false;
333
334 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
335 header, kTestPayload, sizeof(kTestPayload), payload_specific));
336 sources = rtp_receiver_->GetSources();
337 EXPECT_THAT(sources, UnorderedElementsAre(
338 RtpSource(time2_ms, kSsrc1, RtpSourceType::SSRC)));
339 }
340
TEST_F(RtpReceiverTest,UpdatesTimestampsIfAndOnlyIfPacketArrivesInOrder)341 TEST_F(RtpReceiverTest, UpdatesTimestampsIfAndOnlyIfPacketArrivesInOrder) {
342 RTPHeader header;
343 int64_t time1_ms = fake_clock_.TimeInMilliseconds();
344 header.payloadType = kPcmuPayloadType;
345 header.ssrc = kSsrc1;
346 header.timestamp = rtp_timestamp(time1_ms);
347 header.extension.hasAudioLevel = true;
348 header.extension.audioLevel = 10;
349 header.sequenceNumber = 0xfff0;
350
351 const PayloadUnion payload_specific{
352 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
353 uint32_t latest_timestamp;
354 int64_t latest_receive_time_ms;
355
356 // No packet received yet.
357 EXPECT_FALSE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
358 &latest_receive_time_ms));
359 // Initial packet
360 const uint32_t timestamp_1 = header.timestamp;
361 const int64_t receive_time_1 = fake_clock_.TimeInMilliseconds();
362 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
363 header, kTestPayload, sizeof(kTestPayload), payload_specific));
364 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
365 &latest_receive_time_ms));
366 EXPECT_EQ(latest_timestamp, timestamp_1);
367 EXPECT_EQ(latest_receive_time_ms, receive_time_1);
368
369 // Late packet, timestamp not recorded.
370 fake_clock_.AdvanceTimeMilliseconds(10);
371 header.timestamp -= 900;
372 header.sequenceNumber -= 2;
373
374 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
375 header, kTestPayload, sizeof(kTestPayload), payload_specific));
376 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
377 &latest_receive_time_ms));
378 EXPECT_EQ(latest_timestamp, timestamp_1);
379 EXPECT_EQ(latest_receive_time_ms, receive_time_1);
380
381 // New packet, still late, no wraparound.
382 fake_clock_.AdvanceTimeMilliseconds(10);
383 header.timestamp += 1800;
384 header.sequenceNumber += 1;
385
386 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
387 header, kTestPayload, sizeof(kTestPayload), payload_specific));
388 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
389 &latest_receive_time_ms));
390 EXPECT_EQ(latest_timestamp, timestamp_1);
391 EXPECT_EQ(latest_receive_time_ms, receive_time_1);
392
393 // New packet, new timestamp recorded
394 fake_clock_.AdvanceTimeMilliseconds(10);
395 header.timestamp += 900;
396 header.sequenceNumber += 2;
397 const uint32_t timestamp_2 = header.timestamp;
398 const int64_t receive_time_2 = fake_clock_.TimeInMilliseconds();
399 const uint16_t seqno_2 = header.sequenceNumber;
400
401 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
402 header, kTestPayload, sizeof(kTestPayload), payload_specific));
403 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
404 &latest_receive_time_ms));
405 EXPECT_EQ(latest_timestamp, timestamp_2);
406 EXPECT_EQ(latest_receive_time_ms, receive_time_2);
407
408 // New packet, timestamp wraps around
409 fake_clock_.AdvanceTimeMilliseconds(10);
410 header.timestamp += 900;
411 header.sequenceNumber += 20;
412 const uint32_t timestamp_3 = header.timestamp;
413 const int64_t receive_time_3 = fake_clock_.TimeInMilliseconds();
414 EXPECT_LT(header.sequenceNumber, seqno_2); // Wrap-around
415
416 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
417 header, kTestPayload, sizeof(kTestPayload), payload_specific));
418 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
419 &latest_receive_time_ms));
420 EXPECT_EQ(latest_timestamp, timestamp_3);
421 EXPECT_EQ(latest_receive_time_ms, receive_time_3);
422 }
423
TEST_F(RtpReceiverTest,UpdatesTimestampsWhenStreamResets)424 TEST_F(RtpReceiverTest, UpdatesTimestampsWhenStreamResets) {
425 RTPHeader header;
426 int64_t time1_ms = fake_clock_.TimeInMilliseconds();
427 header.payloadType = kPcmuPayloadType;
428 header.ssrc = kSsrc1;
429 header.timestamp = rtp_timestamp(time1_ms);
430 header.extension.hasAudioLevel = true;
431 header.extension.audioLevel = 10;
432 header.sequenceNumber = 0xfff0;
433
434 const PayloadUnion payload_specific{
435 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
436 uint32_t latest_timestamp;
437 int64_t latest_receive_time_ms;
438
439 // No packet received yet.
440 EXPECT_FALSE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
441 &latest_receive_time_ms));
442 // Initial packet
443 const uint32_t timestamp_1 = header.timestamp;
444 const int64_t receive_time_1 = fake_clock_.TimeInMilliseconds();
445 const uint16_t seqno_1 = header.sequenceNumber;
446 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
447 header, kTestPayload, sizeof(kTestPayload), payload_specific));
448 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
449 &latest_receive_time_ms));
450 EXPECT_EQ(latest_timestamp, timestamp_1);
451 EXPECT_EQ(latest_receive_time_ms, receive_time_1);
452
453 // Packet with far in the past seqno, but unlikely to be a wrap-around.
454 // Treated as a seqno discontinuity, and timestamp is recorded.
455 fake_clock_.AdvanceTimeMilliseconds(10);
456 header.timestamp += 900;
457 header.sequenceNumber = 0x9000;
458
459 const uint32_t timestamp_2 = header.timestamp;
460 const int64_t receive_time_2 = fake_clock_.TimeInMilliseconds();
461 const uint16_t seqno_2 = header.sequenceNumber;
462 EXPECT_LT(seqno_1 - seqno_2, 0x8000); // In the past.
463
464 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
465 header, kTestPayload, sizeof(kTestPayload), payload_specific));
466 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
467 &latest_receive_time_ms));
468 EXPECT_EQ(latest_timestamp, timestamp_2);
469 EXPECT_EQ(latest_receive_time_ms, receive_time_2);
470 }
471
472 } // namespace webrtc
473