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