blob: 67a13dc0fc43cf7909e7d492125c72967ad205c9 [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;
Johannes Kron07ba2b92018-09-26 13:33:35 +020036constexpr uint8_t kTwoByteExtensionId = 0xf0;
danilchap1edb7ab2016-04-20 05:25:10 -070037constexpr int32_t kTimeOffset = 0x56ce;
38constexpr bool kVoiceActive = true;
39constexpr uint8_t kAudioLevel = 0x5a;
erikvargae6b16192017-05-11 02:36:32 -070040constexpr char kStreamId[] = "streamid";
Steve Antona3251dd2017-07-21 09:58:31 -070041constexpr char kMid[] = "mid";
Johannes Kron07ba2b92018-09-26 13:33:35 +020042constexpr char kLongMid[] = "extra-long string to test two-byte header";
danilchap1edb7ab2016-04-20 05:25:10 -070043constexpr size_t kMaxPaddingSize = 224u;
danilchap07ec26d2016-06-17 04:18:54 -070044// clang-format off
danilchap1edb7ab2016-04-20 05:25:10 -070045constexpr uint8_t kMinimumPacket[] = {
eladalonae550e32017-05-24 08:28:13 -070046 0x80, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070047 0x65, 0x43, 0x12, 0x78,
48 0x12, 0x34, 0x56, 0x78};
erikvargae6b16192017-05-11 02:36:32 -070049
danilchap1edb7ab2016-04-20 05:25:10 -070050constexpr uint8_t kPacketWithTO[] = {
eladalonae550e32017-05-24 08:28:13 -070051 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070052 0x65, 0x43, 0x12, 0x78,
53 0x12, 0x34, 0x56, 0x78,
54 0xbe, 0xde, 0x00, 0x01,
55 0x12, 0x00, 0x56, 0xce};
56
57constexpr uint8_t kPacketWithTOAndAL[] = {
eladalonae550e32017-05-24 08:28:13 -070058 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070059 0x65, 0x43, 0x12, 0x78,
60 0x12, 0x34, 0x56, 0x78,
61 0xbe, 0xde, 0x00, 0x02,
62 0x12, 0x00, 0x56, 0xce,
63 0x90, 0x80|kAudioLevel, 0x00, 0x00};
64
Johannes Kron07ba2b92018-09-26 13:33:35 +020065constexpr uint8_t kPacketWithTOAndALInvalidPadding[] = {
66 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
67 0x65, 0x43, 0x12, 0x78,
68 0x12, 0x34, 0x56, 0x78,
69 0xbe, 0xde, 0x00, 0x03,
70 0x12, 0x00, 0x56, 0xce,
71 0x00, 0x02, 0x00, 0x00, // 0x02 is invalid padding, parsing should stop.
72 0x90, 0x80|kAudioLevel, 0x00, 0x00};
73
74constexpr uint8_t kPacketWithTOAndALReservedExtensionId[] = {
75 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
76 0x65, 0x43, 0x12, 0x78,
77 0x12, 0x34, 0x56, 0x78,
78 0xbe, 0xde, 0x00, 0x03,
79 0x12, 0x00, 0x56, 0xce,
80 0x00, 0xF0, 0x00, 0x00, // F is a reserved id, parsing should stop.
81 0x90, 0x80|kAudioLevel, 0x00, 0x00};
82
erikvargae6b16192017-05-11 02:36:32 -070083constexpr uint8_t kPacketWithRsid[] = {
eladalonae550e32017-05-24 08:28:13 -070084 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
erikvargae6b16192017-05-11 02:36:32 -070085 0x65, 0x43, 0x12, 0x78,
86 0x12, 0x34, 0x56, 0x78,
87 0xbe, 0xde, 0x00, 0x03,
88 0xa7, 's', 't', 'r',
89 'e', 'a', 'm', 'i',
90 'd' , 0x00, 0x00, 0x00};
91
Steve Antona3251dd2017-07-21 09:58:31 -070092constexpr uint8_t kPacketWithMid[] = {
93 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
94 0x65, 0x43, 0x12, 0x78,
95 0x12, 0x34, 0x56, 0x78,
96 0xbe, 0xde, 0x00, 0x01,
97 0xb2, 'm', 'i', 'd'};
98
danilchap1edb7ab2016-04-20 05:25:10 -070099constexpr uint32_t kCsrcs[] = {0x34567890, 0x32435465};
100constexpr uint8_t kPayload[] = {'p', 'a', 'y', 'l', 'o', 'a', 'd'};
101constexpr uint8_t kPacketPaddingSize = 8;
102constexpr uint8_t kPacket[] = {
eladalonae550e32017-05-24 08:28:13 -0700103 0xb2, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -0700104 0x65, 0x43, 0x12, 0x78,
105 0x12, 0x34, 0x56, 0x78,
106 0x34, 0x56, 0x78, 0x90,
107 0x32, 0x43, 0x54, 0x65,
108 0xbe, 0xde, 0x00, 0x01,
109 0x12, 0x00, 0x56, 0xce,
110 'p', 'a', 'y', 'l', 'o', 'a', 'd',
111 'p', 'a', 'd', 'd', 'i', 'n', 'g', kPacketPaddingSize};
danilchape565a042016-06-16 10:04:50 -0700112
Johannes Kron07ba2b92018-09-26 13:33:35 +0200113constexpr uint8_t kPacketWithTwoByteHeaderExtension[] = {
114 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
115 0x65, 0x43, 0x12, 0x78,
116 0x12, 0x34, 0x56, 0x78,
117 0x10, 0x00, 0x00, 0x02, // Two-byte header extension profile id + length.
118 kTwoByteExtensionId, 0x03, 0x00, 0x56,
119 0xce, 0x00, 0x00, 0x00};
120
121constexpr uint8_t kPacketWithLongTwoByteHeaderExtension[] = {
122 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
123 0x65, 0x43, 0x12, 0x78,
124 0x12, 0x34, 0x56, 0x78,
125 0x10, 0x00, 0x00, 0x0B, // Two-byte header extension profile id + length.
126 kTwoByteExtensionId, 0x29, 'e', 'x',
127 't', 'r', 'a', '-', 'l', 'o', 'n', 'g',
128 ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
129 't', 'o', ' ', 't', 'e', 's', 't', ' ',
130 't', 'w', 'o', '-', 'b', 'y', 't', 'e',
131 ' ', 'h', 'e', 'a', 'd', 'e', 'r', 0x00};
132
133constexpr uint8_t kPacketWithTwoByteHeaderExtensionWithPadding[] = {
134 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
135 0x65, 0x43, 0x12, 0x78,
136 0x12, 0x34, 0x56, 0x78,
137 0x10, 0x00, 0x00, 0x03, // Two-byte header extension profile id + length.
138 kTwoByteExtensionId, 0x03, 0x00, 0x56,
139 0xce, 0x00, 0x00, 0x00, // Three padding bytes.
140 kAudioLevelExtensionId, 0x01, 0x80|kAudioLevel, 0x00};
141
danilchap07ec26d2016-06-17 04:18:54 -0700142constexpr uint8_t kPacketWithInvalidExtension[] = {
eladalonae550e32017-05-24 08:28:13 -0700143 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap07ec26d2016-06-17 04:18:54 -0700144 0x65, 0x43, 0x12, 0x78, // kTimestamp.
145 0x12, 0x34, 0x56, 0x78, // kSSrc.
146 0xbe, 0xde, 0x00, 0x02, // Extension block of size 2 x 32bit words.
147 (kTransmissionOffsetExtensionId << 4) | 6, // (6+1)-byte extension, but
148 'e', 'x', 't', // Transmission Offset
149 'd', 'a', 't', 'a', // expected to be 3-bytes.
sprangba050a62017-08-18 02:51:12 -0700150 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
151
152constexpr uint8_t kPacketWithLegacyTimingExtension[] = {
153 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
154 0x65, 0x43, 0x12, 0x78, // kTimestamp.
155 0x12, 0x34, 0x56, 0x78, // kSSrc.
156 0xbe, 0xde, 0x00, 0x04, // Extension block of size 4 x 32bit words.
157 (kVideoTimingExtensionId << 4)
158 | VideoTimingExtension::kValueSizeBytes - 2, // Old format without flags.
159 0x00, 0x01, 0x00,
160 0x02, 0x00, 0x03, 0x00,
161 0x04, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00};
danilchap07ec26d2016-06-17 04:18:54 -0700163// clang-format on
danilchap1edb7ab2016-04-20 05:25:10 -0700164} // namespace
165
166TEST(RtpPacketTest, CreateMinimum) {
167 RtpPacketToSend packet(nullptr);
168 packet.SetPayloadType(kPayloadType);
169 packet.SetSequenceNumber(kSeqNum);
170 packet.SetTimestamp(kTimestamp);
171 packet.SetSsrc(kSsrc);
172 EXPECT_THAT(kMinimumPacket, ElementsAreArray(packet.data(), packet.size()));
173}
174
175TEST(RtpPacketTest, CreateWithExtension) {
176 RtpPacketToSend::ExtensionManager extensions;
177 extensions.Register(kRtpExtensionTransmissionTimeOffset,
178 kTransmissionOffsetExtensionId);
179 RtpPacketToSend packet(&extensions);
180 packet.SetPayloadType(kPayloadType);
181 packet.SetSequenceNumber(kSeqNum);
182 packet.SetTimestamp(kTimestamp);
183 packet.SetSsrc(kSsrc);
184 packet.SetExtension<TransmissionOffset>(kTimeOffset);
185 EXPECT_THAT(kPacketWithTO, ElementsAreArray(packet.data(), packet.size()));
186}
187
188TEST(RtpPacketTest, CreateWith2Extensions) {
189 RtpPacketToSend::ExtensionManager extensions;
190 extensions.Register(kRtpExtensionTransmissionTimeOffset,
191 kTransmissionOffsetExtensionId);
192 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
193 RtpPacketToSend packet(&extensions);
194 packet.SetPayloadType(kPayloadType);
195 packet.SetSequenceNumber(kSeqNum);
196 packet.SetTimestamp(kTimestamp);
197 packet.SetSsrc(kSsrc);
198 packet.SetExtension<TransmissionOffset>(kTimeOffset);
199 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
200 EXPECT_THAT(kPacketWithTOAndAL,
201 ElementsAreArray(packet.data(), packet.size()));
202}
203
erikvargae6b16192017-05-11 02:36:32 -0700204TEST(RtpPacketTest, CreateWithDynamicSizedExtensions) {
205 RtpPacketToSend::ExtensionManager extensions;
206 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
207 RtpPacketToSend packet(&extensions);
208 packet.SetPayloadType(kPayloadType);
209 packet.SetSequenceNumber(kSeqNum);
210 packet.SetTimestamp(kTimestamp);
211 packet.SetSsrc(kSsrc);
212 packet.SetExtension<RtpStreamId>(kStreamId);
213 EXPECT_THAT(kPacketWithRsid, ElementsAreArray(packet.data(), packet.size()));
214}
215
216TEST(RtpPacketTest, TryToCreateWithEmptyRsid) {
217 RtpPacketToSend::ExtensionManager extensions;
218 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
219 RtpPacketToSend packet(&extensions);
220 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(""));
221}
222
223TEST(RtpPacketTest, TryToCreateWithLongRsid) {
224 RtpPacketToSend::ExtensionManager extensions;
225 constexpr char kLongStreamId[] = "LoooooooooongRsid";
226 ASSERT_EQ(strlen(kLongStreamId), 17u);
227 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
228 RtpPacketToSend packet(&extensions);
229 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kLongStreamId));
230}
231
Steve Antona3251dd2017-07-21 09:58:31 -0700232TEST(RtpPacketTest, TryToCreateWithEmptyMid) {
233 RtpPacketToSend::ExtensionManager extensions;
234 extensions.Register<RtpMid>(kRtpMidExtensionId);
235 RtpPacketToSend packet(&extensions);
236 EXPECT_FALSE(packet.SetExtension<RtpMid>(""));
237}
238
239TEST(RtpPacketTest, TryToCreateWithLongMid) {
240 RtpPacketToSend::ExtensionManager extensions;
241 constexpr char kLongMid[] = "LoooooooooonogMid";
242 ASSERT_EQ(strlen(kLongMid), 17u);
243 extensions.Register<RtpMid>(kRtpMidExtensionId);
244 RtpPacketToSend packet(&extensions);
245 EXPECT_FALSE(packet.SetExtension<RtpMid>(kLongMid));
246}
247
danilchap653063f2017-04-03 06:16:30 -0700248TEST(RtpPacketTest, CreateWithMaxSizeHeaderExtension) {
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200249 const std::string kValue = "123456789abcdef";
250 RtpPacket::ExtensionManager extensions;
251 extensions.Register<RtpMid>(1);
252 extensions.Register<RtpStreamId>(2);
danilchap653063f2017-04-03 06:16:30 -0700253
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200254 RtpPacket packet(&extensions);
255 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700256
257 packet.SetPayloadSize(42);
258 // Rewriting allocated extension is allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200259 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700260 // Adding another extension after payload is set is not allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200261 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700262
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200263 // Read packet with the extension.
264 RtpPacketReceived parsed(&extensions);
danilchap653063f2017-04-03 06:16:30 -0700265 EXPECT_TRUE(parsed.Parse(packet.Buffer()));
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200266 std::string read;
267 EXPECT_TRUE(parsed.GetExtension<RtpMid>(&read));
268 EXPECT_EQ(read, kValue);
danilchap653063f2017-04-03 06:16:30 -0700269}
270
danilchap1edb7ab2016-04-20 05:25:10 -0700271TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
272 const size_t kPayloadSize = 4;
273 RtpPacketToSend::ExtensionManager extensions;
274 extensions.Register(kRtpExtensionTransmissionTimeOffset,
275 kTransmissionOffsetExtensionId);
276 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
277 RtpPacketToSend packet(&extensions);
278
279 EXPECT_TRUE(packet.ReserveExtension<TransmissionOffset>());
danilchap07a01b32017-03-29 07:33:13 -0700280 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700281 // Can't set extension after payload.
282 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
283 // Unless reserved.
284 EXPECT_TRUE(packet.SetExtension<TransmissionOffset>(kTimeOffset));
285}
286
287TEST(RtpPacketTest, CreatePurePadding) {
288 const size_t kPaddingSize = kMaxPaddingSize - 1;
289 RtpPacketToSend packet(nullptr, 12 + kPaddingSize);
290 packet.SetPayloadType(kPayloadType);
291 packet.SetSequenceNumber(kSeqNum);
292 packet.SetTimestamp(kTimestamp);
293 packet.SetSsrc(kSsrc);
294 Random random(0x123456789);
295
296 EXPECT_LT(packet.size(), packet.capacity());
297 EXPECT_FALSE(packet.SetPadding(kPaddingSize + 1, &random));
298 EXPECT_TRUE(packet.SetPadding(kPaddingSize, &random));
299 EXPECT_EQ(packet.size(), packet.capacity());
300}
301
302TEST(RtpPacketTest, CreateUnalignedPadding) {
303 const size_t kPayloadSize = 3; // Make padding start at unaligned address.
304 RtpPacketToSend packet(nullptr, 12 + kPayloadSize + kMaxPaddingSize);
305 packet.SetPayloadType(kPayloadType);
306 packet.SetSequenceNumber(kSeqNum);
307 packet.SetTimestamp(kTimestamp);
308 packet.SetSsrc(kSsrc);
danilchap07a01b32017-03-29 07:33:13 -0700309 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700310 Random r(0x123456789);
311
312 EXPECT_LT(packet.size(), packet.capacity());
313 EXPECT_TRUE(packet.SetPadding(kMaxPaddingSize, &r));
314 EXPECT_EQ(packet.size(), packet.capacity());
315}
316
317TEST(RtpPacketTest, ParseMinimum) {
318 RtpPacketReceived packet;
319 EXPECT_TRUE(packet.Parse(kMinimumPacket, sizeof(kMinimumPacket)));
320 EXPECT_EQ(kPayloadType, packet.PayloadType());
321 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
322 EXPECT_EQ(kTimestamp, packet.Timestamp());
323 EXPECT_EQ(kSsrc, packet.Ssrc());
324 EXPECT_EQ(0u, packet.padding_size());
325 EXPECT_EQ(0u, packet.payload_size());
326}
327
328TEST(RtpPacketTest, ParseBuffer) {
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200329 rtc::CopyOnWriteBuffer unparsed(kMinimumPacket);
danilchap1edb7ab2016-04-20 05:25:10 -0700330 const uint8_t* raw = unparsed.data();
331
332 RtpPacketReceived packet;
333 EXPECT_TRUE(packet.Parse(std::move(unparsed)));
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200334 EXPECT_EQ(raw, packet.data()); // Expect packet take the buffer without copy.
danilchap1edb7ab2016-04-20 05:25:10 -0700335 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
336 EXPECT_EQ(kTimestamp, packet.Timestamp());
337 EXPECT_EQ(kSsrc, packet.Ssrc());
338 EXPECT_EQ(0u, packet.padding_size());
339 EXPECT_EQ(0u, packet.payload_size());
340}
341
342TEST(RtpPacketTest, ParseWithExtension) {
343 RtpPacketToSend::ExtensionManager extensions;
344 extensions.Register(kRtpExtensionTransmissionTimeOffset,
345 kTransmissionOffsetExtensionId);
346
347 RtpPacketReceived packet(&extensions);
348 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
349 EXPECT_EQ(kPayloadType, packet.PayloadType());
350 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
351 EXPECT_EQ(kTimestamp, packet.Timestamp());
352 EXPECT_EQ(kSsrc, packet.Ssrc());
353 int32_t time_offset;
354 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
355 EXPECT_EQ(kTimeOffset, time_offset);
356 EXPECT_EQ(0u, packet.payload_size());
357 EXPECT_EQ(0u, packet.padding_size());
358}
359
danilchap07ec26d2016-06-17 04:18:54 -0700360TEST(RtpPacketTest, ParseWithInvalidSizedExtension) {
361 RtpPacketToSend::ExtensionManager extensions;
362 extensions.Register(kRtpExtensionTransmissionTimeOffset,
363 kTransmissionOffsetExtensionId);
364
365 RtpPacketReceived packet(&extensions);
366 EXPECT_TRUE(packet.Parse(kPacketWithInvalidExtension,
367 sizeof(kPacketWithInvalidExtension)));
368
369 // Extension should be ignored.
370 int32_t time_offset;
371 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
372
373 // But shouldn't prevent reading payload.
danilchap96c15872016-11-21 01:35:29 -0800374 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap07ec26d2016-06-17 04:18:54 -0700375}
376
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200377TEST(RtpPacketTest, ParseWithOverSizedExtension) {
378 // clang-format off
379 const uint8_t bad_packet[] = {
eladalonae550e32017-05-24 08:28:13 -0700380 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200381 0x65, 0x43, 0x12, 0x78, // kTimestamp.
382 0x12, 0x34, 0x56, 0x78, // kSsrc.
383 0xbe, 0xde, 0x00, 0x01, // Extension of size 1x32bit word.
384 0x00, // Add a byte of padding.
385 0x12, // Extension id 1 size (2+1).
386 0xda, 0x1a // Only 2 bytes of extension payload.
387 };
388 // clang-format on
389 RtpPacketToSend::ExtensionManager extensions;
390 extensions.Register(TransmissionOffset::kId, 1);
391 RtpPacketReceived packet(&extensions);
392
393 // Parse should ignore bad extension and proceed.
394 EXPECT_TRUE(packet.Parse(bad_packet, sizeof(bad_packet)));
395 int32_t time_offset;
396 // But extracting extension should fail.
397 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
398}
399
danilchap1edb7ab2016-04-20 05:25:10 -0700400TEST(RtpPacketTest, ParseWith2Extensions) {
401 RtpPacketToSend::ExtensionManager extensions;
402 extensions.Register(kRtpExtensionTransmissionTimeOffset,
403 kTransmissionOffsetExtensionId);
404 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
405 RtpPacketReceived packet(&extensions);
406 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
407 int32_t time_offset;
408 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
409 EXPECT_EQ(kTimeOffset, time_offset);
410 bool voice_active;
411 uint8_t audio_level;
412 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
413 EXPECT_EQ(kVoiceActive, voice_active);
414 EXPECT_EQ(kAudioLevel, audio_level);
415}
416
Johannes Kron6ea77192018-09-24 17:19:52 +0200417TEST(RtpPacketTest, ParseSecondPacketWithFewerExtensions) {
418 RtpPacketToSend::ExtensionManager extensions;
419 extensions.Register(kRtpExtensionTransmissionTimeOffset,
420 kTransmissionOffsetExtensionId);
421 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
422 RtpPacketReceived packet(&extensions);
423 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
424 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
425 EXPECT_TRUE(packet.HasExtension<AudioLevel>());
426
427 // Second packet without audio level.
428 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
429 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
430 EXPECT_FALSE(packet.HasExtension<AudioLevel>());
431}
432
Johannes Kron07ba2b92018-09-26 13:33:35 +0200433TEST(RtpPacketTest, ParseWith2ExtensionsInvalidPadding) {
434 RtpPacketToSend::ExtensionManager extensions;
435 extensions.Register(kRtpExtensionTransmissionTimeOffset,
436 kTransmissionOffsetExtensionId);
437 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
438 RtpPacketReceived packet(&extensions);
439 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALInvalidPadding,
440 sizeof(kPacketWithTOAndALInvalidPadding)));
441 int32_t time_offset;
442 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
443 EXPECT_EQ(kTimeOffset, time_offset);
444 bool voice_active;
445 uint8_t audio_level;
446 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
447}
448
449TEST(RtpPacketTest, ParseWith2ExtensionsReservedExtensionId) {
450 RtpPacketToSend::ExtensionManager extensions;
451 extensions.Register(kRtpExtensionTransmissionTimeOffset,
452 kTransmissionOffsetExtensionId);
453 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
454 RtpPacketReceived packet(&extensions);
455 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALReservedExtensionId,
456 sizeof(kPacketWithTOAndALReservedExtensionId)));
457 int32_t time_offset;
458 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
459 EXPECT_EQ(kTimeOffset, time_offset);
460 bool voice_active;
461 uint8_t audio_level;
462 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
463}
464
danilchap1edb7ab2016-04-20 05:25:10 -0700465TEST(RtpPacketTest, ParseWithAllFeatures) {
466 RtpPacketToSend::ExtensionManager extensions;
467 extensions.Register(kRtpExtensionTransmissionTimeOffset,
468 kTransmissionOffsetExtensionId);
469 RtpPacketReceived packet(&extensions);
470 EXPECT_TRUE(packet.Parse(kPacket, sizeof(kPacket)));
471 EXPECT_EQ(kPayloadType, packet.PayloadType());
472 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
473 EXPECT_EQ(kTimestamp, packet.Timestamp());
474 EXPECT_EQ(kSsrc, packet.Ssrc());
475 EXPECT_THAT(packet.Csrcs(), ElementsAreArray(kCsrcs));
danilchap96c15872016-11-21 01:35:29 -0800476 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap1edb7ab2016-04-20 05:25:10 -0700477 EXPECT_EQ(kPacketPaddingSize, packet.padding_size());
478 int32_t time_offset;
479 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
480}
481
Johannes Kron07ba2b92018-09-26 13:33:35 +0200482TEST(RtpPacketTest, ParseTwoByteHeaderExtension) {
483 RtpPacketToSend::ExtensionManager extensions;
484 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
485 RtpPacketReceived packet(&extensions);
486 EXPECT_TRUE(packet.Parse(kPacketWithTwoByteHeaderExtension,
487 sizeof(kPacketWithTwoByteHeaderExtension)));
488 int32_t time_offset;
489 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
490 EXPECT_EQ(kTimeOffset, time_offset);
491}
492
493TEST(RtpPacketTest, ParseLongTwoByteHeaderExtension) {
494 RtpPacketToSend::ExtensionManager extensions;
495 extensions.Register(kRtpExtensionMid, kTwoByteExtensionId);
496 RtpPacketReceived packet(&extensions);
497 EXPECT_TRUE(packet.Parse(kPacketWithLongTwoByteHeaderExtension,
498 sizeof(kPacketWithLongTwoByteHeaderExtension)));
499 std::string long_rtp_mid;
500 EXPECT_TRUE(packet.GetExtension<RtpMid>(&long_rtp_mid));
501 EXPECT_EQ(kLongMid, long_rtp_mid);
502}
503
504TEST(RtpPacketTest, ParseTwoByteHeaderExtensionWithPadding) {
505 RtpPacketToSend::ExtensionManager extensions;
506 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
507 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
508 RtpPacketReceived packet(&extensions);
509 EXPECT_TRUE(
510 packet.Parse(kPacketWithTwoByteHeaderExtensionWithPadding,
511 sizeof(kPacketWithTwoByteHeaderExtensionWithPadding)));
512 int32_t time_offset;
513 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
514 EXPECT_EQ(kTimeOffset, time_offset);
515 bool voice_active;
516 uint8_t audio_level;
517 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
518 EXPECT_EQ(kVoiceActive, voice_active);
519 EXPECT_EQ(kAudioLevel, audio_level);
520}
521
danilchap1edb7ab2016-04-20 05:25:10 -0700522TEST(RtpPacketTest, ParseWithExtensionDelayed) {
523 RtpPacketReceived packet;
524 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
525 EXPECT_EQ(kPayloadType, packet.PayloadType());
526 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
527 EXPECT_EQ(kTimestamp, packet.Timestamp());
528 EXPECT_EQ(kSsrc, packet.Ssrc());
529
530 RtpPacketToSend::ExtensionManager extensions;
531 extensions.Register(kRtpExtensionTransmissionTimeOffset,
532 kTransmissionOffsetExtensionId);
533
534 int32_t time_offset;
535 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
danilchap70f39a32016-12-16 05:48:18 -0800536 packet.IdentifyExtensions(extensions);
danilchap1edb7ab2016-04-20 05:25:10 -0700537 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
538 EXPECT_EQ(kTimeOffset, time_offset);
539 EXPECT_EQ(0u, packet.payload_size());
540 EXPECT_EQ(0u, packet.padding_size());
541}
542
danilchapef8d7732017-04-19 02:59:48 -0700543TEST(RtpPacketTest, ParseDynamicSizeExtension) {
544 // clang-format off
545 const uint8_t kPacket1[] = {
eladalonae550e32017-05-24 08:28:13 -0700546 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700547 0x65, 0x43, 0x12, 0x78, // Timestamp.
548 0x12, 0x34, 0x56, 0x78, // Ssrc.
549 0xbe, 0xde, 0x00, 0x02, // Extensions block of size 2x32bit words.
550 0x21, 'H', 'D', // Extension with id = 2, size = (1+1).
551 0x12, 'r', 't', 'x', // Extension with id = 1, size = (2+1).
552 0x00}; // Extension padding.
553 const uint8_t kPacket2[] = {
eladalonae550e32017-05-24 08:28:13 -0700554 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700555 0x65, 0x43, 0x12, 0x78, // Timestamp.
556 0x12, 0x34, 0x56, 0x79, // Ssrc.
557 0xbe, 0xde, 0x00, 0x01, // Extensions block of size 1x32bit words.
558 0x11, 'H', 'D', // Extension with id = 1, size = (1+1).
559 0x00}; // Extension padding.
560 // clang-format on
561 RtpPacketReceived::ExtensionManager extensions;
562 extensions.Register<RtpStreamId>(1);
563 extensions.Register<RepairedRtpStreamId>(2);
564 RtpPacketReceived packet(&extensions);
565 ASSERT_TRUE(packet.Parse(kPacket1, sizeof(kPacket1)));
566
567 std::string rsid;
568 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
569 EXPECT_EQ(rsid, "rtx");
570
571 std::string repaired_rsid;
572 EXPECT_TRUE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
573 EXPECT_EQ(repaired_rsid, "HD");
574
575 // Parse another packet with RtpStreamId extension of different size.
576 ASSERT_TRUE(packet.Parse(kPacket2, sizeof(kPacket2)));
577 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
578 EXPECT_EQ(rsid, "HD");
579 EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
580}
581
Steve Antona3251dd2017-07-21 09:58:31 -0700582TEST(RtpPacketTest, ParseWithMid) {
583 RtpPacketReceived::ExtensionManager extensions;
584 extensions.Register<RtpMid>(kRtpMidExtensionId);
585 RtpPacketReceived packet(&extensions);
586 ASSERT_TRUE(packet.Parse(kPacketWithMid, sizeof(kPacketWithMid)));
587
588 std::string mid;
589 EXPECT_TRUE(packet.GetExtension<RtpMid>(&mid));
590 EXPECT_EQ(mid, kMid);
591}
592
sprangba050a62017-08-18 02:51:12 -0700593TEST(RtpPacketTest, CreateAndParseTimingFrameExtension) {
594 // Create a packet with video frame timing extension populated.
595 RtpPacketToSend::ExtensionManager send_extensions;
596 send_extensions.Register(kRtpExtensionVideoTiming, kVideoTimingExtensionId);
597 RtpPacketToSend send_packet(&send_extensions);
598 send_packet.SetPayloadType(kPayloadType);
599 send_packet.SetSequenceNumber(kSeqNum);
600 send_packet.SetTimestamp(kTimestamp);
601 send_packet.SetSsrc(kSsrc);
602
603 VideoSendTiming timing;
604 timing.encode_start_delta_ms = 1;
605 timing.encode_finish_delta_ms = 2;
606 timing.packetization_finish_delta_ms = 3;
607 timing.pacer_exit_delta_ms = 4;
608 timing.flags =
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +0200609 VideoSendTiming::kTriggeredByTimer | VideoSendTiming::kTriggeredBySize;
sprangba050a62017-08-18 02:51:12 -0700610
611 send_packet.SetExtension<VideoTimingExtension>(timing);
612
613 // Serialize the packet and then parse it again.
614 RtpPacketReceived::ExtensionManager extensions;
615 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
616 RtpPacketReceived receive_packet(&extensions);
617 EXPECT_TRUE(receive_packet.Parse(send_packet.Buffer()));
618
619 VideoSendTiming receivied_timing;
620 EXPECT_TRUE(
621 receive_packet.GetExtension<VideoTimingExtension>(&receivied_timing));
622
623 // Only check first and last timestamp (covered by other tests) plus flags.
624 EXPECT_EQ(receivied_timing.encode_start_delta_ms,
625 timing.encode_start_delta_ms);
626 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, timing.pacer_exit_delta_ms);
627 EXPECT_EQ(receivied_timing.flags, timing.flags);
628}
629
630TEST(RtpPacketTest, ParseLegacyTimingFrameExtension) {
631 // Parse the modified packet.
632 RtpPacketReceived::ExtensionManager extensions;
633 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
634 RtpPacketReceived packet(&extensions);
635 EXPECT_TRUE(packet.Parse(kPacketWithLegacyTimingExtension,
636 sizeof(kPacketWithLegacyTimingExtension)));
637 VideoSendTiming receivied_timing;
638 EXPECT_TRUE(packet.GetExtension<VideoTimingExtension>(&receivied_timing));
639
640 // Check first and last timestamp are still OK. Flags should now be 0.
641 EXPECT_EQ(receivied_timing.encode_start_delta_ms, 1);
642 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, 4);
643 EXPECT_EQ(receivied_timing.flags, 0);
644}
645
danilchap1edb7ab2016-04-20 05:25:10 -0700646} // namespace webrtc