blob: 1400288ee95935c8c4ec6e999b9f3654d68085ce [file] [log] [blame]
hbos8d609f62017-04-10 07:39:05 -07001/*
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
Mirko Bonadei71207422017-09-15 13:58:09 +020013#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "test/gmock.h"
20#include "test/gtest.h"
hbos8d609f62017-04-10 07:39:05 -070021
22namespace webrtc {
zhihuang04262222017-04-11 11:28:10 -070023namespace {
24
nisse7fcdb6d2017-06-01 00:30:55 -070025using ::testing::NiceMock;
zhihuang04262222017-04-11 11:28:10 -070026using ::testing::UnorderedElementsAre;
hbos8d609f62017-04-10 07:39:05 -070027
28const uint32_t kTestRate = 64000u;
29const uint8_t kTestPayload[] = {'t', 'e', 's', 't'};
30const uint8_t kPcmuPayloadType = 96;
31const int64_t kGetSourcesTimeoutMs = 10000;
zhihuang04262222017-04-11 11:28:10 -070032const uint32_t kSsrc1 = 123;
33const uint32_t kSsrc2 = 124;
34const uint32_t kCsrc1 = 111;
35const uint32_t kCsrc2 = 222;
zhihuang04262222017-04-11 11:28:10 -070036
37static uint32_t rtp_timestamp(int64_t time_ms) {
38 return static_cast<uint32_t>(time_ms * kTestRate / 1000);
39}
40
41} // namespace
hbos8d609f62017-04-10 07:39:05 -070042
43class RtpReceiverTest : public ::testing::Test {
44 protected:
45 RtpReceiverTest()
46 : fake_clock_(123456),
47 rtp_receiver_(
48 RtpReceiver::CreateAudioReceiver(&fake_clock_,
nisse7fcdb6d2017-06-01 00:30:55 -070049 &mock_rtp_data_,
hbos8d609f62017-04-10 07:39:05 -070050 &rtp_payload_registry_)) {
Karl Wibergc62f6c72017-10-04 12:38:53 +020051 rtp_receiver_->RegisterReceivePayload(kPcmuPayloadType,
52 SdpAudioFormat("PCMU", 8000, 1));
hbos8d609f62017-04-10 07:39:05 -070053 }
54 ~RtpReceiverTest() {}
55
56 bool FindSourceByIdAndType(const std::vector<RtpSource>& sources,
57 uint32_t source_id,
58 RtpSourceType type,
59 RtpSource* source) {
60 for (size_t i = 0; i < sources.size(); ++i) {
61 if (sources[i].source_id() == source_id &&
62 sources[i].source_type() == type) {
63 (*source) = sources[i];
64 return true;
65 }
66 }
67 return false;
68 }
69
70 SimulatedClock fake_clock_;
nisse7fcdb6d2017-06-01 00:30:55 -070071 NiceMock<MockRtpData> mock_rtp_data_;
hbos8d609f62017-04-10 07:39:05 -070072 RTPPayloadRegistry rtp_payload_registry_;
73 std::unique_ptr<RtpReceiver> rtp_receiver_;
74};
75
76TEST_F(RtpReceiverTest, GetSources) {
zhihuang04262222017-04-11 11:28:10 -070077 int64_t now_ms = fake_clock_.TimeInMilliseconds();
78
hbos8d609f62017-04-10 07:39:05 -070079 RTPHeader header;
80 header.payloadType = kPcmuPayloadType;
zhihuang04262222017-04-11 11:28:10 -070081 header.ssrc = kSsrc1;
82 header.timestamp = rtp_timestamp(now_ms);
hbos8d609f62017-04-10 07:39:05 -070083 header.numCSRCs = 2;
zhihuang04262222017-04-11 11:28:10 -070084 header.arrOfCSRCs[0] = kCsrc1;
85 header.arrOfCSRCs[1] = kCsrc2;
Karl Wibergc62f6c72017-10-04 12:38:53 +020086 const PayloadUnion payload_specific{
87 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
hbos8d609f62017-04-10 07:39:05 -070088
zhihuang04262222017-04-11 11:28:10 -070089 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +020090 header, kTestPayload, sizeof(kTestPayload), payload_specific));
hbos8d609f62017-04-10 07:39:05 -070091 auto sources = rtp_receiver_->GetSources();
92 // One SSRC source and two CSRC sources.
zhihuang04262222017-04-11 11:28:10 -070093 EXPECT_THAT(sources, UnorderedElementsAre(
94 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC),
95 RtpSource(now_ms, kCsrc1, RtpSourceType::CSRC),
96 RtpSource(now_ms, kCsrc2, RtpSourceType::CSRC)));
hbos8d609f62017-04-10 07:39:05 -070097
98 // Advance the fake clock and the method is expected to return the
99 // contributing source object with same source id and updated timestamp.
100 fake_clock_.AdvanceTimeMilliseconds(1);
zhihuang04262222017-04-11 11:28:10 -0700101 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200102 header, kTestPayload, sizeof(kTestPayload), payload_specific));
hbos8d609f62017-04-10 07:39:05 -0700103 sources = rtp_receiver_->GetSources();
zhihuang04262222017-04-11 11:28:10 -0700104 now_ms = fake_clock_.TimeInMilliseconds();
105 EXPECT_THAT(sources, UnorderedElementsAre(
106 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC),
107 RtpSource(now_ms, kCsrc1, RtpSourceType::CSRC),
108 RtpSource(now_ms, kCsrc2, RtpSourceType::CSRC)));
hbos8d609f62017-04-10 07:39:05 -0700109
110 // Test the edge case that the sources are still there just before the
111 // timeout.
zhihuang04262222017-04-11 11:28:10 -0700112 int64_t prev_time_ms = fake_clock_.TimeInMilliseconds();
hbos8d609f62017-04-10 07:39:05 -0700113 fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs);
114 sources = rtp_receiver_->GetSources();
zhihuang04262222017-04-11 11:28:10 -0700115 EXPECT_THAT(sources,
116 UnorderedElementsAre(
117 RtpSource(prev_time_ms, kSsrc1, RtpSourceType::SSRC),
118 RtpSource(prev_time_ms, kCsrc1, RtpSourceType::CSRC),
119 RtpSource(prev_time_ms, kCsrc2, RtpSourceType::CSRC)));
hbos8d609f62017-04-10 07:39:05 -0700120
121 // Time out.
122 fake_clock_.AdvanceTimeMilliseconds(1);
123 sources = rtp_receiver_->GetSources();
124 // All the sources should be out of date.
125 ASSERT_EQ(0u, sources.size());
126}
127
128// Test the case that the SSRC is changed.
129TEST_F(RtpReceiverTest, GetSourcesChangeSSRC) {
zhihuang04262222017-04-11 11:28:10 -0700130 int64_t prev_time_ms = -1;
131 int64_t now_ms = fake_clock_.TimeInMilliseconds();
132
hbos8d609f62017-04-10 07:39:05 -0700133 RTPHeader header;
134 header.payloadType = kPcmuPayloadType;
zhihuang04262222017-04-11 11:28:10 -0700135 header.ssrc = kSsrc1;
136 header.timestamp = rtp_timestamp(now_ms);
Karl Wibergc62f6c72017-10-04 12:38:53 +0200137 const PayloadUnion payload_specific{
138 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
hbos8d609f62017-04-10 07:39:05 -0700139
zhihuang04262222017-04-11 11:28:10 -0700140 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200141 header, kTestPayload, sizeof(kTestPayload), payload_specific));
hbos8d609f62017-04-10 07:39:05 -0700142 auto sources = rtp_receiver_->GetSources();
zhihuang04262222017-04-11 11:28:10 -0700143 EXPECT_THAT(sources, UnorderedElementsAre(
144 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC)));
hbos8d609f62017-04-10 07:39:05 -0700145
146 // The SSRC is changed and the old SSRC is expected to be returned.
147 fake_clock_.AdvanceTimeMilliseconds(100);
zhihuang04262222017-04-11 11:28:10 -0700148 prev_time_ms = now_ms;
149 now_ms = fake_clock_.TimeInMilliseconds();
150 header.ssrc = kSsrc2;
151 header.timestamp = rtp_timestamp(now_ms);
152 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200153 header, kTestPayload, sizeof(kTestPayload), payload_specific));
hbos8d609f62017-04-10 07:39:05 -0700154 sources = rtp_receiver_->GetSources();
zhihuang04262222017-04-11 11:28:10 -0700155 EXPECT_THAT(sources, UnorderedElementsAre(
156 RtpSource(prev_time_ms, kSsrc1, RtpSourceType::SSRC),
157 RtpSource(now_ms, kSsrc2, RtpSourceType::SSRC)));
hbos8d609f62017-04-10 07:39:05 -0700158
159 // The SSRC is changed again and happen to be changed back to 1. No
160 // duplication is expected.
161 fake_clock_.AdvanceTimeMilliseconds(100);
zhihuang04262222017-04-11 11:28:10 -0700162 header.ssrc = kSsrc1;
163 header.timestamp = rtp_timestamp(now_ms);
164 prev_time_ms = now_ms;
165 now_ms = fake_clock_.TimeInMilliseconds();
166 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200167 header, kTestPayload, sizeof(kTestPayload), payload_specific));
hbos8d609f62017-04-10 07:39:05 -0700168 sources = rtp_receiver_->GetSources();
zhihuang04262222017-04-11 11:28:10 -0700169 EXPECT_THAT(sources, UnorderedElementsAre(
170 RtpSource(prev_time_ms, kSsrc2, RtpSourceType::SSRC),
171 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC)));
hbos8d609f62017-04-10 07:39:05 -0700172
173 // Old SSRC source timeout.
174 fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs);
zhihuang04262222017-04-11 11:28:10 -0700175 now_ms = fake_clock_.TimeInMilliseconds();
176 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200177 header, kTestPayload, sizeof(kTestPayload), payload_specific));
hbos8d609f62017-04-10 07:39:05 -0700178 sources = rtp_receiver_->GetSources();
zhihuang04262222017-04-11 11:28:10 -0700179 EXPECT_THAT(sources, UnorderedElementsAre(
180 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC)));
hbos8d609f62017-04-10 07:39:05 -0700181}
182
183TEST_F(RtpReceiverTest, GetSourcesRemoveOutdatedSource) {
zhihuang04262222017-04-11 11:28:10 -0700184 int64_t now_ms = fake_clock_.TimeInMilliseconds();
185
hbos8d609f62017-04-10 07:39:05 -0700186 RTPHeader header;
187 header.payloadType = kPcmuPayloadType;
zhihuang04262222017-04-11 11:28:10 -0700188 header.timestamp = rtp_timestamp(now_ms);
Karl Wibergc62f6c72017-10-04 12:38:53 +0200189 const PayloadUnion payload_specific{
190 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
hbos8d609f62017-04-10 07:39:05 -0700191 header.numCSRCs = 1;
zhihuang04262222017-04-11 11:28:10 -0700192 size_t kSourceListSize = 20;
hbos8d609f62017-04-10 07:39:05 -0700193
zhihuang04262222017-04-11 11:28:10 -0700194 for (size_t i = 0; i < kSourceListSize; ++i) {
hbos8d609f62017-04-10 07:39:05 -0700195 header.ssrc = i;
196 header.arrOfCSRCs[0] = (i + 1);
Niels Möller22ec9522017-10-05 08:39:15 +0200197 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
198 header, kTestPayload, sizeof(kTestPayload), payload_specific));
hbos8d609f62017-04-10 07:39:05 -0700199 }
200
zhihuang04262222017-04-11 11:28:10 -0700201 RtpSource source(0, 0, RtpSourceType::SSRC);
hbos8d609f62017-04-10 07:39:05 -0700202 auto sources = rtp_receiver_->GetSources();
zhihuang04262222017-04-11 11:28:10 -0700203 // Expect |kSourceListSize| SSRC sources and |kSourceListSize| CSRC sources.
204 ASSERT_EQ(2 * kSourceListSize, sources.size());
205 for (size_t i = 0; i < kSourceListSize; ++i) {
hbos8d609f62017-04-10 07:39:05 -0700206 // The SSRC source IDs are expected to be 19, 18, 17 ... 0
207 ASSERT_TRUE(
208 FindSourceByIdAndType(sources, i, RtpSourceType::SSRC, &source));
zhihuang04262222017-04-11 11:28:10 -0700209 EXPECT_EQ(now_ms, source.timestamp_ms());
hbos8d609f62017-04-10 07:39:05 -0700210
211 // The CSRC source IDs are expected to be 20, 19, 18 ... 1
212 ASSERT_TRUE(
213 FindSourceByIdAndType(sources, (i + 1), RtpSourceType::CSRC, &source));
zhihuang04262222017-04-11 11:28:10 -0700214 EXPECT_EQ(now_ms, source.timestamp_ms());
hbos8d609f62017-04-10 07:39:05 -0700215 }
216
217 fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs);
zhihuang04262222017-04-11 11:28:10 -0700218 for (size_t i = 0; i < kSourceListSize; ++i) {
hbos8d609f62017-04-10 07:39:05 -0700219 // The SSRC source IDs are expected to be 19, 18, 17 ... 0
220 ASSERT_TRUE(
221 FindSourceByIdAndType(sources, i, RtpSourceType::SSRC, &source));
zhihuang04262222017-04-11 11:28:10 -0700222 EXPECT_EQ(now_ms, source.timestamp_ms());
hbos8d609f62017-04-10 07:39:05 -0700223
224 // The CSRC source IDs are expected to be 20, 19, 18 ... 1
225 ASSERT_TRUE(
226 FindSourceByIdAndType(sources, (i + 1), RtpSourceType::CSRC, &source));
zhihuang04262222017-04-11 11:28:10 -0700227 EXPECT_EQ(now_ms, source.timestamp_ms());
hbos8d609f62017-04-10 07:39:05 -0700228 }
229
230 // Timeout. All the existing objects are out of date and are expected to be
231 // removed.
232 fake_clock_.AdvanceTimeMilliseconds(1);
zhihuang04262222017-04-11 11:28:10 -0700233 header.ssrc = kSsrc1;
234 header.arrOfCSRCs[0] = kCsrc1;
235 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200236 header, kTestPayload, sizeof(kTestPayload), payload_specific));
Niels Mölleraf175952018-08-13 13:23:08 +0200237 now_ms = fake_clock_.TimeInMilliseconds();
238 sources = rtp_receiver_->GetSources();
239 EXPECT_THAT(sources, UnorderedElementsAre(
240 RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC),
241 RtpSource(now_ms, kCsrc1, RtpSourceType::CSRC)));
hbos8d609f62017-04-10 07:39:05 -0700242}
243
zstein2b706342017-08-24 14:52:17 -0700244// The audio level from the RTPHeader extension should be stored in the
245// RtpSource with the matching SSRC.
246TEST_F(RtpReceiverTest, GetSourcesContainsAudioLevelExtension) {
247 RTPHeader header;
248 int64_t time1_ms = fake_clock_.TimeInMilliseconds();
249 header.payloadType = kPcmuPayloadType;
250 header.ssrc = kSsrc1;
251 header.timestamp = rtp_timestamp(time1_ms);
252 header.extension.hasAudioLevel = true;
253 header.extension.audioLevel = 10;
Karl Wibergc62f6c72017-10-04 12:38:53 +0200254 const PayloadUnion payload_specific{
255 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
zstein2b706342017-08-24 14:52:17 -0700256
257 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200258 header, kTestPayload, sizeof(kTestPayload), payload_specific));
zstein2b706342017-08-24 14:52:17 -0700259 auto sources = rtp_receiver_->GetSources();
260 EXPECT_THAT(sources, UnorderedElementsAre(RtpSource(
261 time1_ms, kSsrc1, RtpSourceType::SSRC, 10)));
262
263 // Receive a packet from a different SSRC with a different level and check
264 // that they are both remembered.
265 fake_clock_.AdvanceTimeMilliseconds(1);
266 int64_t time2_ms = fake_clock_.TimeInMilliseconds();
267 header.ssrc = kSsrc2;
268 header.timestamp = rtp_timestamp(time2_ms);
269 header.extension.hasAudioLevel = true;
270 header.extension.audioLevel = 20;
271
272 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200273 header, kTestPayload, sizeof(kTestPayload), payload_specific));
zstein2b706342017-08-24 14:52:17 -0700274 sources = rtp_receiver_->GetSources();
275 EXPECT_THAT(sources,
276 UnorderedElementsAre(
277 RtpSource(time1_ms, kSsrc1, RtpSourceType::SSRC, 10),
278 RtpSource(time2_ms, kSsrc2, RtpSourceType::SSRC, 20)));
279
280 // Receive a packet from the first SSRC again and check that the level is
281 // updated.
282 fake_clock_.AdvanceTimeMilliseconds(1);
283 int64_t time3_ms = fake_clock_.TimeInMilliseconds();
284 header.ssrc = kSsrc1;
285 header.timestamp = rtp_timestamp(time3_ms);
286 header.extension.hasAudioLevel = true;
287 header.extension.audioLevel = 30;
288
289 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200290 header, kTestPayload, sizeof(kTestPayload), payload_specific));
zstein2b706342017-08-24 14:52:17 -0700291 sources = rtp_receiver_->GetSources();
292 EXPECT_THAT(sources,
293 UnorderedElementsAre(
294 RtpSource(time3_ms, kSsrc1, RtpSourceType::SSRC, 30),
295 RtpSource(time2_ms, kSsrc2, RtpSourceType::SSRC, 20)));
296}
297
298TEST_F(RtpReceiverTest,
299 MissingAudioLevelHeaderExtensionClearsRtpSourceAudioLevel) {
300 RTPHeader header;
301 int64_t time1_ms = fake_clock_.TimeInMilliseconds();
302 header.payloadType = kPcmuPayloadType;
303 header.ssrc = kSsrc1;
304 header.timestamp = rtp_timestamp(time1_ms);
305 header.extension.hasAudioLevel = true;
306 header.extension.audioLevel = 10;
Karl Wibergc62f6c72017-10-04 12:38:53 +0200307 const PayloadUnion payload_specific{
308 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
zstein2b706342017-08-24 14:52:17 -0700309
310 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200311 header, kTestPayload, sizeof(kTestPayload), payload_specific));
zstein2b706342017-08-24 14:52:17 -0700312 auto sources = rtp_receiver_->GetSources();
313 EXPECT_THAT(sources, UnorderedElementsAre(RtpSource(
314 time1_ms, kSsrc1, RtpSourceType::SSRC, 10)));
315
316 // Receive a second packet without the audio level header extension and check
317 // that the audio level is cleared.
318 fake_clock_.AdvanceTimeMilliseconds(1);
319 int64_t time2_ms = fake_clock_.TimeInMilliseconds();
320 header.timestamp = rtp_timestamp(time2_ms);
321 header.extension.hasAudioLevel = false;
322
323 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
Niels Möller22ec9522017-10-05 08:39:15 +0200324 header, kTestPayload, sizeof(kTestPayload), payload_specific));
zstein2b706342017-08-24 14:52:17 -0700325 sources = rtp_receiver_->GetSources();
326 EXPECT_THAT(sources, UnorderedElementsAre(
327 RtpSource(time2_ms, kSsrc1, RtpSourceType::SSRC)));
328}
329
Niels Möller22ec9522017-10-05 08:39:15 +0200330TEST_F(RtpReceiverTest, UpdatesTimestampsIfAndOnlyIfPacketArrivesInOrder) {
331 RTPHeader header;
332 int64_t time1_ms = fake_clock_.TimeInMilliseconds();
333 header.payloadType = kPcmuPayloadType;
334 header.ssrc = kSsrc1;
335 header.timestamp = rtp_timestamp(time1_ms);
336 header.extension.hasAudioLevel = true;
337 header.extension.audioLevel = 10;
338 header.sequenceNumber = 0xfff0;
339
340 const PayloadUnion payload_specific{
341 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
342 uint32_t latest_timestamp;
343 int64_t latest_receive_time_ms;
344
345 // No packet received yet.
346 EXPECT_FALSE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
347 &latest_receive_time_ms));
348 // Initial packet
349 const uint32_t timestamp_1 = header.timestamp;
350 const int64_t receive_time_1 = fake_clock_.TimeInMilliseconds();
351 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
352 header, kTestPayload, sizeof(kTestPayload), payload_specific));
353 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
354 &latest_receive_time_ms));
355 EXPECT_EQ(latest_timestamp, timestamp_1);
356 EXPECT_EQ(latest_receive_time_ms, receive_time_1);
357
358 // Late packet, timestamp not recorded.
359 fake_clock_.AdvanceTimeMilliseconds(10);
360 header.timestamp -= 900;
361 header.sequenceNumber -= 2;
362
363 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
364 header, kTestPayload, sizeof(kTestPayload), payload_specific));
365 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
366 &latest_receive_time_ms));
367 EXPECT_EQ(latest_timestamp, timestamp_1);
368 EXPECT_EQ(latest_receive_time_ms, receive_time_1);
369
370 // New packet, still late, no wraparound.
371 fake_clock_.AdvanceTimeMilliseconds(10);
372 header.timestamp += 1800;
373 header.sequenceNumber += 1;
374
375 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
376 header, kTestPayload, sizeof(kTestPayload), payload_specific));
377 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
378 &latest_receive_time_ms));
379 EXPECT_EQ(latest_timestamp, timestamp_1);
380 EXPECT_EQ(latest_receive_time_ms, receive_time_1);
381
382 // New packet, new timestamp recorded
383 fake_clock_.AdvanceTimeMilliseconds(10);
384 header.timestamp += 900;
385 header.sequenceNumber += 2;
386 const uint32_t timestamp_2 = header.timestamp;
387 const int64_t receive_time_2 = fake_clock_.TimeInMilliseconds();
388 const uint16_t seqno_2 = header.sequenceNumber;
389
390 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
391 header, kTestPayload, sizeof(kTestPayload), payload_specific));
392 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
393 &latest_receive_time_ms));
394 EXPECT_EQ(latest_timestamp, timestamp_2);
395 EXPECT_EQ(latest_receive_time_ms, receive_time_2);
396
397 // New packet, timestamp wraps around
398 fake_clock_.AdvanceTimeMilliseconds(10);
399 header.timestamp += 900;
400 header.sequenceNumber += 20;
401 const uint32_t timestamp_3 = header.timestamp;
402 const int64_t receive_time_3 = fake_clock_.TimeInMilliseconds();
403 EXPECT_LT(header.sequenceNumber, seqno_2); // Wrap-around
404
405 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
406 header, kTestPayload, sizeof(kTestPayload), payload_specific));
407 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
408 &latest_receive_time_ms));
409 EXPECT_EQ(latest_timestamp, timestamp_3);
410 EXPECT_EQ(latest_receive_time_ms, receive_time_3);
411}
412
413TEST_F(RtpReceiverTest, UpdatesTimestampsWhenStreamResets) {
414 RTPHeader header;
415 int64_t time1_ms = fake_clock_.TimeInMilliseconds();
416 header.payloadType = kPcmuPayloadType;
417 header.ssrc = kSsrc1;
418 header.timestamp = rtp_timestamp(time1_ms);
419 header.extension.hasAudioLevel = true;
420 header.extension.audioLevel = 10;
421 header.sequenceNumber = 0xfff0;
422
423 const PayloadUnion payload_specific{
424 AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
425 uint32_t latest_timestamp;
426 int64_t latest_receive_time_ms;
427
428 // No packet received yet.
429 EXPECT_FALSE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
430 &latest_receive_time_ms));
431 // Initial packet
432 const uint32_t timestamp_1 = header.timestamp;
433 const int64_t receive_time_1 = fake_clock_.TimeInMilliseconds();
434 const uint16_t seqno_1 = header.sequenceNumber;
435 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
436 header, kTestPayload, sizeof(kTestPayload), payload_specific));
437 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
438 &latest_receive_time_ms));
439 EXPECT_EQ(latest_timestamp, timestamp_1);
440 EXPECT_EQ(latest_receive_time_ms, receive_time_1);
441
442 // Packet with far in the past seqno, but unlikely to be a wrap-around.
443 // Treated as a seqno discontinuity, and timestamp is recorded.
444 fake_clock_.AdvanceTimeMilliseconds(10);
445 header.timestamp += 900;
446 header.sequenceNumber = 0x9000;
447
448 const uint32_t timestamp_2 = header.timestamp;
449 const int64_t receive_time_2 = fake_clock_.TimeInMilliseconds();
450 const uint16_t seqno_2 = header.sequenceNumber;
451 EXPECT_LT(seqno_1 - seqno_2, 0x8000); // In the past.
452
453 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
454 header, kTestPayload, sizeof(kTestPayload), payload_specific));
455 EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp,
456 &latest_receive_time_ms));
457 EXPECT_EQ(latest_timestamp, timestamp_2);
458 EXPECT_EQ(latest_receive_time_ms, receive_time_2);
459}
460
hbos8d609f62017-04-10 07:39:05 -0700461} // namespace webrtc