1 /* 2 * Copyright (c) 2015 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 #include <vector> 12 13 #include "testing/gmock/include/gmock/gmock.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h" 16 #include "webrtc/typedefs.h" 17 18 namespace webrtc { 19 namespace { 20 void VerifyHeader(const RTPVideoHeaderVP9& expected, 21 const RTPVideoHeaderVP9& actual) { 22 EXPECT_EQ(expected.inter_layer_predicted, actual.inter_layer_predicted); 23 EXPECT_EQ(expected.inter_pic_predicted, actual.inter_pic_predicted); 24 EXPECT_EQ(expected.flexible_mode, actual.flexible_mode); 25 EXPECT_EQ(expected.beginning_of_frame, actual.beginning_of_frame); 26 EXPECT_EQ(expected.end_of_frame, actual.end_of_frame); 27 EXPECT_EQ(expected.ss_data_available, actual.ss_data_available); 28 EXPECT_EQ(expected.picture_id, actual.picture_id); 29 EXPECT_EQ(expected.max_picture_id, actual.max_picture_id); 30 EXPECT_EQ(expected.temporal_idx, actual.temporal_idx); 31 EXPECT_EQ(expected.spatial_idx == kNoSpatialIdx ? 0 : expected.spatial_idx, 32 actual.spatial_idx); 33 EXPECT_EQ(expected.gof_idx, actual.gof_idx); 34 EXPECT_EQ(expected.tl0_pic_idx, actual.tl0_pic_idx); 35 EXPECT_EQ(expected.temporal_up_switch, actual.temporal_up_switch); 36 37 EXPECT_EQ(expected.num_ref_pics, actual.num_ref_pics); 38 for (uint8_t i = 0; i < expected.num_ref_pics; ++i) { 39 EXPECT_EQ(expected.pid_diff[i], actual.pid_diff[i]); 40 EXPECT_EQ(expected.ref_picture_id[i], actual.ref_picture_id[i]); 41 } 42 if (expected.ss_data_available) { 43 EXPECT_EQ(expected.spatial_layer_resolution_present, 44 actual.spatial_layer_resolution_present); 45 EXPECT_EQ(expected.num_spatial_layers, actual.num_spatial_layers); 46 if (expected.spatial_layer_resolution_present) { 47 for (size_t i = 0; i < expected.num_spatial_layers; i++) { 48 EXPECT_EQ(expected.width[i], actual.width[i]); 49 EXPECT_EQ(expected.height[i], actual.height[i]); 50 } 51 } 52 EXPECT_EQ(expected.gof.num_frames_in_gof, actual.gof.num_frames_in_gof); 53 for (size_t i = 0; i < expected.gof.num_frames_in_gof; i++) { 54 EXPECT_EQ(expected.gof.temporal_up_switch[i], 55 actual.gof.temporal_up_switch[i]); 56 EXPECT_EQ(expected.gof.temporal_idx[i], actual.gof.temporal_idx[i]); 57 EXPECT_EQ(expected.gof.num_ref_pics[i], actual.gof.num_ref_pics[i]); 58 for (uint8_t j = 0; j < expected.gof.num_ref_pics[i]; j++) { 59 EXPECT_EQ(expected.gof.pid_diff[i][j], actual.gof.pid_diff[i][j]); 60 } 61 } 62 } 63 } 64 65 void VerifyPayload(const RtpDepacketizer::ParsedPayload& parsed, 66 const uint8_t* payload, 67 size_t payload_length) { 68 EXPECT_EQ(payload, parsed.payload); 69 EXPECT_EQ(payload_length, parsed.payload_length); 70 EXPECT_THAT(std::vector<uint8_t>(parsed.payload, 71 parsed.payload + parsed.payload_length), 72 ::testing::ElementsAreArray(payload, payload_length)); 73 } 74 75 void ParseAndCheckPacket(const uint8_t* packet, 76 const RTPVideoHeaderVP9& expected, 77 size_t expected_hdr_length, 78 size_t expected_length) { 79 rtc::scoped_ptr<RtpDepacketizer> depacketizer(new RtpDepacketizerVp9()); 80 RtpDepacketizer::ParsedPayload parsed; 81 ASSERT_TRUE(depacketizer->Parse(&parsed, packet, expected_length)); 82 EXPECT_EQ(kRtpVideoVp9, parsed.type.Video.codec); 83 VerifyHeader(expected, parsed.type.Video.codecHeader.VP9); 84 const size_t kExpectedPayloadLength = expected_length - expected_hdr_length; 85 VerifyPayload(parsed, packet + expected_hdr_length, kExpectedPayloadLength); 86 } 87 } // namespace 88 89 // Payload descriptor for flexible mode 90 // 0 1 2 3 4 5 6 7 91 // +-+-+-+-+-+-+-+-+ 92 // |I|P|L|F|B|E|V|-| (REQUIRED) 93 // +-+-+-+-+-+-+-+-+ 94 // I: |M| PICTURE ID | (RECOMMENDED) 95 // +-+-+-+-+-+-+-+-+ 96 // M: | EXTENDED PID | (RECOMMENDED) 97 // +-+-+-+-+-+-+-+-+ 98 // L: | T |U| S |D| (CONDITIONALLY RECOMMENDED) 99 // +-+-+-+-+-+-+-+-+ -| 100 // P,F: | P_DIFF |N| (CONDITIONALLY RECOMMENDED) . up to 3 times 101 // +-+-+-+-+-+-+-+-+ -| 102 // V: | SS | 103 // | .. | 104 // +-+-+-+-+-+-+-+-+ 105 // 106 // Payload descriptor for non-flexible mode 107 // 0 1 2 3 4 5 6 7 108 // +-+-+-+-+-+-+-+-+ 109 // |I|P|L|F|B|E|V|-| (REQUIRED) 110 // +-+-+-+-+-+-+-+-+ 111 // I: |M| PICTURE ID | (RECOMMENDED) 112 // +-+-+-+-+-+-+-+-+ 113 // M: | EXTENDED PID | (RECOMMENDED) 114 // +-+-+-+-+-+-+-+-+ 115 // L: | T |U| S |D| (CONDITIONALLY RECOMMENDED) 116 // +-+-+-+-+-+-+-+-+ 117 // | TL0PICIDX | (CONDITIONALLY REQUIRED) 118 // +-+-+-+-+-+-+-+-+ 119 // V: | SS | 120 // | .. | 121 // +-+-+-+-+-+-+-+-+ 122 123 class RtpPacketizerVp9Test : public ::testing::Test { 124 protected: 125 RtpPacketizerVp9Test() {} 126 virtual void SetUp() { 127 expected_.InitRTPVideoHeaderVP9(); 128 } 129 130 rtc::scoped_ptr<uint8_t[]> packet_; 131 rtc::scoped_ptr<uint8_t[]> payload_; 132 size_t payload_size_; 133 size_t payload_pos_; 134 RTPVideoHeaderVP9 expected_; 135 rtc::scoped_ptr<RtpPacketizerVp9> packetizer_; 136 137 void Init(size_t payload_size, size_t packet_size) { 138 payload_.reset(new uint8_t[payload_size]); 139 memset(payload_.get(), 7, payload_size); 140 payload_size_ = payload_size; 141 payload_pos_ = 0; 142 packetizer_.reset(new RtpPacketizerVp9(expected_, packet_size)); 143 packetizer_->SetPayloadData(payload_.get(), payload_size_, NULL); 144 145 const int kMaxPayloadDescriptorLength = 100; 146 packet_.reset(new uint8_t[payload_size_ + kMaxPayloadDescriptorLength]); 147 } 148 149 void CheckPayload(const uint8_t* packet, 150 size_t start_pos, 151 size_t end_pos, 152 bool last) { 153 for (size_t i = start_pos; i < end_pos; ++i) { 154 EXPECT_EQ(packet[i], payload_[payload_pos_++]); 155 } 156 EXPECT_EQ(last, payload_pos_ == payload_size_); 157 } 158 159 void CreateParseAndCheckPackets(const size_t* expected_hdr_sizes, 160 const size_t* expected_sizes, 161 size_t expected_num_packets) { 162 ASSERT_TRUE(packetizer_.get() != NULL); 163 size_t length = 0; 164 bool last = false; 165 if (expected_num_packets == 0) { 166 EXPECT_FALSE(packetizer_->NextPacket(packet_.get(), &length, &last)); 167 return; 168 } 169 for (size_t i = 0; i < expected_num_packets; ++i) { 170 EXPECT_TRUE(packetizer_->NextPacket(packet_.get(), &length, &last)); 171 EXPECT_EQ(expected_sizes[i], length); 172 RTPVideoHeaderVP9 hdr = expected_; 173 hdr.beginning_of_frame = (i == 0); 174 hdr.end_of_frame = last; 175 ParseAndCheckPacket(packet_.get(), hdr, expected_hdr_sizes[i], length); 176 CheckPayload(packet_.get(), expected_hdr_sizes[i], length, last); 177 } 178 EXPECT_TRUE(last); 179 } 180 }; 181 182 TEST_F(RtpPacketizerVp9Test, TestEqualSizedMode_OnePacket) { 183 const size_t kFrameSize = 25; 184 const size_t kPacketSize = 26; 185 Init(kFrameSize, kPacketSize); 186 187 // One packet: 188 // I:0, P:0, L:0, F:0, B:1, E:1, V:0 (1hdr + 25 payload) 189 const size_t kExpectedHdrSizes[] = {1}; 190 const size_t kExpectedSizes[] = {26}; 191 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 192 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 193 } 194 195 TEST_F(RtpPacketizerVp9Test, TestEqualSizedMode_TwoPackets) { 196 const size_t kFrameSize = 27; 197 const size_t kPacketSize = 27; 198 Init(kFrameSize, kPacketSize); 199 200 // Two packets: 201 // I:0, P:0, L:0, F:0, B:1, E:0, V:0 (1hdr + 14 payload) 202 // I:0, P:0, L:0, F:0, B:0, E:1, V:0 (1hdr + 13 payload) 203 const size_t kExpectedHdrSizes[] = {1, 1}; 204 const size_t kExpectedSizes[] = {15, 14}; 205 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 206 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 207 } 208 209 TEST_F(RtpPacketizerVp9Test, TestTooShortBufferToFitPayload) { 210 const size_t kFrameSize = 1; 211 const size_t kPacketSize = 1; 212 Init(kFrameSize, kPacketSize); // 1hdr + 1 payload 213 214 const size_t kExpectedNum = 0; 215 CreateParseAndCheckPackets(NULL, NULL, kExpectedNum); 216 } 217 218 TEST_F(RtpPacketizerVp9Test, TestOneBytePictureId) { 219 const size_t kFrameSize = 30; 220 const size_t kPacketSize = 12; 221 222 expected_.picture_id = kMaxOneBytePictureId; // 2 byte payload descriptor 223 expected_.max_picture_id = kMaxOneBytePictureId; 224 Init(kFrameSize, kPacketSize); 225 226 // Three packets: 227 // I:1, P:0, L:0, F:0, B:1, E:0, V:0 (2hdr + 10 payload) 228 // I:1, P:0, L:0, F:0, B:0, E:0, V:0 (2hdr + 10 payload) 229 // I:1, P:0, L:0, F:0, B:0, E:1, V:0 (2hdr + 10 payload) 230 const size_t kExpectedHdrSizes[] = {2, 2, 2}; 231 const size_t kExpectedSizes[] = {12, 12, 12}; 232 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 233 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 234 } 235 236 TEST_F(RtpPacketizerVp9Test, TestTwoBytePictureId) { 237 const size_t kFrameSize = 31; 238 const size_t kPacketSize = 13; 239 240 expected_.picture_id = kMaxTwoBytePictureId; // 3 byte payload descriptor 241 Init(kFrameSize, kPacketSize); 242 243 // Four packets: 244 // I:1, P:0, L:0, F:0, B:1, E:0, V:0 (3hdr + 8 payload) 245 // I:1, P:0, L:0, F:0, B:0, E:0, V:0 (3hdr + 8 payload) 246 // I:1, P:0, L:0, F:0, B:0, E:0, V:0 (3hdr + 8 payload) 247 // I:1, P:0, L:0, F:0, B:0, E:1, V:0 (3hdr + 7 payload) 248 const size_t kExpectedHdrSizes[] = {3, 3, 3, 3}; 249 const size_t kExpectedSizes[] = {11, 11, 11, 10}; 250 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 251 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 252 } 253 254 TEST_F(RtpPacketizerVp9Test, TestLayerInfoWithNonFlexibleMode) { 255 const size_t kFrameSize = 30; 256 const size_t kPacketSize = 25; 257 258 expected_.temporal_idx = 3; 259 expected_.temporal_up_switch = true; // U 260 expected_.num_spatial_layers = 3; 261 expected_.spatial_idx = 2; 262 expected_.inter_layer_predicted = true; // D 263 expected_.tl0_pic_idx = 117; 264 Init(kFrameSize, kPacketSize); 265 266 // Two packets: 267 // | I:0, P:0, L:1, F:0, B:1, E:0, V:0 | (3hdr + 15 payload) 268 // L: | T:3, U:1, S:2, D:1 | TL0PICIDX:117 | 269 // | I:0, P:0, L:1, F:0, B:0, E:1, V:0 | (3hdr + 15 payload) 270 // L: | T:3, U:1, S:2, D:1 | TL0PICIDX:117 | 271 const size_t kExpectedHdrSizes[] = {3, 3}; 272 const size_t kExpectedSizes[] = {18, 18}; 273 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 274 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 275 } 276 277 TEST_F(RtpPacketizerVp9Test, TestLayerInfoWithFlexibleMode) { 278 const size_t kFrameSize = 21; 279 const size_t kPacketSize = 23; 280 281 expected_.flexible_mode = true; 282 expected_.temporal_idx = 3; 283 expected_.temporal_up_switch = true; // U 284 expected_.num_spatial_layers = 3; 285 expected_.spatial_idx = 2; 286 expected_.inter_layer_predicted = false; // D 287 Init(kFrameSize, kPacketSize); 288 289 // One packet: 290 // I:0, P:0, L:1, F:1, B:1, E:1, V:0 (2hdr + 21 payload) 291 // L: T:3, U:1, S:2, D:0 292 const size_t kExpectedHdrSizes[] = {2}; 293 const size_t kExpectedSizes[] = {23}; 294 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 295 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 296 } 297 298 TEST_F(RtpPacketizerVp9Test, TestRefIdx) { 299 const size_t kFrameSize = 16; 300 const size_t kPacketSize = 21; 301 302 expected_.inter_pic_predicted = true; // P 303 expected_.flexible_mode = true; // F 304 expected_.picture_id = 2; 305 expected_.max_picture_id = kMaxOneBytePictureId; 306 307 expected_.num_ref_pics = 3; 308 expected_.pid_diff[0] = 1; 309 expected_.pid_diff[1] = 3; 310 expected_.pid_diff[2] = 127; 311 expected_.ref_picture_id[0] = 1; // 2 - 1 = 1 312 expected_.ref_picture_id[1] = 127; // (kMaxPictureId + 1) + 2 - 3 = 127 313 expected_.ref_picture_id[2] = 3; // (kMaxPictureId + 1) + 2 - 127 = 3 314 Init(kFrameSize, kPacketSize); 315 316 // Two packets: 317 // I:1, P:1, L:0, F:1, B:1, E:1, V:0 (5hdr + 16 payload) 318 // I: 2 319 // P,F: P_DIFF:1, N:1 320 // P_DIFF:3, N:1 321 // P_DIFF:127, N:0 322 const size_t kExpectedHdrSizes[] = {5}; 323 const size_t kExpectedSizes[] = {21}; 324 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 325 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 326 } 327 328 TEST_F(RtpPacketizerVp9Test, TestRefIdxFailsWithoutPictureId) { 329 const size_t kFrameSize = 16; 330 const size_t kPacketSize = 21; 331 332 expected_.inter_pic_predicted = true; 333 expected_.flexible_mode = true; 334 expected_.num_ref_pics = 1; 335 expected_.pid_diff[0] = 3; 336 Init(kFrameSize, kPacketSize); 337 338 const size_t kExpectedNum = 0; 339 CreateParseAndCheckPackets(NULL, NULL, kExpectedNum); 340 } 341 342 TEST_F(RtpPacketizerVp9Test, TestSsDataWithoutSpatialResolutionPresent) { 343 const size_t kFrameSize = 21; 344 const size_t kPacketSize = 26; 345 346 expected_.ss_data_available = true; 347 expected_.num_spatial_layers = 1; 348 expected_.spatial_layer_resolution_present = false; 349 expected_.gof.num_frames_in_gof = 1; 350 expected_.gof.temporal_idx[0] = 0; 351 expected_.gof.temporal_up_switch[0] = true; 352 expected_.gof.num_ref_pics[0] = 1; 353 expected_.gof.pid_diff[0][0] = 4; 354 Init(kFrameSize, kPacketSize); 355 356 // One packet: 357 // I:0, P:0, L:0, F:0, B:1, E:1, V:1 (5hdr + 21 payload) 358 // N_S:0, Y:0, G:1 359 // N_G:1 360 // T:0, U:1, R:1 | P_DIFF[0][0]:4 361 const size_t kExpectedHdrSizes[] = {5}; 362 const size_t kExpectedSizes[] = {26}; 363 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 364 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 365 } 366 367 TEST_F(RtpPacketizerVp9Test, TestSsDataWithoutGbitPresent) { 368 const size_t kFrameSize = 21; 369 const size_t kPacketSize = 23; 370 371 expected_.ss_data_available = true; 372 expected_.num_spatial_layers = 1; 373 expected_.spatial_layer_resolution_present = false; 374 expected_.gof.num_frames_in_gof = 0; 375 Init(kFrameSize, kPacketSize); 376 377 // One packet: 378 // I:0, P:0, L:0, F:0, B:1, E:1, V:1 (2hdr + 21 payload) 379 // N_S:0, Y:0, G:0 380 const size_t kExpectedHdrSizes[] = {2}; 381 const size_t kExpectedSizes[] = {23}; 382 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 383 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 384 } 385 386 TEST_F(RtpPacketizerVp9Test, TestSsData) { 387 const size_t kFrameSize = 21; 388 const size_t kPacketSize = 40; 389 390 expected_.ss_data_available = true; 391 expected_.num_spatial_layers = 2; 392 expected_.spatial_layer_resolution_present = true; 393 expected_.width[0] = 640; 394 expected_.width[1] = 1280; 395 expected_.height[0] = 360; 396 expected_.height[1] = 720; 397 expected_.gof.num_frames_in_gof = 3; 398 expected_.gof.temporal_idx[0] = 0; 399 expected_.gof.temporal_idx[1] = 1; 400 expected_.gof.temporal_idx[2] = 2; 401 expected_.gof.temporal_up_switch[0] = true; 402 expected_.gof.temporal_up_switch[1] = true; 403 expected_.gof.temporal_up_switch[2] = false; 404 expected_.gof.num_ref_pics[0] = 0; 405 expected_.gof.num_ref_pics[1] = 3; 406 expected_.gof.num_ref_pics[2] = 2; 407 expected_.gof.pid_diff[1][0] = 5; 408 expected_.gof.pid_diff[1][1] = 6; 409 expected_.gof.pid_diff[1][2] = 7; 410 expected_.gof.pid_diff[2][0] = 8; 411 expected_.gof.pid_diff[2][1] = 9; 412 Init(kFrameSize, kPacketSize); 413 414 // One packet: 415 // I:0, P:0, L:0, F:0, B:1, E:1, V:1 (19hdr + 21 payload) 416 // N_S:1, Y:1, G:1 417 // WIDTH:640 // 2 bytes 418 // HEIGHT:360 // 2 bytes 419 // WIDTH:1280 // 2 bytes 420 // HEIGHT:720 // 2 bytes 421 // N_G:3 422 // T:0, U:1, R:0 423 // T:1, U:1, R:3 | P_DIFF[1][0]:5 | P_DIFF[1][1]:6 | P_DIFF[1][2]:7 424 // T:2, U:0, R:2 | P_DIFF[2][0]:8 | P_DIFF[2][0]:9 425 const size_t kExpectedHdrSizes[] = {19}; 426 const size_t kExpectedSizes[] = {40}; 427 const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); 428 CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); 429 } 430 431 TEST_F(RtpPacketizerVp9Test, TestBaseLayerProtectionAndStorageType) { 432 const size_t kFrameSize = 10; 433 const size_t kPacketSize = 12; 434 435 // I:0, P:0, L:1, F:1, B:1, E:1, V:0 (2hdr + 10 payload) 436 // L: T:0, U:0, S:0, D:0 437 expected_.flexible_mode = true; 438 expected_.temporal_idx = 0; 439 Init(kFrameSize, kPacketSize); 440 EXPECT_EQ(kProtectedPacket, packetizer_->GetProtectionType()); 441 EXPECT_EQ(kAllowRetransmission, 442 packetizer_->GetStorageType(kRetransmitBaseLayer)); 443 EXPECT_EQ(kDontRetransmit, packetizer_->GetStorageType(kRetransmitOff)); 444 } 445 446 TEST_F(RtpPacketizerVp9Test, TestHigherLayerProtectionAndStorageType) { 447 const size_t kFrameSize = 10; 448 const size_t kPacketSize = 12; 449 450 // I:0, P:0, L:1, F:1, B:1, E:1, V:0 (2hdr + 10 payload) 451 // L: T:1, U:0, S:0, D:0 452 expected_.flexible_mode = true; 453 expected_.temporal_idx = 1; 454 Init(kFrameSize, kPacketSize); 455 EXPECT_EQ(kUnprotectedPacket, packetizer_->GetProtectionType()); 456 EXPECT_EQ(kDontRetransmit, packetizer_->GetStorageType(kRetransmitBaseLayer)); 457 EXPECT_EQ(kAllowRetransmission, 458 packetizer_->GetStorageType(kRetransmitHigherLayers)); 459 } 460 461 462 class RtpDepacketizerVp9Test : public ::testing::Test { 463 protected: 464 RtpDepacketizerVp9Test() 465 : depacketizer_(new RtpDepacketizerVp9()) {} 466 467 virtual void SetUp() { 468 expected_.InitRTPVideoHeaderVP9(); 469 } 470 471 RTPVideoHeaderVP9 expected_; 472 rtc::scoped_ptr<RtpDepacketizer> depacketizer_; 473 }; 474 475 TEST_F(RtpDepacketizerVp9Test, ParseBasicHeader) { 476 const uint8_t kHeaderLength = 1; 477 uint8_t packet[4] = {0}; 478 packet[0] = 0x0C; // I:0 P:0 L:0 F:0 B:1 E:1 V:0 R:0 479 expected_.beginning_of_frame = true; 480 expected_.end_of_frame = true; 481 ParseAndCheckPacket(packet, expected_, kHeaderLength, sizeof(packet)); 482 } 483 484 TEST_F(RtpDepacketizerVp9Test, ParseOneBytePictureId) { 485 const uint8_t kHeaderLength = 2; 486 uint8_t packet[10] = {0}; 487 packet[0] = 0x80; // I:1 P:0 L:0 F:0 B:0 E:0 V:0 R:0 488 packet[1] = kMaxOneBytePictureId; 489 490 expected_.picture_id = kMaxOneBytePictureId; 491 expected_.max_picture_id = kMaxOneBytePictureId; 492 ParseAndCheckPacket(packet, expected_, kHeaderLength, sizeof(packet)); 493 } 494 495 TEST_F(RtpDepacketizerVp9Test, ParseTwoBytePictureId) { 496 const uint8_t kHeaderLength = 3; 497 uint8_t packet[10] = {0}; 498 packet[0] = 0x80; // I:1 P:0 L:0 F:0 B:0 E:0 V:0 R:0 499 packet[1] = 0x80 | ((kMaxTwoBytePictureId >> 8) & 0x7F); 500 packet[2] = kMaxTwoBytePictureId & 0xFF; 501 502 expected_.picture_id = kMaxTwoBytePictureId; 503 expected_.max_picture_id = kMaxTwoBytePictureId; 504 ParseAndCheckPacket(packet, expected_, kHeaderLength, sizeof(packet)); 505 } 506 507 TEST_F(RtpDepacketizerVp9Test, ParseLayerInfoWithNonFlexibleMode) { 508 const uint8_t kHeaderLength = 3; 509 const uint8_t kTemporalIdx = 2; 510 const uint8_t kUbit = 1; 511 const uint8_t kSpatialIdx = 1; 512 const uint8_t kDbit = 1; 513 const uint8_t kTl0PicIdx = 17; 514 uint8_t packet[13] = {0}; 515 packet[0] = 0x20; // I:0 P:0 L:1 F:0 B:0 E:0 V:0 R:0 516 packet[1] = (kTemporalIdx << 5) | (kUbit << 4) | (kSpatialIdx << 1) | kDbit; 517 packet[2] = kTl0PicIdx; 518 519 // T:2 U:1 S:1 D:1 520 // TL0PICIDX:17 521 expected_.temporal_idx = kTemporalIdx; 522 expected_.temporal_up_switch = kUbit ? true : false; 523 expected_.spatial_idx = kSpatialIdx; 524 expected_.inter_layer_predicted = kDbit ? true : false; 525 expected_.tl0_pic_idx = kTl0PicIdx; 526 ParseAndCheckPacket(packet, expected_, kHeaderLength, sizeof(packet)); 527 } 528 529 TEST_F(RtpDepacketizerVp9Test, ParseLayerInfoWithFlexibleMode) { 530 const uint8_t kHeaderLength = 2; 531 const uint8_t kTemporalIdx = 2; 532 const uint8_t kUbit = 1; 533 const uint8_t kSpatialIdx = 0; 534 const uint8_t kDbit = 0; 535 uint8_t packet[13] = {0}; 536 packet[0] = 0x38; // I:0 P:0 L:1 F:1 B:1 E:0 V:0 R:0 537 packet[1] = (kTemporalIdx << 5) | (kUbit << 4) | (kSpatialIdx << 1) | kDbit; 538 539 // I:0 P:0 L:1 F:1 B:1 E:0 V:0 540 // L: T:2 U:1 S:0 D:0 541 expected_.beginning_of_frame = true; 542 expected_.flexible_mode = true; 543 expected_.temporal_idx = kTemporalIdx; 544 expected_.temporal_up_switch = kUbit ? true : false; 545 expected_.spatial_idx = kSpatialIdx; 546 expected_.inter_layer_predicted = kDbit ? true : false; 547 ParseAndCheckPacket(packet, expected_, kHeaderLength, sizeof(packet)); 548 } 549 550 TEST_F(RtpDepacketizerVp9Test, ParseRefIdx) { 551 const uint8_t kHeaderLength = 6; 552 const int16_t kPictureId = 17; 553 const uint8_t kPdiff1 = 17; 554 const uint8_t kPdiff2 = 18; 555 const uint8_t kPdiff3 = 127; 556 uint8_t packet[13] = {0}; 557 packet[0] = 0xD8; // I:1 P:1 L:0 F:1 B:1 E:0 V:0 R:0 558 packet[1] = 0x80 | ((kPictureId >> 8) & 0x7F); // Two byte pictureID. 559 packet[2] = kPictureId; 560 packet[3] = (kPdiff1 << 1) | 1; // P_DIFF N:1 561 packet[4] = (kPdiff2 << 1) | 1; // P_DIFF N:1 562 packet[5] = (kPdiff3 << 1) | 0; // P_DIFF N:0 563 564 // I:1 P:1 L:0 F:1 B:1 E:0 V:0 565 // I: PICTURE ID:17 566 // I: 567 // P,F: P_DIFF:17 N:1 => refPicId = 17 - 17 = 0 568 // P,F: P_DIFF:18 N:1 => refPicId = (kMaxPictureId + 1) + 17 - 18 = 0x7FFF 569 // P,F: P_DIFF:127 N:0 => refPicId = (kMaxPictureId + 1) + 17 - 127 = 32658 570 expected_.beginning_of_frame = true; 571 expected_.inter_pic_predicted = true; 572 expected_.flexible_mode = true; 573 expected_.picture_id = kPictureId; 574 expected_.num_ref_pics = 3; 575 expected_.pid_diff[0] = kPdiff1; 576 expected_.pid_diff[1] = kPdiff2; 577 expected_.pid_diff[2] = kPdiff3; 578 expected_.ref_picture_id[0] = 0; 579 expected_.ref_picture_id[1] = 0x7FFF; 580 expected_.ref_picture_id[2] = 32658; 581 ParseAndCheckPacket(packet, expected_, kHeaderLength, sizeof(packet)); 582 } 583 584 TEST_F(RtpDepacketizerVp9Test, ParseRefIdxFailsWithNoPictureId) { 585 const uint8_t kPdiff = 3; 586 uint8_t packet[13] = {0}; 587 packet[0] = 0x58; // I:0 P:1 L:0 F:1 B:1 E:0 V:0 R:0 588 packet[1] = (kPdiff << 1); // P,F: P_DIFF:3 N:0 589 590 RtpDepacketizer::ParsedPayload parsed; 591 EXPECT_FALSE(depacketizer_->Parse(&parsed, packet, sizeof(packet))); 592 } 593 594 TEST_F(RtpDepacketizerVp9Test, ParseRefIdxFailsWithTooManyRefPics) { 595 const uint8_t kPdiff = 3; 596 uint8_t packet[13] = {0}; 597 packet[0] = 0xD8; // I:1 P:1 L:0 F:1 B:1 E:0 V:0 R:0 598 packet[1] = kMaxOneBytePictureId; // I: PICTURE ID:127 599 packet[2] = (kPdiff << 1) | 1; // P,F: P_DIFF:3 N:1 600 packet[3] = (kPdiff << 1) | 1; // P,F: P_DIFF:3 N:1 601 packet[4] = (kPdiff << 1) | 1; // P,F: P_DIFF:3 N:1 602 packet[5] = (kPdiff << 1) | 0; // P,F: P_DIFF:3 N:0 603 604 RtpDepacketizer::ParsedPayload parsed; 605 EXPECT_FALSE(depacketizer_->Parse(&parsed, packet, sizeof(packet))); 606 } 607 608 TEST_F(RtpDepacketizerVp9Test, ParseSsData) { 609 const uint8_t kHeaderLength = 6; 610 const uint8_t kYbit = 0; 611 const size_t kNs = 2; 612 const size_t kNg = 2; 613 uint8_t packet[23] = {0}; 614 packet[0] = 0x0A; // I:0 P:0 L:0 F:0 B:1 E:0 V:1 R:0 615 packet[1] = ((kNs - 1) << 5) | (kYbit << 4) | (1 << 3); // N_S Y G:1 - 616 packet[2] = kNg; // N_G 617 packet[3] = (0 << 5) | (1 << 4) | (0 << 2) | 0; // T:0 U:1 R:0 - 618 packet[4] = (2 << 5) | (0 << 4) | (1 << 2) | 0; // T:2 U:0 R:1 - 619 packet[5] = 33; 620 621 expected_.beginning_of_frame = true; 622 expected_.ss_data_available = true; 623 expected_.num_spatial_layers = kNs; 624 expected_.spatial_layer_resolution_present = kYbit ? true : false; 625 expected_.gof.num_frames_in_gof = kNg; 626 expected_.gof.temporal_idx[0] = 0; 627 expected_.gof.temporal_idx[1] = 2; 628 expected_.gof.temporal_up_switch[0] = true; 629 expected_.gof.temporal_up_switch[1] = false; 630 expected_.gof.num_ref_pics[0] = 0; 631 expected_.gof.num_ref_pics[1] = 1; 632 expected_.gof.pid_diff[1][0] = 33; 633 ParseAndCheckPacket(packet, expected_, kHeaderLength, sizeof(packet)); 634 } 635 636 TEST_F(RtpDepacketizerVp9Test, ParseFirstPacketInKeyFrame) { 637 uint8_t packet[2] = {0}; 638 packet[0] = 0x08; // I:0 P:0 L:0 F:0 B:1 E:0 V:0 R:0 639 640 RtpDepacketizer::ParsedPayload parsed; 641 ASSERT_TRUE(depacketizer_->Parse(&parsed, packet, sizeof(packet))); 642 EXPECT_EQ(kVideoFrameKey, parsed.frame_type); 643 EXPECT_TRUE(parsed.type.Video.isFirstPacket); 644 } 645 646 TEST_F(RtpDepacketizerVp9Test, ParseLastPacketInDeltaFrame) { 647 uint8_t packet[2] = {0}; 648 packet[0] = 0x44; // I:0 P:1 L:0 F:0 B:0 E:1 V:0 R:0 649 650 RtpDepacketizer::ParsedPayload parsed; 651 ASSERT_TRUE(depacketizer_->Parse(&parsed, packet, sizeof(packet))); 652 EXPECT_EQ(kVideoFrameDelta, parsed.frame_type); 653 EXPECT_FALSE(parsed.type.Video.isFirstPacket); 654 } 655 656 TEST_F(RtpDepacketizerVp9Test, ParseResolution) { 657 const uint16_t kWidth[2] = {640, 1280}; 658 const uint16_t kHeight[2] = {360, 720}; 659 uint8_t packet[20] = {0}; 660 packet[0] = 0x0A; // I:0 P:0 L:0 F:0 B:1 E:0 V:1 R:0 661 packet[1] = (1 << 5) | (1 << 4) | 0; // N_S:1 Y:1 G:0 662 packet[2] = kWidth[0] >> 8; 663 packet[3] = kWidth[0] & 0xFF; 664 packet[4] = kHeight[0] >> 8; 665 packet[5] = kHeight[0] & 0xFF; 666 packet[6] = kWidth[1] >> 8; 667 packet[7] = kWidth[1] & 0xFF; 668 packet[8] = kHeight[1] >> 8; 669 packet[9] = kHeight[1] & 0xFF; 670 671 RtpDepacketizer::ParsedPayload parsed; 672 ASSERT_TRUE(depacketizer_->Parse(&parsed, packet, sizeof(packet))); 673 EXPECT_EQ(kWidth[0], parsed.type.Video.width); 674 EXPECT_EQ(kHeight[0], parsed.type.Video.height); 675 } 676 677 TEST_F(RtpDepacketizerVp9Test, ParseFailsForNoPayloadLength) { 678 uint8_t packet[1] = {0}; 679 RtpDepacketizer::ParsedPayload parsed; 680 EXPECT_FALSE(depacketizer_->Parse(&parsed, packet, 0)); 681 } 682 683 TEST_F(RtpDepacketizerVp9Test, ParseFailsForTooShortBufferToFitPayload) { 684 const uint8_t kHeaderLength = 1; 685 uint8_t packet[kHeaderLength] = {0}; 686 RtpDepacketizer::ParsedPayload parsed; 687 EXPECT_FALSE(depacketizer_->Parse(&parsed, packet, sizeof(packet))); 688 } 689 690 } // namespace webrtc 691