1 /* 2 * Copyright (c) 2012 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 */ 10 11 /* 12 * This file includes unit tests for the VP8 packetizer. 13 */ 14 15 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h" 18 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h" 19 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h" 20 #include "webrtc/system_wrappers/interface/compile_assert.h" 21 #include "webrtc/typedefs.h" 22 23 #define CHECK_ARRAY_SIZE(expected_size, array) \ 24 COMPILE_ASSERT(expected_size == sizeof(array) / sizeof(array[0]), \ 25 check_array_size); 26 27 using ::testing::_; 28 using ::testing::Args; 29 using ::testing::ElementsAreArray; 30 using ::testing::Return; 31 32 namespace webrtc { 33 namespace { 34 // Payload descriptor 35 // 0 1 2 3 4 5 6 7 36 // +-+-+-+-+-+-+-+-+ 37 // |X|R|N|S|PartID | (REQUIRED) 38 // +-+-+-+-+-+-+-+-+ 39 // X: |I|L|T|K| RSV | (OPTIONAL) 40 // +-+-+-+-+-+-+-+-+ 41 // I: | PictureID | (OPTIONAL) 42 // +-+-+-+-+-+-+-+-+ 43 // L: | TL0PICIDX | (OPTIONAL) 44 // +-+-+-+-+-+-+-+-+ 45 // T/K: |TID:Y| KEYIDX | (OPTIONAL) 46 // +-+-+-+-+-+-+-+-+ 47 // 48 // Payload header 49 // 0 1 2 3 4 5 6 7 50 // +-+-+-+-+-+-+-+-+ 51 // |Size0|H| VER |P| 52 // +-+-+-+-+-+-+-+-+ 53 // | Size1 | 54 // +-+-+-+-+-+-+-+-+ 55 // | Size2 | 56 // +-+-+-+-+-+-+-+-+ 57 // | Bytes 4..N of | 58 // | VP8 payload | 59 // : : 60 // +-+-+-+-+-+-+-+-+ 61 // | OPTIONAL RTP | 62 // | padding | 63 // : : 64 // +-+-+-+-+-+-+-+-+ 65 66 void VerifyBasicHeader(WebRtcRTPHeader* header, bool N, bool S, int part_id) { 67 ASSERT_TRUE(header != NULL); 68 EXPECT_EQ(N, header->type.Video.codecHeader.VP8.nonReference); 69 EXPECT_EQ(S, header->type.Video.codecHeader.VP8.beginningOfPartition); 70 EXPECT_EQ(part_id, header->type.Video.codecHeader.VP8.partitionId); 71 } 72 73 void VerifyExtensions(WebRtcRTPHeader* header, 74 int16_t picture_id, /* I */ 75 int16_t tl0_pic_idx, /* L */ 76 uint8_t temporal_idx, /* T */ 77 int key_idx /* K */) { 78 ASSERT_TRUE(header != NULL); 79 EXPECT_EQ(picture_id, header->type.Video.codecHeader.VP8.pictureId); 80 EXPECT_EQ(tl0_pic_idx, header->type.Video.codecHeader.VP8.tl0PicIdx); 81 EXPECT_EQ(temporal_idx, header->type.Video.codecHeader.VP8.temporalIdx); 82 EXPECT_EQ(key_idx, header->type.Video.codecHeader.VP8.keyIdx); 83 } 84 } // namespace 85 86 class RtpPacketizerVp8Test : public ::testing::Test { 87 protected: 88 RtpPacketizerVp8Test() : helper_(NULL) {} 89 virtual void TearDown() { delete helper_; } 90 bool Init(const int* partition_sizes, int num_partitions) { 91 hdr_info_.pictureId = kNoPictureId; 92 hdr_info_.nonReference = false; 93 hdr_info_.temporalIdx = kNoTemporalIdx; 94 hdr_info_.layerSync = false; 95 hdr_info_.tl0PicIdx = kNoTl0PicIdx; 96 hdr_info_.keyIdx = kNoKeyIdx; 97 if (helper_ != NULL) 98 return false; 99 helper_ = new test::RtpFormatVp8TestHelper(&hdr_info_); 100 return helper_->Init(partition_sizes, num_partitions); 101 } 102 103 RTPVideoHeaderVP8 hdr_info_; 104 test::RtpFormatVp8TestHelper* helper_; 105 }; 106 107 TEST_F(RtpPacketizerVp8Test, TestStrictMode) { 108 const int kSizeVector[] = {10, 8, 27}; 109 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 110 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 111 112 hdr_info_.pictureId = 200; // > 0x7F should produce 2-byte PictureID. 113 const int kMaxSize = 13; 114 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize, kStrict); 115 packetizer.SetPayloadData(helper_->payload_data(), 116 helper_->payload_size(), 117 helper_->fragmentation()); 118 119 // The expected sizes are obtained by running a verified good implementation. 120 const int kExpectedSizes[] = {9, 9, 12, 11, 11, 11, 10}; 121 const int kExpectedPart[] = {0, 0, 1, 2, 2, 2, 2}; 122 const bool kExpectedFragStart[] = {true, false, true, true, 123 false, false, false}; 124 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 125 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 126 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 127 128 helper_->GetAllPacketsAndCheck(&packetizer, 129 kExpectedSizes, 130 kExpectedPart, 131 kExpectedFragStart, 132 kExpectedNum); 133 } 134 135 TEST_F(RtpPacketizerVp8Test, TestAggregateMode) { 136 const int kSizeVector[] = {60, 10, 10}; 137 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 138 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 139 140 hdr_info_.pictureId = 20; // <= 0x7F should produce 1-byte PictureID. 141 const int kMaxSize = 25; 142 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize, kAggregate); 143 packetizer.SetPayloadData(helper_->payload_data(), 144 helper_->payload_size(), 145 helper_->fragmentation()); 146 147 // The expected sizes are obtained by running a verified good implementation. 148 const int kExpectedSizes[] = {23, 23, 23, 23}; 149 const int kExpectedPart[] = {0, 0, 0, 1}; 150 const bool kExpectedFragStart[] = {true, false, false, true}; 151 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 152 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 153 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 154 155 helper_->GetAllPacketsAndCheck(&packetizer, 156 kExpectedSizes, 157 kExpectedPart, 158 kExpectedFragStart, 159 kExpectedNum); 160 } 161 162 TEST_F(RtpPacketizerVp8Test, TestAggregateModeManyPartitions1) { 163 const int kSizeVector[] = {1600, 200, 200, 200, 200, 200, 200, 200, 200}; 164 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 165 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 166 167 hdr_info_.pictureId = 20; // <= 0x7F should produce 1-byte PictureID. 168 const int kMaxSize = 1500; 169 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize, kAggregate); 170 packetizer.SetPayloadData(helper_->payload_data(), 171 helper_->payload_size(), 172 helper_->fragmentation()); 173 174 // The expected sizes are obtained by running a verified good implementation. 175 const int kExpectedSizes[] = {803, 803, 803, 803}; 176 const int kExpectedPart[] = {0, 0, 1, 5}; 177 const bool kExpectedFragStart[] = {true, false, true, true}; 178 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 179 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 180 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 181 182 helper_->GetAllPacketsAndCheck(&packetizer, 183 kExpectedSizes, 184 kExpectedPart, 185 kExpectedFragStart, 186 kExpectedNum); 187 } 188 189 TEST_F(RtpPacketizerVp8Test, TestAggregateModeManyPartitions2) { 190 const int kSizeVector[] = {1599, 200, 200, 200, 1600, 200, 200, 200, 200}; 191 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 192 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 193 194 hdr_info_.pictureId = 20; // <= 0x7F should produce 1-byte PictureID. 195 const int kMaxSize = 1500; 196 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize, kAggregate); 197 packetizer.SetPayloadData(helper_->payload_data(), 198 helper_->payload_size(), 199 helper_->fragmentation()); 200 201 // The expected sizes are obtained by running a verified good implementation. 202 const int kExpectedSizes[] = {803, 802, 603, 803, 803, 803}; 203 const int kExpectedPart[] = {0, 0, 1, 4, 4, 5}; 204 const bool kExpectedFragStart[] = {true, false, true, true, false, true}; 205 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 206 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 207 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 208 209 helper_->GetAllPacketsAndCheck(&packetizer, 210 kExpectedSizes, 211 kExpectedPart, 212 kExpectedFragStart, 213 kExpectedNum); 214 } 215 216 TEST_F(RtpPacketizerVp8Test, TestAggregateModeTwoLargePartitions) { 217 const int kSizeVector[] = {1654, 2268}; 218 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 219 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 220 221 hdr_info_.pictureId = 20; // <= 0x7F should produce 1-byte PictureID. 222 const int kMaxSize = 1460; 223 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize, kAggregate); 224 packetizer.SetPayloadData(helper_->payload_data(), 225 helper_->payload_size(), 226 helper_->fragmentation()); 227 228 // The expected sizes are obtained by running a verified good implementation. 229 const int kExpectedSizes[] = {830, 830, 1137, 1137}; 230 const int kExpectedPart[] = {0, 0, 1, 1}; 231 const bool kExpectedFragStart[] = {true, false, true, false}; 232 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 233 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 234 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 235 236 helper_->GetAllPacketsAndCheck(&packetizer, 237 kExpectedSizes, 238 kExpectedPart, 239 kExpectedFragStart, 240 kExpectedNum); 241 } 242 243 // Verify that EqualSize mode is forced if fragmentation info is missing. 244 TEST_F(RtpPacketizerVp8Test, TestEqualSizeModeFallback) { 245 const int kSizeVector[] = {10, 10, 10}; 246 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 247 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 248 249 hdr_info_.pictureId = 200; // > 0x7F should produce 2-byte PictureID 250 const int kMaxSize = 12; // Small enough to produce 4 packets. 251 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize); 252 packetizer.SetPayloadData( 253 helper_->payload_data(), helper_->payload_size(), NULL); 254 255 // Expecting three full packets, and one with the remainder. 256 const int kExpectedSizes[] = {12, 11, 12, 11}; 257 const int kExpectedPart[] = {0, 0, 0, 0}; // Always 0 for equal size mode. 258 // Frag start only true for first packet in equal size mode. 259 const bool kExpectedFragStart[] = {true, false, false, false}; 260 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 261 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 262 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 263 264 helper_->set_sloppy_partitioning(true); 265 helper_->GetAllPacketsAndCheck(&packetizer, 266 kExpectedSizes, 267 kExpectedPart, 268 kExpectedFragStart, 269 kExpectedNum); 270 } 271 272 // Verify that non-reference bit is set. EqualSize mode fallback is expected. 273 TEST_F(RtpPacketizerVp8Test, TestNonReferenceBit) { 274 const int kSizeVector[] = {10, 10, 10}; 275 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 276 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 277 278 hdr_info_.nonReference = true; 279 const int kMaxSize = 25; // Small enough to produce two packets. 280 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize); 281 packetizer.SetPayloadData( 282 helper_->payload_data(), helper_->payload_size(), NULL); 283 284 // EqualSize mode => First packet full; other not. 285 const int kExpectedSizes[] = {16, 16}; 286 const int kExpectedPart[] = {0, 0}; // Always 0 for equal size mode. 287 // Frag start only true for first packet in equal size mode. 288 const bool kExpectedFragStart[] = {true, false}; 289 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 290 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 291 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 292 293 helper_->set_sloppy_partitioning(true); 294 helper_->GetAllPacketsAndCheck(&packetizer, 295 kExpectedSizes, 296 kExpectedPart, 297 kExpectedFragStart, 298 kExpectedNum); 299 } 300 301 // Verify Tl0PicIdx and TID fields, and layerSync bit. 302 TEST_F(RtpPacketizerVp8Test, TestTl0PicIdxAndTID) { 303 const int kSizeVector[] = {10, 10, 10}; 304 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 305 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 306 307 hdr_info_.tl0PicIdx = 117; 308 hdr_info_.temporalIdx = 2; 309 hdr_info_.layerSync = true; 310 // kMaxSize is only limited by allocated buffer size. 311 const int kMaxSize = helper_->buffer_size(); 312 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize, kAggregate); 313 packetizer.SetPayloadData(helper_->payload_data(), 314 helper_->payload_size(), 315 helper_->fragmentation()); 316 317 // Expect one single packet of payload_size() + 4 bytes header. 318 const int kExpectedSizes[1] = {helper_->payload_size() + 4}; 319 const int kExpectedPart[1] = {0}; // Packet starts with partition 0. 320 const bool kExpectedFragStart[1] = {true}; 321 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 322 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 323 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 324 325 helper_->GetAllPacketsAndCheck(&packetizer, 326 kExpectedSizes, 327 kExpectedPart, 328 kExpectedFragStart, 329 kExpectedNum); 330 } 331 332 // Verify KeyIdx field. 333 TEST_F(RtpPacketizerVp8Test, TestKeyIdx) { 334 const int kSizeVector[] = {10, 10, 10}; 335 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 336 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 337 338 hdr_info_.keyIdx = 17; 339 // kMaxSize is only limited by allocated buffer size. 340 const int kMaxSize = helper_->buffer_size(); 341 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize, kAggregate); 342 packetizer.SetPayloadData(helper_->payload_data(), 343 helper_->payload_size(), 344 helper_->fragmentation()); 345 346 // Expect one single packet of payload_size() + 3 bytes header. 347 const int kExpectedSizes[1] = {helper_->payload_size() + 3}; 348 const int kExpectedPart[1] = {0}; // Packet starts with partition 0. 349 const bool kExpectedFragStart[1] = {true}; 350 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 351 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 352 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 353 354 helper_->GetAllPacketsAndCheck(&packetizer, 355 kExpectedSizes, 356 kExpectedPart, 357 kExpectedFragStart, 358 kExpectedNum); 359 } 360 361 // Verify TID field and KeyIdx field in combination. 362 TEST_F(RtpPacketizerVp8Test, TestTIDAndKeyIdx) { 363 const int kSizeVector[] = {10, 10, 10}; 364 const int kNumPartitions = sizeof(kSizeVector) / sizeof(kSizeVector[0]); 365 ASSERT_TRUE(Init(kSizeVector, kNumPartitions)); 366 367 hdr_info_.temporalIdx = 1; 368 hdr_info_.keyIdx = 5; 369 // kMaxSize is only limited by allocated buffer size. 370 const int kMaxSize = helper_->buffer_size(); 371 RtpPacketizerVp8 packetizer(hdr_info_, kMaxSize, kAggregate); 372 packetizer.SetPayloadData(helper_->payload_data(), 373 helper_->payload_size(), 374 helper_->fragmentation()); 375 376 // Expect one single packet of payload_size() + 3 bytes header. 377 const int kExpectedSizes[1] = {helper_->payload_size() + 3}; 378 const int kExpectedPart[1] = {0}; // Packet starts with partition 0. 379 const bool kExpectedFragStart[1] = {true}; 380 const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]); 381 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart); 382 CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart); 383 384 helper_->GetAllPacketsAndCheck(&packetizer, 385 kExpectedSizes, 386 kExpectedPart, 387 kExpectedFragStart, 388 kExpectedNum); 389 } 390 391 class RtpDepacketizerVp8Test : public ::testing::Test { 392 protected: 393 RtpDepacketizerVp8Test() 394 : callback_(), 395 depacketizer_(RtpDepacketizer::Create(kRtpVideoVp8, &callback_)) {} 396 397 void ExpectPacket(const uint8_t* data, size_t length) { 398 EXPECT_CALL(callback_, OnReceivedPayloadData(_, length, _)) 399 .With(Args<0, 1>(ElementsAreArray(data, length))) 400 .Times(1) 401 .WillOnce(Return(0)); 402 } 403 404 MockRtpData callback_; 405 scoped_ptr<RtpDepacketizer> depacketizer_; 406 }; 407 408 TEST_F(RtpDepacketizerVp8Test, BasicHeader) { 409 const uint8_t kHeaderLength = 1; 410 uint8_t packet[4] = {0}; 411 packet[0] = 0x14; // Binary 0001 0100; S = 1, PartID = 4. 412 packet[1] = 0x01; // P frame. 413 414 WebRtcRTPHeader rtp_header; 415 memset(&rtp_header, 0, sizeof(rtp_header)); 416 417 ExpectPacket(packet + kHeaderLength, sizeof(packet) - kHeaderLength); 418 EXPECT_TRUE(depacketizer_->Parse(&rtp_header, packet, sizeof(packet))); 419 420 EXPECT_EQ(kVideoFrameDelta, rtp_header.frameType); 421 VerifyBasicHeader(&rtp_header, 0, 1, 4); 422 VerifyExtensions( 423 &rtp_header, kNoPictureId, kNoTl0PicIdx, kNoTemporalIdx, kNoKeyIdx); 424 } 425 426 TEST_F(RtpDepacketizerVp8Test, PictureID) { 427 const uint8_t kHeaderLength1 = 3; 428 const uint8_t kHeaderLength2 = 4; 429 const uint8_t kPictureId = 17; 430 uint8_t packet[10] = {0}; 431 packet[0] = 0xA0; 432 packet[1] = 0x80; 433 packet[2] = kPictureId; 434 435 WebRtcRTPHeader rtp_header; 436 memset(&rtp_header, 0, sizeof(rtp_header)); 437 438 ExpectPacket(packet + kHeaderLength1, sizeof(packet) - kHeaderLength1); 439 EXPECT_TRUE(depacketizer_->Parse(&rtp_header, packet, sizeof(packet))); 440 EXPECT_EQ(kVideoFrameDelta, rtp_header.frameType); 441 VerifyBasicHeader(&rtp_header, 1, 0, 0); 442 VerifyExtensions( 443 &rtp_header, kPictureId, kNoTl0PicIdx, kNoTemporalIdx, kNoKeyIdx); 444 445 // Re-use packet, but change to long PictureID. 446 packet[2] = 0x80 | kPictureId; 447 packet[3] = kPictureId; 448 memset(&rtp_header, 0, sizeof(rtp_header)); 449 450 ExpectPacket(packet + kHeaderLength2, sizeof(packet) - kHeaderLength2); 451 EXPECT_TRUE(depacketizer_->Parse(&rtp_header, packet, sizeof(packet))); 452 VerifyBasicHeader(&rtp_header, 1, 0, 0); 453 VerifyExtensions(&rtp_header, 454 (kPictureId << 8) + kPictureId, 455 kNoTl0PicIdx, 456 kNoTemporalIdx, 457 kNoKeyIdx); 458 } 459 460 TEST_F(RtpDepacketizerVp8Test, Tl0PicIdx) { 461 const uint8_t kHeaderLength = 3; 462 const uint8_t kTl0PicIdx = 17; 463 uint8_t packet[13] = {0}; 464 packet[0] = 0x90; 465 packet[1] = 0x40; 466 packet[2] = kTl0PicIdx; 467 468 WebRtcRTPHeader rtp_header; 469 memset(&rtp_header, 0, sizeof(rtp_header)); 470 471 ExpectPacket(packet + kHeaderLength, sizeof(packet) - kHeaderLength); 472 EXPECT_TRUE(depacketizer_->Parse(&rtp_header, packet, sizeof(packet))); 473 EXPECT_EQ(kVideoFrameKey, rtp_header.frameType); 474 VerifyBasicHeader(&rtp_header, 0, 1, 0); 475 VerifyExtensions( 476 &rtp_header, kNoPictureId, kTl0PicIdx, kNoTemporalIdx, kNoKeyIdx); 477 } 478 479 TEST_F(RtpDepacketizerVp8Test, TIDAndLayerSync) { 480 const uint8_t kHeaderLength = 3; 481 uint8_t packet[10] = {0}; 482 packet[0] = 0x88; 483 packet[1] = 0x20; 484 packet[2] = 0x80; // TID(2) + LayerSync(false) 485 486 WebRtcRTPHeader rtp_header; 487 memset(&rtp_header, 0, sizeof(rtp_header)); 488 489 ExpectPacket(packet + kHeaderLength, sizeof(packet) - kHeaderLength); 490 EXPECT_TRUE(depacketizer_->Parse(&rtp_header, packet, sizeof(packet))); 491 EXPECT_EQ(kVideoFrameDelta, rtp_header.frameType); 492 VerifyBasicHeader(&rtp_header, 0, 0, 8); 493 VerifyExtensions(&rtp_header, kNoPictureId, kNoTl0PicIdx, 2, kNoKeyIdx); 494 EXPECT_FALSE(rtp_header.type.Video.codecHeader.VP8.layerSync); 495 } 496 497 TEST_F(RtpDepacketizerVp8Test, KeyIdx) { 498 const uint8_t kHeaderLength = 3; 499 const uint8_t kKeyIdx = 17; 500 uint8_t packet[10] = {0}; 501 packet[0] = 0x88; 502 packet[1] = 0x10; // K = 1. 503 packet[2] = kKeyIdx; 504 505 WebRtcRTPHeader rtp_header; 506 memset(&rtp_header, 0, sizeof(rtp_header)); 507 508 ExpectPacket(packet + kHeaderLength, sizeof(packet) - kHeaderLength); 509 EXPECT_TRUE(depacketizer_->Parse(&rtp_header, packet, sizeof(packet))); 510 EXPECT_EQ(kVideoFrameDelta, rtp_header.frameType); 511 VerifyBasicHeader(&rtp_header, 0, 0, 8); 512 VerifyExtensions( 513 &rtp_header, kNoPictureId, kNoTl0PicIdx, kNoTemporalIdx, kKeyIdx); 514 } 515 516 TEST_F(RtpDepacketizerVp8Test, MultipleExtensions) { 517 const uint8_t kHeaderLength = 6; 518 uint8_t packet[10] = {0}; 519 packet[0] = 0x88; 520 packet[1] = 0x80 | 0x40 | 0x20 | 0x10; 521 packet[2] = 0x80 | 17; // PictureID, high 7 bits. 522 packet[3] = 17; // PictureID, low 8 bits. 523 packet[4] = 42; // Tl0PicIdx. 524 packet[5] = 0x40 | 0x20 | 0x11; // TID(1) + LayerSync(true) + KEYIDX(17). 525 526 WebRtcRTPHeader rtp_header; 527 memset(&rtp_header, 0, sizeof(rtp_header)); 528 529 ExpectPacket(packet + kHeaderLength, sizeof(packet) - kHeaderLength); 530 EXPECT_TRUE(depacketizer_->Parse(&rtp_header, packet, sizeof(packet))); 531 EXPECT_EQ(kVideoFrameDelta, rtp_header.frameType); 532 VerifyBasicHeader(&rtp_header, 0, 0, 8); 533 VerifyExtensions(&rtp_header, (17 << 8) + 17, 42, 1, 17); 534 } 535 536 TEST_F(RtpDepacketizerVp8Test, TooShortHeader) { 537 uint8_t packet[4] = {0}; 538 packet[0] = 0x88; 539 packet[1] = 0x80 | 0x40 | 0x20 | 0x10; // All extensions are enabled... 540 packet[2] = 0x80 | 17; // ... but only 2 bytes PictureID is provided. 541 packet[3] = 17; // PictureID, low 8 bits. 542 543 WebRtcRTPHeader rtp_header; 544 memset(&rtp_header, 0, sizeof(rtp_header)); 545 546 EXPECT_FALSE(depacketizer_->Parse(&rtp_header, packet, sizeof(packet))); 547 } 548 549 TEST_F(RtpDepacketizerVp8Test, TestWithPacketizer) { 550 const uint8_t kHeaderLength = 5; 551 uint8_t payload[10] = {0}; 552 uint8_t packet[20] = {0}; 553 RTPVideoHeaderVP8 input_header; 554 input_header.nonReference = true; 555 input_header.pictureId = 300; 556 input_header.temporalIdx = 1; 557 input_header.layerSync = false; 558 input_header.tl0PicIdx = kNoTl0PicIdx; // Disable. 559 input_header.keyIdx = 31; 560 RtpPacketizerVp8 packetizer(input_header, 20); 561 packetizer.SetPayloadData(payload, 10, NULL); 562 bool last; 563 size_t send_bytes; 564 ASSERT_TRUE(packetizer.NextPacket(packet, &send_bytes, &last)); 565 ASSERT_TRUE(last); 566 567 WebRtcRTPHeader rtp_header; 568 memset(&rtp_header, 0, sizeof(rtp_header)); 569 570 ExpectPacket(packet + kHeaderLength, sizeof(packet) - kHeaderLength); 571 EXPECT_TRUE(depacketizer_->Parse(&rtp_header, packet, sizeof(packet))); 572 EXPECT_EQ(kVideoFrameKey, rtp_header.frameType); 573 VerifyBasicHeader(&rtp_header, 1, 1, 0); 574 VerifyExtensions(&rtp_header, 575 input_header.pictureId, 576 input_header.tl0PicIdx, 577 input_header.temporalIdx, 578 input_header.keyIdx); 579 EXPECT_EQ(rtp_header.type.Video.codecHeader.VP8.layerSync, 580 input_header.layerSync); 581 } 582 } // namespace webrtc 583