blob: b1c0e42525eae52677c0f80a0ccf64171459e4e7 [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
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +020022using ::testing::Each;
Danil Chapovalove19953b2018-10-01 16:12:28 +020023using ::testing::ElementsAre;
danilchapc547e842017-04-10 01:31:49 -070024using ::testing::ElementsAreArray;
25using ::testing::IsEmpty;
26using ::testing::make_tuple;
27
danilchap1edb7ab2016-04-20 05:25:10 -070028constexpr int8_t kPayloadType = 100;
29constexpr uint32_t kSsrc = 0x12345678;
eladalonae550e32017-05-24 08:28:13 -070030constexpr uint16_t kSeqNum = 0x1234;
31constexpr uint8_t kSeqNumFirstByte = kSeqNum >> 8;
32constexpr uint8_t kSeqNumSecondByte = kSeqNum & 0xff;
danilchap1edb7ab2016-04-20 05:25:10 -070033constexpr uint32_t kTimestamp = 0x65431278;
34constexpr uint8_t kTransmissionOffsetExtensionId = 1;
35constexpr uint8_t kAudioLevelExtensionId = 9;
erikvargae6b16192017-05-11 02:36:32 -070036constexpr uint8_t kRtpStreamIdExtensionId = 0xa;
Steve Antona3251dd2017-07-21 09:58:31 -070037constexpr uint8_t kRtpMidExtensionId = 0xb;
sprangba050a62017-08-18 02:51:12 -070038constexpr uint8_t kVideoTimingExtensionId = 0xc;
Johannes Kron07ba2b92018-09-26 13:33:35 +020039constexpr uint8_t kTwoByteExtensionId = 0xf0;
danilchap1edb7ab2016-04-20 05:25:10 -070040constexpr int32_t kTimeOffset = 0x56ce;
41constexpr bool kVoiceActive = true;
42constexpr uint8_t kAudioLevel = 0x5a;
erikvargae6b16192017-05-11 02:36:32 -070043constexpr char kStreamId[] = "streamid";
Steve Antona3251dd2017-07-21 09:58:31 -070044constexpr char kMid[] = "mid";
Johannes Kron07ba2b92018-09-26 13:33:35 +020045constexpr char kLongMid[] = "extra-long string to test two-byte header";
danilchap1edb7ab2016-04-20 05:25:10 -070046constexpr size_t kMaxPaddingSize = 224u;
danilchap07ec26d2016-06-17 04:18:54 -070047// clang-format off
danilchap1edb7ab2016-04-20 05:25:10 -070048constexpr uint8_t kMinimumPacket[] = {
eladalonae550e32017-05-24 08:28:13 -070049 0x80, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070050 0x65, 0x43, 0x12, 0x78,
51 0x12, 0x34, 0x56, 0x78};
erikvargae6b16192017-05-11 02:36:32 -070052
danilchap1edb7ab2016-04-20 05:25:10 -070053constexpr uint8_t kPacketWithTO[] = {
eladalonae550e32017-05-24 08:28:13 -070054 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070055 0x65, 0x43, 0x12, 0x78,
56 0x12, 0x34, 0x56, 0x78,
57 0xbe, 0xde, 0x00, 0x01,
58 0x12, 0x00, 0x56, 0xce};
59
60constexpr uint8_t kPacketWithTOAndAL[] = {
eladalonae550e32017-05-24 08:28:13 -070061 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -070062 0x65, 0x43, 0x12, 0x78,
63 0x12, 0x34, 0x56, 0x78,
64 0xbe, 0xde, 0x00, 0x02,
65 0x12, 0x00, 0x56, 0xce,
66 0x90, 0x80|kAudioLevel, 0x00, 0x00};
67
Johannes Kron78cdde32018-10-05 10:00:46 +020068constexpr uint8_t kPacketWithTwoByteExtensionIdLast[] = {
69 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
70 0x65, 0x43, 0x12, 0x78,
71 0x12, 0x34, 0x56, 0x78,
72 0x10, 0x00, 0x00, 0x04,
73 0x01, 0x03, 0x00, 0x56,
74 0xce, 0x09, 0x01, 0x80|kAudioLevel,
75 kTwoByteExtensionId, 0x03, 0x00, 0x30, // => 0x00 0x30 0x22
76 0x22, 0x00, 0x00, 0x00}; // => Playout delay.min_ms = 3*10
77 // => Playout delay.max_ms = 34*10
78
79constexpr uint8_t kPacketWithTwoByteExtensionIdFirst[] = {
80 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
81 0x65, 0x43, 0x12, 0x78,
82 0x12, 0x34, 0x56, 0x78,
83 0x10, 0x00, 0x00, 0x04,
84 kTwoByteExtensionId, 0x03, 0x00, 0x30, // => 0x00 0x30 0x22
85 0x22, 0x01, 0x03, 0x00, // => Playout delay.min_ms = 3*10
86 0x56, 0xce, 0x09, 0x01, // => Playout delay.max_ms = 34*10
87 0x80|kAudioLevel, 0x00, 0x00, 0x00};
88
Johannes Kron07ba2b92018-09-26 13:33:35 +020089constexpr uint8_t kPacketWithTOAndALInvalidPadding[] = {
90 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
91 0x65, 0x43, 0x12, 0x78,
92 0x12, 0x34, 0x56, 0x78,
93 0xbe, 0xde, 0x00, 0x03,
94 0x12, 0x00, 0x56, 0xce,
95 0x00, 0x02, 0x00, 0x00, // 0x02 is invalid padding, parsing should stop.
96 0x90, 0x80|kAudioLevel, 0x00, 0x00};
97
98constexpr uint8_t kPacketWithTOAndALReservedExtensionId[] = {
99 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
100 0x65, 0x43, 0x12, 0x78,
101 0x12, 0x34, 0x56, 0x78,
102 0xbe, 0xde, 0x00, 0x03,
103 0x12, 0x00, 0x56, 0xce,
104 0x00, 0xF0, 0x00, 0x00, // F is a reserved id, parsing should stop.
105 0x90, 0x80|kAudioLevel, 0x00, 0x00};
106
erikvargae6b16192017-05-11 02:36:32 -0700107constexpr uint8_t kPacketWithRsid[] = {
eladalonae550e32017-05-24 08:28:13 -0700108 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
erikvargae6b16192017-05-11 02:36:32 -0700109 0x65, 0x43, 0x12, 0x78,
110 0x12, 0x34, 0x56, 0x78,
111 0xbe, 0xde, 0x00, 0x03,
112 0xa7, 's', 't', 'r',
113 'e', 'a', 'm', 'i',
114 'd' , 0x00, 0x00, 0x00};
115
Steve Antona3251dd2017-07-21 09:58:31 -0700116constexpr uint8_t kPacketWithMid[] = {
117 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
118 0x65, 0x43, 0x12, 0x78,
119 0x12, 0x34, 0x56, 0x78,
120 0xbe, 0xde, 0x00, 0x01,
121 0xb2, 'm', 'i', 'd'};
122
danilchap1edb7ab2016-04-20 05:25:10 -0700123constexpr uint32_t kCsrcs[] = {0x34567890, 0x32435465};
124constexpr uint8_t kPayload[] = {'p', 'a', 'y', 'l', 'o', 'a', 'd'};
125constexpr uint8_t kPacketPaddingSize = 8;
126constexpr uint8_t kPacket[] = {
eladalonae550e32017-05-24 08:28:13 -0700127 0xb2, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap1edb7ab2016-04-20 05:25:10 -0700128 0x65, 0x43, 0x12, 0x78,
129 0x12, 0x34, 0x56, 0x78,
130 0x34, 0x56, 0x78, 0x90,
131 0x32, 0x43, 0x54, 0x65,
132 0xbe, 0xde, 0x00, 0x01,
133 0x12, 0x00, 0x56, 0xce,
134 'p', 'a', 'y', 'l', 'o', 'a', 'd',
135 'p', 'a', 'd', 'd', 'i', 'n', 'g', kPacketPaddingSize};
danilchape565a042016-06-16 10:04:50 -0700136
Johannes Kron07ba2b92018-09-26 13:33:35 +0200137constexpr uint8_t kPacketWithTwoByteHeaderExtension[] = {
138 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
139 0x65, 0x43, 0x12, 0x78,
140 0x12, 0x34, 0x56, 0x78,
141 0x10, 0x00, 0x00, 0x02, // Two-byte header extension profile id + length.
142 kTwoByteExtensionId, 0x03, 0x00, 0x56,
143 0xce, 0x00, 0x00, 0x00};
144
145constexpr uint8_t kPacketWithLongTwoByteHeaderExtension[] = {
146 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
147 0x65, 0x43, 0x12, 0x78,
148 0x12, 0x34, 0x56, 0x78,
149 0x10, 0x00, 0x00, 0x0B, // Two-byte header extension profile id + length.
150 kTwoByteExtensionId, 0x29, 'e', 'x',
151 't', 'r', 'a', '-', 'l', 'o', 'n', 'g',
152 ' ', 's', 't', 'r', 'i', 'n', 'g', ' ',
153 't', 'o', ' ', 't', 'e', 's', 't', ' ',
154 't', 'w', 'o', '-', 'b', 'y', 't', 'e',
155 ' ', 'h', 'e', 'a', 'd', 'e', 'r', 0x00};
156
157constexpr uint8_t kPacketWithTwoByteHeaderExtensionWithPadding[] = {
158 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
159 0x65, 0x43, 0x12, 0x78,
160 0x12, 0x34, 0x56, 0x78,
161 0x10, 0x00, 0x00, 0x03, // Two-byte header extension profile id + length.
162 kTwoByteExtensionId, 0x03, 0x00, 0x56,
163 0xce, 0x00, 0x00, 0x00, // Three padding bytes.
164 kAudioLevelExtensionId, 0x01, 0x80|kAudioLevel, 0x00};
165
danilchap07ec26d2016-06-17 04:18:54 -0700166constexpr uint8_t kPacketWithInvalidExtension[] = {
eladalonae550e32017-05-24 08:28:13 -0700167 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchap07ec26d2016-06-17 04:18:54 -0700168 0x65, 0x43, 0x12, 0x78, // kTimestamp.
169 0x12, 0x34, 0x56, 0x78, // kSSrc.
170 0xbe, 0xde, 0x00, 0x02, // Extension block of size 2 x 32bit words.
171 (kTransmissionOffsetExtensionId << 4) | 6, // (6+1)-byte extension, but
172 'e', 'x', 't', // Transmission Offset
173 'd', 'a', 't', 'a', // expected to be 3-bytes.
sprangba050a62017-08-18 02:51:12 -0700174 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
175
176constexpr uint8_t kPacketWithLegacyTimingExtension[] = {
177 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
178 0x65, 0x43, 0x12, 0x78, // kTimestamp.
179 0x12, 0x34, 0x56, 0x78, // kSSrc.
180 0xbe, 0xde, 0x00, 0x04, // Extension block of size 4 x 32bit words.
181 (kVideoTimingExtensionId << 4)
182 | VideoTimingExtension::kValueSizeBytes - 2, // Old format without flags.
183 0x00, 0x01, 0x00,
184 0x02, 0x00, 0x03, 0x00,
185 0x04, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00};
danilchap07ec26d2016-06-17 04:18:54 -0700187// clang-format on
Johannes Kronad1d9f02018-11-09 11:12:36 +0100188
189HdrMetadata CreateTestHdrMetadata() {
190 // Random but reasonable HDR metadata.
191 HdrMetadata hdr_metadata;
192 hdr_metadata.mastering_metadata.luminance_max = 2000.0;
193 hdr_metadata.mastering_metadata.luminance_min = 2.0001;
194 hdr_metadata.mastering_metadata.primary_r.x = 0.3003;
195 hdr_metadata.mastering_metadata.primary_r.y = 0.4004;
196 hdr_metadata.mastering_metadata.primary_g.x = 0.3201;
197 hdr_metadata.mastering_metadata.primary_g.y = 0.4604;
198 hdr_metadata.mastering_metadata.primary_b.x = 0.3409;
199 hdr_metadata.mastering_metadata.primary_b.y = 0.4907;
200 hdr_metadata.mastering_metadata.white_point.x = 0.4103;
201 hdr_metadata.mastering_metadata.white_point.y = 0.4806;
202 hdr_metadata.max_content_light_level = 2345;
203 hdr_metadata.max_frame_average_light_level = 1789;
204 return hdr_metadata;
205}
Johannes Kron09d65882018-11-27 14:36:41 +0100206
207ColorSpace CreateTestColorSpace(bool with_hdr_metadata) {
208 ColorSpace color_space(
209 ColorSpace::PrimaryID::kBT709, ColorSpace::TransferID::kGAMMA22,
210 ColorSpace::MatrixID::kSMPTE2085, ColorSpace::RangeID::kFull);
211 if (with_hdr_metadata) {
212 HdrMetadata hdr_metadata = CreateTestHdrMetadata();
213 color_space.set_hdr_metadata(&hdr_metadata);
214 }
215 return color_space;
216}
217
218void TestCreateAndParseColorSpaceExtension(bool with_hdr_metadata) {
219 // Create packet with extension.
220 RtpPacket::ExtensionManager extensions(/*extmap-allow-mixed=*/true);
221 extensions.Register<ColorSpaceExtension>(1);
222 RtpPacket packet(&extensions);
223 const ColorSpace kColorSpace = CreateTestColorSpace(with_hdr_metadata);
224 EXPECT_TRUE(packet.SetExtension<ColorSpaceExtension>(kColorSpace));
225 packet.SetPayloadSize(42);
226
227 // Read packet with the extension.
228 RtpPacketReceived parsed(&extensions);
229 EXPECT_TRUE(parsed.Parse(packet.Buffer()));
230 ColorSpace parsed_color_space;
231 EXPECT_TRUE(parsed.GetExtension<ColorSpaceExtension>(&parsed_color_space));
232 EXPECT_EQ(kColorSpace, parsed_color_space);
233}
danilchap1edb7ab2016-04-20 05:25:10 -0700234} // namespace
235
236TEST(RtpPacketTest, CreateMinimum) {
237 RtpPacketToSend packet(nullptr);
238 packet.SetPayloadType(kPayloadType);
239 packet.SetSequenceNumber(kSeqNum);
240 packet.SetTimestamp(kTimestamp);
241 packet.SetSsrc(kSsrc);
242 EXPECT_THAT(kMinimumPacket, ElementsAreArray(packet.data(), packet.size()));
243}
244
245TEST(RtpPacketTest, CreateWithExtension) {
246 RtpPacketToSend::ExtensionManager extensions;
247 extensions.Register(kRtpExtensionTransmissionTimeOffset,
248 kTransmissionOffsetExtensionId);
249 RtpPacketToSend packet(&extensions);
250 packet.SetPayloadType(kPayloadType);
251 packet.SetSequenceNumber(kSeqNum);
252 packet.SetTimestamp(kTimestamp);
253 packet.SetSsrc(kSsrc);
254 packet.SetExtension<TransmissionOffset>(kTimeOffset);
255 EXPECT_THAT(kPacketWithTO, ElementsAreArray(packet.data(), packet.size()));
256}
257
258TEST(RtpPacketTest, CreateWith2Extensions) {
259 RtpPacketToSend::ExtensionManager extensions;
260 extensions.Register(kRtpExtensionTransmissionTimeOffset,
261 kTransmissionOffsetExtensionId);
262 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
263 RtpPacketToSend packet(&extensions);
264 packet.SetPayloadType(kPayloadType);
265 packet.SetSequenceNumber(kSeqNum);
266 packet.SetTimestamp(kTimestamp);
267 packet.SetSsrc(kSsrc);
268 packet.SetExtension<TransmissionOffset>(kTimeOffset);
269 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
270 EXPECT_THAT(kPacketWithTOAndAL,
271 ElementsAreArray(packet.data(), packet.size()));
272}
273
Johannes Kron78cdde32018-10-05 10:00:46 +0200274TEST(RtpPacketTest, CreateWithTwoByteHeaderExtensionFirst) {
Johannes Kron9581bc42018-10-23 10:17:39 +0200275 RtpPacketToSend::ExtensionManager extensions(true);
Johannes Kron78cdde32018-10-05 10:00:46 +0200276 extensions.Register(kRtpExtensionTransmissionTimeOffset,
277 kTransmissionOffsetExtensionId);
278 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
279 extensions.Register(kRtpExtensionPlayoutDelay, kTwoByteExtensionId);
280 RtpPacketToSend packet(&extensions);
281 packet.SetPayloadType(kPayloadType);
282 packet.SetSequenceNumber(kSeqNum);
283 packet.SetTimestamp(kTimestamp);
284 packet.SetSsrc(kSsrc);
285 // Set extension that requires two-byte header.
286 PlayoutDelay playoutDelay = {30, 340};
287 ASSERT_TRUE(packet.SetExtension<PlayoutDelayLimits>(playoutDelay));
288 packet.SetExtension<TransmissionOffset>(kTimeOffset);
289 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
290 EXPECT_THAT(kPacketWithTwoByteExtensionIdFirst,
291 ElementsAreArray(packet.data(), packet.size()));
292}
293
294TEST(RtpPacketTest, CreateWithTwoByteHeaderExtensionLast) {
295 // This test will trigger RtpPacket::PromoteToTwoByteHeaderExtension().
Johannes Kron9581bc42018-10-23 10:17:39 +0200296 RtpPacketToSend::ExtensionManager extensions(true);
Johannes Kron78cdde32018-10-05 10:00:46 +0200297 extensions.Register(kRtpExtensionTransmissionTimeOffset,
298 kTransmissionOffsetExtensionId);
299 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
300 extensions.Register(kRtpExtensionPlayoutDelay, kTwoByteExtensionId);
301 RtpPacketToSend packet(&extensions);
302 packet.SetPayloadType(kPayloadType);
303 packet.SetSequenceNumber(kSeqNum);
304 packet.SetTimestamp(kTimestamp);
305 packet.SetSsrc(kSsrc);
306 packet.SetExtension<TransmissionOffset>(kTimeOffset);
307 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
308 EXPECT_THAT(kPacketWithTOAndAL,
309 ElementsAreArray(packet.data(), packet.size()));
310 // Set extension that requires two-byte header.
311 PlayoutDelay playoutDelay = {30, 340};
312 ASSERT_TRUE(packet.SetExtension<PlayoutDelayLimits>(playoutDelay));
313 EXPECT_THAT(kPacketWithTwoByteExtensionIdLast,
314 ElementsAreArray(packet.data(), packet.size()));
315}
316
erikvargae6b16192017-05-11 02:36:32 -0700317TEST(RtpPacketTest, CreateWithDynamicSizedExtensions) {
318 RtpPacketToSend::ExtensionManager extensions;
319 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
320 RtpPacketToSend packet(&extensions);
321 packet.SetPayloadType(kPayloadType);
322 packet.SetSequenceNumber(kSeqNum);
323 packet.SetTimestamp(kTimestamp);
324 packet.SetSsrc(kSsrc);
325 packet.SetExtension<RtpStreamId>(kStreamId);
326 EXPECT_THAT(kPacketWithRsid, ElementsAreArray(packet.data(), packet.size()));
327}
328
329TEST(RtpPacketTest, TryToCreateWithEmptyRsid) {
330 RtpPacketToSend::ExtensionManager extensions;
331 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
332 RtpPacketToSend packet(&extensions);
333 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(""));
334}
335
336TEST(RtpPacketTest, TryToCreateWithLongRsid) {
337 RtpPacketToSend::ExtensionManager extensions;
338 constexpr char kLongStreamId[] = "LoooooooooongRsid";
339 ASSERT_EQ(strlen(kLongStreamId), 17u);
340 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
341 RtpPacketToSend packet(&extensions);
342 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kLongStreamId));
343}
344
Steve Antona3251dd2017-07-21 09:58:31 -0700345TEST(RtpPacketTest, TryToCreateWithEmptyMid) {
346 RtpPacketToSend::ExtensionManager extensions;
347 extensions.Register<RtpMid>(kRtpMidExtensionId);
348 RtpPacketToSend packet(&extensions);
349 EXPECT_FALSE(packet.SetExtension<RtpMid>(""));
350}
351
352TEST(RtpPacketTest, TryToCreateWithLongMid) {
353 RtpPacketToSend::ExtensionManager extensions;
354 constexpr char kLongMid[] = "LoooooooooonogMid";
355 ASSERT_EQ(strlen(kLongMid), 17u);
356 extensions.Register<RtpMid>(kRtpMidExtensionId);
357 RtpPacketToSend packet(&extensions);
358 EXPECT_FALSE(packet.SetExtension<RtpMid>(kLongMid));
359}
360
Johannes Kron78cdde32018-10-05 10:00:46 +0200361TEST(RtpPacketTest, TryToCreateTwoByteHeaderNotSupported) {
362 RtpPacketToSend::ExtensionManager extensions;
363 extensions.Register(kRtpExtensionAudioLevel, kTwoByteExtensionId);
364 RtpPacketToSend packet(&extensions);
365 // Set extension that requires two-byte header.
366 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
367}
368
danilchap653063f2017-04-03 06:16:30 -0700369TEST(RtpPacketTest, CreateWithMaxSizeHeaderExtension) {
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200370 const std::string kValue = "123456789abcdef";
371 RtpPacket::ExtensionManager extensions;
372 extensions.Register<RtpMid>(1);
373 extensions.Register<RtpStreamId>(2);
danilchap653063f2017-04-03 06:16:30 -0700374
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200375 RtpPacket packet(&extensions);
376 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700377
378 packet.SetPayloadSize(42);
379 // Rewriting allocated extension is allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200380 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700381 // Adding another extension after payload is set is not allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200382 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700383
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200384 // Read packet with the extension.
385 RtpPacketReceived parsed(&extensions);
danilchap653063f2017-04-03 06:16:30 -0700386 EXPECT_TRUE(parsed.Parse(packet.Buffer()));
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200387 std::string read;
388 EXPECT_TRUE(parsed.GetExtension<RtpMid>(&read));
389 EXPECT_EQ(read, kValue);
danilchap653063f2017-04-03 06:16:30 -0700390}
391
danilchap1edb7ab2016-04-20 05:25:10 -0700392TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
393 const size_t kPayloadSize = 4;
394 RtpPacketToSend::ExtensionManager extensions;
395 extensions.Register(kRtpExtensionTransmissionTimeOffset,
396 kTransmissionOffsetExtensionId);
397 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
398 RtpPacketToSend packet(&extensions);
399
400 EXPECT_TRUE(packet.ReserveExtension<TransmissionOffset>());
danilchap07a01b32017-03-29 07:33:13 -0700401 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700402 // Can't set extension after payload.
403 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
404 // Unless reserved.
405 EXPECT_TRUE(packet.SetExtension<TransmissionOffset>(kTimeOffset));
406}
407
408TEST(RtpPacketTest, CreatePurePadding) {
409 const size_t kPaddingSize = kMaxPaddingSize - 1;
410 RtpPacketToSend packet(nullptr, 12 + kPaddingSize);
411 packet.SetPayloadType(kPayloadType);
412 packet.SetSequenceNumber(kSeqNum);
413 packet.SetTimestamp(kTimestamp);
414 packet.SetSsrc(kSsrc);
danilchap1edb7ab2016-04-20 05:25:10 -0700415
416 EXPECT_LT(packet.size(), packet.capacity());
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +0200417 EXPECT_FALSE(packet.SetPadding(kPaddingSize + 1));
418 EXPECT_TRUE(packet.SetPadding(kPaddingSize));
danilchap1edb7ab2016-04-20 05:25:10 -0700419 EXPECT_EQ(packet.size(), packet.capacity());
420}
421
422TEST(RtpPacketTest, CreateUnalignedPadding) {
423 const size_t kPayloadSize = 3; // Make padding start at unaligned address.
424 RtpPacketToSend packet(nullptr, 12 + kPayloadSize + kMaxPaddingSize);
425 packet.SetPayloadType(kPayloadType);
426 packet.SetSequenceNumber(kSeqNum);
427 packet.SetTimestamp(kTimestamp);
428 packet.SetSsrc(kSsrc);
danilchap07a01b32017-03-29 07:33:13 -0700429 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700430
431 EXPECT_LT(packet.size(), packet.capacity());
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +0200432 EXPECT_TRUE(packet.SetPadding(kMaxPaddingSize));
danilchap1edb7ab2016-04-20 05:25:10 -0700433 EXPECT_EQ(packet.size(), packet.capacity());
434}
435
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +0200436TEST(RtpPacketTest, WritesPaddingSizeToLastByte) {
437 const size_t kPaddingSize = 5;
438 RtpPacket packet;
439
440 EXPECT_TRUE(packet.SetPadding(kPaddingSize));
441 EXPECT_EQ(packet.data()[packet.size() - 1], kPaddingSize);
442}
443
444TEST(RtpPacketTest, UsesZerosForPadding) {
445 const size_t kPaddingSize = 5;
446 RtpPacket packet;
447
448 EXPECT_TRUE(packet.SetPadding(kPaddingSize));
449 EXPECT_THAT(rtc::MakeArrayView(packet.data() + 12, kPaddingSize - 1),
450 Each(0));
451}
452
453TEST(RtpPacketTest, CreateOneBytePadding) {
454 size_t kPayloadSize = 123;
455 RtpPacket packet(nullptr, 12 + kPayloadSize + 1);
456 packet.SetPayloadSize(kPayloadSize);
457
458 EXPECT_TRUE(packet.SetPadding(1));
459
460 EXPECT_EQ(packet.size(), 12 + kPayloadSize + 1);
461 EXPECT_EQ(packet.padding_size(), 1u);
462}
463
464TEST(RtpPacketTest, FailsToAddPaddingWithoutCapacity) {
465 size_t kPayloadSize = 123;
466 RtpPacket packet(nullptr, 12 + kPayloadSize);
467 packet.SetPayloadSize(kPayloadSize);
468
469 EXPECT_FALSE(packet.SetPadding(1));
470}
471
danilchap1edb7ab2016-04-20 05:25:10 -0700472TEST(RtpPacketTest, ParseMinimum) {
473 RtpPacketReceived packet;
474 EXPECT_TRUE(packet.Parse(kMinimumPacket, sizeof(kMinimumPacket)));
475 EXPECT_EQ(kPayloadType, packet.PayloadType());
476 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
477 EXPECT_EQ(kTimestamp, packet.Timestamp());
478 EXPECT_EQ(kSsrc, packet.Ssrc());
479 EXPECT_EQ(0u, packet.padding_size());
480 EXPECT_EQ(0u, packet.payload_size());
481}
482
483TEST(RtpPacketTest, ParseBuffer) {
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200484 rtc::CopyOnWriteBuffer unparsed(kMinimumPacket);
danilchap1edb7ab2016-04-20 05:25:10 -0700485 const uint8_t* raw = unparsed.data();
486
487 RtpPacketReceived packet;
488 EXPECT_TRUE(packet.Parse(std::move(unparsed)));
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200489 EXPECT_EQ(raw, packet.data()); // Expect packet take the buffer without copy.
danilchap1edb7ab2016-04-20 05:25:10 -0700490 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
491 EXPECT_EQ(kTimestamp, packet.Timestamp());
492 EXPECT_EQ(kSsrc, packet.Ssrc());
493 EXPECT_EQ(0u, packet.padding_size());
494 EXPECT_EQ(0u, packet.payload_size());
495}
496
497TEST(RtpPacketTest, ParseWithExtension) {
498 RtpPacketToSend::ExtensionManager extensions;
499 extensions.Register(kRtpExtensionTransmissionTimeOffset,
500 kTransmissionOffsetExtensionId);
501
502 RtpPacketReceived packet(&extensions);
503 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
504 EXPECT_EQ(kPayloadType, packet.PayloadType());
505 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
506 EXPECT_EQ(kTimestamp, packet.Timestamp());
507 EXPECT_EQ(kSsrc, packet.Ssrc());
508 int32_t time_offset;
509 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
510 EXPECT_EQ(kTimeOffset, time_offset);
511 EXPECT_EQ(0u, packet.payload_size());
512 EXPECT_EQ(0u, packet.padding_size());
513}
514
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100515TEST(RtpPacketTest, GetExtensionWithoutParametersReturnsOptionalValue) {
516 RtpPacket::ExtensionManager extensions;
517 extensions.Register<TransmissionOffset>(kTransmissionOffsetExtensionId);
518 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
519
520 RtpPacketReceived packet(&extensions);
521 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
522
523 auto time_offset = packet.GetExtension<TransmissionOffset>();
524 static_assert(
525 std::is_same<decltype(time_offset),
526 absl::optional<TransmissionOffset::value_type>>::value,
527 "");
528 EXPECT_EQ(time_offset, kTimeOffset);
529 EXPECT_FALSE(packet.GetExtension<RtpStreamId>().has_value());
530}
531
Danil Chapovalove19953b2018-10-01 16:12:28 +0200532TEST(RtpPacketTest, GetRawExtensionWhenPresent) {
533 constexpr uint8_t kRawPacket[] = {
534 // comment for clang-format to align kRawPacket nicer.
535 0x90, 100, 0x5e, 0x04, //
536 0x65, 0x43, 0x12, 0x78, // Timestamp.
537 0x12, 0x34, 0x56, 0x78, // Ssrc
538 0xbe, 0xde, 0x00, 0x01, // Extension header
539 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
540 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
541 RtpPacketToSend::ExtensionManager extensions;
542 extensions.Register<RtpMid>(1);
543 RtpPacket packet(&extensions);
544 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
545 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), ElementsAre('m', 'i', 'd'));
546}
547
548TEST(RtpPacketTest, GetRawExtensionWhenAbsent) {
549 constexpr uint8_t kRawPacket[] = {
550 // comment for clang-format to align kRawPacket nicer.
551 0x90, 100, 0x5e, 0x04, //
552 0x65, 0x43, 0x12, 0x78, // Timestamp.
553 0x12, 0x34, 0x56, 0x78, // Ssrc
554 0xbe, 0xde, 0x00, 0x01, // Extension header
555 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
556 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
557 RtpPacketToSend::ExtensionManager extensions;
558 extensions.Register<RtpMid>(2);
559 RtpPacket packet(&extensions);
560 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
561 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), IsEmpty());
562}
563
danilchap07ec26d2016-06-17 04:18:54 -0700564TEST(RtpPacketTest, ParseWithInvalidSizedExtension) {
565 RtpPacketToSend::ExtensionManager extensions;
566 extensions.Register(kRtpExtensionTransmissionTimeOffset,
567 kTransmissionOffsetExtensionId);
568
569 RtpPacketReceived packet(&extensions);
570 EXPECT_TRUE(packet.Parse(kPacketWithInvalidExtension,
571 sizeof(kPacketWithInvalidExtension)));
572
573 // Extension should be ignored.
574 int32_t time_offset;
575 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
576
577 // But shouldn't prevent reading payload.
danilchap96c15872016-11-21 01:35:29 -0800578 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap07ec26d2016-06-17 04:18:54 -0700579}
580
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200581TEST(RtpPacketTest, ParseWithOverSizedExtension) {
582 // clang-format off
583 const uint8_t bad_packet[] = {
eladalonae550e32017-05-24 08:28:13 -0700584 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200585 0x65, 0x43, 0x12, 0x78, // kTimestamp.
586 0x12, 0x34, 0x56, 0x78, // kSsrc.
587 0xbe, 0xde, 0x00, 0x01, // Extension of size 1x32bit word.
588 0x00, // Add a byte of padding.
589 0x12, // Extension id 1 size (2+1).
590 0xda, 0x1a // Only 2 bytes of extension payload.
591 };
592 // clang-format on
593 RtpPacketToSend::ExtensionManager extensions;
594 extensions.Register(TransmissionOffset::kId, 1);
595 RtpPacketReceived packet(&extensions);
596
597 // Parse should ignore bad extension and proceed.
598 EXPECT_TRUE(packet.Parse(bad_packet, sizeof(bad_packet)));
599 int32_t time_offset;
600 // But extracting extension should fail.
601 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
602}
603
danilchap1edb7ab2016-04-20 05:25:10 -0700604TEST(RtpPacketTest, ParseWith2Extensions) {
605 RtpPacketToSend::ExtensionManager extensions;
606 extensions.Register(kRtpExtensionTransmissionTimeOffset,
607 kTransmissionOffsetExtensionId);
608 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
609 RtpPacketReceived packet(&extensions);
610 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
611 int32_t time_offset;
612 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
613 EXPECT_EQ(kTimeOffset, time_offset);
614 bool voice_active;
615 uint8_t audio_level;
616 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
617 EXPECT_EQ(kVoiceActive, voice_active);
618 EXPECT_EQ(kAudioLevel, audio_level);
619}
620
Johannes Kron6ea77192018-09-24 17:19:52 +0200621TEST(RtpPacketTest, ParseSecondPacketWithFewerExtensions) {
622 RtpPacketToSend::ExtensionManager extensions;
623 extensions.Register(kRtpExtensionTransmissionTimeOffset,
624 kTransmissionOffsetExtensionId);
625 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
626 RtpPacketReceived packet(&extensions);
627 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
628 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
629 EXPECT_TRUE(packet.HasExtension<AudioLevel>());
630
631 // Second packet without audio level.
632 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
633 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
634 EXPECT_FALSE(packet.HasExtension<AudioLevel>());
635}
636
Johannes Kron07ba2b92018-09-26 13:33:35 +0200637TEST(RtpPacketTest, ParseWith2ExtensionsInvalidPadding) {
638 RtpPacketToSend::ExtensionManager extensions;
639 extensions.Register(kRtpExtensionTransmissionTimeOffset,
640 kTransmissionOffsetExtensionId);
641 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
642 RtpPacketReceived packet(&extensions);
643 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALInvalidPadding,
644 sizeof(kPacketWithTOAndALInvalidPadding)));
645 int32_t time_offset;
646 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
647 EXPECT_EQ(kTimeOffset, time_offset);
648 bool voice_active;
649 uint8_t audio_level;
650 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
651}
652
653TEST(RtpPacketTest, ParseWith2ExtensionsReservedExtensionId) {
654 RtpPacketToSend::ExtensionManager extensions;
655 extensions.Register(kRtpExtensionTransmissionTimeOffset,
656 kTransmissionOffsetExtensionId);
657 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
658 RtpPacketReceived packet(&extensions);
659 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALReservedExtensionId,
660 sizeof(kPacketWithTOAndALReservedExtensionId)));
661 int32_t time_offset;
662 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
663 EXPECT_EQ(kTimeOffset, time_offset);
664 bool voice_active;
665 uint8_t audio_level;
666 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
667}
668
danilchap1edb7ab2016-04-20 05:25:10 -0700669TEST(RtpPacketTest, ParseWithAllFeatures) {
670 RtpPacketToSend::ExtensionManager extensions;
671 extensions.Register(kRtpExtensionTransmissionTimeOffset,
672 kTransmissionOffsetExtensionId);
673 RtpPacketReceived packet(&extensions);
674 EXPECT_TRUE(packet.Parse(kPacket, sizeof(kPacket)));
675 EXPECT_EQ(kPayloadType, packet.PayloadType());
676 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
677 EXPECT_EQ(kTimestamp, packet.Timestamp());
678 EXPECT_EQ(kSsrc, packet.Ssrc());
679 EXPECT_THAT(packet.Csrcs(), ElementsAreArray(kCsrcs));
danilchap96c15872016-11-21 01:35:29 -0800680 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap1edb7ab2016-04-20 05:25:10 -0700681 EXPECT_EQ(kPacketPaddingSize, packet.padding_size());
682 int32_t time_offset;
683 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
684}
685
Johannes Kron07ba2b92018-09-26 13:33:35 +0200686TEST(RtpPacketTest, ParseTwoByteHeaderExtension) {
687 RtpPacketToSend::ExtensionManager extensions;
688 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
689 RtpPacketReceived packet(&extensions);
690 EXPECT_TRUE(packet.Parse(kPacketWithTwoByteHeaderExtension,
691 sizeof(kPacketWithTwoByteHeaderExtension)));
692 int32_t time_offset;
693 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
694 EXPECT_EQ(kTimeOffset, time_offset);
695}
696
697TEST(RtpPacketTest, ParseLongTwoByteHeaderExtension) {
698 RtpPacketToSend::ExtensionManager extensions;
699 extensions.Register(kRtpExtensionMid, kTwoByteExtensionId);
700 RtpPacketReceived packet(&extensions);
701 EXPECT_TRUE(packet.Parse(kPacketWithLongTwoByteHeaderExtension,
702 sizeof(kPacketWithLongTwoByteHeaderExtension)));
703 std::string long_rtp_mid;
704 EXPECT_TRUE(packet.GetExtension<RtpMid>(&long_rtp_mid));
705 EXPECT_EQ(kLongMid, long_rtp_mid);
706}
707
708TEST(RtpPacketTest, ParseTwoByteHeaderExtensionWithPadding) {
709 RtpPacketToSend::ExtensionManager extensions;
710 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
711 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
712 RtpPacketReceived packet(&extensions);
713 EXPECT_TRUE(
714 packet.Parse(kPacketWithTwoByteHeaderExtensionWithPadding,
715 sizeof(kPacketWithTwoByteHeaderExtensionWithPadding)));
716 int32_t time_offset;
717 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
718 EXPECT_EQ(kTimeOffset, time_offset);
719 bool voice_active;
720 uint8_t audio_level;
721 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
722 EXPECT_EQ(kVoiceActive, voice_active);
723 EXPECT_EQ(kAudioLevel, audio_level);
724}
725
danilchap1edb7ab2016-04-20 05:25:10 -0700726TEST(RtpPacketTest, ParseWithExtensionDelayed) {
727 RtpPacketReceived packet;
728 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
729 EXPECT_EQ(kPayloadType, packet.PayloadType());
730 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
731 EXPECT_EQ(kTimestamp, packet.Timestamp());
732 EXPECT_EQ(kSsrc, packet.Ssrc());
733
734 RtpPacketToSend::ExtensionManager extensions;
735 extensions.Register(kRtpExtensionTransmissionTimeOffset,
736 kTransmissionOffsetExtensionId);
737
738 int32_t time_offset;
739 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
danilchap70f39a32016-12-16 05:48:18 -0800740 packet.IdentifyExtensions(extensions);
danilchap1edb7ab2016-04-20 05:25:10 -0700741 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
742 EXPECT_EQ(kTimeOffset, time_offset);
743 EXPECT_EQ(0u, packet.payload_size());
744 EXPECT_EQ(0u, packet.padding_size());
745}
746
danilchapef8d7732017-04-19 02:59:48 -0700747TEST(RtpPacketTest, ParseDynamicSizeExtension) {
748 // clang-format off
749 const uint8_t kPacket1[] = {
eladalonae550e32017-05-24 08:28:13 -0700750 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700751 0x65, 0x43, 0x12, 0x78, // Timestamp.
752 0x12, 0x34, 0x56, 0x78, // Ssrc.
753 0xbe, 0xde, 0x00, 0x02, // Extensions block of size 2x32bit words.
754 0x21, 'H', 'D', // Extension with id = 2, size = (1+1).
755 0x12, 'r', 't', 'x', // Extension with id = 1, size = (2+1).
756 0x00}; // Extension padding.
757 const uint8_t kPacket2[] = {
eladalonae550e32017-05-24 08:28:13 -0700758 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700759 0x65, 0x43, 0x12, 0x78, // Timestamp.
760 0x12, 0x34, 0x56, 0x79, // Ssrc.
761 0xbe, 0xde, 0x00, 0x01, // Extensions block of size 1x32bit words.
762 0x11, 'H', 'D', // Extension with id = 1, size = (1+1).
763 0x00}; // Extension padding.
764 // clang-format on
765 RtpPacketReceived::ExtensionManager extensions;
766 extensions.Register<RtpStreamId>(1);
767 extensions.Register<RepairedRtpStreamId>(2);
768 RtpPacketReceived packet(&extensions);
769 ASSERT_TRUE(packet.Parse(kPacket1, sizeof(kPacket1)));
770
771 std::string rsid;
772 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
773 EXPECT_EQ(rsid, "rtx");
774
775 std::string repaired_rsid;
776 EXPECT_TRUE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
777 EXPECT_EQ(repaired_rsid, "HD");
778
779 // Parse another packet with RtpStreamId extension of different size.
780 ASSERT_TRUE(packet.Parse(kPacket2, sizeof(kPacket2)));
781 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
782 EXPECT_EQ(rsid, "HD");
783 EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
784}
785
Steve Antona3251dd2017-07-21 09:58:31 -0700786TEST(RtpPacketTest, ParseWithMid) {
787 RtpPacketReceived::ExtensionManager extensions;
788 extensions.Register<RtpMid>(kRtpMidExtensionId);
789 RtpPacketReceived packet(&extensions);
790 ASSERT_TRUE(packet.Parse(kPacketWithMid, sizeof(kPacketWithMid)));
791
792 std::string mid;
793 EXPECT_TRUE(packet.GetExtension<RtpMid>(&mid));
794 EXPECT_EQ(mid, kMid);
795}
796
sprangba050a62017-08-18 02:51:12 -0700797TEST(RtpPacketTest, CreateAndParseTimingFrameExtension) {
798 // Create a packet with video frame timing extension populated.
799 RtpPacketToSend::ExtensionManager send_extensions;
800 send_extensions.Register(kRtpExtensionVideoTiming, kVideoTimingExtensionId);
801 RtpPacketToSend send_packet(&send_extensions);
802 send_packet.SetPayloadType(kPayloadType);
803 send_packet.SetSequenceNumber(kSeqNum);
804 send_packet.SetTimestamp(kTimestamp);
805 send_packet.SetSsrc(kSsrc);
806
807 VideoSendTiming timing;
808 timing.encode_start_delta_ms = 1;
809 timing.encode_finish_delta_ms = 2;
810 timing.packetization_finish_delta_ms = 3;
811 timing.pacer_exit_delta_ms = 4;
812 timing.flags =
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +0200813 VideoSendTiming::kTriggeredByTimer | VideoSendTiming::kTriggeredBySize;
sprangba050a62017-08-18 02:51:12 -0700814
815 send_packet.SetExtension<VideoTimingExtension>(timing);
816
817 // Serialize the packet and then parse it again.
818 RtpPacketReceived::ExtensionManager extensions;
819 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
820 RtpPacketReceived receive_packet(&extensions);
821 EXPECT_TRUE(receive_packet.Parse(send_packet.Buffer()));
822
823 VideoSendTiming receivied_timing;
824 EXPECT_TRUE(
825 receive_packet.GetExtension<VideoTimingExtension>(&receivied_timing));
826
827 // Only check first and last timestamp (covered by other tests) plus flags.
828 EXPECT_EQ(receivied_timing.encode_start_delta_ms,
829 timing.encode_start_delta_ms);
830 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, timing.pacer_exit_delta_ms);
831 EXPECT_EQ(receivied_timing.flags, timing.flags);
832}
833
834TEST(RtpPacketTest, ParseLegacyTimingFrameExtension) {
835 // Parse the modified packet.
836 RtpPacketReceived::ExtensionManager extensions;
837 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
838 RtpPacketReceived packet(&extensions);
839 EXPECT_TRUE(packet.Parse(kPacketWithLegacyTimingExtension,
840 sizeof(kPacketWithLegacyTimingExtension)));
841 VideoSendTiming receivied_timing;
842 EXPECT_TRUE(packet.GetExtension<VideoTimingExtension>(&receivied_timing));
843
844 // Check first and last timestamp are still OK. Flags should now be 0.
845 EXPECT_EQ(receivied_timing.encode_start_delta_ms, 1);
846 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, 4);
847 EXPECT_EQ(receivied_timing.flags, 0);
848}
849
Johannes Kron09d65882018-11-27 14:36:41 +0100850TEST(RtpPacketTest, CreateAndParseColorSpaceExtension) {
851 TestCreateAndParseColorSpaceExtension(/*with_hdr_metadata=*/true);
852}
Johannes Kronad1d9f02018-11-09 11:12:36 +0100853
Johannes Kron09d65882018-11-27 14:36:41 +0100854TEST(RtpPacketTest, CreateAndParseColorSpaceExtensionWithoutHdrMetadata) {
855 TestCreateAndParseColorSpaceExtension(/*with_hdr_metadata=*/false);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100856}
857
danilchap1edb7ab2016-04-20 05:25:10 -0700858} // namespace webrtc