Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 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 /*
     13  * This file conatins unit tests for the ModuleRTPUtility.
     14  */
     15 
     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_utility.h"
     19 #include "webrtc/typedefs.h"
     20 
     21 namespace webrtc {
     22 
     23 using ModuleRTPUtility::RTPPayloadParser;
     24 using ModuleRTPUtility::RTPPayload;
     25 using ModuleRTPUtility::RTPPayloadVP8;
     26 
     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 
     59 void VerifyBasicHeader(const RTPPayloadVP8 &header,
     60                        bool N, bool S, int PartID) {
     61   EXPECT_EQ(N, header.nonReferenceFrame);
     62   EXPECT_EQ(S, header.beginningOfPartition);
     63   EXPECT_EQ(PartID, header.partitionID);
     64 }
     65 
     66 void VerifyExtensions(const RTPPayloadVP8 &header,
     67                       bool I, bool L, bool T, bool K) {
     68   EXPECT_EQ(I, header.hasPictureID);
     69   EXPECT_EQ(L, header.hasTl0PicIdx);
     70   EXPECT_EQ(T, header.hasTID);
     71   EXPECT_EQ(K, header.hasKeyIdx);
     72 }
     73 
     74 TEST(ParseVP8Test, BasicHeader) {
     75   uint8_t payload[4] = {0};
     76   payload[0] = 0x14;  // Binary 0001 0100; S = 1, PartID = 4.
     77   payload[1] = 0x01;  // P frame.
     78 
     79   RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4);
     80 
     81   RTPPayload parsedPacket;
     82   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
     83 
     84   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
     85   EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
     86 
     87   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 4 /*PartID*/);
     88   VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
     89 
     90   EXPECT_EQ(payload + 1, parsedPacket.info.VP8.data);
     91   EXPECT_EQ(4 - 1, parsedPacket.info.VP8.dataLength);
     92 }
     93 
     94 TEST(ParseVP8Test, PictureID) {
     95   uint8_t payload[10] = {0};
     96   payload[0] = 0xA0;
     97   payload[1] = 0x80;
     98   payload[2] = 17;
     99 
    100   RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
    101 
    102   RTPPayload parsedPacket;
    103   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
    104 
    105   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
    106   EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
    107 
    108   VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
    109   VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
    110 
    111   EXPECT_EQ(17, parsedPacket.info.VP8.pictureID);
    112 
    113   EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
    114   EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
    115 
    116 
    117   // Re-use payload, but change to long PictureID.
    118   payload[2] = 0x80 | 17;
    119   payload[3] = 17;
    120   RTPPayloadParser rtpPayloadParser2(kRtpVideoVp8, payload, 10);
    121 
    122   ASSERT_TRUE(rtpPayloadParser2.Parse(parsedPacket));
    123 
    124   VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
    125   VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
    126 
    127   EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
    128 
    129   EXPECT_EQ(payload + 4, parsedPacket.info.VP8.data);
    130   EXPECT_EQ(10 - 4, parsedPacket.info.VP8.dataLength);
    131 }
    132 
    133 TEST(ParseVP8Test, Tl0PicIdx) {
    134   uint8_t payload[13] = {0};
    135   payload[0] = 0x90;
    136   payload[1] = 0x40;
    137   payload[2] = 17;
    138 
    139   RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 13);
    140 
    141   RTPPayload parsedPacket;
    142   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
    143 
    144   EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType);
    145   EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
    146 
    147   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 0 /*PartID*/);
    148   VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 1 /*L*/, 0 /*T*/, 0 /*K*/);
    149 
    150   EXPECT_EQ(17, parsedPacket.info.VP8.tl0PicIdx);
    151 
    152   EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
    153   EXPECT_EQ(13 - 3, parsedPacket.info.VP8.dataLength);
    154 }
    155 
    156 TEST(ParseVP8Test, TIDAndLayerSync) {
    157   uint8_t payload[10] = {0};
    158   payload[0] = 0x88;
    159   payload[1] = 0x20;
    160   payload[2] = 0x80;  // TID(2) + LayerSync(false)
    161 
    162   RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
    163 
    164   RTPPayload parsedPacket;
    165   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
    166 
    167   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
    168   EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
    169 
    170   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
    171   VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 1 /*T*/, 0 /*K*/);
    172 
    173   EXPECT_EQ(2, parsedPacket.info.VP8.tID);
    174   EXPECT_FALSE(parsedPacket.info.VP8.layerSync);
    175 
    176   EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
    177   EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
    178 }
    179 
    180 TEST(ParseVP8Test, KeyIdx) {
    181   uint8_t payload[10] = {0};
    182   payload[0] = 0x88;
    183   payload[1] = 0x10;  // K = 1.
    184   payload[2] = 0x11;  // KEYIDX = 17 decimal.
    185 
    186   RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
    187 
    188   RTPPayload parsedPacket;
    189   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
    190 
    191   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
    192   EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
    193 
    194   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
    195   VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 1 /*K*/);
    196 
    197   EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
    198 
    199   EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
    200   EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
    201 }
    202 
    203 TEST(ParseVP8Test, MultipleExtensions) {
    204   uint8_t payload[10] = {0};
    205   payload[0] = 0x88;
    206   payload[1] = 0x80 | 0x40 | 0x20 | 0x10;
    207   payload[2] = 0x80 | 17;    // PictureID, high 7 bits.
    208   payload[3] = 17;           // PictureID, low 8 bits.
    209   payload[4] = 42;           // Tl0PicIdx.
    210   payload[5] = 0x40 | 0x20 | 0x11;  // TID(1) + LayerSync(true) + KEYIDX(17).
    211 
    212   RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10);
    213 
    214   RTPPayload parsedPacket;
    215   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
    216 
    217   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
    218   EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
    219 
    220   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
    221   VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 1 /*L*/, 1 /*T*/, 1 /*K*/);
    222 
    223   EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
    224   EXPECT_EQ(42, parsedPacket.info.VP8.tl0PicIdx);
    225   EXPECT_EQ(1, parsedPacket.info.VP8.tID);
    226   EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
    227 
    228   EXPECT_EQ(payload + 6, parsedPacket.info.VP8.data);
    229   EXPECT_EQ(10 - 6, parsedPacket.info.VP8.dataLength);
    230 }
    231 
    232 TEST(ParseVP8Test, TooShortHeader) {
    233   uint8_t payload[4] = {0};
    234   payload[0] = 0x88;
    235   payload[1] = 0x80 | 0x40 | 0x20 | 0x10;  // All extensions are enabled...
    236   payload[2] = 0x80 | 17;  // ... but only 2 bytes PictureID is provided.
    237   payload[3] = 17;  // PictureID, low 8 bits.
    238 
    239   RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4);
    240 
    241   RTPPayload parsedPacket;
    242   EXPECT_FALSE(rtpPayloadParser.Parse(parsedPacket));
    243 }
    244 
    245 TEST(ParseVP8Test, TestWithPacketizer) {
    246   uint8_t payload[10] = {0};
    247   uint8_t packet[20] = {0};
    248   RTPVideoHeaderVP8 inputHeader;
    249   inputHeader.nonReference = true;
    250   inputHeader.pictureId = 300;
    251   inputHeader.temporalIdx = 1;
    252   inputHeader.layerSync = false;
    253   inputHeader.tl0PicIdx = kNoTl0PicIdx;  // Disable.
    254   inputHeader.keyIdx = 31;
    255   RtpFormatVp8 packetizer(payload, 10, inputHeader, 20);
    256   bool last;
    257   int send_bytes;
    258   ASSERT_EQ(0, packetizer.NextPacket(packet, &send_bytes, &last));
    259   ASSERT_TRUE(last);
    260 
    261   RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, packet, send_bytes);
    262 
    263   RTPPayload parsedPacket;
    264   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
    265 
    266   EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType);
    267   EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
    268 
    269   VerifyBasicHeader(parsedPacket.info.VP8,
    270                     inputHeader.nonReference /*N*/,
    271                     1 /*S*/,
    272                     0 /*PartID*/);
    273   VerifyExtensions(parsedPacket.info.VP8,
    274                    1 /*I*/,
    275                    0 /*L*/,
    276                    1 /*T*/,
    277                    1 /*K*/);
    278 
    279   EXPECT_EQ(inputHeader.pictureId, parsedPacket.info.VP8.pictureID);
    280   EXPECT_EQ(inputHeader.temporalIdx, parsedPacket.info.VP8.tID);
    281   EXPECT_EQ(inputHeader.layerSync, parsedPacket.info.VP8.layerSync);
    282   EXPECT_EQ(inputHeader.keyIdx, parsedPacket.info.VP8.keyIdx);
    283 
    284   EXPECT_EQ(packet + 5, parsedPacket.info.VP8.data);
    285   EXPECT_EQ(send_bytes - 5, parsedPacket.info.VP8.dataLength);
    286 }
    287 
    288 }  // namespace
    289