Home | History | Annotate | Download | only in source
      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