blob: e19f1914398a4da9d2d9c442a3d0ed09415813e3 [file] [log] [blame]
danilchap1edb7ab2016-04-20 05:25:10 -07001/*
2 * Copyright (c) 2016 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 */
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020010#include "modules/rtp_rtcp/source/rtp_packet_received.h"
11#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
danilchap1edb7ab2016-04-20 05:25:10 -070012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
14#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
15#include "rtc_base/random.h"
16#include "test/gmock.h"
17#include "test/gtest.h"
danilchap1edb7ab2016-04-20 05:25:10 -070018
danilchap1edb7ab2016-04-20 05:25:10 -070019namespace webrtc {
20namespace {
danilchapc547e842017-04-10 01:31:49 -070021using ::testing::ElementsAreArray;
22using ::testing::IsEmpty;
23using ::testing::make_tuple;
24
danilchap1edb7ab2016-04-20 05:25:10 -070025constexpr int8_t kPayloadType = 100;
26constexpr uint32_t kSsrc = 0x12345678;
eladalonae550e32017-05-24 08:28:13 -070027constexpr uint16_t kSeqNum = 0x1234;
28constexpr uint8_t kSeqNumFirstByte = kSeqNum >> 8;
29constexpr uint8_t kSeqNumSecondByte = kSeqNum & 0xff;
danilchap1edb7ab2016-04-20 05:25:10 -070030constexpr uint32_t kTimestamp = 0x65431278;
31constexpr uint8_t kTransmissionOffsetExtensionId = 1;
32constexpr uint8_t kAudioLevelExtensionId = 9;
erikvargae6b16192017-05-11 02:36:32 -070033constexpr uint8_t kRtpStreamIdExtensionId = 0xa;
Steve Antona3251dd2017-07-21 09:58:31 -070034constexpr uint8_t kRtpMidExtensionId = 0xb;
sprangba050a62017-08-18 02:51:12 -070035constexpr uint8_t kVideoTimingExtensionId = 0xc;
danilchap1edb7ab2016-04-20 05:25:10 -070036constexpr int32_t kTimeOffset = 0x56ce;
37constexpr bool kVoiceActive = true;
38constexpr uint8_t kAudioLevel = 0x5a;
erikvargae6b16192017-05-11 02:36:32 -070039constexpr char kStreamId[] = "streamid";
Steve Antona3251dd2017-07-21 09:58:31 -070040constexpr char kMid[] = "mid";
danilchap1edb7ab2016-04-20 05:25:10 -070041constexpr size_t kMaxPaddingSize = 224u;
danilchap07ec26d2016-06-17 04:18:54 -070042// clang-format off
danilchap1edb7ab2016-04-20 05:25:10 -070043constexpr uint8_t kMinimumPacket[] = {
eladalonae550e32017-05-24 08:28:13 -070044 0x80, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070045 0x65, 0x43, 0x12, 0x78,
46 0x12, 0x34, 0x56, 0x78};
erikvargae6b16192017-05-11 02:36:32 -070047
danilchap1edb7ab2016-04-20 05:25:10 -070048constexpr uint8_t kPacketWithTO[] = {
eladalonae550e32017-05-24 08:28:13 -070049 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070050 0x65, 0x43, 0x12, 0x78,
51 0x12, 0x34, 0x56, 0x78,
52 0xbe, 0xde, 0x00, 0x01,
53 0x12, 0x00, 0x56, 0xce};
54
55constexpr uint8_t kPacketWithTOAndAL[] = {
eladalonae550e32017-05-24 08:28:13 -070056 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070057 0x65, 0x43, 0x12, 0x78,
58 0x12, 0x34, 0x56, 0x78,
59 0xbe, 0xde, 0x00, 0x02,
60 0x12, 0x00, 0x56, 0xce,
61 0x90, 0x80|kAudioLevel, 0x00, 0x00};
62
erikvargae6b16192017-05-11 02:36:32 -070063constexpr uint8_t kPacketWithRsid[] = {
eladalonae550e32017-05-24 08:28:13 -070064 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
erikvargae6b16192017-05-11 02:36:32 -070065 0x65, 0x43, 0x12, 0x78,
66 0x12, 0x34, 0x56, 0x78,
67 0xbe, 0xde, 0x00, 0x03,
68 0xa7, 's', 't', 'r',
69 'e', 'a', 'm', 'i',
70 'd' , 0x00, 0x00, 0x00};
71
Steve Antona3251dd2017-07-21 09:58:31 -070072constexpr uint8_t kPacketWithMid[] = {
73 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
74 0x65, 0x43, 0x12, 0x78,
75 0x12, 0x34, 0x56, 0x78,
76 0xbe, 0xde, 0x00, 0x01,
77 0xb2, 'm', 'i', 'd'};
78
danilchap1edb7ab2016-04-20 05:25:10 -070079constexpr uint32_t kCsrcs[] = {0x34567890, 0x32435465};
80constexpr uint8_t kPayload[] = {'p', 'a', 'y', 'l', 'o', 'a', 'd'};
81constexpr uint8_t kPacketPaddingSize = 8;
82constexpr uint8_t kPacket[] = {
eladalonae550e32017-05-24 08:28:13 -070083 0xb2, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070084 0x65, 0x43, 0x12, 0x78,
85 0x12, 0x34, 0x56, 0x78,
86 0x34, 0x56, 0x78, 0x90,
87 0x32, 0x43, 0x54, 0x65,
88 0xbe, 0xde, 0x00, 0x01,
89 0x12, 0x00, 0x56, 0xce,
90 'p', 'a', 'y', 'l', 'o', 'a', 'd',
91 'p', 'a', 'd', 'd', 'i', 'n', 'g', kPacketPaddingSize};
danilchape565a042016-06-16 10:04:50 -070092
danilchap07ec26d2016-06-17 04:18:54 -070093constexpr uint8_t kPacketWithInvalidExtension[] = {
eladalonae550e32017-05-24 08:28:13 -070094 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap07ec26d2016-06-17 04:18:54 -070095 0x65, 0x43, 0x12, 0x78, // kTimestamp.
96 0x12, 0x34, 0x56, 0x78, // kSSrc.
97 0xbe, 0xde, 0x00, 0x02, // Extension block of size 2 x 32bit words.
98 (kTransmissionOffsetExtensionId << 4) | 6, // (6+1)-byte extension, but
99 'e', 'x', 't', // Transmission Offset
100 'd', 'a', 't', 'a', // expected to be 3-bytes.
sprangba050a62017-08-18 02:51:12 -0700101 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
102
103constexpr uint8_t kPacketWithLegacyTimingExtension[] = {
104 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
105 0x65, 0x43, 0x12, 0x78, // kTimestamp.
106 0x12, 0x34, 0x56, 0x78, // kSSrc.
107 0xbe, 0xde, 0x00, 0x04, // Extension block of size 4 x 32bit words.
108 (kVideoTimingExtensionId << 4)
109 | VideoTimingExtension::kValueSizeBytes - 2, // Old format without flags.
110 0x00, 0x01, 0x00,
111 0x02, 0x00, 0x03, 0x00,
112 0x04, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00};
danilchap07ec26d2016-06-17 04:18:54 -0700114// clang-format on
danilchap1edb7ab2016-04-20 05:25:10 -0700115} // namespace
116
117TEST(RtpPacketTest, CreateMinimum) {
118 RtpPacketToSend packet(nullptr);
119 packet.SetPayloadType(kPayloadType);
120 packet.SetSequenceNumber(kSeqNum);
121 packet.SetTimestamp(kTimestamp);
122 packet.SetSsrc(kSsrc);
123 EXPECT_THAT(kMinimumPacket, ElementsAreArray(packet.data(), packet.size()));
124}
125
126TEST(RtpPacketTest, CreateWithExtension) {
127 RtpPacketToSend::ExtensionManager extensions;
128 extensions.Register(kRtpExtensionTransmissionTimeOffset,
129 kTransmissionOffsetExtensionId);
130 RtpPacketToSend packet(&extensions);
131 packet.SetPayloadType(kPayloadType);
132 packet.SetSequenceNumber(kSeqNum);
133 packet.SetTimestamp(kTimestamp);
134 packet.SetSsrc(kSsrc);
135 packet.SetExtension<TransmissionOffset>(kTimeOffset);
136 EXPECT_THAT(kPacketWithTO, ElementsAreArray(packet.data(), packet.size()));
137}
138
139TEST(RtpPacketTest, CreateWith2Extensions) {
140 RtpPacketToSend::ExtensionManager extensions;
141 extensions.Register(kRtpExtensionTransmissionTimeOffset,
142 kTransmissionOffsetExtensionId);
143 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
144 RtpPacketToSend packet(&extensions);
145 packet.SetPayloadType(kPayloadType);
146 packet.SetSequenceNumber(kSeqNum);
147 packet.SetTimestamp(kTimestamp);
148 packet.SetSsrc(kSsrc);
149 packet.SetExtension<TransmissionOffset>(kTimeOffset);
150 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
151 EXPECT_THAT(kPacketWithTOAndAL,
152 ElementsAreArray(packet.data(), packet.size()));
153}
154
erikvargae6b16192017-05-11 02:36:32 -0700155TEST(RtpPacketTest, CreateWithDynamicSizedExtensions) {
156 RtpPacketToSend::ExtensionManager extensions;
157 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
158 RtpPacketToSend packet(&extensions);
159 packet.SetPayloadType(kPayloadType);
160 packet.SetSequenceNumber(kSeqNum);
161 packet.SetTimestamp(kTimestamp);
162 packet.SetSsrc(kSsrc);
163 packet.SetExtension<RtpStreamId>(kStreamId);
164 EXPECT_THAT(kPacketWithRsid, ElementsAreArray(packet.data(), packet.size()));
165}
166
167TEST(RtpPacketTest, TryToCreateWithEmptyRsid) {
168 RtpPacketToSend::ExtensionManager extensions;
169 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
170 RtpPacketToSend packet(&extensions);
171 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(""));
172}
173
174TEST(RtpPacketTest, TryToCreateWithLongRsid) {
175 RtpPacketToSend::ExtensionManager extensions;
176 constexpr char kLongStreamId[] = "LoooooooooongRsid";
177 ASSERT_EQ(strlen(kLongStreamId), 17u);
178 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
179 RtpPacketToSend packet(&extensions);
180 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kLongStreamId));
181}
182
Steve Antona3251dd2017-07-21 09:58:31 -0700183TEST(RtpPacketTest, TryToCreateWithEmptyMid) {
184 RtpPacketToSend::ExtensionManager extensions;
185 extensions.Register<RtpMid>(kRtpMidExtensionId);
186 RtpPacketToSend packet(&extensions);
187 EXPECT_FALSE(packet.SetExtension<RtpMid>(""));
188}
189
190TEST(RtpPacketTest, TryToCreateWithLongMid) {
191 RtpPacketToSend::ExtensionManager extensions;
192 constexpr char kLongMid[] = "LoooooooooonogMid";
193 ASSERT_EQ(strlen(kLongMid), 17u);
194 extensions.Register<RtpMid>(kRtpMidExtensionId);
195 RtpPacketToSend packet(&extensions);
196 EXPECT_FALSE(packet.SetExtension<RtpMid>(kLongMid));
197}
198
danilchap653063f2017-04-03 06:16:30 -0700199TEST(RtpPacketTest, CreateWithMaxSizeHeaderExtension) {
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200200 const std::string kValue = "123456789abcdef";
201 RtpPacket::ExtensionManager extensions;
202 extensions.Register<RtpMid>(1);
203 extensions.Register<RtpStreamId>(2);
danilchap653063f2017-04-03 06:16:30 -0700204
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200205 RtpPacket packet(&extensions);
206 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700207
208 packet.SetPayloadSize(42);
209 // Rewriting allocated extension is allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200210 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700211 // Adding another extension after payload is set is not allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200212 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700213
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200214 // Read packet with the extension.
215 RtpPacketReceived parsed(&extensions);
danilchap653063f2017-04-03 06:16:30 -0700216 EXPECT_TRUE(parsed.Parse(packet.Buffer()));
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200217 std::string read;
218 EXPECT_TRUE(parsed.GetExtension<RtpMid>(&read));
219 EXPECT_EQ(read, kValue);
danilchap653063f2017-04-03 06:16:30 -0700220}
221
danilchap1edb7ab2016-04-20 05:25:10 -0700222TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
223 const size_t kPayloadSize = 4;
224 RtpPacketToSend::ExtensionManager extensions;
225 extensions.Register(kRtpExtensionTransmissionTimeOffset,
226 kTransmissionOffsetExtensionId);
227 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
228 RtpPacketToSend packet(&extensions);
229
230 EXPECT_TRUE(packet.ReserveExtension<TransmissionOffset>());
danilchap07a01b32017-03-29 07:33:13 -0700231 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700232 // Can't set extension after payload.
233 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
234 // Unless reserved.
235 EXPECT_TRUE(packet.SetExtension<TransmissionOffset>(kTimeOffset));
236}
237
238TEST(RtpPacketTest, CreatePurePadding) {
239 const size_t kPaddingSize = kMaxPaddingSize - 1;
240 RtpPacketToSend packet(nullptr, 12 + kPaddingSize);
241 packet.SetPayloadType(kPayloadType);
242 packet.SetSequenceNumber(kSeqNum);
243 packet.SetTimestamp(kTimestamp);
244 packet.SetSsrc(kSsrc);
245 Random random(0x123456789);
246
247 EXPECT_LT(packet.size(), packet.capacity());
248 EXPECT_FALSE(packet.SetPadding(kPaddingSize + 1, &random));
249 EXPECT_TRUE(packet.SetPadding(kPaddingSize, &random));
250 EXPECT_EQ(packet.size(), packet.capacity());
251}
252
253TEST(RtpPacketTest, CreateUnalignedPadding) {
254 const size_t kPayloadSize = 3; // Make padding start at unaligned address.
255 RtpPacketToSend packet(nullptr, 12 + kPayloadSize + kMaxPaddingSize);
256 packet.SetPayloadType(kPayloadType);
257 packet.SetSequenceNumber(kSeqNum);
258 packet.SetTimestamp(kTimestamp);
259 packet.SetSsrc(kSsrc);
danilchap07a01b32017-03-29 07:33:13 -0700260 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700261 Random r(0x123456789);
262
263 EXPECT_LT(packet.size(), packet.capacity());
264 EXPECT_TRUE(packet.SetPadding(kMaxPaddingSize, &r));
265 EXPECT_EQ(packet.size(), packet.capacity());
266}
267
268TEST(RtpPacketTest, ParseMinimum) {
269 RtpPacketReceived packet;
270 EXPECT_TRUE(packet.Parse(kMinimumPacket, sizeof(kMinimumPacket)));
271 EXPECT_EQ(kPayloadType, packet.PayloadType());
272 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
273 EXPECT_EQ(kTimestamp, packet.Timestamp());
274 EXPECT_EQ(kSsrc, packet.Ssrc());
275 EXPECT_EQ(0u, packet.padding_size());
276 EXPECT_EQ(0u, packet.payload_size());
277}
278
279TEST(RtpPacketTest, ParseBuffer) {
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200280 rtc::CopyOnWriteBuffer unparsed(kMinimumPacket);
danilchap1edb7ab2016-04-20 05:25:10 -0700281 const uint8_t* raw = unparsed.data();
282
283 RtpPacketReceived packet;
284 EXPECT_TRUE(packet.Parse(std::move(unparsed)));
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200285 EXPECT_EQ(raw, packet.data()); // Expect packet take the buffer without copy.
danilchap1edb7ab2016-04-20 05:25:10 -0700286 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
287 EXPECT_EQ(kTimestamp, packet.Timestamp());
288 EXPECT_EQ(kSsrc, packet.Ssrc());
289 EXPECT_EQ(0u, packet.padding_size());
290 EXPECT_EQ(0u, packet.payload_size());
291}
292
293TEST(RtpPacketTest, ParseWithExtension) {
294 RtpPacketToSend::ExtensionManager extensions;
295 extensions.Register(kRtpExtensionTransmissionTimeOffset,
296 kTransmissionOffsetExtensionId);
297
298 RtpPacketReceived packet(&extensions);
299 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
300 EXPECT_EQ(kPayloadType, packet.PayloadType());
301 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
302 EXPECT_EQ(kTimestamp, packet.Timestamp());
303 EXPECT_EQ(kSsrc, packet.Ssrc());
304 int32_t time_offset;
305 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
306 EXPECT_EQ(kTimeOffset, time_offset);
307 EXPECT_EQ(0u, packet.payload_size());
308 EXPECT_EQ(0u, packet.padding_size());
309}
310
danilchap07ec26d2016-06-17 04:18:54 -0700311TEST(RtpPacketTest, ParseWithInvalidSizedExtension) {
312 RtpPacketToSend::ExtensionManager extensions;
313 extensions.Register(kRtpExtensionTransmissionTimeOffset,
314 kTransmissionOffsetExtensionId);
315
316 RtpPacketReceived packet(&extensions);
317 EXPECT_TRUE(packet.Parse(kPacketWithInvalidExtension,
318 sizeof(kPacketWithInvalidExtension)));
319
320 // Extension should be ignored.
321 int32_t time_offset;
322 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
323
324 // But shouldn't prevent reading payload.
danilchap96c15872016-11-21 01:35:29 -0800325 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap07ec26d2016-06-17 04:18:54 -0700326}
327
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200328TEST(RtpPacketTest, ParseWithOverSizedExtension) {
329 // clang-format off
330 const uint8_t bad_packet[] = {
eladalonae550e32017-05-24 08:28:13 -0700331 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200332 0x65, 0x43, 0x12, 0x78, // kTimestamp.
333 0x12, 0x34, 0x56, 0x78, // kSsrc.
334 0xbe, 0xde, 0x00, 0x01, // Extension of size 1x32bit word.
335 0x00, // Add a byte of padding.
336 0x12, // Extension id 1 size (2+1).
337 0xda, 0x1a // Only 2 bytes of extension payload.
338 };
339 // clang-format on
340 RtpPacketToSend::ExtensionManager extensions;
341 extensions.Register(TransmissionOffset::kId, 1);
342 RtpPacketReceived packet(&extensions);
343
344 // Parse should ignore bad extension and proceed.
345 EXPECT_TRUE(packet.Parse(bad_packet, sizeof(bad_packet)));
346 int32_t time_offset;
347 // But extracting extension should fail.
348 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
349}
350
danilchap1edb7ab2016-04-20 05:25:10 -0700351TEST(RtpPacketTest, ParseWith2Extensions) {
352 RtpPacketToSend::ExtensionManager extensions;
353 extensions.Register(kRtpExtensionTransmissionTimeOffset,
354 kTransmissionOffsetExtensionId);
355 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
356 RtpPacketReceived packet(&extensions);
357 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
358 int32_t time_offset;
359 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
360 EXPECT_EQ(kTimeOffset, time_offset);
361 bool voice_active;
362 uint8_t audio_level;
363 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
364 EXPECT_EQ(kVoiceActive, voice_active);
365 EXPECT_EQ(kAudioLevel, audio_level);
366}
367
368TEST(RtpPacketTest, ParseWithAllFeatures) {
369 RtpPacketToSend::ExtensionManager extensions;
370 extensions.Register(kRtpExtensionTransmissionTimeOffset,
371 kTransmissionOffsetExtensionId);
372 RtpPacketReceived packet(&extensions);
373 EXPECT_TRUE(packet.Parse(kPacket, sizeof(kPacket)));
374 EXPECT_EQ(kPayloadType, packet.PayloadType());
375 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
376 EXPECT_EQ(kTimestamp, packet.Timestamp());
377 EXPECT_EQ(kSsrc, packet.Ssrc());
378 EXPECT_THAT(packet.Csrcs(), ElementsAreArray(kCsrcs));
danilchap96c15872016-11-21 01:35:29 -0800379 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap1edb7ab2016-04-20 05:25:10 -0700380 EXPECT_EQ(kPacketPaddingSize, packet.padding_size());
381 int32_t time_offset;
382 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
383}
384
385TEST(RtpPacketTest, ParseWithExtensionDelayed) {
386 RtpPacketReceived packet;
387 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
388 EXPECT_EQ(kPayloadType, packet.PayloadType());
389 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
390 EXPECT_EQ(kTimestamp, packet.Timestamp());
391 EXPECT_EQ(kSsrc, packet.Ssrc());
392
393 RtpPacketToSend::ExtensionManager extensions;
394 extensions.Register(kRtpExtensionTransmissionTimeOffset,
395 kTransmissionOffsetExtensionId);
396
397 int32_t time_offset;
398 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
danilchap70f39a32016-12-16 05:48:18 -0800399 packet.IdentifyExtensions(extensions);
danilchap1edb7ab2016-04-20 05:25:10 -0700400 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
401 EXPECT_EQ(kTimeOffset, time_offset);
402 EXPECT_EQ(0u, packet.payload_size());
403 EXPECT_EQ(0u, packet.padding_size());
404}
405
danilchapef8d7732017-04-19 02:59:48 -0700406TEST(RtpPacketTest, ParseDynamicSizeExtension) {
407 // clang-format off
408 const uint8_t kPacket1[] = {
eladalonae550e32017-05-24 08:28:13 -0700409 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700410 0x65, 0x43, 0x12, 0x78, // Timestamp.
411 0x12, 0x34, 0x56, 0x78, // Ssrc.
412 0xbe, 0xde, 0x00, 0x02, // Extensions block of size 2x32bit words.
413 0x21, 'H', 'D', // Extension with id = 2, size = (1+1).
414 0x12, 'r', 't', 'x', // Extension with id = 1, size = (2+1).
415 0x00}; // Extension padding.
416 const uint8_t kPacket2[] = {
eladalonae550e32017-05-24 08:28:13 -0700417 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700418 0x65, 0x43, 0x12, 0x78, // Timestamp.
419 0x12, 0x34, 0x56, 0x79, // Ssrc.
420 0xbe, 0xde, 0x00, 0x01, // Extensions block of size 1x32bit words.
421 0x11, 'H', 'D', // Extension with id = 1, size = (1+1).
422 0x00}; // Extension padding.
423 // clang-format on
424 RtpPacketReceived::ExtensionManager extensions;
425 extensions.Register<RtpStreamId>(1);
426 extensions.Register<RepairedRtpStreamId>(2);
427 RtpPacketReceived packet(&extensions);
428 ASSERT_TRUE(packet.Parse(kPacket1, sizeof(kPacket1)));
429
430 std::string rsid;
431 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
432 EXPECT_EQ(rsid, "rtx");
433
434 std::string repaired_rsid;
435 EXPECT_TRUE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
436 EXPECT_EQ(repaired_rsid, "HD");
437
438 // Parse another packet with RtpStreamId extension of different size.
439 ASSERT_TRUE(packet.Parse(kPacket2, sizeof(kPacket2)));
440 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
441 EXPECT_EQ(rsid, "HD");
442 EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
443}
444
Steve Antona3251dd2017-07-21 09:58:31 -0700445TEST(RtpPacketTest, ParseWithMid) {
446 RtpPacketReceived::ExtensionManager extensions;
447 extensions.Register<RtpMid>(kRtpMidExtensionId);
448 RtpPacketReceived packet(&extensions);
449 ASSERT_TRUE(packet.Parse(kPacketWithMid, sizeof(kPacketWithMid)));
450
451 std::string mid;
452 EXPECT_TRUE(packet.GetExtension<RtpMid>(&mid));
453 EXPECT_EQ(mid, kMid);
454}
455
sprangba050a62017-08-18 02:51:12 -0700456TEST(RtpPacketTest, CreateAndParseTimingFrameExtension) {
457 // Create a packet with video frame timing extension populated.
458 RtpPacketToSend::ExtensionManager send_extensions;
459 send_extensions.Register(kRtpExtensionVideoTiming, kVideoTimingExtensionId);
460 RtpPacketToSend send_packet(&send_extensions);
461 send_packet.SetPayloadType(kPayloadType);
462 send_packet.SetSequenceNumber(kSeqNum);
463 send_packet.SetTimestamp(kTimestamp);
464 send_packet.SetSsrc(kSsrc);
465
466 VideoSendTiming timing;
467 timing.encode_start_delta_ms = 1;
468 timing.encode_finish_delta_ms = 2;
469 timing.packetization_finish_delta_ms = 3;
470 timing.pacer_exit_delta_ms = 4;
471 timing.flags =
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +0200472 VideoSendTiming::kTriggeredByTimer | VideoSendTiming::kTriggeredBySize;
sprangba050a62017-08-18 02:51:12 -0700473
474 send_packet.SetExtension<VideoTimingExtension>(timing);
475
476 // Serialize the packet and then parse it again.
477 RtpPacketReceived::ExtensionManager extensions;
478 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
479 RtpPacketReceived receive_packet(&extensions);
480 EXPECT_TRUE(receive_packet.Parse(send_packet.Buffer()));
481
482 VideoSendTiming receivied_timing;
483 EXPECT_TRUE(
484 receive_packet.GetExtension<VideoTimingExtension>(&receivied_timing));
485
486 // Only check first and last timestamp (covered by other tests) plus flags.
487 EXPECT_EQ(receivied_timing.encode_start_delta_ms,
488 timing.encode_start_delta_ms);
489 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, timing.pacer_exit_delta_ms);
490 EXPECT_EQ(receivied_timing.flags, timing.flags);
491}
492
493TEST(RtpPacketTest, ParseLegacyTimingFrameExtension) {
494 // Parse the modified packet.
495 RtpPacketReceived::ExtensionManager extensions;
496 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
497 RtpPacketReceived packet(&extensions);
498 EXPECT_TRUE(packet.Parse(kPacketWithLegacyTimingExtension,
499 sizeof(kPacketWithLegacyTimingExtension)));
500 VideoSendTiming receivied_timing;
501 EXPECT_TRUE(packet.GetExtension<VideoTimingExtension>(&receivied_timing));
502
503 // Check first and last timestamp are still OK. Flags should now be 0.
504 EXPECT_EQ(receivied_timing.encode_start_delta_ms, 1);
505 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, 4);
506 EXPECT_EQ(receivied_timing.flags, 0);
507}
508
danilchap1edb7ab2016-04-20 05:25:10 -0700509} // namespace webrtc