blob: 125000d2dc94ed4be17862e04b24406bf3d2747c [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 Kron78cdde32018-10-05 10:00:46 +020067constexpr uint8_t kPacketWithTwoByteExtensionIdLast[] = {
68 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
69 0x65, 0x43, 0x12, 0x78,
70 0x12, 0x34, 0x56, 0x78,
71 0x10, 0x00, 0x00, 0x04,
72 0x01, 0x03, 0x00, 0x56,
73 0xce, 0x09, 0x01, 0x80|kAudioLevel,
74 kTwoByteExtensionId, 0x03, 0x00, 0x30, // => 0x00 0x30 0x22
75 0x22, 0x00, 0x00, 0x00}; // => Playout delay.min_ms = 3*10
76 // => Playout delay.max_ms = 34*10
77
78constexpr uint8_t kPacketWithTwoByteExtensionIdFirst[] = {
79 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
80 0x65, 0x43, 0x12, 0x78,
81 0x12, 0x34, 0x56, 0x78,
82 0x10, 0x00, 0x00, 0x04,
83 kTwoByteExtensionId, 0x03, 0x00, 0x30, // => 0x00 0x30 0x22
84 0x22, 0x01, 0x03, 0x00, // => Playout delay.min_ms = 3*10
85 0x56, 0xce, 0x09, 0x01, // => Playout delay.max_ms = 34*10
86 0x80|kAudioLevel, 0x00, 0x00, 0x00};
87
Johannes Kron07ba2b92018-09-26 13:33:35 +020088constexpr uint8_t kPacketWithTOAndALInvalidPadding[] = {
89 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
90 0x65, 0x43, 0x12, 0x78,
91 0x12, 0x34, 0x56, 0x78,
92 0xbe, 0xde, 0x00, 0x03,
93 0x12, 0x00, 0x56, 0xce,
94 0x00, 0x02, 0x00, 0x00, // 0x02 is invalid padding, parsing should stop.
95 0x90, 0x80|kAudioLevel, 0x00, 0x00};
96
97constexpr uint8_t kPacketWithTOAndALReservedExtensionId[] = {
98 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
99 0x65, 0x43, 0x12, 0x78,
100 0x12, 0x34, 0x56, 0x78,
101 0xbe, 0xde, 0x00, 0x03,
102 0x12, 0x00, 0x56, 0xce,
103 0x00, 0xF0, 0x00, 0x00, // F is a reserved id, parsing should stop.
104 0x90, 0x80|kAudioLevel, 0x00, 0x00};
105
erikvargae6b16192017-05-11 02:36:32 -0700106constexpr uint8_t kPacketWithRsid[] = {
eladalonae550e32017-05-24 08:28:13 -0700107 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
erikvargae6b16192017-05-11 02:36:32 -0700108 0x65, 0x43, 0x12, 0x78,
109 0x12, 0x34, 0x56, 0x78,
110 0xbe, 0xde, 0x00, 0x03,
111 0xa7, 's', 't', 'r',
112 'e', 'a', 'm', 'i',
113 'd' , 0x00, 0x00, 0x00};
114
Steve Antona3251dd2017-07-21 09:58:31 -0700115constexpr uint8_t kPacketWithMid[] = {
116 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
117 0x65, 0x43, 0x12, 0x78,
118 0x12, 0x34, 0x56, 0x78,
119 0xbe, 0xde, 0x00, 0x01,
120 0xb2, 'm', 'i', 'd'};
121
danilchap1edb7ab2016-04-20 05:25:10 -0700122constexpr uint32_t kCsrcs[] = {0x34567890, 0x32435465};
123constexpr uint8_t kPayload[] = {'p', 'a', 'y', 'l', 'o', 'a', 'd'};
124constexpr uint8_t kPacketPaddingSize = 8;
125constexpr uint8_t kPacket[] = {
eladalonae550e32017-05-24 08:28:13 -0700126 0xb2, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -0700127 0x65, 0x43, 0x12, 0x78,
128 0x12, 0x34, 0x56, 0x78,
129 0x34, 0x56, 0x78, 0x90,
130 0x32, 0x43, 0x54, 0x65,
131 0xbe, 0xde, 0x00, 0x01,
132 0x12, 0x00, 0x56, 0xce,
133 'p', 'a', 'y', 'l', 'o', 'a', 'd',
134 'p', 'a', 'd', 'd', 'i', 'n', 'g', kPacketPaddingSize};
danilchape565a042016-06-16 10:04:50 -0700135
Johannes Kron07ba2b92018-09-26 13:33:35 +0200136constexpr uint8_t kPacketWithTwoByteHeaderExtension[] = {
137 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
138 0x65, 0x43, 0x12, 0x78,
139 0x12, 0x34, 0x56, 0x78,
140 0x10, 0x00, 0x00, 0x02, // Two-byte header extension profile id + length.
141 kTwoByteExtensionId, 0x03, 0x00, 0x56,
142 0xce, 0x00, 0x00, 0x00};
143
144constexpr uint8_t kPacketWithLongTwoByteHeaderExtension[] = {
145 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
146 0x65, 0x43, 0x12, 0x78,
147 0x12, 0x34, 0x56, 0x78,
148 0x10, 0x00, 0x00, 0x0B, // Two-byte header extension profile id + length.
149 kTwoByteExtensionId, 0x29, 'e', 'x',
150 't', 'r', 'a', '-', 'l', 'o', 'n', 'g',
151 ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
152 't', 'o', ' ', 't', 'e', 's', 't', ' ',
153 't', 'w', 'o', '-', 'b', 'y', 't', 'e',
154 ' ', 'h', 'e', 'a', 'd', 'e', 'r', 0x00};
155
156constexpr uint8_t kPacketWithTwoByteHeaderExtensionWithPadding[] = {
157 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
158 0x65, 0x43, 0x12, 0x78,
159 0x12, 0x34, 0x56, 0x78,
160 0x10, 0x00, 0x00, 0x03, // Two-byte header extension profile id + length.
161 kTwoByteExtensionId, 0x03, 0x00, 0x56,
162 0xce, 0x00, 0x00, 0x00, // Three padding bytes.
163 kAudioLevelExtensionId, 0x01, 0x80|kAudioLevel, 0x00};
164
danilchap07ec26d2016-06-17 04:18:54 -0700165constexpr uint8_t kPacketWithInvalidExtension[] = {
eladalonae550e32017-05-24 08:28:13 -0700166 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap07ec26d2016-06-17 04:18:54 -0700167 0x65, 0x43, 0x12, 0x78, // kTimestamp.
168 0x12, 0x34, 0x56, 0x78, // kSSrc.
169 0xbe, 0xde, 0x00, 0x02, // Extension block of size 2 x 32bit words.
170 (kTransmissionOffsetExtensionId << 4) | 6, // (6+1)-byte extension, but
171 'e', 'x', 't', // Transmission Offset
172 'd', 'a', 't', 'a', // expected to be 3-bytes.
sprangba050a62017-08-18 02:51:12 -0700173 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
174
175constexpr uint8_t kPacketWithLegacyTimingExtension[] = {
176 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
177 0x65, 0x43, 0x12, 0x78, // kTimestamp.
178 0x12, 0x34, 0x56, 0x78, // kSSrc.
179 0xbe, 0xde, 0x00, 0x04, // Extension block of size 4 x 32bit words.
180 (kVideoTimingExtensionId << 4)
181 | VideoTimingExtension::kValueSizeBytes - 2, // Old format without flags.
182 0x00, 0x01, 0x00,
183 0x02, 0x00, 0x03, 0x00,
184 0x04, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00};
danilchap07ec26d2016-06-17 04:18:54 -0700186// clang-format on
danilchap1edb7ab2016-04-20 05:25:10 -0700187} // namespace
188
189TEST(RtpPacketTest, CreateMinimum) {
190 RtpPacketToSend packet(nullptr);
191 packet.SetPayloadType(kPayloadType);
192 packet.SetSequenceNumber(kSeqNum);
193 packet.SetTimestamp(kTimestamp);
194 packet.SetSsrc(kSsrc);
195 EXPECT_THAT(kMinimumPacket, ElementsAreArray(packet.data(), packet.size()));
196}
197
198TEST(RtpPacketTest, CreateWithExtension) {
199 RtpPacketToSend::ExtensionManager extensions;
200 extensions.Register(kRtpExtensionTransmissionTimeOffset,
201 kTransmissionOffsetExtensionId);
202 RtpPacketToSend packet(&extensions);
203 packet.SetPayloadType(kPayloadType);
204 packet.SetSequenceNumber(kSeqNum);
205 packet.SetTimestamp(kTimestamp);
206 packet.SetSsrc(kSsrc);
207 packet.SetExtension<TransmissionOffset>(kTimeOffset);
208 EXPECT_THAT(kPacketWithTO, ElementsAreArray(packet.data(), packet.size()));
209}
210
211TEST(RtpPacketTest, CreateWith2Extensions) {
212 RtpPacketToSend::ExtensionManager extensions;
213 extensions.Register(kRtpExtensionTransmissionTimeOffset,
214 kTransmissionOffsetExtensionId);
215 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
216 RtpPacketToSend packet(&extensions);
217 packet.SetPayloadType(kPayloadType);
218 packet.SetSequenceNumber(kSeqNum);
219 packet.SetTimestamp(kTimestamp);
220 packet.SetSsrc(kSsrc);
221 packet.SetExtension<TransmissionOffset>(kTimeOffset);
222 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
223 EXPECT_THAT(kPacketWithTOAndAL,
224 ElementsAreArray(packet.data(), packet.size()));
225}
226
Johannes Kron78cdde32018-10-05 10:00:46 +0200227TEST(RtpPacketTest, CreateWithTwoByteHeaderExtensionFirst) {
228 RtpPacketToSend::ExtensionManager extensions;
229 extensions.SetMixedOneTwoByteHeaderSupported(true);
230 extensions.Register(kRtpExtensionTransmissionTimeOffset,
231 kTransmissionOffsetExtensionId);
232 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
233 extensions.Register(kRtpExtensionPlayoutDelay, kTwoByteExtensionId);
234 RtpPacketToSend packet(&extensions);
235 packet.SetPayloadType(kPayloadType);
236 packet.SetSequenceNumber(kSeqNum);
237 packet.SetTimestamp(kTimestamp);
238 packet.SetSsrc(kSsrc);
239 // Set extension that requires two-byte header.
240 PlayoutDelay playoutDelay = {30, 340};
241 ASSERT_TRUE(packet.SetExtension<PlayoutDelayLimits>(playoutDelay));
242 packet.SetExtension<TransmissionOffset>(kTimeOffset);
243 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
244 EXPECT_THAT(kPacketWithTwoByteExtensionIdFirst,
245 ElementsAreArray(packet.data(), packet.size()));
246}
247
248TEST(RtpPacketTest, CreateWithTwoByteHeaderExtensionLast) {
249 // This test will trigger RtpPacket::PromoteToTwoByteHeaderExtension().
250 RtpPacketToSend::ExtensionManager extensions;
251 extensions.SetMixedOneTwoByteHeaderSupported(true);
252 extensions.Register(kRtpExtensionTransmissionTimeOffset,
253 kTransmissionOffsetExtensionId);
254 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
255 extensions.Register(kRtpExtensionPlayoutDelay, kTwoByteExtensionId);
256 RtpPacketToSend packet(&extensions);
257 packet.SetPayloadType(kPayloadType);
258 packet.SetSequenceNumber(kSeqNum);
259 packet.SetTimestamp(kTimestamp);
260 packet.SetSsrc(kSsrc);
261 packet.SetExtension<TransmissionOffset>(kTimeOffset);
262 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
263 EXPECT_THAT(kPacketWithTOAndAL,
264 ElementsAreArray(packet.data(), packet.size()));
265 // Set extension that requires two-byte header.
266 PlayoutDelay playoutDelay = {30, 340};
267 ASSERT_TRUE(packet.SetExtension<PlayoutDelayLimits>(playoutDelay));
268 EXPECT_THAT(kPacketWithTwoByteExtensionIdLast,
269 ElementsAreArray(packet.data(), packet.size()));
270}
271
erikvargae6b16192017-05-11 02:36:32 -0700272TEST(RtpPacketTest, CreateWithDynamicSizedExtensions) {
273 RtpPacketToSend::ExtensionManager extensions;
274 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
275 RtpPacketToSend packet(&extensions);
276 packet.SetPayloadType(kPayloadType);
277 packet.SetSequenceNumber(kSeqNum);
278 packet.SetTimestamp(kTimestamp);
279 packet.SetSsrc(kSsrc);
280 packet.SetExtension<RtpStreamId>(kStreamId);
281 EXPECT_THAT(kPacketWithRsid, ElementsAreArray(packet.data(), packet.size()));
282}
283
284TEST(RtpPacketTest, TryToCreateWithEmptyRsid) {
285 RtpPacketToSend::ExtensionManager extensions;
286 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
287 RtpPacketToSend packet(&extensions);
288 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(""));
289}
290
291TEST(RtpPacketTest, TryToCreateWithLongRsid) {
292 RtpPacketToSend::ExtensionManager extensions;
293 constexpr char kLongStreamId[] = "LoooooooooongRsid";
294 ASSERT_EQ(strlen(kLongStreamId), 17u);
295 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
296 RtpPacketToSend packet(&extensions);
297 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kLongStreamId));
298}
299
Steve Antona3251dd2017-07-21 09:58:31 -0700300TEST(RtpPacketTest, TryToCreateWithEmptyMid) {
301 RtpPacketToSend::ExtensionManager extensions;
302 extensions.Register<RtpMid>(kRtpMidExtensionId);
303 RtpPacketToSend packet(&extensions);
304 EXPECT_FALSE(packet.SetExtension<RtpMid>(""));
305}
306
307TEST(RtpPacketTest, TryToCreateWithLongMid) {
308 RtpPacketToSend::ExtensionManager extensions;
309 constexpr char kLongMid[] = "LoooooooooonogMid";
310 ASSERT_EQ(strlen(kLongMid), 17u);
311 extensions.Register<RtpMid>(kRtpMidExtensionId);
312 RtpPacketToSend packet(&extensions);
313 EXPECT_FALSE(packet.SetExtension<RtpMid>(kLongMid));
314}
315
Johannes Kron78cdde32018-10-05 10:00:46 +0200316TEST(RtpPacketTest, TryToCreateTwoByteHeaderNotSupported) {
317 RtpPacketToSend::ExtensionManager extensions;
318 extensions.Register(kRtpExtensionAudioLevel, kTwoByteExtensionId);
319 RtpPacketToSend packet(&extensions);
320 // Set extension that requires two-byte header.
321 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
322}
323
danilchap653063f2017-04-03 06:16:30 -0700324TEST(RtpPacketTest, CreateWithMaxSizeHeaderExtension) {
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200325 const std::string kValue = "123456789abcdef";
326 RtpPacket::ExtensionManager extensions;
327 extensions.Register<RtpMid>(1);
328 extensions.Register<RtpStreamId>(2);
danilchap653063f2017-04-03 06:16:30 -0700329
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200330 RtpPacket packet(&extensions);
331 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700332
333 packet.SetPayloadSize(42);
334 // Rewriting allocated extension is allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200335 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700336 // Adding another extension after payload is set is not allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200337 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700338
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200339 // Read packet with the extension.
340 RtpPacketReceived parsed(&extensions);
danilchap653063f2017-04-03 06:16:30 -0700341 EXPECT_TRUE(parsed.Parse(packet.Buffer()));
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200342 std::string read;
343 EXPECT_TRUE(parsed.GetExtension<RtpMid>(&read));
344 EXPECT_EQ(read, kValue);
danilchap653063f2017-04-03 06:16:30 -0700345}
346
danilchap1edb7ab2016-04-20 05:25:10 -0700347TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
348 const size_t kPayloadSize = 4;
349 RtpPacketToSend::ExtensionManager extensions;
350 extensions.Register(kRtpExtensionTransmissionTimeOffset,
351 kTransmissionOffsetExtensionId);
352 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
353 RtpPacketToSend packet(&extensions);
354
355 EXPECT_TRUE(packet.ReserveExtension<TransmissionOffset>());
danilchap07a01b32017-03-29 07:33:13 -0700356 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700357 // Can't set extension after payload.
358 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
359 // Unless reserved.
360 EXPECT_TRUE(packet.SetExtension<TransmissionOffset>(kTimeOffset));
361}
362
363TEST(RtpPacketTest, CreatePurePadding) {
364 const size_t kPaddingSize = kMaxPaddingSize - 1;
365 RtpPacketToSend packet(nullptr, 12 + kPaddingSize);
366 packet.SetPayloadType(kPayloadType);
367 packet.SetSequenceNumber(kSeqNum);
368 packet.SetTimestamp(kTimestamp);
369 packet.SetSsrc(kSsrc);
370 Random random(0x123456789);
371
372 EXPECT_LT(packet.size(), packet.capacity());
373 EXPECT_FALSE(packet.SetPadding(kPaddingSize + 1, &random));
374 EXPECT_TRUE(packet.SetPadding(kPaddingSize, &random));
375 EXPECT_EQ(packet.size(), packet.capacity());
376}
377
378TEST(RtpPacketTest, CreateUnalignedPadding) {
379 const size_t kPayloadSize = 3; // Make padding start at unaligned address.
380 RtpPacketToSend packet(nullptr, 12 + kPayloadSize + kMaxPaddingSize);
381 packet.SetPayloadType(kPayloadType);
382 packet.SetSequenceNumber(kSeqNum);
383 packet.SetTimestamp(kTimestamp);
384 packet.SetSsrc(kSsrc);
danilchap07a01b32017-03-29 07:33:13 -0700385 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700386 Random r(0x123456789);
387
388 EXPECT_LT(packet.size(), packet.capacity());
389 EXPECT_TRUE(packet.SetPadding(kMaxPaddingSize, &r));
390 EXPECT_EQ(packet.size(), packet.capacity());
391}
392
393TEST(RtpPacketTest, ParseMinimum) {
394 RtpPacketReceived packet;
395 EXPECT_TRUE(packet.Parse(kMinimumPacket, sizeof(kMinimumPacket)));
396 EXPECT_EQ(kPayloadType, packet.PayloadType());
397 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
398 EXPECT_EQ(kTimestamp, packet.Timestamp());
399 EXPECT_EQ(kSsrc, packet.Ssrc());
400 EXPECT_EQ(0u, packet.padding_size());
401 EXPECT_EQ(0u, packet.payload_size());
402}
403
404TEST(RtpPacketTest, ParseBuffer) {
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200405 rtc::CopyOnWriteBuffer unparsed(kMinimumPacket);
danilchap1edb7ab2016-04-20 05:25:10 -0700406 const uint8_t* raw = unparsed.data();
407
408 RtpPacketReceived packet;
409 EXPECT_TRUE(packet.Parse(std::move(unparsed)));
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200410 EXPECT_EQ(raw, packet.data()); // Expect packet take the buffer without copy.
danilchap1edb7ab2016-04-20 05:25:10 -0700411 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
412 EXPECT_EQ(kTimestamp, packet.Timestamp());
413 EXPECT_EQ(kSsrc, packet.Ssrc());
414 EXPECT_EQ(0u, packet.padding_size());
415 EXPECT_EQ(0u, packet.payload_size());
416}
417
418TEST(RtpPacketTest, ParseWithExtension) {
419 RtpPacketToSend::ExtensionManager extensions;
420 extensions.Register(kRtpExtensionTransmissionTimeOffset,
421 kTransmissionOffsetExtensionId);
422
423 RtpPacketReceived packet(&extensions);
424 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
425 EXPECT_EQ(kPayloadType, packet.PayloadType());
426 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
427 EXPECT_EQ(kTimestamp, packet.Timestamp());
428 EXPECT_EQ(kSsrc, packet.Ssrc());
429 int32_t time_offset;
430 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
431 EXPECT_EQ(kTimeOffset, time_offset);
432 EXPECT_EQ(0u, packet.payload_size());
433 EXPECT_EQ(0u, packet.padding_size());
434}
435
Danil Chapovalove19953b2018-10-01 16:12:28 +0200436TEST(RtpPacketTest, GetRawExtensionWhenPresent) {
437 constexpr uint8_t kRawPacket[] = {
438 // comment for clang-format to align kRawPacket nicer.
439 0x90, 100, 0x5e, 0x04, //
440 0x65, 0x43, 0x12, 0x78, // Timestamp.
441 0x12, 0x34, 0x56, 0x78, // Ssrc
442 0xbe, 0xde, 0x00, 0x01, // Extension header
443 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
444 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
445 RtpPacketToSend::ExtensionManager extensions;
446 extensions.Register<RtpMid>(1);
447 RtpPacket packet(&extensions);
448 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
449 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), ElementsAre('m', 'i', 'd'));
450}
451
452TEST(RtpPacketTest, GetRawExtensionWhenAbsent) {
453 constexpr uint8_t kRawPacket[] = {
454 // comment for clang-format to align kRawPacket nicer.
455 0x90, 100, 0x5e, 0x04, //
456 0x65, 0x43, 0x12, 0x78, // Timestamp.
457 0x12, 0x34, 0x56, 0x78, // Ssrc
458 0xbe, 0xde, 0x00, 0x01, // Extension header
459 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
460 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
461 RtpPacketToSend::ExtensionManager extensions;
462 extensions.Register<RtpMid>(2);
463 RtpPacket packet(&extensions);
464 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
465 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), IsEmpty());
466}
467
danilchap07ec26d2016-06-17 04:18:54 -0700468TEST(RtpPacketTest, ParseWithInvalidSizedExtension) {
469 RtpPacketToSend::ExtensionManager extensions;
470 extensions.Register(kRtpExtensionTransmissionTimeOffset,
471 kTransmissionOffsetExtensionId);
472
473 RtpPacketReceived packet(&extensions);
474 EXPECT_TRUE(packet.Parse(kPacketWithInvalidExtension,
475 sizeof(kPacketWithInvalidExtension)));
476
477 // Extension should be ignored.
478 int32_t time_offset;
479 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
480
481 // But shouldn't prevent reading payload.
danilchap96c15872016-11-21 01:35:29 -0800482 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap07ec26d2016-06-17 04:18:54 -0700483}
484
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200485TEST(RtpPacketTest, ParseWithOverSizedExtension) {
486 // clang-format off
487 const uint8_t bad_packet[] = {
eladalonae550e32017-05-24 08:28:13 -0700488 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200489 0x65, 0x43, 0x12, 0x78, // kTimestamp.
490 0x12, 0x34, 0x56, 0x78, // kSsrc.
491 0xbe, 0xde, 0x00, 0x01, // Extension of size 1x32bit word.
492 0x00, // Add a byte of padding.
493 0x12, // Extension id 1 size (2+1).
494 0xda, 0x1a // Only 2 bytes of extension payload.
495 };
496 // clang-format on
497 RtpPacketToSend::ExtensionManager extensions;
498 extensions.Register(TransmissionOffset::kId, 1);
499 RtpPacketReceived packet(&extensions);
500
501 // Parse should ignore bad extension and proceed.
502 EXPECT_TRUE(packet.Parse(bad_packet, sizeof(bad_packet)));
503 int32_t time_offset;
504 // But extracting extension should fail.
505 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
506}
507
danilchap1edb7ab2016-04-20 05:25:10 -0700508TEST(RtpPacketTest, ParseWith2Extensions) {
509 RtpPacketToSend::ExtensionManager extensions;
510 extensions.Register(kRtpExtensionTransmissionTimeOffset,
511 kTransmissionOffsetExtensionId);
512 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
513 RtpPacketReceived packet(&extensions);
514 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
515 int32_t time_offset;
516 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
517 EXPECT_EQ(kTimeOffset, time_offset);
518 bool voice_active;
519 uint8_t audio_level;
520 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
521 EXPECT_EQ(kVoiceActive, voice_active);
522 EXPECT_EQ(kAudioLevel, audio_level);
523}
524
Johannes Kron6ea77192018-09-24 17:19:52 +0200525TEST(RtpPacketTest, ParseSecondPacketWithFewerExtensions) {
526 RtpPacketToSend::ExtensionManager extensions;
527 extensions.Register(kRtpExtensionTransmissionTimeOffset,
528 kTransmissionOffsetExtensionId);
529 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
530 RtpPacketReceived packet(&extensions);
531 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
532 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
533 EXPECT_TRUE(packet.HasExtension<AudioLevel>());
534
535 // Second packet without audio level.
536 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
537 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
538 EXPECT_FALSE(packet.HasExtension<AudioLevel>());
539}
540
Johannes Kron07ba2b92018-09-26 13:33:35 +0200541TEST(RtpPacketTest, ParseWith2ExtensionsInvalidPadding) {
542 RtpPacketToSend::ExtensionManager extensions;
543 extensions.Register(kRtpExtensionTransmissionTimeOffset,
544 kTransmissionOffsetExtensionId);
545 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
546 RtpPacketReceived packet(&extensions);
547 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALInvalidPadding,
548 sizeof(kPacketWithTOAndALInvalidPadding)));
549 int32_t time_offset;
550 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
551 EXPECT_EQ(kTimeOffset, time_offset);
552 bool voice_active;
553 uint8_t audio_level;
554 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
555}
556
557TEST(RtpPacketTest, ParseWith2ExtensionsReservedExtensionId) {
558 RtpPacketToSend::ExtensionManager extensions;
559 extensions.Register(kRtpExtensionTransmissionTimeOffset,
560 kTransmissionOffsetExtensionId);
561 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
562 RtpPacketReceived packet(&extensions);
563 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALReservedExtensionId,
564 sizeof(kPacketWithTOAndALReservedExtensionId)));
565 int32_t time_offset;
566 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
567 EXPECT_EQ(kTimeOffset, time_offset);
568 bool voice_active;
569 uint8_t audio_level;
570 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
571}
572
danilchap1edb7ab2016-04-20 05:25:10 -0700573TEST(RtpPacketTest, ParseWithAllFeatures) {
574 RtpPacketToSend::ExtensionManager extensions;
575 extensions.Register(kRtpExtensionTransmissionTimeOffset,
576 kTransmissionOffsetExtensionId);
577 RtpPacketReceived packet(&extensions);
578 EXPECT_TRUE(packet.Parse(kPacket, sizeof(kPacket)));
579 EXPECT_EQ(kPayloadType, packet.PayloadType());
580 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
581 EXPECT_EQ(kTimestamp, packet.Timestamp());
582 EXPECT_EQ(kSsrc, packet.Ssrc());
583 EXPECT_THAT(packet.Csrcs(), ElementsAreArray(kCsrcs));
danilchap96c15872016-11-21 01:35:29 -0800584 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap1edb7ab2016-04-20 05:25:10 -0700585 EXPECT_EQ(kPacketPaddingSize, packet.padding_size());
586 int32_t time_offset;
587 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
588}
589
Johannes Kron07ba2b92018-09-26 13:33:35 +0200590TEST(RtpPacketTest, ParseTwoByteHeaderExtension) {
591 RtpPacketToSend::ExtensionManager extensions;
592 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
593 RtpPacketReceived packet(&extensions);
594 EXPECT_TRUE(packet.Parse(kPacketWithTwoByteHeaderExtension,
595 sizeof(kPacketWithTwoByteHeaderExtension)));
596 int32_t time_offset;
597 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
598 EXPECT_EQ(kTimeOffset, time_offset);
599}
600
601TEST(RtpPacketTest, ParseLongTwoByteHeaderExtension) {
602 RtpPacketToSend::ExtensionManager extensions;
603 extensions.Register(kRtpExtensionMid, kTwoByteExtensionId);
604 RtpPacketReceived packet(&extensions);
605 EXPECT_TRUE(packet.Parse(kPacketWithLongTwoByteHeaderExtension,
606 sizeof(kPacketWithLongTwoByteHeaderExtension)));
607 std::string long_rtp_mid;
608 EXPECT_TRUE(packet.GetExtension<RtpMid>(&long_rtp_mid));
609 EXPECT_EQ(kLongMid, long_rtp_mid);
610}
611
612TEST(RtpPacketTest, ParseTwoByteHeaderExtensionWithPadding) {
613 RtpPacketToSend::ExtensionManager extensions;
614 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
615 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
616 RtpPacketReceived packet(&extensions);
617 EXPECT_TRUE(
618 packet.Parse(kPacketWithTwoByteHeaderExtensionWithPadding,
619 sizeof(kPacketWithTwoByteHeaderExtensionWithPadding)));
620 int32_t time_offset;
621 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
622 EXPECT_EQ(kTimeOffset, time_offset);
623 bool voice_active;
624 uint8_t audio_level;
625 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
626 EXPECT_EQ(kVoiceActive, voice_active);
627 EXPECT_EQ(kAudioLevel, audio_level);
628}
629
danilchap1edb7ab2016-04-20 05:25:10 -0700630TEST(RtpPacketTest, ParseWithExtensionDelayed) {
631 RtpPacketReceived packet;
632 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
633 EXPECT_EQ(kPayloadType, packet.PayloadType());
634 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
635 EXPECT_EQ(kTimestamp, packet.Timestamp());
636 EXPECT_EQ(kSsrc, packet.Ssrc());
637
638 RtpPacketToSend::ExtensionManager extensions;
639 extensions.Register(kRtpExtensionTransmissionTimeOffset,
640 kTransmissionOffsetExtensionId);
641
642 int32_t time_offset;
643 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
danilchap70f39a32016-12-16 05:48:18 -0800644 packet.IdentifyExtensions(extensions);
danilchap1edb7ab2016-04-20 05:25:10 -0700645 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
646 EXPECT_EQ(kTimeOffset, time_offset);
647 EXPECT_EQ(0u, packet.payload_size());
648 EXPECT_EQ(0u, packet.padding_size());
649}
650
danilchapef8d7732017-04-19 02:59:48 -0700651TEST(RtpPacketTest, ParseDynamicSizeExtension) {
652 // clang-format off
653 const uint8_t kPacket1[] = {
eladalonae550e32017-05-24 08:28:13 -0700654 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700655 0x65, 0x43, 0x12, 0x78, // Timestamp.
656 0x12, 0x34, 0x56, 0x78, // Ssrc.
657 0xbe, 0xde, 0x00, 0x02, // Extensions block of size 2x32bit words.
658 0x21, 'H', 'D', // Extension with id = 2, size = (1+1).
659 0x12, 'r', 't', 'x', // Extension with id = 1, size = (2+1).
660 0x00}; // Extension padding.
661 const uint8_t kPacket2[] = {
eladalonae550e32017-05-24 08:28:13 -0700662 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700663 0x65, 0x43, 0x12, 0x78, // Timestamp.
664 0x12, 0x34, 0x56, 0x79, // Ssrc.
665 0xbe, 0xde, 0x00, 0x01, // Extensions block of size 1x32bit words.
666 0x11, 'H', 'D', // Extension with id = 1, size = (1+1).
667 0x00}; // Extension padding.
668 // clang-format on
669 RtpPacketReceived::ExtensionManager extensions;
670 extensions.Register<RtpStreamId>(1);
671 extensions.Register<RepairedRtpStreamId>(2);
672 RtpPacketReceived packet(&extensions);
673 ASSERT_TRUE(packet.Parse(kPacket1, sizeof(kPacket1)));
674
675 std::string rsid;
676 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
677 EXPECT_EQ(rsid, "rtx");
678
679 std::string repaired_rsid;
680 EXPECT_TRUE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
681 EXPECT_EQ(repaired_rsid, "HD");
682
683 // Parse another packet with RtpStreamId extension of different size.
684 ASSERT_TRUE(packet.Parse(kPacket2, sizeof(kPacket2)));
685 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
686 EXPECT_EQ(rsid, "HD");
687 EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
688}
689
Steve Antona3251dd2017-07-21 09:58:31 -0700690TEST(RtpPacketTest, ParseWithMid) {
691 RtpPacketReceived::ExtensionManager extensions;
692 extensions.Register<RtpMid>(kRtpMidExtensionId);
693 RtpPacketReceived packet(&extensions);
694 ASSERT_TRUE(packet.Parse(kPacketWithMid, sizeof(kPacketWithMid)));
695
696 std::string mid;
697 EXPECT_TRUE(packet.GetExtension<RtpMid>(&mid));
698 EXPECT_EQ(mid, kMid);
699}
700
sprangba050a62017-08-18 02:51:12 -0700701TEST(RtpPacketTest, CreateAndParseTimingFrameExtension) {
702 // Create a packet with video frame timing extension populated.
703 RtpPacketToSend::ExtensionManager send_extensions;
704 send_extensions.Register(kRtpExtensionVideoTiming, kVideoTimingExtensionId);
705 RtpPacketToSend send_packet(&send_extensions);
706 send_packet.SetPayloadType(kPayloadType);
707 send_packet.SetSequenceNumber(kSeqNum);
708 send_packet.SetTimestamp(kTimestamp);
709 send_packet.SetSsrc(kSsrc);
710
711 VideoSendTiming timing;
712 timing.encode_start_delta_ms = 1;
713 timing.encode_finish_delta_ms = 2;
714 timing.packetization_finish_delta_ms = 3;
715 timing.pacer_exit_delta_ms = 4;
716 timing.flags =
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +0200717 VideoSendTiming::kTriggeredByTimer | VideoSendTiming::kTriggeredBySize;
sprangba050a62017-08-18 02:51:12 -0700718
719 send_packet.SetExtension<VideoTimingExtension>(timing);
720
721 // Serialize the packet and then parse it again.
722 RtpPacketReceived::ExtensionManager extensions;
723 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
724 RtpPacketReceived receive_packet(&extensions);
725 EXPECT_TRUE(receive_packet.Parse(send_packet.Buffer()));
726
727 VideoSendTiming receivied_timing;
728 EXPECT_TRUE(
729 receive_packet.GetExtension<VideoTimingExtension>(&receivied_timing));
730
731 // Only check first and last timestamp (covered by other tests) plus flags.
732 EXPECT_EQ(receivied_timing.encode_start_delta_ms,
733 timing.encode_start_delta_ms);
734 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, timing.pacer_exit_delta_ms);
735 EXPECT_EQ(receivied_timing.flags, timing.flags);
736}
737
738TEST(RtpPacketTest, ParseLegacyTimingFrameExtension) {
739 // Parse the modified packet.
740 RtpPacketReceived::ExtensionManager extensions;
741 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
742 RtpPacketReceived packet(&extensions);
743 EXPECT_TRUE(packet.Parse(kPacketWithLegacyTimingExtension,
744 sizeof(kPacketWithLegacyTimingExtension)));
745 VideoSendTiming receivied_timing;
746 EXPECT_TRUE(packet.GetExtension<VideoTimingExtension>(&receivied_timing));
747
748 // Check first and last timestamp are still OK. Flags should now be 0.
749 EXPECT_EQ(receivied_timing.encode_start_delta_ms, 1);
750 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, 4);
751 EXPECT_EQ(receivied_timing.flags, 0);
752}
753
danilchap1edb7ab2016-04-20 05:25:10 -0700754} // namespace webrtc