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     RtpFormatVp8* 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   int 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_EQ(expected_part[i],
     80               packetizer->NextPacket(buffer_, &send_bytes, &last));
     81     CheckPacket(send_bytes, expected_sizes[i], last,
     82                 expected_frag_start[i]);
     83   }
     84   EXPECT_TRUE(last);
     85 }
     86 
     87 // Payload descriptor
     88 //       0 1 2 3 4 5 6 7
     89 //      +-+-+-+-+-+-+-+-+
     90 //      |X|R|N|S|PartID | (REQUIRED)
     91 //      +-+-+-+-+-+-+-+-+
     92 // X:   |I|L|T|K|  RSV  | (OPTIONAL)
     93 //      +-+-+-+-+-+-+-+-+
     94 // I:   |   PictureID   | (OPTIONAL)
     95 //      +-+-+-+-+-+-+-+-+
     96 // L:   |   TL0PICIDX   | (OPTIONAL)
     97 //      +-+-+-+-+-+-+-+-+
     98 // T/K: | TID | KEYIDX  | (OPTIONAL)
     99 //      +-+-+-+-+-+-+-+-+
    100 
    101 // First octet tests.
    102 #define EXPECT_BIT_EQ(x, n, a) EXPECT_EQ((((x) >> (n)) & 0x1), a)
    103 
    104 #define EXPECT_RSV_ZERO(x) EXPECT_EQ(((x) & 0xE0), 0)
    105 
    106 #define EXPECT_BIT_X_EQ(x, a) EXPECT_BIT_EQ(x, 7, a)
    107 
    108 #define EXPECT_BIT_N_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)
    109 
    110 #define EXPECT_BIT_S_EQ(x, a) EXPECT_BIT_EQ(x, 4, a)
    111 
    112 #define EXPECT_PART_ID_EQ(x, a) EXPECT_EQ(((x) & 0x0F), a)
    113 
    114 // Extension fields tests
    115 #define EXPECT_BIT_I_EQ(x, a) EXPECT_BIT_EQ(x, 7, a)
    116 
    117 #define EXPECT_BIT_L_EQ(x, a) EXPECT_BIT_EQ(x, 6, a)
    118 
    119 #define EXPECT_BIT_T_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)
    120 
    121 #define EXPECT_BIT_K_EQ(x, a) EXPECT_BIT_EQ(x, 4, a)
    122 
    123 #define EXPECT_TID_EQ(x, a) EXPECT_EQ((((x) & 0xC0) >> 6), a)
    124 
    125 #define EXPECT_BIT_Y_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)
    126 
    127 #define EXPECT_KEYIDX_EQ(x, a) EXPECT_EQ(((x) & 0x1F), a)
    128 
    129 void RtpFormatVp8TestHelper::CheckHeader(bool frag_start) {
    130   payload_start_ = 1;
    131   EXPECT_BIT_EQ(buffer_[0], 6, 0);  // Check reserved bit.
    132 
    133   if (hdr_info_->pictureId != kNoPictureId ||
    134       hdr_info_->temporalIdx != kNoTemporalIdx ||
    135       hdr_info_->tl0PicIdx != kNoTl0PicIdx ||
    136       hdr_info_->keyIdx != kNoKeyIdx) {
    137     EXPECT_BIT_X_EQ(buffer_[0], 1);
    138     ++payload_start_;
    139     CheckPictureID();
    140     CheckTl0PicIdx();
    141     CheckTIDAndKeyIdx();
    142   } else {
    143     EXPECT_BIT_X_EQ(buffer_[0], 0);
    144   }
    145 
    146   EXPECT_BIT_N_EQ(buffer_[0], hdr_info_->nonReference ? 1 : 0);
    147   EXPECT_BIT_S_EQ(buffer_[0], frag_start ? 1 : 0);
    148 
    149   // Check partition index.
    150   if (!sloppy_partitioning_) {
    151     // The test payload data is constructed such that the payload value is the
    152     // same as the partition index.
    153     EXPECT_EQ(buffer_[0] & 0x0F, buffer_[payload_start_]);
    154   } else {
    155     // Partition should be set to 0.
    156     EXPECT_EQ(buffer_[0] & 0x0F, 0);
    157   }
    158 }
    159 
    160 // Verify that the I bit and the PictureID field are both set in accordance
    161 // with the information in hdr_info_->pictureId.
    162 void RtpFormatVp8TestHelper::CheckPictureID() {
    163   if (hdr_info_->pictureId != kNoPictureId) {
    164     EXPECT_BIT_I_EQ(buffer_[1], 1);
    165     if (hdr_info_->pictureId > 0x7F) {
    166       EXPECT_BIT_EQ(buffer_[payload_start_], 7, 1);
    167       EXPECT_EQ(buffer_[payload_start_] & 0x7F,
    168                 (hdr_info_->pictureId >> 8) & 0x7F);
    169       EXPECT_EQ(buffer_[payload_start_ + 1],
    170                 hdr_info_->pictureId & 0xFF);
    171       payload_start_ += 2;
    172     } else {
    173       EXPECT_BIT_EQ(buffer_[payload_start_], 7, 0);
    174       EXPECT_EQ(buffer_[payload_start_] & 0x7F,
    175                 (hdr_info_->pictureId) & 0x7F);
    176       payload_start_ += 1;
    177     }
    178   } else {
    179     EXPECT_BIT_I_EQ(buffer_[1], 0);
    180   }
    181 }
    182 
    183 // Verify that the L bit and the TL0PICIDX field are both set in accordance
    184 // with the information in hdr_info_->tl0PicIdx.
    185 void RtpFormatVp8TestHelper::CheckTl0PicIdx() {
    186   if (hdr_info_->tl0PicIdx != kNoTl0PicIdx) {
    187     EXPECT_BIT_L_EQ(buffer_[1], 1);
    188     EXPECT_EQ(buffer_[payload_start_], hdr_info_->tl0PicIdx);
    189     ++payload_start_;
    190   } else {
    191     EXPECT_BIT_L_EQ(buffer_[1], 0);
    192   }
    193 }
    194 
    195 // Verify that the T bit and the TL0PICIDX field, and the K bit and KEYIDX
    196 // field are all set in accordance with the information in
    197 // hdr_info_->temporalIdx and hdr_info_->keyIdx, respectively.
    198 void RtpFormatVp8TestHelper::CheckTIDAndKeyIdx() {
    199   if (hdr_info_->temporalIdx == kNoTemporalIdx &&
    200       hdr_info_->keyIdx == kNoKeyIdx) {
    201     EXPECT_BIT_T_EQ(buffer_[1], 0);
    202     EXPECT_BIT_K_EQ(buffer_[1], 0);
    203     return;
    204   }
    205   if (hdr_info_->temporalIdx != kNoTemporalIdx) {
    206     EXPECT_BIT_T_EQ(buffer_[1], 1);
    207     EXPECT_TID_EQ(buffer_[payload_start_], hdr_info_->temporalIdx);
    208     EXPECT_BIT_Y_EQ(buffer_[payload_start_], hdr_info_->layerSync ? 1 : 0);
    209   } else {
    210     EXPECT_BIT_T_EQ(buffer_[1], 0);
    211     EXPECT_TID_EQ(buffer_[payload_start_], 0);
    212     EXPECT_BIT_Y_EQ(buffer_[payload_start_], 0);
    213   }
    214   if (hdr_info_->keyIdx != kNoKeyIdx) {
    215     EXPECT_BIT_K_EQ(buffer_[1], 1);
    216     EXPECT_KEYIDX_EQ(buffer_[payload_start_], hdr_info_->keyIdx);
    217   } else {
    218     EXPECT_BIT_K_EQ(buffer_[1], 0);
    219     EXPECT_KEYIDX_EQ(buffer_[payload_start_], 0);
    220   }
    221   ++payload_start_;
    222 }
    223 
    224 // Verify that the payload (i.e., after the headers) of the packet stored in
    225 // buffer_ is identical to the expected (as found in data_ptr_).
    226 void RtpFormatVp8TestHelper::CheckPayload(int payload_end) {
    227   for (int i = payload_start_; i < payload_end; ++i, ++data_ptr_)
    228     EXPECT_EQ(buffer_[i], *data_ptr_);
    229 }
    230 
    231 // Verify that the input variable "last" agrees with the position of data_ptr_.
    232 // If data_ptr_ has advanced payload_size_ bytes from the start (payload_data_)
    233 // we are at the end and last should be true. Otherwise, it should be false.
    234 void RtpFormatVp8TestHelper::CheckLast(bool last) const {
    235   EXPECT_EQ(last, data_ptr_ == payload_data_ + payload_size_);
    236 }
    237 
    238 // Verify the contents of a packet. Check the length versus expected_bytes,
    239 // the header, payload, and "last" flag.
    240 void RtpFormatVp8TestHelper::CheckPacket(int send_bytes,
    241                                          int expect_bytes,
    242                                          bool last,
    243                                          bool frag_start) {
    244   EXPECT_EQ(expect_bytes, send_bytes);
    245   CheckHeader(frag_start);
    246   CheckPayload(send_bytes);
    247   CheckLast(last);
    248 }
    249 
    250 }  // namespace test
    251 
    252 }  // namespace webrtc
    253