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