blob: e53125b4aaca92496887ee9ace1dc1d9ab7bbf4a [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) {
Johannes Kronc13f4be2018-12-12 09:52:53 +0100208 HdrMetadata hdr_metadata = CreateTestHdrMetadata();
209 return ColorSpace(
Johannes Kron09d65882018-11-27 14:36:41 +0100210 ColorSpace::PrimaryID::kBT709, ColorSpace::TransferID::kGAMMA22,
Johannes Kronc13f4be2018-12-12 09:52:53 +0100211 ColorSpace::MatrixID::kSMPTE2085, ColorSpace::RangeID::kFull,
212 ColorSpace::ChromaSiting::kCollocated,
213 ColorSpace::ChromaSiting::kCollocated,
214 with_hdr_metadata ? &hdr_metadata : nullptr);
Johannes Kron09d65882018-11-27 14:36:41 +0100215}
216
217void TestCreateAndParseColorSpaceExtension(bool with_hdr_metadata) {
218 // Create packet with extension.
219 RtpPacket::ExtensionManager extensions(/*extmap-allow-mixed=*/true);
220 extensions.Register<ColorSpaceExtension>(1);
221 RtpPacket packet(&extensions);
222 const ColorSpace kColorSpace = CreateTestColorSpace(with_hdr_metadata);
223 EXPECT_TRUE(packet.SetExtension<ColorSpaceExtension>(kColorSpace));
224 packet.SetPayloadSize(42);
225
226 // Read packet with the extension.
227 RtpPacketReceived parsed(&extensions);
228 EXPECT_TRUE(parsed.Parse(packet.Buffer()));
229 ColorSpace parsed_color_space;
230 EXPECT_TRUE(parsed.GetExtension<ColorSpaceExtension>(&parsed_color_space));
231 EXPECT_EQ(kColorSpace, parsed_color_space);
232}
danilchap1edb7ab2016-04-20 05:25:10 -0700233} // namespace
234
235TEST(RtpPacketTest, CreateMinimum) {
236 RtpPacketToSend packet(nullptr);
237 packet.SetPayloadType(kPayloadType);
238 packet.SetSequenceNumber(kSeqNum);
239 packet.SetTimestamp(kTimestamp);
240 packet.SetSsrc(kSsrc);
241 EXPECT_THAT(kMinimumPacket, ElementsAreArray(packet.data(), packet.size()));
242}
243
244TEST(RtpPacketTest, CreateWithExtension) {
245 RtpPacketToSend::ExtensionManager extensions;
246 extensions.Register(kRtpExtensionTransmissionTimeOffset,
247 kTransmissionOffsetExtensionId);
248 RtpPacketToSend packet(&extensions);
249 packet.SetPayloadType(kPayloadType);
250 packet.SetSequenceNumber(kSeqNum);
251 packet.SetTimestamp(kTimestamp);
252 packet.SetSsrc(kSsrc);
253 packet.SetExtension<TransmissionOffset>(kTimeOffset);
254 EXPECT_THAT(kPacketWithTO, ElementsAreArray(packet.data(), packet.size()));
255}
256
257TEST(RtpPacketTest, CreateWith2Extensions) {
258 RtpPacketToSend::ExtensionManager extensions;
259 extensions.Register(kRtpExtensionTransmissionTimeOffset,
260 kTransmissionOffsetExtensionId);
261 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
262 RtpPacketToSend packet(&extensions);
263 packet.SetPayloadType(kPayloadType);
264 packet.SetSequenceNumber(kSeqNum);
265 packet.SetTimestamp(kTimestamp);
266 packet.SetSsrc(kSsrc);
267 packet.SetExtension<TransmissionOffset>(kTimeOffset);
268 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
269 EXPECT_THAT(kPacketWithTOAndAL,
270 ElementsAreArray(packet.data(), packet.size()));
271}
272
Johannes Kron78cdde32018-10-05 10:00:46 +0200273TEST(RtpPacketTest, CreateWithTwoByteHeaderExtensionFirst) {
Johannes Kron9581bc42018-10-23 10:17:39 +0200274 RtpPacketToSend::ExtensionManager extensions(true);
Johannes Kron78cdde32018-10-05 10:00:46 +0200275 extensions.Register(kRtpExtensionTransmissionTimeOffset,
276 kTransmissionOffsetExtensionId);
277 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
278 extensions.Register(kRtpExtensionPlayoutDelay, kTwoByteExtensionId);
279 RtpPacketToSend packet(&extensions);
280 packet.SetPayloadType(kPayloadType);
281 packet.SetSequenceNumber(kSeqNum);
282 packet.SetTimestamp(kTimestamp);
283 packet.SetSsrc(kSsrc);
284 // Set extension that requires two-byte header.
285 PlayoutDelay playoutDelay = {30, 340};
286 ASSERT_TRUE(packet.SetExtension<PlayoutDelayLimits>(playoutDelay));
287 packet.SetExtension<TransmissionOffset>(kTimeOffset);
288 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
289 EXPECT_THAT(kPacketWithTwoByteExtensionIdFirst,
290 ElementsAreArray(packet.data(), packet.size()));
291}
292
293TEST(RtpPacketTest, CreateWithTwoByteHeaderExtensionLast) {
294 // This test will trigger RtpPacket::PromoteToTwoByteHeaderExtension().
Johannes Kron9581bc42018-10-23 10:17:39 +0200295 RtpPacketToSend::ExtensionManager extensions(true);
Johannes Kron78cdde32018-10-05 10:00:46 +0200296 extensions.Register(kRtpExtensionTransmissionTimeOffset,
297 kTransmissionOffsetExtensionId);
298 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
299 extensions.Register(kRtpExtensionPlayoutDelay, kTwoByteExtensionId);
300 RtpPacketToSend packet(&extensions);
301 packet.SetPayloadType(kPayloadType);
302 packet.SetSequenceNumber(kSeqNum);
303 packet.SetTimestamp(kTimestamp);
304 packet.SetSsrc(kSsrc);
305 packet.SetExtension<TransmissionOffset>(kTimeOffset);
306 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
307 EXPECT_THAT(kPacketWithTOAndAL,
308 ElementsAreArray(packet.data(), packet.size()));
309 // Set extension that requires two-byte header.
310 PlayoutDelay playoutDelay = {30, 340};
311 ASSERT_TRUE(packet.SetExtension<PlayoutDelayLimits>(playoutDelay));
312 EXPECT_THAT(kPacketWithTwoByteExtensionIdLast,
313 ElementsAreArray(packet.data(), packet.size()));
314}
315
erikvargae6b16192017-05-11 02:36:32 -0700316TEST(RtpPacketTest, CreateWithDynamicSizedExtensions) {
317 RtpPacketToSend::ExtensionManager extensions;
318 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
319 RtpPacketToSend packet(&extensions);
320 packet.SetPayloadType(kPayloadType);
321 packet.SetSequenceNumber(kSeqNum);
322 packet.SetTimestamp(kTimestamp);
323 packet.SetSsrc(kSsrc);
324 packet.SetExtension<RtpStreamId>(kStreamId);
325 EXPECT_THAT(kPacketWithRsid, ElementsAreArray(packet.data(), packet.size()));
326}
327
328TEST(RtpPacketTest, TryToCreateWithEmptyRsid) {
329 RtpPacketToSend::ExtensionManager extensions;
330 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
331 RtpPacketToSend packet(&extensions);
332 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(""));
333}
334
335TEST(RtpPacketTest, TryToCreateWithLongRsid) {
336 RtpPacketToSend::ExtensionManager extensions;
337 constexpr char kLongStreamId[] = "LoooooooooongRsid";
338 ASSERT_EQ(strlen(kLongStreamId), 17u);
339 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
340 RtpPacketToSend packet(&extensions);
341 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kLongStreamId));
342}
343
Steve Antona3251dd2017-07-21 09:58:31 -0700344TEST(RtpPacketTest, TryToCreateWithEmptyMid) {
345 RtpPacketToSend::ExtensionManager extensions;
346 extensions.Register<RtpMid>(kRtpMidExtensionId);
347 RtpPacketToSend packet(&extensions);
348 EXPECT_FALSE(packet.SetExtension<RtpMid>(""));
349}
350
351TEST(RtpPacketTest, TryToCreateWithLongMid) {
352 RtpPacketToSend::ExtensionManager extensions;
353 constexpr char kLongMid[] = "LoooooooooonogMid";
354 ASSERT_EQ(strlen(kLongMid), 17u);
355 extensions.Register<RtpMid>(kRtpMidExtensionId);
356 RtpPacketToSend packet(&extensions);
357 EXPECT_FALSE(packet.SetExtension<RtpMid>(kLongMid));
358}
359
Johannes Kron78cdde32018-10-05 10:00:46 +0200360TEST(RtpPacketTest, TryToCreateTwoByteHeaderNotSupported) {
361 RtpPacketToSend::ExtensionManager extensions;
362 extensions.Register(kRtpExtensionAudioLevel, kTwoByteExtensionId);
363 RtpPacketToSend packet(&extensions);
364 // Set extension that requires two-byte header.
365 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
366}
367
danilchap653063f2017-04-03 06:16:30 -0700368TEST(RtpPacketTest, CreateWithMaxSizeHeaderExtension) {
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200369 const std::string kValue = "123456789abcdef";
370 RtpPacket::ExtensionManager extensions;
371 extensions.Register<RtpMid>(1);
372 extensions.Register<RtpStreamId>(2);
danilchap653063f2017-04-03 06:16:30 -0700373
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200374 RtpPacket packet(&extensions);
375 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700376
377 packet.SetPayloadSize(42);
378 // Rewriting allocated extension is allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200379 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700380 // Adding another extension after payload is set is not allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200381 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700382
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200383 // Read packet with the extension.
384 RtpPacketReceived parsed(&extensions);
danilchap653063f2017-04-03 06:16:30 -0700385 EXPECT_TRUE(parsed.Parse(packet.Buffer()));
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200386 std::string read;
387 EXPECT_TRUE(parsed.GetExtension<RtpMid>(&read));
388 EXPECT_EQ(read, kValue);
danilchap653063f2017-04-03 06:16:30 -0700389}
390
danilchap1edb7ab2016-04-20 05:25:10 -0700391TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
392 const size_t kPayloadSize = 4;
393 RtpPacketToSend::ExtensionManager extensions;
394 extensions.Register(kRtpExtensionTransmissionTimeOffset,
395 kTransmissionOffsetExtensionId);
396 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
397 RtpPacketToSend packet(&extensions);
398
399 EXPECT_TRUE(packet.ReserveExtension<TransmissionOffset>());
danilchap07a01b32017-03-29 07:33:13 -0700400 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700401 // Can't set extension after payload.
402 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
403 // Unless reserved.
404 EXPECT_TRUE(packet.SetExtension<TransmissionOffset>(kTimeOffset));
405}
406
407TEST(RtpPacketTest, CreatePurePadding) {
408 const size_t kPaddingSize = kMaxPaddingSize - 1;
409 RtpPacketToSend packet(nullptr, 12 + kPaddingSize);
410 packet.SetPayloadType(kPayloadType);
411 packet.SetSequenceNumber(kSeqNum);
412 packet.SetTimestamp(kTimestamp);
413 packet.SetSsrc(kSsrc);
danilchap1edb7ab2016-04-20 05:25:10 -0700414
415 EXPECT_LT(packet.size(), packet.capacity());
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +0200416 EXPECT_FALSE(packet.SetPadding(kPaddingSize + 1));
417 EXPECT_TRUE(packet.SetPadding(kPaddingSize));
danilchap1edb7ab2016-04-20 05:25:10 -0700418 EXPECT_EQ(packet.size(), packet.capacity());
419}
420
421TEST(RtpPacketTest, CreateUnalignedPadding) {
422 const size_t kPayloadSize = 3; // Make padding start at unaligned address.
423 RtpPacketToSend packet(nullptr, 12 + kPayloadSize + kMaxPaddingSize);
424 packet.SetPayloadType(kPayloadType);
425 packet.SetSequenceNumber(kSeqNum);
426 packet.SetTimestamp(kTimestamp);
427 packet.SetSsrc(kSsrc);
danilchap07a01b32017-03-29 07:33:13 -0700428 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700429
430 EXPECT_LT(packet.size(), packet.capacity());
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +0200431 EXPECT_TRUE(packet.SetPadding(kMaxPaddingSize));
danilchap1edb7ab2016-04-20 05:25:10 -0700432 EXPECT_EQ(packet.size(), packet.capacity());
433}
434
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +0200435TEST(RtpPacketTest, WritesPaddingSizeToLastByte) {
436 const size_t kPaddingSize = 5;
437 RtpPacket packet;
438
439 EXPECT_TRUE(packet.SetPadding(kPaddingSize));
440 EXPECT_EQ(packet.data()[packet.size() - 1], kPaddingSize);
441}
442
443TEST(RtpPacketTest, UsesZerosForPadding) {
444 const size_t kPaddingSize = 5;
445 RtpPacket packet;
446
447 EXPECT_TRUE(packet.SetPadding(kPaddingSize));
448 EXPECT_THAT(rtc::MakeArrayView(packet.data() + 12, kPaddingSize - 1),
449 Each(0));
450}
451
452TEST(RtpPacketTest, CreateOneBytePadding) {
453 size_t kPayloadSize = 123;
454 RtpPacket packet(nullptr, 12 + kPayloadSize + 1);
455 packet.SetPayloadSize(kPayloadSize);
456
457 EXPECT_TRUE(packet.SetPadding(1));
458
459 EXPECT_EQ(packet.size(), 12 + kPayloadSize + 1);
460 EXPECT_EQ(packet.padding_size(), 1u);
461}
462
463TEST(RtpPacketTest, FailsToAddPaddingWithoutCapacity) {
464 size_t kPayloadSize = 123;
465 RtpPacket packet(nullptr, 12 + kPayloadSize);
466 packet.SetPayloadSize(kPayloadSize);
467
468 EXPECT_FALSE(packet.SetPadding(1));
469}
470
danilchap1edb7ab2016-04-20 05:25:10 -0700471TEST(RtpPacketTest, ParseMinimum) {
472 RtpPacketReceived packet;
473 EXPECT_TRUE(packet.Parse(kMinimumPacket, sizeof(kMinimumPacket)));
474 EXPECT_EQ(kPayloadType, packet.PayloadType());
475 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
476 EXPECT_EQ(kTimestamp, packet.Timestamp());
477 EXPECT_EQ(kSsrc, packet.Ssrc());
478 EXPECT_EQ(0u, packet.padding_size());
479 EXPECT_EQ(0u, packet.payload_size());
480}
481
482TEST(RtpPacketTest, ParseBuffer) {
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200483 rtc::CopyOnWriteBuffer unparsed(kMinimumPacket);
danilchap1edb7ab2016-04-20 05:25:10 -0700484 const uint8_t* raw = unparsed.data();
485
486 RtpPacketReceived packet;
487 EXPECT_TRUE(packet.Parse(std::move(unparsed)));
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200488 EXPECT_EQ(raw, packet.data()); // Expect packet take the buffer without copy.
danilchap1edb7ab2016-04-20 05:25:10 -0700489 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
490 EXPECT_EQ(kTimestamp, packet.Timestamp());
491 EXPECT_EQ(kSsrc, packet.Ssrc());
492 EXPECT_EQ(0u, packet.padding_size());
493 EXPECT_EQ(0u, packet.payload_size());
494}
495
496TEST(RtpPacketTest, ParseWithExtension) {
497 RtpPacketToSend::ExtensionManager extensions;
498 extensions.Register(kRtpExtensionTransmissionTimeOffset,
499 kTransmissionOffsetExtensionId);
500
501 RtpPacketReceived packet(&extensions);
502 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
503 EXPECT_EQ(kPayloadType, packet.PayloadType());
504 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
505 EXPECT_EQ(kTimestamp, packet.Timestamp());
506 EXPECT_EQ(kSsrc, packet.Ssrc());
507 int32_t time_offset;
508 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
509 EXPECT_EQ(kTimeOffset, time_offset);
510 EXPECT_EQ(0u, packet.payload_size());
511 EXPECT_EQ(0u, packet.padding_size());
512}
513
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100514TEST(RtpPacketTest, GetExtensionWithoutParametersReturnsOptionalValue) {
515 RtpPacket::ExtensionManager extensions;
516 extensions.Register<TransmissionOffset>(kTransmissionOffsetExtensionId);
517 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
518
519 RtpPacketReceived packet(&extensions);
520 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
521
522 auto time_offset = packet.GetExtension<TransmissionOffset>();
523 static_assert(
524 std::is_same<decltype(time_offset),
525 absl::optional<TransmissionOffset::value_type>>::value,
526 "");
527 EXPECT_EQ(time_offset, kTimeOffset);
528 EXPECT_FALSE(packet.GetExtension<RtpStreamId>().has_value());
529}
530
Danil Chapovalove19953b2018-10-01 16:12:28 +0200531TEST(RtpPacketTest, GetRawExtensionWhenPresent) {
532 constexpr uint8_t kRawPacket[] = {
533 // comment for clang-format to align kRawPacket nicer.
534 0x90, 100, 0x5e, 0x04, //
535 0x65, 0x43, 0x12, 0x78, // Timestamp.
536 0x12, 0x34, 0x56, 0x78, // Ssrc
537 0xbe, 0xde, 0x00, 0x01, // Extension header
538 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
539 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
540 RtpPacketToSend::ExtensionManager extensions;
541 extensions.Register<RtpMid>(1);
542 RtpPacket packet(&extensions);
543 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
544 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), ElementsAre('m', 'i', 'd'));
545}
546
547TEST(RtpPacketTest, GetRawExtensionWhenAbsent) {
548 constexpr uint8_t kRawPacket[] = {
549 // comment for clang-format to align kRawPacket nicer.
550 0x90, 100, 0x5e, 0x04, //
551 0x65, 0x43, 0x12, 0x78, // Timestamp.
552 0x12, 0x34, 0x56, 0x78, // Ssrc
553 0xbe, 0xde, 0x00, 0x01, // Extension header
554 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
555 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
556 RtpPacketToSend::ExtensionManager extensions;
557 extensions.Register<RtpMid>(2);
558 RtpPacket packet(&extensions);
559 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
560 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), IsEmpty());
561}
562
danilchap07ec26d2016-06-17 04:18:54 -0700563TEST(RtpPacketTest, ParseWithInvalidSizedExtension) {
564 RtpPacketToSend::ExtensionManager extensions;
565 extensions.Register(kRtpExtensionTransmissionTimeOffset,
566 kTransmissionOffsetExtensionId);
567
568 RtpPacketReceived packet(&extensions);
569 EXPECT_TRUE(packet.Parse(kPacketWithInvalidExtension,
570 sizeof(kPacketWithInvalidExtension)));
571
572 // Extension should be ignored.
573 int32_t time_offset;
574 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
575
576 // But shouldn't prevent reading payload.
danilchap96c15872016-11-21 01:35:29 -0800577 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap07ec26d2016-06-17 04:18:54 -0700578}
579
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200580TEST(RtpPacketTest, ParseWithOverSizedExtension) {
581 // clang-format off
582 const uint8_t bad_packet[] = {
eladalonae550e32017-05-24 08:28:13 -0700583 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200584 0x65, 0x43, 0x12, 0x78, // kTimestamp.
585 0x12, 0x34, 0x56, 0x78, // kSsrc.
586 0xbe, 0xde, 0x00, 0x01, // Extension of size 1x32bit word.
587 0x00, // Add a byte of padding.
588 0x12, // Extension id 1 size (2+1).
589 0xda, 0x1a // Only 2 bytes of extension payload.
590 };
591 // clang-format on
592 RtpPacketToSend::ExtensionManager extensions;
593 extensions.Register(TransmissionOffset::kId, 1);
594 RtpPacketReceived packet(&extensions);
595
596 // Parse should ignore bad extension and proceed.
597 EXPECT_TRUE(packet.Parse(bad_packet, sizeof(bad_packet)));
598 int32_t time_offset;
599 // But extracting extension should fail.
600 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
601}
602
danilchap1edb7ab2016-04-20 05:25:10 -0700603TEST(RtpPacketTest, ParseWith2Extensions) {
604 RtpPacketToSend::ExtensionManager extensions;
605 extensions.Register(kRtpExtensionTransmissionTimeOffset,
606 kTransmissionOffsetExtensionId);
607 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
608 RtpPacketReceived packet(&extensions);
609 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
610 int32_t time_offset;
611 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
612 EXPECT_EQ(kTimeOffset, time_offset);
613 bool voice_active;
614 uint8_t audio_level;
615 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
616 EXPECT_EQ(kVoiceActive, voice_active);
617 EXPECT_EQ(kAudioLevel, audio_level);
618}
619
Johannes Kron6ea77192018-09-24 17:19:52 +0200620TEST(RtpPacketTest, ParseSecondPacketWithFewerExtensions) {
621 RtpPacketToSend::ExtensionManager extensions;
622 extensions.Register(kRtpExtensionTransmissionTimeOffset,
623 kTransmissionOffsetExtensionId);
624 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
625 RtpPacketReceived packet(&extensions);
626 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
627 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
628 EXPECT_TRUE(packet.HasExtension<AudioLevel>());
629
630 // Second packet without audio level.
631 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
632 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
633 EXPECT_FALSE(packet.HasExtension<AudioLevel>());
634}
635
Johannes Kron07ba2b92018-09-26 13:33:35 +0200636TEST(RtpPacketTest, ParseWith2ExtensionsInvalidPadding) {
637 RtpPacketToSend::ExtensionManager extensions;
638 extensions.Register(kRtpExtensionTransmissionTimeOffset,
639 kTransmissionOffsetExtensionId);
640 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
641 RtpPacketReceived packet(&extensions);
642 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALInvalidPadding,
643 sizeof(kPacketWithTOAndALInvalidPadding)));
644 int32_t time_offset;
645 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
646 EXPECT_EQ(kTimeOffset, time_offset);
647 bool voice_active;
648 uint8_t audio_level;
649 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
650}
651
652TEST(RtpPacketTest, ParseWith2ExtensionsReservedExtensionId) {
653 RtpPacketToSend::ExtensionManager extensions;
654 extensions.Register(kRtpExtensionTransmissionTimeOffset,
655 kTransmissionOffsetExtensionId);
656 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
657 RtpPacketReceived packet(&extensions);
658 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALReservedExtensionId,
659 sizeof(kPacketWithTOAndALReservedExtensionId)));
660 int32_t time_offset;
661 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
662 EXPECT_EQ(kTimeOffset, time_offset);
663 bool voice_active;
664 uint8_t audio_level;
665 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
666}
667
danilchap1edb7ab2016-04-20 05:25:10 -0700668TEST(RtpPacketTest, ParseWithAllFeatures) {
669 RtpPacketToSend::ExtensionManager extensions;
670 extensions.Register(kRtpExtensionTransmissionTimeOffset,
671 kTransmissionOffsetExtensionId);
672 RtpPacketReceived packet(&extensions);
673 EXPECT_TRUE(packet.Parse(kPacket, sizeof(kPacket)));
674 EXPECT_EQ(kPayloadType, packet.PayloadType());
675 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
676 EXPECT_EQ(kTimestamp, packet.Timestamp());
677 EXPECT_EQ(kSsrc, packet.Ssrc());
678 EXPECT_THAT(packet.Csrcs(), ElementsAreArray(kCsrcs));
danilchap96c15872016-11-21 01:35:29 -0800679 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap1edb7ab2016-04-20 05:25:10 -0700680 EXPECT_EQ(kPacketPaddingSize, packet.padding_size());
681 int32_t time_offset;
682 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
683}
684
Johannes Kron07ba2b92018-09-26 13:33:35 +0200685TEST(RtpPacketTest, ParseTwoByteHeaderExtension) {
686 RtpPacketToSend::ExtensionManager extensions;
687 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
688 RtpPacketReceived packet(&extensions);
689 EXPECT_TRUE(packet.Parse(kPacketWithTwoByteHeaderExtension,
690 sizeof(kPacketWithTwoByteHeaderExtension)));
691 int32_t time_offset;
692 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
693 EXPECT_EQ(kTimeOffset, time_offset);
694}
695
696TEST(RtpPacketTest, ParseLongTwoByteHeaderExtension) {
697 RtpPacketToSend::ExtensionManager extensions;
698 extensions.Register(kRtpExtensionMid, kTwoByteExtensionId);
699 RtpPacketReceived packet(&extensions);
700 EXPECT_TRUE(packet.Parse(kPacketWithLongTwoByteHeaderExtension,
701 sizeof(kPacketWithLongTwoByteHeaderExtension)));
702 std::string long_rtp_mid;
703 EXPECT_TRUE(packet.GetExtension<RtpMid>(&long_rtp_mid));
704 EXPECT_EQ(kLongMid, long_rtp_mid);
705}
706
707TEST(RtpPacketTest, ParseTwoByteHeaderExtensionWithPadding) {
708 RtpPacketToSend::ExtensionManager extensions;
709 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
710 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
711 RtpPacketReceived packet(&extensions);
712 EXPECT_TRUE(
713 packet.Parse(kPacketWithTwoByteHeaderExtensionWithPadding,
714 sizeof(kPacketWithTwoByteHeaderExtensionWithPadding)));
715 int32_t time_offset;
716 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
717 EXPECT_EQ(kTimeOffset, time_offset);
718 bool voice_active;
719 uint8_t audio_level;
720 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
721 EXPECT_EQ(kVoiceActive, voice_active);
722 EXPECT_EQ(kAudioLevel, audio_level);
723}
724
danilchap1edb7ab2016-04-20 05:25:10 -0700725TEST(RtpPacketTest, ParseWithExtensionDelayed) {
726 RtpPacketReceived packet;
727 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
728 EXPECT_EQ(kPayloadType, packet.PayloadType());
729 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
730 EXPECT_EQ(kTimestamp, packet.Timestamp());
731 EXPECT_EQ(kSsrc, packet.Ssrc());
732
733 RtpPacketToSend::ExtensionManager extensions;
734 extensions.Register(kRtpExtensionTransmissionTimeOffset,
735 kTransmissionOffsetExtensionId);
736
737 int32_t time_offset;
738 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
danilchap70f39a32016-12-16 05:48:18 -0800739 packet.IdentifyExtensions(extensions);
danilchap1edb7ab2016-04-20 05:25:10 -0700740 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
741 EXPECT_EQ(kTimeOffset, time_offset);
742 EXPECT_EQ(0u, packet.payload_size());
743 EXPECT_EQ(0u, packet.padding_size());
744}
745
danilchapef8d7732017-04-19 02:59:48 -0700746TEST(RtpPacketTest, ParseDynamicSizeExtension) {
747 // clang-format off
748 const uint8_t kPacket1[] = {
eladalonae550e32017-05-24 08:28:13 -0700749 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700750 0x65, 0x43, 0x12, 0x78, // Timestamp.
751 0x12, 0x34, 0x56, 0x78, // Ssrc.
752 0xbe, 0xde, 0x00, 0x02, // Extensions block of size 2x32bit words.
753 0x21, 'H', 'D', // Extension with id = 2, size = (1+1).
754 0x12, 'r', 't', 'x', // Extension with id = 1, size = (2+1).
755 0x00}; // Extension padding.
756 const uint8_t kPacket2[] = {
eladalonae550e32017-05-24 08:28:13 -0700757 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700758 0x65, 0x43, 0x12, 0x78, // Timestamp.
759 0x12, 0x34, 0x56, 0x79, // Ssrc.
760 0xbe, 0xde, 0x00, 0x01, // Extensions block of size 1x32bit words.
761 0x11, 'H', 'D', // Extension with id = 1, size = (1+1).
762 0x00}; // Extension padding.
763 // clang-format on
764 RtpPacketReceived::ExtensionManager extensions;
765 extensions.Register<RtpStreamId>(1);
766 extensions.Register<RepairedRtpStreamId>(2);
767 RtpPacketReceived packet(&extensions);
768 ASSERT_TRUE(packet.Parse(kPacket1, sizeof(kPacket1)));
769
770 std::string rsid;
771 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
772 EXPECT_EQ(rsid, "rtx");
773
774 std::string repaired_rsid;
775 EXPECT_TRUE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
776 EXPECT_EQ(repaired_rsid, "HD");
777
778 // Parse another packet with RtpStreamId extension of different size.
779 ASSERT_TRUE(packet.Parse(kPacket2, sizeof(kPacket2)));
780 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
781 EXPECT_EQ(rsid, "HD");
782 EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
783}
784
Steve Antona3251dd2017-07-21 09:58:31 -0700785TEST(RtpPacketTest, ParseWithMid) {
786 RtpPacketReceived::ExtensionManager extensions;
787 extensions.Register<RtpMid>(kRtpMidExtensionId);
788 RtpPacketReceived packet(&extensions);
789 ASSERT_TRUE(packet.Parse(kPacketWithMid, sizeof(kPacketWithMid)));
790
791 std::string mid;
792 EXPECT_TRUE(packet.GetExtension<RtpMid>(&mid));
793 EXPECT_EQ(mid, kMid);
794}
795
sprangba050a62017-08-18 02:51:12 -0700796TEST(RtpPacketTest, CreateAndParseTimingFrameExtension) {
797 // Create a packet with video frame timing extension populated.
798 RtpPacketToSend::ExtensionManager send_extensions;
799 send_extensions.Register(kRtpExtensionVideoTiming, kVideoTimingExtensionId);
800 RtpPacketToSend send_packet(&send_extensions);
801 send_packet.SetPayloadType(kPayloadType);
802 send_packet.SetSequenceNumber(kSeqNum);
803 send_packet.SetTimestamp(kTimestamp);
804 send_packet.SetSsrc(kSsrc);
805
806 VideoSendTiming timing;
807 timing.encode_start_delta_ms = 1;
808 timing.encode_finish_delta_ms = 2;
809 timing.packetization_finish_delta_ms = 3;
810 timing.pacer_exit_delta_ms = 4;
811 timing.flags =
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +0200812 VideoSendTiming::kTriggeredByTimer | VideoSendTiming::kTriggeredBySize;
sprangba050a62017-08-18 02:51:12 -0700813
814 send_packet.SetExtension<VideoTimingExtension>(timing);
815
816 // Serialize the packet and then parse it again.
817 RtpPacketReceived::ExtensionManager extensions;
818 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
819 RtpPacketReceived receive_packet(&extensions);
820 EXPECT_TRUE(receive_packet.Parse(send_packet.Buffer()));
821
822 VideoSendTiming receivied_timing;
823 EXPECT_TRUE(
824 receive_packet.GetExtension<VideoTimingExtension>(&receivied_timing));
825
826 // Only check first and last timestamp (covered by other tests) plus flags.
827 EXPECT_EQ(receivied_timing.encode_start_delta_ms,
828 timing.encode_start_delta_ms);
829 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, timing.pacer_exit_delta_ms);
830 EXPECT_EQ(receivied_timing.flags, timing.flags);
831}
832
833TEST(RtpPacketTest, ParseLegacyTimingFrameExtension) {
834 // Parse the modified packet.
835 RtpPacketReceived::ExtensionManager extensions;
836 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
837 RtpPacketReceived packet(&extensions);
838 EXPECT_TRUE(packet.Parse(kPacketWithLegacyTimingExtension,
839 sizeof(kPacketWithLegacyTimingExtension)));
840 VideoSendTiming receivied_timing;
841 EXPECT_TRUE(packet.GetExtension<VideoTimingExtension>(&receivied_timing));
842
843 // Check first and last timestamp are still OK. Flags should now be 0.
844 EXPECT_EQ(receivied_timing.encode_start_delta_ms, 1);
845 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, 4);
846 EXPECT_EQ(receivied_timing.flags, 0);
847}
848
Johannes Kron09d65882018-11-27 14:36:41 +0100849TEST(RtpPacketTest, CreateAndParseColorSpaceExtension) {
850 TestCreateAndParseColorSpaceExtension(/*with_hdr_metadata=*/true);
851}
Johannes Kronad1d9f02018-11-09 11:12:36 +0100852
Johannes Kron09d65882018-11-27 14:36:41 +0100853TEST(RtpPacketTest, CreateAndParseColorSpaceExtensionWithoutHdrMetadata) {
854 TestCreateAndParseColorSpaceExtension(/*with_hdr_metadata=*/false);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100855}
856
danilchap1edb7ab2016-04-20 05:25:10 -0700857} // namespace webrtc