blob: 0fd500191f07cffcef657ad89e888a74412aca6f [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 {
Danil Chapovalove19953b2018-10-01 16:12:28 +020021
22using ::testing::ElementsAre;
danilchapc547e842017-04-10 01:31:49 -070023using ::testing::ElementsAreArray;
24using ::testing::IsEmpty;
25using ::testing::make_tuple;
26
danilchap1edb7ab2016-04-20 05:25:10 -070027constexpr int8_t kPayloadType = 100;
28constexpr uint32_t kSsrc = 0x12345678;
eladalonae550e32017-05-24 08:28:13 -070029constexpr uint16_t kSeqNum = 0x1234;
30constexpr uint8_t kSeqNumFirstByte = kSeqNum >> 8;
31constexpr uint8_t kSeqNumSecondByte = kSeqNum & 0xff;
danilchap1edb7ab2016-04-20 05:25:10 -070032constexpr uint32_t kTimestamp = 0x65431278;
33constexpr uint8_t kTransmissionOffsetExtensionId = 1;
34constexpr uint8_t kAudioLevelExtensionId = 9;
erikvargae6b16192017-05-11 02:36:32 -070035constexpr uint8_t kRtpStreamIdExtensionId = 0xa;
Steve Antona3251dd2017-07-21 09:58:31 -070036constexpr uint8_t kRtpMidExtensionId = 0xb;
sprangba050a62017-08-18 02:51:12 -070037constexpr uint8_t kVideoTimingExtensionId = 0xc;
Johannes Kron07ba2b92018-09-26 13:33:35 +020038constexpr uint8_t kTwoByteExtensionId = 0xf0;
danilchap1edb7ab2016-04-20 05:25:10 -070039constexpr int32_t kTimeOffset = 0x56ce;
40constexpr bool kVoiceActive = true;
41constexpr uint8_t kAudioLevel = 0x5a;
erikvargae6b16192017-05-11 02:36:32 -070042constexpr char kStreamId[] = "streamid";
Steve Antona3251dd2017-07-21 09:58:31 -070043constexpr char kMid[] = "mid";
Johannes Kron07ba2b92018-09-26 13:33:35 +020044constexpr char kLongMid[] = "extra-long string to test two-byte header";
danilchap1edb7ab2016-04-20 05:25:10 -070045constexpr size_t kMaxPaddingSize = 224u;
danilchap07ec26d2016-06-17 04:18:54 -070046// clang-format off
danilchap1edb7ab2016-04-20 05:25:10 -070047constexpr uint8_t kMinimumPacket[] = {
eladalonae550e32017-05-24 08:28:13 -070048 0x80, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070049 0x65, 0x43, 0x12, 0x78,
50 0x12, 0x34, 0x56, 0x78};
erikvargae6b16192017-05-11 02:36:32 -070051
danilchap1edb7ab2016-04-20 05:25:10 -070052constexpr uint8_t kPacketWithTO[] = {
eladalonae550e32017-05-24 08:28:13 -070053 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070054 0x65, 0x43, 0x12, 0x78,
55 0x12, 0x34, 0x56, 0x78,
56 0xbe, 0xde, 0x00, 0x01,
57 0x12, 0x00, 0x56, 0xce};
58
59constexpr uint8_t kPacketWithTOAndAL[] = {
eladalonae550e32017-05-24 08:28:13 -070060 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070061 0x65, 0x43, 0x12, 0x78,
62 0x12, 0x34, 0x56, 0x78,
63 0xbe, 0xde, 0x00, 0x02,
64 0x12, 0x00, 0x56, 0xce,
65 0x90, 0x80|kAudioLevel, 0x00, 0x00};
66
Johannes Kron07ba2b92018-09-26 13:33:35 +020067constexpr uint8_t kPacketWithTOAndALInvalidPadding[] = {
68 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
69 0x65, 0x43, 0x12, 0x78,
70 0x12, 0x34, 0x56, 0x78,
71 0xbe, 0xde, 0x00, 0x03,
72 0x12, 0x00, 0x56, 0xce,
73 0x00, 0x02, 0x00, 0x00, // 0x02 is invalid padding, parsing should stop.
74 0x90, 0x80|kAudioLevel, 0x00, 0x00};
75
76constexpr uint8_t kPacketWithTOAndALReservedExtensionId[] = {
77 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
78 0x65, 0x43, 0x12, 0x78,
79 0x12, 0x34, 0x56, 0x78,
80 0xbe, 0xde, 0x00, 0x03,
81 0x12, 0x00, 0x56, 0xce,
82 0x00, 0xF0, 0x00, 0x00, // F is a reserved id, parsing should stop.
83 0x90, 0x80|kAudioLevel, 0x00, 0x00};
84
erikvargae6b16192017-05-11 02:36:32 -070085constexpr uint8_t kPacketWithRsid[] = {
eladalonae550e32017-05-24 08:28:13 -070086 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
erikvargae6b16192017-05-11 02:36:32 -070087 0x65, 0x43, 0x12, 0x78,
88 0x12, 0x34, 0x56, 0x78,
89 0xbe, 0xde, 0x00, 0x03,
90 0xa7, 's', 't', 'r',
91 'e', 'a', 'm', 'i',
92 'd' , 0x00, 0x00, 0x00};
93
Steve Antona3251dd2017-07-21 09:58:31 -070094constexpr uint8_t kPacketWithMid[] = {
95 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
96 0x65, 0x43, 0x12, 0x78,
97 0x12, 0x34, 0x56, 0x78,
98 0xbe, 0xde, 0x00, 0x01,
99 0xb2, 'm', 'i', 'd'};
100
danilchap1edb7ab2016-04-20 05:25:10 -0700101constexpr uint32_t kCsrcs[] = {0x34567890, 0x32435465};
102constexpr uint8_t kPayload[] = {'p', 'a', 'y', 'l', 'o', 'a', 'd'};
103constexpr uint8_t kPacketPaddingSize = 8;
104constexpr uint8_t kPacket[] = {
eladalonae550e32017-05-24 08:28:13 -0700105 0xb2, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -0700106 0x65, 0x43, 0x12, 0x78,
107 0x12, 0x34, 0x56, 0x78,
108 0x34, 0x56, 0x78, 0x90,
109 0x32, 0x43, 0x54, 0x65,
110 0xbe, 0xde, 0x00, 0x01,
111 0x12, 0x00, 0x56, 0xce,
112 'p', 'a', 'y', 'l', 'o', 'a', 'd',
113 'p', 'a', 'd', 'd', 'i', 'n', 'g', kPacketPaddingSize};
danilchape565a042016-06-16 10:04:50 -0700114
Johannes Kron07ba2b92018-09-26 13:33:35 +0200115constexpr uint8_t kPacketWithTwoByteHeaderExtension[] = {
116 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
117 0x65, 0x43, 0x12, 0x78,
118 0x12, 0x34, 0x56, 0x78,
119 0x10, 0x00, 0x00, 0x02, // Two-byte header extension profile id + length.
120 kTwoByteExtensionId, 0x03, 0x00, 0x56,
121 0xce, 0x00, 0x00, 0x00};
122
123constexpr uint8_t kPacketWithLongTwoByteHeaderExtension[] = {
124 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
125 0x65, 0x43, 0x12, 0x78,
126 0x12, 0x34, 0x56, 0x78,
127 0x10, 0x00, 0x00, 0x0B, // Two-byte header extension profile id + length.
128 kTwoByteExtensionId, 0x29, 'e', 'x',
129 't', 'r', 'a', '-', 'l', 'o', 'n', 'g',
130 ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
131 't', 'o', ' ', 't', 'e', 's', 't', ' ',
132 't', 'w', 'o', '-', 'b', 'y', 't', 'e',
133 ' ', 'h', 'e', 'a', 'd', 'e', 'r', 0x00};
134
135constexpr uint8_t kPacketWithTwoByteHeaderExtensionWithPadding[] = {
136 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
137 0x65, 0x43, 0x12, 0x78,
138 0x12, 0x34, 0x56, 0x78,
139 0x10, 0x00, 0x00, 0x03, // Two-byte header extension profile id + length.
140 kTwoByteExtensionId, 0x03, 0x00, 0x56,
141 0xce, 0x00, 0x00, 0x00, // Three padding bytes.
142 kAudioLevelExtensionId, 0x01, 0x80|kAudioLevel, 0x00};
143
danilchap07ec26d2016-06-17 04:18:54 -0700144constexpr uint8_t kPacketWithInvalidExtension[] = {
eladalonae550e32017-05-24 08:28:13 -0700145 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap07ec26d2016-06-17 04:18:54 -0700146 0x65, 0x43, 0x12, 0x78, // kTimestamp.
147 0x12, 0x34, 0x56, 0x78, // kSSrc.
148 0xbe, 0xde, 0x00, 0x02, // Extension block of size 2 x 32bit words.
149 (kTransmissionOffsetExtensionId << 4) | 6, // (6+1)-byte extension, but
150 'e', 'x', 't', // Transmission Offset
151 'd', 'a', 't', 'a', // expected to be 3-bytes.
sprangba050a62017-08-18 02:51:12 -0700152 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
153
154constexpr uint8_t kPacketWithLegacyTimingExtension[] = {
155 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
156 0x65, 0x43, 0x12, 0x78, // kTimestamp.
157 0x12, 0x34, 0x56, 0x78, // kSSrc.
158 0xbe, 0xde, 0x00, 0x04, // Extension block of size 4 x 32bit words.
159 (kVideoTimingExtensionId << 4)
160 | VideoTimingExtension::kValueSizeBytes - 2, // Old format without flags.
161 0x00, 0x01, 0x00,
162 0x02, 0x00, 0x03, 0x00,
163 0x04, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00};
danilchap07ec26d2016-06-17 04:18:54 -0700165// clang-format on
danilchap1edb7ab2016-04-20 05:25:10 -0700166} // namespace
167
168TEST(RtpPacketTest, CreateMinimum) {
169 RtpPacketToSend packet(nullptr);
170 packet.SetPayloadType(kPayloadType);
171 packet.SetSequenceNumber(kSeqNum);
172 packet.SetTimestamp(kTimestamp);
173 packet.SetSsrc(kSsrc);
174 EXPECT_THAT(kMinimumPacket, ElementsAreArray(packet.data(), packet.size()));
175}
176
177TEST(RtpPacketTest, CreateWithExtension) {
178 RtpPacketToSend::ExtensionManager extensions;
179 extensions.Register(kRtpExtensionTransmissionTimeOffset,
180 kTransmissionOffsetExtensionId);
181 RtpPacketToSend packet(&extensions);
182 packet.SetPayloadType(kPayloadType);
183 packet.SetSequenceNumber(kSeqNum);
184 packet.SetTimestamp(kTimestamp);
185 packet.SetSsrc(kSsrc);
186 packet.SetExtension<TransmissionOffset>(kTimeOffset);
187 EXPECT_THAT(kPacketWithTO, ElementsAreArray(packet.data(), packet.size()));
188}
189
190TEST(RtpPacketTest, CreateWith2Extensions) {
191 RtpPacketToSend::ExtensionManager extensions;
192 extensions.Register(kRtpExtensionTransmissionTimeOffset,
193 kTransmissionOffsetExtensionId);
194 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
195 RtpPacketToSend packet(&extensions);
196 packet.SetPayloadType(kPayloadType);
197 packet.SetSequenceNumber(kSeqNum);
198 packet.SetTimestamp(kTimestamp);
199 packet.SetSsrc(kSsrc);
200 packet.SetExtension<TransmissionOffset>(kTimeOffset);
201 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
202 EXPECT_THAT(kPacketWithTOAndAL,
203 ElementsAreArray(packet.data(), packet.size()));
204}
205
erikvargae6b16192017-05-11 02:36:32 -0700206TEST(RtpPacketTest, CreateWithDynamicSizedExtensions) {
207 RtpPacketToSend::ExtensionManager extensions;
208 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
209 RtpPacketToSend packet(&extensions);
210 packet.SetPayloadType(kPayloadType);
211 packet.SetSequenceNumber(kSeqNum);
212 packet.SetTimestamp(kTimestamp);
213 packet.SetSsrc(kSsrc);
214 packet.SetExtension<RtpStreamId>(kStreamId);
215 EXPECT_THAT(kPacketWithRsid, ElementsAreArray(packet.data(), packet.size()));
216}
217
218TEST(RtpPacketTest, TryToCreateWithEmptyRsid) {
219 RtpPacketToSend::ExtensionManager extensions;
220 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
221 RtpPacketToSend packet(&extensions);
222 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(""));
223}
224
225TEST(RtpPacketTest, TryToCreateWithLongRsid) {
226 RtpPacketToSend::ExtensionManager extensions;
227 constexpr char kLongStreamId[] = "LoooooooooongRsid";
228 ASSERT_EQ(strlen(kLongStreamId), 17u);
229 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
230 RtpPacketToSend packet(&extensions);
231 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kLongStreamId));
232}
233
Steve Antona3251dd2017-07-21 09:58:31 -0700234TEST(RtpPacketTest, TryToCreateWithEmptyMid) {
235 RtpPacketToSend::ExtensionManager extensions;
236 extensions.Register<RtpMid>(kRtpMidExtensionId);
237 RtpPacketToSend packet(&extensions);
238 EXPECT_FALSE(packet.SetExtension<RtpMid>(""));
239}
240
241TEST(RtpPacketTest, TryToCreateWithLongMid) {
242 RtpPacketToSend::ExtensionManager extensions;
243 constexpr char kLongMid[] = "LoooooooooonogMid";
244 ASSERT_EQ(strlen(kLongMid), 17u);
245 extensions.Register<RtpMid>(kRtpMidExtensionId);
246 RtpPacketToSend packet(&extensions);
247 EXPECT_FALSE(packet.SetExtension<RtpMid>(kLongMid));
248}
249
danilchap653063f2017-04-03 06:16:30 -0700250TEST(RtpPacketTest, CreateWithMaxSizeHeaderExtension) {
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200251 const std::string kValue = "123456789abcdef";
252 RtpPacket::ExtensionManager extensions;
253 extensions.Register<RtpMid>(1);
254 extensions.Register<RtpStreamId>(2);
danilchap653063f2017-04-03 06:16:30 -0700255
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200256 RtpPacket packet(&extensions);
257 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700258
259 packet.SetPayloadSize(42);
260 // Rewriting allocated extension is allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200261 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700262 // Adding another extension after payload is set is not allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200263 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700264
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200265 // Read packet with the extension.
266 RtpPacketReceived parsed(&extensions);
danilchap653063f2017-04-03 06:16:30 -0700267 EXPECT_TRUE(parsed.Parse(packet.Buffer()));
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200268 std::string read;
269 EXPECT_TRUE(parsed.GetExtension<RtpMid>(&read));
270 EXPECT_EQ(read, kValue);
danilchap653063f2017-04-03 06:16:30 -0700271}
272
danilchap1edb7ab2016-04-20 05:25:10 -0700273TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
274 const size_t kPayloadSize = 4;
275 RtpPacketToSend::ExtensionManager extensions;
276 extensions.Register(kRtpExtensionTransmissionTimeOffset,
277 kTransmissionOffsetExtensionId);
278 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
279 RtpPacketToSend packet(&extensions);
280
281 EXPECT_TRUE(packet.ReserveExtension<TransmissionOffset>());
danilchap07a01b32017-03-29 07:33:13 -0700282 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700283 // Can't set extension after payload.
284 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
285 // Unless reserved.
286 EXPECT_TRUE(packet.SetExtension<TransmissionOffset>(kTimeOffset));
287}
288
289TEST(RtpPacketTest, CreatePurePadding) {
290 const size_t kPaddingSize = kMaxPaddingSize - 1;
291 RtpPacketToSend packet(nullptr, 12 + kPaddingSize);
292 packet.SetPayloadType(kPayloadType);
293 packet.SetSequenceNumber(kSeqNum);
294 packet.SetTimestamp(kTimestamp);
295 packet.SetSsrc(kSsrc);
296 Random random(0x123456789);
297
298 EXPECT_LT(packet.size(), packet.capacity());
299 EXPECT_FALSE(packet.SetPadding(kPaddingSize + 1, &random));
300 EXPECT_TRUE(packet.SetPadding(kPaddingSize, &random));
301 EXPECT_EQ(packet.size(), packet.capacity());
302}
303
304TEST(RtpPacketTest, CreateUnalignedPadding) {
305 const size_t kPayloadSize = 3; // Make padding start at unaligned address.
306 RtpPacketToSend packet(nullptr, 12 + kPayloadSize + kMaxPaddingSize);
307 packet.SetPayloadType(kPayloadType);
308 packet.SetSequenceNumber(kSeqNum);
309 packet.SetTimestamp(kTimestamp);
310 packet.SetSsrc(kSsrc);
danilchap07a01b32017-03-29 07:33:13 -0700311 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700312 Random r(0x123456789);
313
314 EXPECT_LT(packet.size(), packet.capacity());
315 EXPECT_TRUE(packet.SetPadding(kMaxPaddingSize, &r));
316 EXPECT_EQ(packet.size(), packet.capacity());
317}
318
319TEST(RtpPacketTest, ParseMinimum) {
320 RtpPacketReceived packet;
321 EXPECT_TRUE(packet.Parse(kMinimumPacket, sizeof(kMinimumPacket)));
322 EXPECT_EQ(kPayloadType, packet.PayloadType());
323 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
324 EXPECT_EQ(kTimestamp, packet.Timestamp());
325 EXPECT_EQ(kSsrc, packet.Ssrc());
326 EXPECT_EQ(0u, packet.padding_size());
327 EXPECT_EQ(0u, packet.payload_size());
328}
329
330TEST(RtpPacketTest, ParseBuffer) {
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200331 rtc::CopyOnWriteBuffer unparsed(kMinimumPacket);
danilchap1edb7ab2016-04-20 05:25:10 -0700332 const uint8_t* raw = unparsed.data();
333
334 RtpPacketReceived packet;
335 EXPECT_TRUE(packet.Parse(std::move(unparsed)));
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200336 EXPECT_EQ(raw, packet.data()); // Expect packet take the buffer without copy.
danilchap1edb7ab2016-04-20 05:25:10 -0700337 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
338 EXPECT_EQ(kTimestamp, packet.Timestamp());
339 EXPECT_EQ(kSsrc, packet.Ssrc());
340 EXPECT_EQ(0u, packet.padding_size());
341 EXPECT_EQ(0u, packet.payload_size());
342}
343
344TEST(RtpPacketTest, ParseWithExtension) {
345 RtpPacketToSend::ExtensionManager extensions;
346 extensions.Register(kRtpExtensionTransmissionTimeOffset,
347 kTransmissionOffsetExtensionId);
348
349 RtpPacketReceived packet(&extensions);
350 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
351 EXPECT_EQ(kPayloadType, packet.PayloadType());
352 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
353 EXPECT_EQ(kTimestamp, packet.Timestamp());
354 EXPECT_EQ(kSsrc, packet.Ssrc());
355 int32_t time_offset;
356 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
357 EXPECT_EQ(kTimeOffset, time_offset);
358 EXPECT_EQ(0u, packet.payload_size());
359 EXPECT_EQ(0u, packet.padding_size());
360}
361
Danil Chapovalove19953b2018-10-01 16:12:28 +0200362TEST(RtpPacketTest, GetRawExtensionWhenPresent) {
363 constexpr uint8_t kRawPacket[] = {
364 // comment for clang-format to align kRawPacket nicer.
365 0x90, 100, 0x5e, 0x04, //
366 0x65, 0x43, 0x12, 0x78, // Timestamp.
367 0x12, 0x34, 0x56, 0x78, // Ssrc
368 0xbe, 0xde, 0x00, 0x01, // Extension header
369 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
370 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
371 RtpPacketToSend::ExtensionManager extensions;
372 extensions.Register<RtpMid>(1);
373 RtpPacket packet(&extensions);
374 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
375 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), ElementsAre('m', 'i', 'd'));
376}
377
378TEST(RtpPacketTest, GetRawExtensionWhenAbsent) {
379 constexpr uint8_t kRawPacket[] = {
380 // comment for clang-format to align kRawPacket nicer.
381 0x90, 100, 0x5e, 0x04, //
382 0x65, 0x43, 0x12, 0x78, // Timestamp.
383 0x12, 0x34, 0x56, 0x78, // Ssrc
384 0xbe, 0xde, 0x00, 0x01, // Extension header
385 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
386 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
387 RtpPacketToSend::ExtensionManager extensions;
388 extensions.Register<RtpMid>(2);
389 RtpPacket packet(&extensions);
390 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
391 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), IsEmpty());
392}
393
danilchap07ec26d2016-06-17 04:18:54 -0700394TEST(RtpPacketTest, ParseWithInvalidSizedExtension) {
395 RtpPacketToSend::ExtensionManager extensions;
396 extensions.Register(kRtpExtensionTransmissionTimeOffset,
397 kTransmissionOffsetExtensionId);
398
399 RtpPacketReceived packet(&extensions);
400 EXPECT_TRUE(packet.Parse(kPacketWithInvalidExtension,
401 sizeof(kPacketWithInvalidExtension)));
402
403 // Extension should be ignored.
404 int32_t time_offset;
405 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
406
407 // But shouldn't prevent reading payload.
danilchap96c15872016-11-21 01:35:29 -0800408 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap07ec26d2016-06-17 04:18:54 -0700409}
410
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200411TEST(RtpPacketTest, ParseWithOverSizedExtension) {
412 // clang-format off
413 const uint8_t bad_packet[] = {
eladalonae550e32017-05-24 08:28:13 -0700414 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200415 0x65, 0x43, 0x12, 0x78, // kTimestamp.
416 0x12, 0x34, 0x56, 0x78, // kSsrc.
417 0xbe, 0xde, 0x00, 0x01, // Extension of size 1x32bit word.
418 0x00, // Add a byte of padding.
419 0x12, // Extension id 1 size (2+1).
420 0xda, 0x1a // Only 2 bytes of extension payload.
421 };
422 // clang-format on
423 RtpPacketToSend::ExtensionManager extensions;
424 extensions.Register(TransmissionOffset::kId, 1);
425 RtpPacketReceived packet(&extensions);
426
427 // Parse should ignore bad extension and proceed.
428 EXPECT_TRUE(packet.Parse(bad_packet, sizeof(bad_packet)));
429 int32_t time_offset;
430 // But extracting extension should fail.
431 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
432}
433
danilchap1edb7ab2016-04-20 05:25:10 -0700434TEST(RtpPacketTest, ParseWith2Extensions) {
435 RtpPacketToSend::ExtensionManager extensions;
436 extensions.Register(kRtpExtensionTransmissionTimeOffset,
437 kTransmissionOffsetExtensionId);
438 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
439 RtpPacketReceived packet(&extensions);
440 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
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_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
447 EXPECT_EQ(kVoiceActive, voice_active);
448 EXPECT_EQ(kAudioLevel, audio_level);
449}
450
Johannes Kron6ea77192018-09-24 17:19:52 +0200451TEST(RtpPacketTest, ParseSecondPacketWithFewerExtensions) {
452 RtpPacketToSend::ExtensionManager extensions;
453 extensions.Register(kRtpExtensionTransmissionTimeOffset,
454 kTransmissionOffsetExtensionId);
455 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
456 RtpPacketReceived packet(&extensions);
457 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
458 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
459 EXPECT_TRUE(packet.HasExtension<AudioLevel>());
460
461 // Second packet without audio level.
462 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
463 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
464 EXPECT_FALSE(packet.HasExtension<AudioLevel>());
465}
466
Johannes Kron07ba2b92018-09-26 13:33:35 +0200467TEST(RtpPacketTest, ParseWith2ExtensionsInvalidPadding) {
468 RtpPacketToSend::ExtensionManager extensions;
469 extensions.Register(kRtpExtensionTransmissionTimeOffset,
470 kTransmissionOffsetExtensionId);
471 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
472 RtpPacketReceived packet(&extensions);
473 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALInvalidPadding,
474 sizeof(kPacketWithTOAndALInvalidPadding)));
475 int32_t time_offset;
476 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
477 EXPECT_EQ(kTimeOffset, time_offset);
478 bool voice_active;
479 uint8_t audio_level;
480 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
481}
482
483TEST(RtpPacketTest, ParseWith2ExtensionsReservedExtensionId) {
484 RtpPacketToSend::ExtensionManager extensions;
485 extensions.Register(kRtpExtensionTransmissionTimeOffset,
486 kTransmissionOffsetExtensionId);
487 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
488 RtpPacketReceived packet(&extensions);
489 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALReservedExtensionId,
490 sizeof(kPacketWithTOAndALReservedExtensionId)));
491 int32_t time_offset;
492 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
493 EXPECT_EQ(kTimeOffset, time_offset);
494 bool voice_active;
495 uint8_t audio_level;
496 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
497}
498
danilchap1edb7ab2016-04-20 05:25:10 -0700499TEST(RtpPacketTest, ParseWithAllFeatures) {
500 RtpPacketToSend::ExtensionManager extensions;
501 extensions.Register(kRtpExtensionTransmissionTimeOffset,
502 kTransmissionOffsetExtensionId);
503 RtpPacketReceived packet(&extensions);
504 EXPECT_TRUE(packet.Parse(kPacket, sizeof(kPacket)));
505 EXPECT_EQ(kPayloadType, packet.PayloadType());
506 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
507 EXPECT_EQ(kTimestamp, packet.Timestamp());
508 EXPECT_EQ(kSsrc, packet.Ssrc());
509 EXPECT_THAT(packet.Csrcs(), ElementsAreArray(kCsrcs));
danilchap96c15872016-11-21 01:35:29 -0800510 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap1edb7ab2016-04-20 05:25:10 -0700511 EXPECT_EQ(kPacketPaddingSize, packet.padding_size());
512 int32_t time_offset;
513 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
514}
515
Johannes Kron07ba2b92018-09-26 13:33:35 +0200516TEST(RtpPacketTest, ParseTwoByteHeaderExtension) {
517 RtpPacketToSend::ExtensionManager extensions;
518 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
519 RtpPacketReceived packet(&extensions);
520 EXPECT_TRUE(packet.Parse(kPacketWithTwoByteHeaderExtension,
521 sizeof(kPacketWithTwoByteHeaderExtension)));
522 int32_t time_offset;
523 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
524 EXPECT_EQ(kTimeOffset, time_offset);
525}
526
527TEST(RtpPacketTest, ParseLongTwoByteHeaderExtension) {
528 RtpPacketToSend::ExtensionManager extensions;
529 extensions.Register(kRtpExtensionMid, kTwoByteExtensionId);
530 RtpPacketReceived packet(&extensions);
531 EXPECT_TRUE(packet.Parse(kPacketWithLongTwoByteHeaderExtension,
532 sizeof(kPacketWithLongTwoByteHeaderExtension)));
533 std::string long_rtp_mid;
534 EXPECT_TRUE(packet.GetExtension<RtpMid>(&long_rtp_mid));
535 EXPECT_EQ(kLongMid, long_rtp_mid);
536}
537
538TEST(RtpPacketTest, ParseTwoByteHeaderExtensionWithPadding) {
539 RtpPacketToSend::ExtensionManager extensions;
540 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
541 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
542 RtpPacketReceived packet(&extensions);
543 EXPECT_TRUE(
544 packet.Parse(kPacketWithTwoByteHeaderExtensionWithPadding,
545 sizeof(kPacketWithTwoByteHeaderExtensionWithPadding)));
546 int32_t time_offset;
547 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
548 EXPECT_EQ(kTimeOffset, time_offset);
549 bool voice_active;
550 uint8_t audio_level;
551 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
552 EXPECT_EQ(kVoiceActive, voice_active);
553 EXPECT_EQ(kAudioLevel, audio_level);
554}
555
danilchap1edb7ab2016-04-20 05:25:10 -0700556TEST(RtpPacketTest, ParseWithExtensionDelayed) {
557 RtpPacketReceived packet;
558 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
559 EXPECT_EQ(kPayloadType, packet.PayloadType());
560 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
561 EXPECT_EQ(kTimestamp, packet.Timestamp());
562 EXPECT_EQ(kSsrc, packet.Ssrc());
563
564 RtpPacketToSend::ExtensionManager extensions;
565 extensions.Register(kRtpExtensionTransmissionTimeOffset,
566 kTransmissionOffsetExtensionId);
567
568 int32_t time_offset;
569 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
danilchap70f39a32016-12-16 05:48:18 -0800570 packet.IdentifyExtensions(extensions);
danilchap1edb7ab2016-04-20 05:25:10 -0700571 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
572 EXPECT_EQ(kTimeOffset, time_offset);
573 EXPECT_EQ(0u, packet.payload_size());
574 EXPECT_EQ(0u, packet.padding_size());
575}
576
danilchapef8d7732017-04-19 02:59:48 -0700577TEST(RtpPacketTest, ParseDynamicSizeExtension) {
578 // clang-format off
579 const uint8_t kPacket1[] = {
eladalonae550e32017-05-24 08:28:13 -0700580 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700581 0x65, 0x43, 0x12, 0x78, // Timestamp.
582 0x12, 0x34, 0x56, 0x78, // Ssrc.
583 0xbe, 0xde, 0x00, 0x02, // Extensions block of size 2x32bit words.
584 0x21, 'H', 'D', // Extension with id = 2, size = (1+1).
585 0x12, 'r', 't', 'x', // Extension with id = 1, size = (2+1).
586 0x00}; // Extension padding.
587 const uint8_t kPacket2[] = {
eladalonae550e32017-05-24 08:28:13 -0700588 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700589 0x65, 0x43, 0x12, 0x78, // Timestamp.
590 0x12, 0x34, 0x56, 0x79, // Ssrc.
591 0xbe, 0xde, 0x00, 0x01, // Extensions block of size 1x32bit words.
592 0x11, 'H', 'D', // Extension with id = 1, size = (1+1).
593 0x00}; // Extension padding.
594 // clang-format on
595 RtpPacketReceived::ExtensionManager extensions;
596 extensions.Register<RtpStreamId>(1);
597 extensions.Register<RepairedRtpStreamId>(2);
598 RtpPacketReceived packet(&extensions);
599 ASSERT_TRUE(packet.Parse(kPacket1, sizeof(kPacket1)));
600
601 std::string rsid;
602 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
603 EXPECT_EQ(rsid, "rtx");
604
605 std::string repaired_rsid;
606 EXPECT_TRUE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
607 EXPECT_EQ(repaired_rsid, "HD");
608
609 // Parse another packet with RtpStreamId extension of different size.
610 ASSERT_TRUE(packet.Parse(kPacket2, sizeof(kPacket2)));
611 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
612 EXPECT_EQ(rsid, "HD");
613 EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
614}
615
Steve Antona3251dd2017-07-21 09:58:31 -0700616TEST(RtpPacketTest, ParseWithMid) {
617 RtpPacketReceived::ExtensionManager extensions;
618 extensions.Register<RtpMid>(kRtpMidExtensionId);
619 RtpPacketReceived packet(&extensions);
620 ASSERT_TRUE(packet.Parse(kPacketWithMid, sizeof(kPacketWithMid)));
621
622 std::string mid;
623 EXPECT_TRUE(packet.GetExtension<RtpMid>(&mid));
624 EXPECT_EQ(mid, kMid);
625}
626
sprangba050a62017-08-18 02:51:12 -0700627TEST(RtpPacketTest, CreateAndParseTimingFrameExtension) {
628 // Create a packet with video frame timing extension populated.
629 RtpPacketToSend::ExtensionManager send_extensions;
630 send_extensions.Register(kRtpExtensionVideoTiming, kVideoTimingExtensionId);
631 RtpPacketToSend send_packet(&send_extensions);
632 send_packet.SetPayloadType(kPayloadType);
633 send_packet.SetSequenceNumber(kSeqNum);
634 send_packet.SetTimestamp(kTimestamp);
635 send_packet.SetSsrc(kSsrc);
636
637 VideoSendTiming timing;
638 timing.encode_start_delta_ms = 1;
639 timing.encode_finish_delta_ms = 2;
640 timing.packetization_finish_delta_ms = 3;
641 timing.pacer_exit_delta_ms = 4;
642 timing.flags =
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +0200643 VideoSendTiming::kTriggeredByTimer | VideoSendTiming::kTriggeredBySize;
sprangba050a62017-08-18 02:51:12 -0700644
645 send_packet.SetExtension<VideoTimingExtension>(timing);
646
647 // Serialize the packet and then parse it again.
648 RtpPacketReceived::ExtensionManager extensions;
649 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
650 RtpPacketReceived receive_packet(&extensions);
651 EXPECT_TRUE(receive_packet.Parse(send_packet.Buffer()));
652
653 VideoSendTiming receivied_timing;
654 EXPECT_TRUE(
655 receive_packet.GetExtension<VideoTimingExtension>(&receivied_timing));
656
657 // Only check first and last timestamp (covered by other tests) plus flags.
658 EXPECT_EQ(receivied_timing.encode_start_delta_ms,
659 timing.encode_start_delta_ms);
660 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, timing.pacer_exit_delta_ms);
661 EXPECT_EQ(receivied_timing.flags, timing.flags);
662}
663
664TEST(RtpPacketTest, ParseLegacyTimingFrameExtension) {
665 // Parse the modified packet.
666 RtpPacketReceived::ExtensionManager extensions;
667 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
668 RtpPacketReceived packet(&extensions);
669 EXPECT_TRUE(packet.Parse(kPacketWithLegacyTimingExtension,
670 sizeof(kPacketWithLegacyTimingExtension)));
671 VideoSendTiming receivied_timing;
672 EXPECT_TRUE(packet.GetExtension<VideoTimingExtension>(&receivied_timing));
673
674 // Check first and last timestamp are still OK. Flags should now be 0.
675 EXPECT_EQ(receivied_timing.encode_start_delta_ms, 1);
676 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, 4);
677 EXPECT_EQ(receivied_timing.flags, 0);
678}
679
danilchap1edb7ab2016-04-20 05:25:10 -0700680} // namespace webrtc