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 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h"
     13 
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 namespace webrtc {
     17 
     18 namespace test {
     19 
     20 RtpFormatVp8TestHelper::RtpFormatVp8TestHelper(const RTPVideoHeaderVP8* hdr)
     21     : payload_data_(NULL),
     22       buffer_(NULL),
     23       data_ptr_(NULL),
     24       fragmentation_(NULL),
     25       hdr_info_(hdr),
     26       payload_start_(0),
     27       payload_size_(0),
     28       buffer_size_(0),
     29       sloppy_partitioning_(false),
     30       inited_(false) {}
     31 
     32 RtpFormatVp8TestHelper::~RtpFormatVp8TestHelper() {
     33   delete fragmentation_;
     34   delete [] payload_data_;
     35   delete [] buffer_;
     36 }
     37 
     38 bool RtpFormatVp8TestHelper::Init(const int* partition_sizes,
     39                                   int num_partitions) {
     40   if (inited_) return false;
     41   fragmentation_ = new RTPFragmentationHeader;
     42   fragmentation_->VerifyAndAllocateFragmentationHeader(num_partitions);
     43   payload_size_ = 0;
     44   // Calculate sum payload size.
     45   for (int p = 0; p < num_partitions; ++p) {
     46     payload_size_ += partition_sizes[p];
     47   }
     48   buffer_size_ = payload_size_ + 6;  // Add space for payload descriptor.
     49   payload_data_ = new uint8_t[payload_size_];
     50   buffer_ = new uint8_t[buffer_size_];
     51   int j = 0;
     52   // Loop through the partitions again.
     53   for (int p = 0; p < num_partitions; ++p) {
     54     fragmentation_->fragmentationLength[p] = partition_sizes[p];
     55     fragmentation_->fragmentationOffset[p] = j;
     56     for (int i = 0; i < partition_sizes[p]; ++i) {
     57       assert(j < payload_size_);
     58       payload_data_[j++] = p;  // Set the payload value to the partition index.
     59     }
     60   }
     61   data_ptr_ = payload_data_;
     62   inited_ = true;
     63   return true;
     64 }
     65 
     66 void RtpFormatVp8TestHelper::GetAllPacketsAndCheck(
     67     RtpPacketizerVp8* packetizer,
     68     const int* expected_sizes,
     69     const int* expected_part,
     70     const bool* expected_frag_start,
     71     int expected_num_packets) {
     72   ASSERT_TRUE(inited_);
     73   size_t send_bytes = 0;
     74   bool last = false;
     75   for (int i = 0; i < expected_num_packets; ++i) {
     76     std::ostringstream ss;
     77     ss << "Checking packet " << i;
     78     SCOPED_TRACE(ss.str());
     79     EXPECT_TRUE(packetizer->NextPacket(buffer_, &send_bytes, &last));
     80     CheckPacket(send_bytes, expected_sizes[i], last,
     81                 expected_frag_start[i]);
     82   }
     83   EXPECT_TRUE(last);
     84 }
     85 
     86 // Payload descriptor
     87 //       0 1 2 3 4 5 6 7
     88 //      +-+-+-+-+-+-+-+-+
     89 //      |X|R|N|S|PartID | (REQUIRED)
     90 //      +-+-+-+-+-+-+-+-+
     91 // X:   |I|L|T|K|  RSV  | (OPTIONAL)
     92 //      +-+-+-+-+-+-+-+-+
     93 // I:   |   PictureID   | (OPTIONAL)
     94 //      +-+-+-+-+-+-+-+-+
     95 // L:   |   TL0PICIDX   | (OPTIONAL)
     96 //      +-+-+-+-+-+-+-+-+
     97 // T/K: | TID | KEYIDX  | (OPTIONAL)
     98 //      +-+-+-+-+-+-+-+-+
     99 
    100 // First octet tests.
    101 #define EXPECT_BIT_EQ(x, n, a) EXPECT_EQ((((x) >> (n)) & 0x1), a)
    102 
    103 #define EXPECT_RSV_ZERO(x) EXPECT_EQ(((x) & 0xE0), 0)
    104 
    105 #define EXPECT_BIT_X_EQ(x, a) EXPECT_BIT_EQ(x, 7, a)
    106 
    107 #define EXPECT_BIT_N_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)
    108 
    109 #define EXPECT_BIT_S_EQ(x, a) EXPECT_BIT_EQ(x, 4, a)
    110 
    111 #define EXPECT_PART_ID_EQ(x, a) EXPECT_EQ(((x) & 0x0F), a)
    112 
    113 // Extension fields tests
    114 #define EXPECT_BIT_I_EQ(x, a) EXPECT_BIT_EQ(x, 7, a)
    115 
    116 #define EXPECT_BIT_L_EQ(x, a) EXPECT_BIT_EQ(x, 6, a)
    117 
    118 #define EXPECT_BIT_T_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)
    119 
    120 #define EXPECT_BIT_K_EQ(x, a) EXPECT_BIT_EQ(x, 4, a)
    121 
    122 #define EXPECT_TID_EQ(x, a) EXPECT_EQ((((x) & 0xC0) >> 6), a)
    123 
    124 #define EXPECT_BIT_Y_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)
    125 
    126 #define EXPECT_KEYIDX_EQ(x, a) EXPECT_EQ(((x) & 0x1F), a)
    127 
    128 void RtpFormatVp8TestHelper::CheckHeader(bool frag_start) {
    129   payload_start_ = 1;
    130   EXPECT_BIT_EQ(buffer_[0], 6, 0);  // Check reserved bit.
    131 
    132   if (hdr_info_->pictureId != kNoPictureId ||
    133       hdr_info_->temporalIdx != kNoTemporalIdx ||
    134       hdr_info_->tl0PicIdx != kNoTl0PicIdx ||
    135       hdr_info_->keyIdx != kNoKeyIdx) {
    136     EXPECT_BIT_X_EQ(buffer_[0], 1);
    137     ++payload_start_;
    138     CheckPictureID();
    139     CheckTl0PicIdx();
    140     CheckTIDAndKeyIdx();
    141   } else {
    142     EXPECT_BIT_X_EQ(buffer_[0], 0);
    143   }
    144 
    145   EXPECT_BIT_N_EQ(buffer_[0], hdr_info_->nonReference ? 1 : 0);
    146   EXPECT_BIT_S_EQ(buffer_[0], frag_start ? 1 : 0);
    147 
    148   // Check partition index.
    149   if (!sloppy_partitioning_) {
    150     // The test payload data is constructed such that the payload value is the
    151     // same as the partition index.
    152     EXPECT_EQ(buffer_[0] & 0x0F, buffer_[payload_start_]);
    153   } else {
    154     // Partition should be set to 0.
    155     EXPECT_EQ(buffer_[0] & 0x0F, 0);
    156   }
    157 }
    158 
    159 // Verify that the I bit and the PictureID field are both set in accordance
    160 // with the information in hdr_info_->pictureId.
    161 void RtpFormatVp8TestHelper::CheckPictureID() {
    162   if (hdr_info_->pictureId != kNoPictureId) {
    163     EXPECT_BIT_I_EQ(buffer_[1], 1);
    164     if (hdr_info_->pictureId > 0x7F) {
    165       EXPECT_BIT_EQ(buffer_[payload_start_], 7, 1);
    166       EXPECT_EQ(buffer_[payload_start_] & 0x7F,
    167                 (hdr_info_->pictureId >> 8) & 0x7F);
    168       EXPECT_EQ(buffer_[payload_start_ + 1],
    169                 hdr_info_->pictureId & 0xFF);
    170       payload_start_ += 2;
    171     } else {
    172       EXPECT_BIT_EQ(buffer_[payload_start_], 7, 0);
    173       EXPECT_EQ(buffer_[payload_start_] & 0x7F,
    174                 (hdr_info_->pictureId) & 0x7F);
    175       payload_start_ += 1;
    176     }
    177   } else {
    178     EXPECT_BIT_I_EQ(buffer_[1], 0);
    179   }
    180 }
    181 
    182 // Verify that the L bit and the TL0PICIDX field are both set in accordance
    183 // with the information in hdr_info_->tl0PicIdx.
    184 void RtpFormatVp8TestHelper::CheckTl0PicIdx() {
    185   if (hdr_info_->tl0PicIdx != kNoTl0PicIdx) {
    186     EXPECT_BIT_L_EQ(buffer_[1], 1);
    187     EXPECT_EQ(buffer_[payload_start_], hdr_info_->tl0PicIdx);
    188     ++payload_start_;
    189   } else {
    190     EXPECT_BIT_L_EQ(buffer_[1], 0);
    191   }
    192 }
    193 
    194 // Verify that the T bit and the TL0PICIDX field, and the K bit and KEYIDX
    195 // field are all set in accordance with the information in
    196 // hdr_info_->temporalIdx and hdr_info_->keyIdx, respectively.
    197 void RtpFormatVp8TestHelper::CheckTIDAndKeyIdx() {
    198   if (hdr_info_->temporalIdx == kNoTemporalIdx &&
    199       hdr_info_->keyIdx == kNoKeyIdx) {
    200     EXPECT_BIT_T_EQ(buffer_[1], 0);
    201     EXPECT_BIT_K_EQ(buffer_[1], 0);
    202     return;
    203   }
    204   if (hdr_info_->temporalIdx != kNoTemporalIdx) {
    205     EXPECT_BIT_T_EQ(buffer_[1], 1);
    206     EXPECT_TID_EQ(buffer_[payload_start_], hdr_info_->temporalIdx);
    207     EXPECT_BIT_Y_EQ(buffer_[payload_start_], hdr_info_->layerSync ? 1 : 0);
    208   } else {
    209     EXPECT_BIT_T_EQ(buffer_[1], 0);
    210     EXPECT_TID_EQ(buffer_[payload_start_], 0);
    211     EXPECT_BIT_Y_EQ(buffer_[payload_start_], 0);
    212   }
    213   if (hdr_info_->keyIdx != kNoKeyIdx) {
    214     EXPECT_BIT_K_EQ(buffer_[1], 1);
    215     EXPECT_KEYIDX_EQ(buffer_[payload_start_], hdr_info_->keyIdx);
    216   } else {
    217     EXPECT_BIT_K_EQ(buffer_[1], 0);
    218     EXPECT_KEYIDX_EQ(buffer_[payload_start_], 0);
    219   }
    220   ++payload_start_;
    221 }
    222 
    223 // Verify that the payload (i.e., after the headers) of the packet stored in
    224 // buffer_ is identical to the expected (as found in data_ptr_).
    225 void RtpFormatVp8TestHelper::CheckPayload(int payload_end) {
    226   for (int i = payload_start_; i < payload_end; ++i, ++data_ptr_)
    227     EXPECT_EQ(buffer_[i], *data_ptr_);
    228 }
    229 
    230 // Verify that the input variable "last" agrees with the position of data_ptr_.
    231 // If data_ptr_ has advanced payload_size_ bytes from the start (payload_data_)
    232 // we are at the end and last should be true. Otherwise, it should be false.
    233 void RtpFormatVp8TestHelper::CheckLast(bool last) const {
    234   EXPECT_EQ(last, data_ptr_ == payload_data_ + payload_size_);
    235 }
    236 
    237 // Verify the contents of a packet. Check the length versus expected_bytes,
    238 // the header, payload, and "last" flag.
    239 void RtpFormatVp8TestHelper::CheckPacket(int send_bytes,
    240                                          int expect_bytes,
    241                                          bool last,
    242                                          bool frag_start) {
    243   EXPECT_EQ(expect_bytes, send_bytes);
    244   CheckHeader(frag_start);
    245   CheckPayload(send_bytes);
    246   CheckLast(last);
    247 }
    248 
    249 }  // namespace test
    250 
    251 }  // namespace webrtc
    252