blob: 431bf5e3d040fc7ed0b76f9cbda18b15be5ae56b [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
danilchap1edb7ab2016-04-20 05:25:10 -0700188} // namespace
189
190TEST(RtpPacketTest, CreateMinimum) {
191 RtpPacketToSend packet(nullptr);
192 packet.SetPayloadType(kPayloadType);
193 packet.SetSequenceNumber(kSeqNum);
194 packet.SetTimestamp(kTimestamp);
195 packet.SetSsrc(kSsrc);
196 EXPECT_THAT(kMinimumPacket, ElementsAreArray(packet.data(), packet.size()));
197}
198
199TEST(RtpPacketTest, CreateWithExtension) {
200 RtpPacketToSend::ExtensionManager extensions;
201 extensions.Register(kRtpExtensionTransmissionTimeOffset,
202 kTransmissionOffsetExtensionId);
203 RtpPacketToSend packet(&extensions);
204 packet.SetPayloadType(kPayloadType);
205 packet.SetSequenceNumber(kSeqNum);
206 packet.SetTimestamp(kTimestamp);
207 packet.SetSsrc(kSsrc);
208 packet.SetExtension<TransmissionOffset>(kTimeOffset);
209 EXPECT_THAT(kPacketWithTO, ElementsAreArray(packet.data(), packet.size()));
210}
211
212TEST(RtpPacketTest, CreateWith2Extensions) {
213 RtpPacketToSend::ExtensionManager extensions;
214 extensions.Register(kRtpExtensionTransmissionTimeOffset,
215 kTransmissionOffsetExtensionId);
216 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
217 RtpPacketToSend packet(&extensions);
218 packet.SetPayloadType(kPayloadType);
219 packet.SetSequenceNumber(kSeqNum);
220 packet.SetTimestamp(kTimestamp);
221 packet.SetSsrc(kSsrc);
222 packet.SetExtension<TransmissionOffset>(kTimeOffset);
223 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
224 EXPECT_THAT(kPacketWithTOAndAL,
225 ElementsAreArray(packet.data(), packet.size()));
226}
227
Johannes Kron78cdde32018-10-05 10:00:46 +0200228TEST(RtpPacketTest, CreateWithTwoByteHeaderExtensionFirst) {
Johannes Kron9581bc42018-10-23 10:17:39 +0200229 RtpPacketToSend::ExtensionManager extensions(true);
Johannes Kron78cdde32018-10-05 10:00:46 +0200230 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().
Johannes Kron9581bc42018-10-23 10:17:39 +0200250 RtpPacketToSend::ExtensionManager extensions(true);
Johannes Kron78cdde32018-10-05 10:00:46 +0200251 extensions.Register(kRtpExtensionTransmissionTimeOffset,
252 kTransmissionOffsetExtensionId);
253 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
254 extensions.Register(kRtpExtensionPlayoutDelay, kTwoByteExtensionId);
255 RtpPacketToSend packet(&extensions);
256 packet.SetPayloadType(kPayloadType);
257 packet.SetSequenceNumber(kSeqNum);
258 packet.SetTimestamp(kTimestamp);
259 packet.SetSsrc(kSsrc);
260 packet.SetExtension<TransmissionOffset>(kTimeOffset);
261 packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
262 EXPECT_THAT(kPacketWithTOAndAL,
263 ElementsAreArray(packet.data(), packet.size()));
264 // Set extension that requires two-byte header.
265 PlayoutDelay playoutDelay = {30, 340};
266 ASSERT_TRUE(packet.SetExtension<PlayoutDelayLimits>(playoutDelay));
267 EXPECT_THAT(kPacketWithTwoByteExtensionIdLast,
268 ElementsAreArray(packet.data(), packet.size()));
269}
270
erikvargae6b16192017-05-11 02:36:32 -0700271TEST(RtpPacketTest, CreateWithDynamicSizedExtensions) {
272 RtpPacketToSend::ExtensionManager extensions;
273 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
274 RtpPacketToSend packet(&extensions);
275 packet.SetPayloadType(kPayloadType);
276 packet.SetSequenceNumber(kSeqNum);
277 packet.SetTimestamp(kTimestamp);
278 packet.SetSsrc(kSsrc);
279 packet.SetExtension<RtpStreamId>(kStreamId);
280 EXPECT_THAT(kPacketWithRsid, ElementsAreArray(packet.data(), packet.size()));
281}
282
283TEST(RtpPacketTest, TryToCreateWithEmptyRsid) {
284 RtpPacketToSend::ExtensionManager extensions;
285 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
286 RtpPacketToSend packet(&extensions);
287 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(""));
288}
289
290TEST(RtpPacketTest, TryToCreateWithLongRsid) {
291 RtpPacketToSend::ExtensionManager extensions;
292 constexpr char kLongStreamId[] = "LoooooooooongRsid";
293 ASSERT_EQ(strlen(kLongStreamId), 17u);
294 extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
295 RtpPacketToSend packet(&extensions);
296 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kLongStreamId));
297}
298
Steve Antona3251dd2017-07-21 09:58:31 -0700299TEST(RtpPacketTest, TryToCreateWithEmptyMid) {
300 RtpPacketToSend::ExtensionManager extensions;
301 extensions.Register<RtpMid>(kRtpMidExtensionId);
302 RtpPacketToSend packet(&extensions);
303 EXPECT_FALSE(packet.SetExtension<RtpMid>(""));
304}
305
306TEST(RtpPacketTest, TryToCreateWithLongMid) {
307 RtpPacketToSend::ExtensionManager extensions;
308 constexpr char kLongMid[] = "LoooooooooonogMid";
309 ASSERT_EQ(strlen(kLongMid), 17u);
310 extensions.Register<RtpMid>(kRtpMidExtensionId);
311 RtpPacketToSend packet(&extensions);
312 EXPECT_FALSE(packet.SetExtension<RtpMid>(kLongMid));
313}
314
Johannes Kron78cdde32018-10-05 10:00:46 +0200315TEST(RtpPacketTest, TryToCreateTwoByteHeaderNotSupported) {
316 RtpPacketToSend::ExtensionManager extensions;
317 extensions.Register(kRtpExtensionAudioLevel, kTwoByteExtensionId);
318 RtpPacketToSend packet(&extensions);
319 // Set extension that requires two-byte header.
320 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
321}
322
danilchap653063f2017-04-03 06:16:30 -0700323TEST(RtpPacketTest, CreateWithMaxSizeHeaderExtension) {
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200324 const std::string kValue = "123456789abcdef";
325 RtpPacket::ExtensionManager extensions;
326 extensions.Register<RtpMid>(1);
327 extensions.Register<RtpStreamId>(2);
danilchap653063f2017-04-03 06:16:30 -0700328
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200329 RtpPacket packet(&extensions);
330 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700331
332 packet.SetPayloadSize(42);
333 // Rewriting allocated extension is allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200334 EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700335 // Adding another extension after payload is set is not allowed.
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200336 EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kValue));
danilchap653063f2017-04-03 06:16:30 -0700337
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200338 // Read packet with the extension.
339 RtpPacketReceived parsed(&extensions);
danilchap653063f2017-04-03 06:16:30 -0700340 EXPECT_TRUE(parsed.Parse(packet.Buffer()));
Danil Chapovalov527ff1e2018-08-06 19:34:32 +0200341 std::string read;
342 EXPECT_TRUE(parsed.GetExtension<RtpMid>(&read));
343 EXPECT_EQ(read, kValue);
danilchap653063f2017-04-03 06:16:30 -0700344}
345
danilchap1edb7ab2016-04-20 05:25:10 -0700346TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
347 const size_t kPayloadSize = 4;
348 RtpPacketToSend::ExtensionManager extensions;
349 extensions.Register(kRtpExtensionTransmissionTimeOffset,
350 kTransmissionOffsetExtensionId);
351 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
352 RtpPacketToSend packet(&extensions);
353
354 EXPECT_TRUE(packet.ReserveExtension<TransmissionOffset>());
danilchap07a01b32017-03-29 07:33:13 -0700355 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700356 // Can't set extension after payload.
357 EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
358 // Unless reserved.
359 EXPECT_TRUE(packet.SetExtension<TransmissionOffset>(kTimeOffset));
360}
361
362TEST(RtpPacketTest, CreatePurePadding) {
363 const size_t kPaddingSize = kMaxPaddingSize - 1;
364 RtpPacketToSend packet(nullptr, 12 + kPaddingSize);
365 packet.SetPayloadType(kPayloadType);
366 packet.SetSequenceNumber(kSeqNum);
367 packet.SetTimestamp(kTimestamp);
368 packet.SetSsrc(kSsrc);
danilchap1edb7ab2016-04-20 05:25:10 -0700369
370 EXPECT_LT(packet.size(), packet.capacity());
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +0200371 EXPECT_FALSE(packet.SetPadding(kPaddingSize + 1));
372 EXPECT_TRUE(packet.SetPadding(kPaddingSize));
danilchap1edb7ab2016-04-20 05:25:10 -0700373 EXPECT_EQ(packet.size(), packet.capacity());
374}
375
376TEST(RtpPacketTest, CreateUnalignedPadding) {
377 const size_t kPayloadSize = 3; // Make padding start at unaligned address.
378 RtpPacketToSend packet(nullptr, 12 + kPayloadSize + kMaxPaddingSize);
379 packet.SetPayloadType(kPayloadType);
380 packet.SetSequenceNumber(kSeqNum);
381 packet.SetTimestamp(kTimestamp);
382 packet.SetSsrc(kSsrc);
danilchap07a01b32017-03-29 07:33:13 -0700383 packet.SetPayloadSize(kPayloadSize);
danilchap1edb7ab2016-04-20 05:25:10 -0700384
385 EXPECT_LT(packet.size(), packet.capacity());
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +0200386 EXPECT_TRUE(packet.SetPadding(kMaxPaddingSize));
danilchap1edb7ab2016-04-20 05:25:10 -0700387 EXPECT_EQ(packet.size(), packet.capacity());
388}
389
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +0200390TEST(RtpPacketTest, WritesPaddingSizeToLastByte) {
391 const size_t kPaddingSize = 5;
392 RtpPacket packet;
393
394 EXPECT_TRUE(packet.SetPadding(kPaddingSize));
395 EXPECT_EQ(packet.data()[packet.size() - 1], kPaddingSize);
396}
397
398TEST(RtpPacketTest, UsesZerosForPadding) {
399 const size_t kPaddingSize = 5;
400 RtpPacket packet;
401
402 EXPECT_TRUE(packet.SetPadding(kPaddingSize));
403 EXPECT_THAT(rtc::MakeArrayView(packet.data() + 12, kPaddingSize - 1),
404 Each(0));
405}
406
407TEST(RtpPacketTest, CreateOneBytePadding) {
408 size_t kPayloadSize = 123;
409 RtpPacket packet(nullptr, 12 + kPayloadSize + 1);
410 packet.SetPayloadSize(kPayloadSize);
411
412 EXPECT_TRUE(packet.SetPadding(1));
413
414 EXPECT_EQ(packet.size(), 12 + kPayloadSize + 1);
415 EXPECT_EQ(packet.padding_size(), 1u);
416}
417
418TEST(RtpPacketTest, FailsToAddPaddingWithoutCapacity) {
419 size_t kPayloadSize = 123;
420 RtpPacket packet(nullptr, 12 + kPayloadSize);
421 packet.SetPayloadSize(kPayloadSize);
422
423 EXPECT_FALSE(packet.SetPadding(1));
424}
425
danilchap1edb7ab2016-04-20 05:25:10 -0700426TEST(RtpPacketTest, ParseMinimum) {
427 RtpPacketReceived packet;
428 EXPECT_TRUE(packet.Parse(kMinimumPacket, sizeof(kMinimumPacket)));
429 EXPECT_EQ(kPayloadType, packet.PayloadType());
430 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
431 EXPECT_EQ(kTimestamp, packet.Timestamp());
432 EXPECT_EQ(kSsrc, packet.Ssrc());
433 EXPECT_EQ(0u, packet.padding_size());
434 EXPECT_EQ(0u, packet.payload_size());
435}
436
437TEST(RtpPacketTest, ParseBuffer) {
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200438 rtc::CopyOnWriteBuffer unparsed(kMinimumPacket);
danilchap1edb7ab2016-04-20 05:25:10 -0700439 const uint8_t* raw = unparsed.data();
440
441 RtpPacketReceived packet;
442 EXPECT_TRUE(packet.Parse(std::move(unparsed)));
Danil Chapovalov31e4e802016-08-03 18:27:40 +0200443 EXPECT_EQ(raw, packet.data()); // Expect packet take the buffer without copy.
danilchap1edb7ab2016-04-20 05:25:10 -0700444 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
445 EXPECT_EQ(kTimestamp, packet.Timestamp());
446 EXPECT_EQ(kSsrc, packet.Ssrc());
447 EXPECT_EQ(0u, packet.padding_size());
448 EXPECT_EQ(0u, packet.payload_size());
449}
450
451TEST(RtpPacketTest, ParseWithExtension) {
452 RtpPacketToSend::ExtensionManager extensions;
453 extensions.Register(kRtpExtensionTransmissionTimeOffset,
454 kTransmissionOffsetExtensionId);
455
456 RtpPacketReceived packet(&extensions);
457 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
458 EXPECT_EQ(kPayloadType, packet.PayloadType());
459 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
460 EXPECT_EQ(kTimestamp, packet.Timestamp());
461 EXPECT_EQ(kSsrc, packet.Ssrc());
462 int32_t time_offset;
463 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
464 EXPECT_EQ(kTimeOffset, time_offset);
465 EXPECT_EQ(0u, packet.payload_size());
466 EXPECT_EQ(0u, packet.padding_size());
467}
468
Danil Chapovalove19953b2018-10-01 16:12:28 +0200469TEST(RtpPacketTest, GetRawExtensionWhenPresent) {
470 constexpr uint8_t kRawPacket[] = {
471 // comment for clang-format to align kRawPacket nicer.
472 0x90, 100, 0x5e, 0x04, //
473 0x65, 0x43, 0x12, 0x78, // Timestamp.
474 0x12, 0x34, 0x56, 0x78, // Ssrc
475 0xbe, 0xde, 0x00, 0x01, // Extension header
476 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
477 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
478 RtpPacketToSend::ExtensionManager extensions;
479 extensions.Register<RtpMid>(1);
480 RtpPacket packet(&extensions);
481 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
482 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), ElementsAre('m', 'i', 'd'));
483}
484
485TEST(RtpPacketTest, GetRawExtensionWhenAbsent) {
486 constexpr uint8_t kRawPacket[] = {
487 // comment for clang-format to align kRawPacket nicer.
488 0x90, 100, 0x5e, 0x04, //
489 0x65, 0x43, 0x12, 0x78, // Timestamp.
490 0x12, 0x34, 0x56, 0x78, // Ssrc
491 0xbe, 0xde, 0x00, 0x01, // Extension header
492 0x12, 'm', 'i', 'd', // 3-byte extension with id=1.
493 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
494 RtpPacketToSend::ExtensionManager extensions;
495 extensions.Register<RtpMid>(2);
496 RtpPacket packet(&extensions);
497 ASSERT_TRUE(packet.Parse(kRawPacket, sizeof(kRawPacket)));
498 EXPECT_THAT(packet.GetRawExtension<RtpMid>(), IsEmpty());
499}
500
danilchap07ec26d2016-06-17 04:18:54 -0700501TEST(RtpPacketTest, ParseWithInvalidSizedExtension) {
502 RtpPacketToSend::ExtensionManager extensions;
503 extensions.Register(kRtpExtensionTransmissionTimeOffset,
504 kTransmissionOffsetExtensionId);
505
506 RtpPacketReceived packet(&extensions);
507 EXPECT_TRUE(packet.Parse(kPacketWithInvalidExtension,
508 sizeof(kPacketWithInvalidExtension)));
509
510 // Extension should be ignored.
511 int32_t time_offset;
512 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
513
514 // But shouldn't prevent reading payload.
danilchap96c15872016-11-21 01:35:29 -0800515 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap07ec26d2016-06-17 04:18:54 -0700516}
517
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200518TEST(RtpPacketTest, ParseWithOverSizedExtension) {
519 // clang-format off
520 const uint8_t bad_packet[] = {
eladalonae550e32017-05-24 08:28:13 -0700521 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
Danil Chapovalova64a2fb2016-09-12 11:41:35 +0200522 0x65, 0x43, 0x12, 0x78, // kTimestamp.
523 0x12, 0x34, 0x56, 0x78, // kSsrc.
524 0xbe, 0xde, 0x00, 0x01, // Extension of size 1x32bit word.
525 0x00, // Add a byte of padding.
526 0x12, // Extension id 1 size (2+1).
527 0xda, 0x1a // Only 2 bytes of extension payload.
528 };
529 // clang-format on
530 RtpPacketToSend::ExtensionManager extensions;
531 extensions.Register(TransmissionOffset::kId, 1);
532 RtpPacketReceived packet(&extensions);
533
534 // Parse should ignore bad extension and proceed.
535 EXPECT_TRUE(packet.Parse(bad_packet, sizeof(bad_packet)));
536 int32_t time_offset;
537 // But extracting extension should fail.
538 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
539}
540
danilchap1edb7ab2016-04-20 05:25:10 -0700541TEST(RtpPacketTest, ParseWith2Extensions) {
542 RtpPacketToSend::ExtensionManager extensions;
543 extensions.Register(kRtpExtensionTransmissionTimeOffset,
544 kTransmissionOffsetExtensionId);
545 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
546 RtpPacketReceived packet(&extensions);
547 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
548 int32_t time_offset;
549 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
550 EXPECT_EQ(kTimeOffset, time_offset);
551 bool voice_active;
552 uint8_t audio_level;
553 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
554 EXPECT_EQ(kVoiceActive, voice_active);
555 EXPECT_EQ(kAudioLevel, audio_level);
556}
557
Johannes Kron6ea77192018-09-24 17:19:52 +0200558TEST(RtpPacketTest, ParseSecondPacketWithFewerExtensions) {
559 RtpPacketToSend::ExtensionManager extensions;
560 extensions.Register(kRtpExtensionTransmissionTimeOffset,
561 kTransmissionOffsetExtensionId);
562 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
563 RtpPacketReceived packet(&extensions);
564 EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
565 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
566 EXPECT_TRUE(packet.HasExtension<AudioLevel>());
567
568 // Second packet without audio level.
569 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
570 EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
571 EXPECT_FALSE(packet.HasExtension<AudioLevel>());
572}
573
Johannes Kron07ba2b92018-09-26 13:33:35 +0200574TEST(RtpPacketTest, ParseWith2ExtensionsInvalidPadding) {
575 RtpPacketToSend::ExtensionManager extensions;
576 extensions.Register(kRtpExtensionTransmissionTimeOffset,
577 kTransmissionOffsetExtensionId);
578 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
579 RtpPacketReceived packet(&extensions);
580 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALInvalidPadding,
581 sizeof(kPacketWithTOAndALInvalidPadding)));
582 int32_t time_offset;
583 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
584 EXPECT_EQ(kTimeOffset, time_offset);
585 bool voice_active;
586 uint8_t audio_level;
587 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
588}
589
590TEST(RtpPacketTest, ParseWith2ExtensionsReservedExtensionId) {
591 RtpPacketToSend::ExtensionManager extensions;
592 extensions.Register(kRtpExtensionTransmissionTimeOffset,
593 kTransmissionOffsetExtensionId);
594 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
595 RtpPacketReceived packet(&extensions);
596 EXPECT_TRUE(packet.Parse(kPacketWithTOAndALReservedExtensionId,
597 sizeof(kPacketWithTOAndALReservedExtensionId)));
598 int32_t time_offset;
599 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
600 EXPECT_EQ(kTimeOffset, time_offset);
601 bool voice_active;
602 uint8_t audio_level;
603 EXPECT_FALSE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
604}
605
danilchap1edb7ab2016-04-20 05:25:10 -0700606TEST(RtpPacketTest, ParseWithAllFeatures) {
607 RtpPacketToSend::ExtensionManager extensions;
608 extensions.Register(kRtpExtensionTransmissionTimeOffset,
609 kTransmissionOffsetExtensionId);
610 RtpPacketReceived packet(&extensions);
611 EXPECT_TRUE(packet.Parse(kPacket, sizeof(kPacket)));
612 EXPECT_EQ(kPayloadType, packet.PayloadType());
613 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
614 EXPECT_EQ(kTimestamp, packet.Timestamp());
615 EXPECT_EQ(kSsrc, packet.Ssrc());
616 EXPECT_THAT(packet.Csrcs(), ElementsAreArray(kCsrcs));
danilchap96c15872016-11-21 01:35:29 -0800617 EXPECT_THAT(packet.payload(), ElementsAreArray(kPayload));
danilchap1edb7ab2016-04-20 05:25:10 -0700618 EXPECT_EQ(kPacketPaddingSize, packet.padding_size());
619 int32_t time_offset;
620 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
621}
622
Johannes Kron07ba2b92018-09-26 13:33:35 +0200623TEST(RtpPacketTest, ParseTwoByteHeaderExtension) {
624 RtpPacketToSend::ExtensionManager extensions;
625 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
626 RtpPacketReceived packet(&extensions);
627 EXPECT_TRUE(packet.Parse(kPacketWithTwoByteHeaderExtension,
628 sizeof(kPacketWithTwoByteHeaderExtension)));
629 int32_t time_offset;
630 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
631 EXPECT_EQ(kTimeOffset, time_offset);
632}
633
634TEST(RtpPacketTest, ParseLongTwoByteHeaderExtension) {
635 RtpPacketToSend::ExtensionManager extensions;
636 extensions.Register(kRtpExtensionMid, kTwoByteExtensionId);
637 RtpPacketReceived packet(&extensions);
638 EXPECT_TRUE(packet.Parse(kPacketWithLongTwoByteHeaderExtension,
639 sizeof(kPacketWithLongTwoByteHeaderExtension)));
640 std::string long_rtp_mid;
641 EXPECT_TRUE(packet.GetExtension<RtpMid>(&long_rtp_mid));
642 EXPECT_EQ(kLongMid, long_rtp_mid);
643}
644
645TEST(RtpPacketTest, ParseTwoByteHeaderExtensionWithPadding) {
646 RtpPacketToSend::ExtensionManager extensions;
647 extensions.Register(kRtpExtensionTransmissionTimeOffset, kTwoByteExtensionId);
648 extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
649 RtpPacketReceived packet(&extensions);
650 EXPECT_TRUE(
651 packet.Parse(kPacketWithTwoByteHeaderExtensionWithPadding,
652 sizeof(kPacketWithTwoByteHeaderExtensionWithPadding)));
653 int32_t time_offset;
654 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
655 EXPECT_EQ(kTimeOffset, time_offset);
656 bool voice_active;
657 uint8_t audio_level;
658 EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
659 EXPECT_EQ(kVoiceActive, voice_active);
660 EXPECT_EQ(kAudioLevel, audio_level);
661}
662
danilchap1edb7ab2016-04-20 05:25:10 -0700663TEST(RtpPacketTest, ParseWithExtensionDelayed) {
664 RtpPacketReceived packet;
665 EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
666 EXPECT_EQ(kPayloadType, packet.PayloadType());
667 EXPECT_EQ(kSeqNum, packet.SequenceNumber());
668 EXPECT_EQ(kTimestamp, packet.Timestamp());
669 EXPECT_EQ(kSsrc, packet.Ssrc());
670
671 RtpPacketToSend::ExtensionManager extensions;
672 extensions.Register(kRtpExtensionTransmissionTimeOffset,
673 kTransmissionOffsetExtensionId);
674
675 int32_t time_offset;
676 EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
danilchap70f39a32016-12-16 05:48:18 -0800677 packet.IdentifyExtensions(extensions);
danilchap1edb7ab2016-04-20 05:25:10 -0700678 EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
679 EXPECT_EQ(kTimeOffset, time_offset);
680 EXPECT_EQ(0u, packet.payload_size());
681 EXPECT_EQ(0u, packet.padding_size());
682}
683
danilchapef8d7732017-04-19 02:59:48 -0700684TEST(RtpPacketTest, ParseDynamicSizeExtension) {
685 // clang-format off
686 const uint8_t kPacket1[] = {
eladalonae550e32017-05-24 08:28:13 -0700687 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700688 0x65, 0x43, 0x12, 0x78, // Timestamp.
689 0x12, 0x34, 0x56, 0x78, // Ssrc.
690 0xbe, 0xde, 0x00, 0x02, // Extensions block of size 2x32bit words.
691 0x21, 'H', 'D', // Extension with id = 2, size = (1+1).
692 0x12, 'r', 't', 'x', // Extension with id = 1, size = (2+1).
693 0x00}; // Extension padding.
694 const uint8_t kPacket2[] = {
eladalonae550e32017-05-24 08:28:13 -0700695 0x90, kPayloadType, kSeqNumFirstByte, kSeqNumSecondByte,
danilchapef8d7732017-04-19 02:59:48 -0700696 0x65, 0x43, 0x12, 0x78, // Timestamp.
697 0x12, 0x34, 0x56, 0x79, // Ssrc.
698 0xbe, 0xde, 0x00, 0x01, // Extensions block of size 1x32bit words.
699 0x11, 'H', 'D', // Extension with id = 1, size = (1+1).
700 0x00}; // Extension padding.
701 // clang-format on
702 RtpPacketReceived::ExtensionManager extensions;
703 extensions.Register<RtpStreamId>(1);
704 extensions.Register<RepairedRtpStreamId>(2);
705 RtpPacketReceived packet(&extensions);
706 ASSERT_TRUE(packet.Parse(kPacket1, sizeof(kPacket1)));
707
708 std::string rsid;
709 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
710 EXPECT_EQ(rsid, "rtx");
711
712 std::string repaired_rsid;
713 EXPECT_TRUE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
714 EXPECT_EQ(repaired_rsid, "HD");
715
716 // Parse another packet with RtpStreamId extension of different size.
717 ASSERT_TRUE(packet.Parse(kPacket2, sizeof(kPacket2)));
718 EXPECT_TRUE(packet.GetExtension<RtpStreamId>(&rsid));
719 EXPECT_EQ(rsid, "HD");
720 EXPECT_FALSE(packet.GetExtension<RepairedRtpStreamId>(&repaired_rsid));
721}
722
Steve Antona3251dd2017-07-21 09:58:31 -0700723TEST(RtpPacketTest, ParseWithMid) {
724 RtpPacketReceived::ExtensionManager extensions;
725 extensions.Register<RtpMid>(kRtpMidExtensionId);
726 RtpPacketReceived packet(&extensions);
727 ASSERT_TRUE(packet.Parse(kPacketWithMid, sizeof(kPacketWithMid)));
728
729 std::string mid;
730 EXPECT_TRUE(packet.GetExtension<RtpMid>(&mid));
731 EXPECT_EQ(mid, kMid);
732}
733
sprangba050a62017-08-18 02:51:12 -0700734TEST(RtpPacketTest, CreateAndParseTimingFrameExtension) {
735 // Create a packet with video frame timing extension populated.
736 RtpPacketToSend::ExtensionManager send_extensions;
737 send_extensions.Register(kRtpExtensionVideoTiming, kVideoTimingExtensionId);
738 RtpPacketToSend send_packet(&send_extensions);
739 send_packet.SetPayloadType(kPayloadType);
740 send_packet.SetSequenceNumber(kSeqNum);
741 send_packet.SetTimestamp(kTimestamp);
742 send_packet.SetSsrc(kSsrc);
743
744 VideoSendTiming timing;
745 timing.encode_start_delta_ms = 1;
746 timing.encode_finish_delta_ms = 2;
747 timing.packetization_finish_delta_ms = 3;
748 timing.pacer_exit_delta_ms = 4;
749 timing.flags =
Ilya Nikolaevskiyb6c462d2018-06-05 15:21:32 +0200750 VideoSendTiming::kTriggeredByTimer | VideoSendTiming::kTriggeredBySize;
sprangba050a62017-08-18 02:51:12 -0700751
752 send_packet.SetExtension<VideoTimingExtension>(timing);
753
754 // Serialize the packet and then parse it again.
755 RtpPacketReceived::ExtensionManager extensions;
756 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
757 RtpPacketReceived receive_packet(&extensions);
758 EXPECT_TRUE(receive_packet.Parse(send_packet.Buffer()));
759
760 VideoSendTiming receivied_timing;
761 EXPECT_TRUE(
762 receive_packet.GetExtension<VideoTimingExtension>(&receivied_timing));
763
764 // Only check first and last timestamp (covered by other tests) plus flags.
765 EXPECT_EQ(receivied_timing.encode_start_delta_ms,
766 timing.encode_start_delta_ms);
767 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, timing.pacer_exit_delta_ms);
768 EXPECT_EQ(receivied_timing.flags, timing.flags);
769}
770
771TEST(RtpPacketTest, ParseLegacyTimingFrameExtension) {
772 // Parse the modified packet.
773 RtpPacketReceived::ExtensionManager extensions;
774 extensions.Register<VideoTimingExtension>(kVideoTimingExtensionId);
775 RtpPacketReceived packet(&extensions);
776 EXPECT_TRUE(packet.Parse(kPacketWithLegacyTimingExtension,
777 sizeof(kPacketWithLegacyTimingExtension)));
778 VideoSendTiming receivied_timing;
779 EXPECT_TRUE(packet.GetExtension<VideoTimingExtension>(&receivied_timing));
780
781 // Check first and last timestamp are still OK. Flags should now be 0.
782 EXPECT_EQ(receivied_timing.encode_start_delta_ms, 1);
783 EXPECT_EQ(receivied_timing.pacer_exit_delta_ms, 4);
784 EXPECT_EQ(receivied_timing.flags, 0);
785}
786
danilchap1edb7ab2016-04-20 05:25:10 -0700787} // namespace webrtc