Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. | 24 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. |
| 25 const uint8_t kTransportOverhead = 28; | 25 const uint8_t kTransportOverhead = 28; |
| 26 | 26 |
| 27 // Maximum number of media packets used in the FEC (RFC 5109). | 27 // Maximum number of media packets used in the FEC (RFC 5109). |
| 28 const uint8_t kMaxNumberMediaPackets = ForwardErrorCorrection::kMaxMediaPackets; | 28 const uint8_t kMaxNumberMediaPackets = ForwardErrorCorrection::kMaxMediaPackets; |
| 29 | 29 |
| 30 using PacketList = ForwardErrorCorrection::PacketList; | 30 using PacketList = ForwardErrorCorrection::PacketList; |
| 31 using ReceivedPacketList = ForwardErrorCorrection::ReceivedPacketList; | 31 using ReceivedPacketList = ForwardErrorCorrection::ReceivedPacketList; |
| 32 using RecoveredPacketList = ForwardErrorCorrection::RecoveredPacketList; | 32 using RecoveredPacketList = ForwardErrorCorrection::RecoveredPacketList; |
| 33 | 33 |
| 34 template <typename T> void ClearList(std::list<T*>* my_list) { | |
| 35 T* packet = NULL; | |
| 36 while (!my_list->empty()) { | |
| 37 packet = my_list->front(); | |
| 38 delete packet; | |
| 39 my_list->pop_front(); | |
| 40 } | |
| 41 } | |
| 42 | |
| 43 class RtpFecTest : public ::testing::Test { | 34 class RtpFecTest : public ::testing::Test { |
| 44 protected: | 35 protected: |
| 45 RtpFecTest() | 36 RtpFecTest() |
| 46 : random_(0xfec133700742), | 37 : random_(0xfec133700742), |
| 47 fec_(new ForwardErrorCorrection()), | 38 fec_(new ForwardErrorCorrection()), |
| 48 ssrc_(random_.Rand<uint32_t>()), | 39 ssrc_(random_.Rand<uint32_t>()), |
| 49 fec_seq_num_(0) {} | 40 fec_seq_num_(0) {} |
| 50 | 41 |
| 51 webrtc::Random random_; | 42 webrtc::Random random_; |
| 52 ForwardErrorCorrection* fec_; | 43 ForwardErrorCorrection* fec_; |
| 53 int ssrc_; | 44 int ssrc_; |
| 54 uint16_t fec_seq_num_; | 45 uint16_t fec_seq_num_; |
| 55 | 46 |
| 56 PacketList media_packet_list_; | 47 PacketList media_packet_list_; |
| 57 PacketList fec_packet_list_; | 48 std::list<ForwardErrorCorrection::Packet*> fec_packet_list_; |
| 58 ReceivedPacketList received_packet_list_; | 49 ReceivedPacketList received_packet_list_; |
| 59 RecoveredPacketList recovered_packet_list_; | 50 RecoveredPacketList recovered_packet_list_; |
| 60 | 51 |
| 61 // Media packet "i" is lost if media_loss_mask_[i] = 1, | 52 // Media packet "i" is lost if media_loss_mask_[i] = 1, |
| 62 // received if media_loss_mask_[i] = 0. | 53 // received if media_loss_mask_[i] = 0. |
| 63 int media_loss_mask_[kMaxNumberMediaPackets]; | 54 int media_loss_mask_[kMaxNumberMediaPackets]; |
| 64 | 55 |
| 65 // FEC packet "i" is lost if fec_loss_mask_[i] = 1, | 56 // FEC packet "i" is lost if fec_loss_mask_[i] = 1, |
| 66 // received if fec_loss_mask_[i] = 0. | 57 // received if fec_loss_mask_[i] = 0. |
| 67 int fec_loss_mask_[kMaxNumberMediaPackets]; | 58 int fec_loss_mask_[kMaxNumberMediaPackets]; |
| 68 | 59 |
| 69 // Construct the media packet list, up to |num_media_packets| packets. | 60 // Construct the media packet list, up to |num_media_packets| packets. |
| 70 // Returns the next sequence number after the last media packet. | 61 // Returns the next sequence number after the last media packet. |
| 71 // (this will be the sequence of the first FEC packet) | 62 // (this will be the sequence of the first FEC packet) |
| 72 int ConstructMediaPacketsSeqNum(int num_media_packets, int start_seq_num); | 63 int ConstructMediaPacketsSeqNum(int num_media_packets, int start_seq_num); |
| 73 int ConstructMediaPackets(int num_media_packets); | 64 int ConstructMediaPackets(int num_media_packets); |
| 74 | 65 |
| 66 // Deep copies |src| to |dst|, but only keeps every Nth packet. | |
| 67 void DeepCopyEveryNthPacket(const PacketList& src, int n, PacketList* dst); | |
| 68 | |
| 75 // Construct the received packet list: a subset of the media and FEC packets. | 69 // Construct the received packet list: a subset of the media and FEC packets. |
| 76 void NetworkReceivedPackets(); | 70 void NetworkReceivedPackets(); |
| 77 | 71 |
| 78 // Add packet from |packet_list| to list of received packets, using the | 72 // Add packet from |packet_list| to list of received packets, using the |
| 79 // |loss_mask|. | 73 // |loss_mask|. |
| 80 // The |packet_list| may be a media packet list (is_fec = false), or a | 74 // The |packet_list| may be a media packet list (is_fec = false), or a |
| 81 // FEC packet list (is_fec = true). | 75 // FEC packet list (is_fec = true). |
| 82 void ReceivedPackets(const PacketList& packet_list, int* loss_mask, | 76 template <typename T> |
| 83 bool is_fec); | 77 void ReceivedPackets(const T& packet_list, int* loss_mask, bool is_fec); |
| 84 | 78 |
| 85 // Check for complete recovery after FEC decoding. | 79 // Check for complete recovery after FEC decoding. |
| 86 bool IsRecoveryComplete(); | 80 bool IsRecoveryComplete(); |
| 87 | 81 |
| 88 // Delete the received packets. | |
| 89 void FreeRecoveredPacketList(); | |
| 90 | |
| 91 // Delete the media and FEC packets. | 82 // Delete the media and FEC packets. |
| 92 void TearDown(); | 83 void TearDown(); |
| 93 }; | 84 }; |
| 94 | 85 |
| 95 TEST_F(RtpFecTest, FecRecoveryNoLoss) { | 86 TEST_F(RtpFecTest, FecRecoveryNoLoss) { |
| 96 const int kNumImportantPackets = 0; | 87 const int kNumImportantPackets = 0; |
| 97 const bool kUseUnequalProtection = false; | 88 const bool kUseUnequalProtection = false; |
| 98 const int kNumMediaPackets = 4; | 89 const int kNumMediaPackets = 4; |
| 99 uint8_t kProtectionFactor = 60; | 90 uint8_t kProtectionFactor = 60; |
| 100 | 91 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 129 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 139 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 130 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 140 media_loss_mask_[3] = 1; | 131 media_loss_mask_[3] = 1; |
| 141 NetworkReceivedPackets(); | 132 NetworkReceivedPackets(); |
| 142 | 133 |
| 143 EXPECT_EQ(0, | 134 EXPECT_EQ(0, |
| 144 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 135 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
| 145 | 136 |
| 146 // One packet lost, one FEC packet, expect complete recovery. | 137 // One packet lost, one FEC packet, expect complete recovery. |
| 147 EXPECT_TRUE(IsRecoveryComplete()); | 138 EXPECT_TRUE(IsRecoveryComplete()); |
| 148 FreeRecoveredPacketList(); | 139 recovered_packet_list_.clear(); |
| 149 | 140 |
| 150 // 2 media packets lost. | 141 // 2 media packets lost. |
| 151 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 142 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 152 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 143 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 153 media_loss_mask_[1] = 1; | 144 media_loss_mask_[1] = 1; |
| 154 media_loss_mask_[3] = 1; | 145 media_loss_mask_[3] = 1; |
| 155 NetworkReceivedPackets(); | 146 NetworkReceivedPackets(); |
| 156 | 147 |
| 157 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 148 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 158 &recovered_packet_list_)); | 149 &recovered_packet_list_)); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 181 kNumImportantPackets, kUseUnequalProtection, | 172 kNumImportantPackets, kUseUnequalProtection, |
| 182 webrtc::kFecMaskBursty, &fec_packet_list_)); | 173 webrtc::kFecMaskBursty, &fec_packet_list_)); |
| 183 // Expect 1 FEC packet. | 174 // Expect 1 FEC packet. |
| 184 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 175 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
| 185 // Add FEC packet (seq#2) of this first frame to received list (i.e., assume | 176 // Add FEC packet (seq#2) of this first frame to received list (i.e., assume |
| 186 // the two media packet were lost). | 177 // the two media packet were lost). |
| 187 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 178 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 188 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 179 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
| 189 | 180 |
| 190 // Construct media packets for second frame, with sequence number wrap. | 181 // Construct media packets for second frame, with sequence number wrap. |
| 191 ClearList(&media_packet_list_); | 182 media_packet_list_.clear(); |
| 192 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65535); | 183 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65535); |
| 193 | 184 |
| 194 // Expect 3 media packets for this frame. | 185 // Expect 3 media packets for this frame. |
| 195 EXPECT_EQ(3, static_cast<int>(media_packet_list_.size())); | 186 EXPECT_EQ(3, static_cast<int>(media_packet_list_.size())); |
| 196 | 187 |
| 197 // Second media packet lost (seq#0). | 188 // Second media packet lost (seq#0). |
| 198 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 189 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 199 media_loss_mask_[1] = 1; | 190 media_loss_mask_[1] = 1; |
| 200 // Add packets #65535, and #1 to received list. | 191 // Add packets #65535, and #1 to received list. |
| 201 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 192 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
| 202 | 193 |
| 203 EXPECT_EQ(0, | 194 EXPECT_EQ(0, |
| 204 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 195 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
| 205 | 196 |
| 206 // Expect that no decoding is done to get missing packet (seq#0) of second | 197 // Expect that no decoding is done to get missing packet (seq#0) of second |
| 207 // frame, using old FEC packet (seq#2) from first (old) frame. So number of | 198 // frame, using old FEC packet (seq#2) from first (old) frame. So number of |
| 208 // recovered packets is 2, and not equal to number of media packets (=3). | 199 // recovered packets is 2, and not equal to number of media packets (=3). |
| 209 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); | 200 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); |
| 210 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); | 201 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); |
| 211 FreeRecoveredPacketList(); | |
| 212 } | 202 } |
| 213 | 203 |
| 214 // Verify we can still recovery frame if sequence number wrap occurs within | 204 // Verify we can still recovery frame if sequence number wrap occurs within |
| 215 // the frame and FEC packet following wrap is received after media packets. | 205 // the frame and FEC packet following wrap is received after media packets. |
| 216 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { | 206 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { |
| 217 const int kNumImportantPackets = 0; | 207 const int kNumImportantPackets = 0; |
| 218 const bool kUseUnequalProtection = false; | 208 const bool kUseUnequalProtection = false; |
| 219 uint8_t kProtectionFactor = 20; | 209 uint8_t kProtectionFactor = 20; |
| 220 | 210 |
| 221 // One frame, with sequence number wrap in media packets. | 211 // One frame, with sequence number wrap in media packets. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 238 // Add FEC packet to received list following the media packets. | 228 // Add FEC packet to received list following the media packets. |
| 239 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 229 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
| 240 | 230 |
| 241 EXPECT_EQ(0, | 231 EXPECT_EQ(0, |
| 242 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 232 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
| 243 | 233 |
| 244 // Expect 3 media packets in recovered list, and complete recovery. | 234 // Expect 3 media packets in recovered list, and complete recovery. |
| 245 // Wrap-around won't remove FEC packet, as it follows the wrap. | 235 // Wrap-around won't remove FEC packet, as it follows the wrap. |
| 246 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); | 236 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); |
| 247 EXPECT_TRUE(IsRecoveryComplete()); | 237 EXPECT_TRUE(IsRecoveryComplete()); |
| 248 FreeRecoveredPacketList(); | |
| 249 } | 238 } |
| 250 | 239 |
| 251 // Sequence number wrap occurs within the FEC packets for the frame. | 240 // Sequence number wrap occurs within the FEC packets for the frame. |
| 252 // In this case we will discard FEC packet and full recovery is not expected. | 241 // In this case we will discard FEC packet and full recovery is not expected. |
| 253 // Same problem will occur if wrap is within media packets but FEC packet is | 242 // Same problem will occur if wrap is within media packets but FEC packet is |
| 254 // received before the media packets. This may be improved if timing information | 243 // received before the media packets. This may be improved if timing information |
| 255 // is used to detect old FEC packets. | 244 // is used to detect old FEC packets. |
| 256 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding. | 245 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding. |
| 257 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { | 246 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { |
| 258 const int kNumImportantPackets = 0; | 247 const int kNumImportantPackets = 0; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 283 EXPECT_EQ(0, | 272 EXPECT_EQ(0, |
| 284 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 273 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
| 285 | 274 |
| 286 // The two FEC packets are received and should allow for complete recovery, | 275 // The two FEC packets are received and should allow for complete recovery, |
| 287 // but because of the wrap the second FEC packet will be discarded, and only | 276 // but because of the wrap the second FEC packet will be discarded, and only |
| 288 // one media packet is recoverable. So exepct 2 media packets on recovered | 277 // one media packet is recoverable. So exepct 2 media packets on recovered |
| 289 // list and no complete recovery. | 278 // list and no complete recovery. |
| 290 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); | 279 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); |
| 291 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); | 280 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); |
| 292 EXPECT_FALSE(IsRecoveryComplete()); | 281 EXPECT_FALSE(IsRecoveryComplete()); |
| 293 FreeRecoveredPacketList(); | |
| 294 } | 282 } |
| 295 | 283 |
| 296 // Verify we can still recovery frame if FEC is received before media packets. | 284 // Verify we can still recovery frame if FEC is received before media packets. |
| 297 TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { | 285 TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { |
| 298 const int kNumImportantPackets = 0; | 286 const int kNumImportantPackets = 0; |
| 299 const bool kUseUnequalProtection = false; | 287 const bool kUseUnequalProtection = false; |
| 300 uint8_t kProtectionFactor = 20; | 288 uint8_t kProtectionFactor = 20; |
| 301 | 289 |
| 302 // One frame: 3 media packets, 1 FEC packet. | 290 // One frame: 3 media packets, 1 FEC packet. |
| 303 // -----Frame 1---- | 291 // -----Frame 1---- |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 319 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 307 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
| 320 // Add media packets to received list. | 308 // Add media packets to received list. |
| 321 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 309 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
| 322 | 310 |
| 323 EXPECT_EQ(0, | 311 EXPECT_EQ(0, |
| 324 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 312 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
| 325 | 313 |
| 326 // Expect 3 media packets in recovered list, and complete recovery. | 314 // Expect 3 media packets in recovered list, and complete recovery. |
| 327 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); | 315 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); |
| 328 EXPECT_TRUE(IsRecoveryComplete()); | 316 EXPECT_TRUE(IsRecoveryComplete()); |
| 329 FreeRecoveredPacketList(); | |
| 330 } | 317 } |
| 331 | 318 |
| 332 // Test 50% protection with random mask type: Two cases are considered: | 319 // Test 50% protection with random mask type: Two cases are considered: |
| 333 // a 50% non-consecutive loss which can be fully recovered, and a 50% | 320 // a 50% non-consecutive loss which can be fully recovered, and a 50% |
| 334 // consecutive loss which cannot be fully recovered. | 321 // consecutive loss which cannot be fully recovered. |
| 335 TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { | 322 TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { |
| 336 const int kNumImportantPackets = 0; | 323 const int kNumImportantPackets = 0; |
| 337 const bool kUseUnequalProtection = false; | 324 const bool kUseUnequalProtection = false; |
| 338 const int kNumMediaPackets = 4; | 325 const int kNumMediaPackets = 4; |
| 339 const uint8_t kProtectionFactor = 255; | 326 const uint8_t kProtectionFactor = 255; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 364 media_loss_mask_[0] = 1; | 351 media_loss_mask_[0] = 1; |
| 365 media_loss_mask_[2] = 1; | 352 media_loss_mask_[2] = 1; |
| 366 media_loss_mask_[3] = 1; | 353 media_loss_mask_[3] = 1; |
| 367 NetworkReceivedPackets(); | 354 NetworkReceivedPackets(); |
| 368 | 355 |
| 369 EXPECT_EQ(0, | 356 EXPECT_EQ(0, |
| 370 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 357 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
| 371 | 358 |
| 372 // With media packet#1 and FEC packets #1, #2, #3, expect complete recovery. | 359 // With media packet#1 and FEC packets #1, #2, #3, expect complete recovery. |
| 373 EXPECT_TRUE(IsRecoveryComplete()); | 360 EXPECT_TRUE(IsRecoveryComplete()); |
| 374 FreeRecoveredPacketList(); | 361 recovered_packet_list_.clear(); |
| 375 | 362 |
| 376 // 4 consecutive packets lost: media packets 0, 1, 2, 3. | 363 // 4 consecutive packets lost: media packets 0, 1, 2, 3. |
| 377 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 364 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 378 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 365 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 379 media_loss_mask_[0] = 1; | 366 media_loss_mask_[0] = 1; |
| 380 media_loss_mask_[1] = 1; | 367 media_loss_mask_[1] = 1; |
| 381 media_loss_mask_[2] = 1; | 368 media_loss_mask_[2] = 1; |
| 382 media_loss_mask_[3] = 1; | 369 media_loss_mask_[3] = 1; |
| 383 NetworkReceivedPackets(); | 370 NetworkReceivedPackets(); |
| 384 | 371 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 media_loss_mask_[1] = 1; | 411 media_loss_mask_[1] = 1; |
| 425 media_loss_mask_[2] = 1; | 412 media_loss_mask_[2] = 1; |
| 426 media_loss_mask_[3] = 1; | 413 media_loss_mask_[3] = 1; |
| 427 NetworkReceivedPackets(); | 414 NetworkReceivedPackets(); |
| 428 | 415 |
| 429 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 416 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 430 &recovered_packet_list_)); | 417 &recovered_packet_list_)); |
| 431 | 418 |
| 432 // Expect complete recovery for consecutive packet loss <= 50%. | 419 // Expect complete recovery for consecutive packet loss <= 50%. |
| 433 EXPECT_TRUE(IsRecoveryComplete()); | 420 EXPECT_TRUE(IsRecoveryComplete()); |
| 434 FreeRecoveredPacketList(); | 421 recovered_packet_list_.clear(); |
| 435 | 422 |
| 436 // 4 consecutive packets lost: media packets 1,2, 3, and FEC packet 0. | 423 // 4 consecutive packets lost: media packets 1,2, 3, and FEC packet 0. |
| 437 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 424 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 438 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 425 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 439 fec_loss_mask_[0] = 1; | 426 fec_loss_mask_[0] = 1; |
| 440 media_loss_mask_[1] = 1; | 427 media_loss_mask_[1] = 1; |
| 441 media_loss_mask_[2] = 1; | 428 media_loss_mask_[2] = 1; |
| 442 media_loss_mask_[3] = 1; | 429 media_loss_mask_[3] = 1; |
| 443 NetworkReceivedPackets(); | 430 NetworkReceivedPackets(); |
| 444 | 431 |
| 445 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 432 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 446 &recovered_packet_list_)); | 433 &recovered_packet_list_)); |
| 447 | 434 |
| 448 // Expect complete recovery for consecutive packet loss <= 50%. | 435 // Expect complete recovery for consecutive packet loss <= 50%. |
| 449 EXPECT_TRUE(IsRecoveryComplete()); | 436 EXPECT_TRUE(IsRecoveryComplete()); |
| 450 FreeRecoveredPacketList(); | 437 recovered_packet_list_.clear(); |
| 451 | 438 |
| 452 // 4 packets lost (non-consecutive loss): media packets 0, 3, and FEC# 0, 3. | 439 // 4 packets lost (non-consecutive loss): media packets 0, 3, and FEC# 0, 3. |
| 453 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 440 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 454 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 441 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 455 fec_loss_mask_[0] = 1; | 442 fec_loss_mask_[0] = 1; |
| 456 fec_loss_mask_[3] = 1; | 443 fec_loss_mask_[3] = 1; |
| 457 media_loss_mask_[0] = 1; | 444 media_loss_mask_[0] = 1; |
| 458 media_loss_mask_[3] = 1; | 445 media_loss_mask_[3] = 1; |
| 459 NetworkReceivedPackets(); | 446 NetworkReceivedPackets(); |
| 460 | 447 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 498 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 512 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 499 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 513 media_loss_mask_[3] = 1; | 500 media_loss_mask_[3] = 1; |
| 514 NetworkReceivedPackets(); | 501 NetworkReceivedPackets(); |
| 515 | 502 |
| 516 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 503 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 517 &recovered_packet_list_)); | 504 &recovered_packet_list_)); |
| 518 | 505 |
| 519 // One packet lost, one FEC packet, expect complete recovery. | 506 // One packet lost, one FEC packet, expect complete recovery. |
| 520 EXPECT_TRUE(IsRecoveryComplete()); | 507 EXPECT_TRUE(IsRecoveryComplete()); |
| 521 FreeRecoveredPacketList(); | 508 recovered_packet_list_.clear(); |
| 522 | 509 |
| 523 // 2 media packets lost. | 510 // 2 media packets lost. |
| 524 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 511 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 525 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 512 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 526 media_loss_mask_[1] = 1; | 513 media_loss_mask_[1] = 1; |
| 527 media_loss_mask_[3] = 1; | 514 media_loss_mask_[3] = 1; |
| 528 NetworkReceivedPackets(); | 515 NetworkReceivedPackets(); |
| 529 | 516 |
| 530 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 517 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 531 &recovered_packet_list_)); | 518 &recovered_packet_list_)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 media_loss_mask_[0] = 1; | 554 media_loss_mask_[0] = 1; |
| 568 media_loss_mask_[2] = 1; | 555 media_loss_mask_[2] = 1; |
| 569 media_loss_mask_[3] = 1; | 556 media_loss_mask_[3] = 1; |
| 570 NetworkReceivedPackets(); | 557 NetworkReceivedPackets(); |
| 571 | 558 |
| 572 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 559 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 573 &recovered_packet_list_)); | 560 &recovered_packet_list_)); |
| 574 | 561 |
| 575 // With media packet#3 and FEC packets #0, #1, #3, expect complete recovery. | 562 // With media packet#3 and FEC packets #0, #1, #3, expect complete recovery. |
| 576 EXPECT_TRUE(IsRecoveryComplete()); | 563 EXPECT_TRUE(IsRecoveryComplete()); |
| 577 FreeRecoveredPacketList(); | 564 recovered_packet_list_.clear(); |
| 578 | 565 |
| 579 // 5 packets lost: 4 media packets and one FEC packet#2 lost. | 566 // 5 packets lost: 4 media packets and one FEC packet#2 lost. |
| 580 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 567 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 581 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 568 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 582 fec_loss_mask_[2] = 1; | 569 fec_loss_mask_[2] = 1; |
| 583 media_loss_mask_[0] = 1; | 570 media_loss_mask_[0] = 1; |
| 584 media_loss_mask_[1] = 1; | 571 media_loss_mask_[1] = 1; |
| 585 media_loss_mask_[2] = 1; | 572 media_loss_mask_[2] = 1; |
| 586 media_loss_mask_[3] = 1; | 573 media_loss_mask_[3] = 1; |
| 587 NetworkReceivedPackets(); | 574 NetworkReceivedPackets(); |
| 588 | 575 |
| 589 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 576 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 590 &recovered_packet_list_)); | 577 &recovered_packet_list_)); |
| 591 | 578 |
| 592 // Cannot get complete recovery for this loss configuration. | 579 // Cannot get complete recovery for this loss configuration. |
| 593 EXPECT_FALSE(IsRecoveryComplete()); | 580 EXPECT_FALSE(IsRecoveryComplete()); |
| 594 } | 581 } |
| 595 | 582 |
| 596 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { | 583 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { |
| 597 const int kNumImportantPackets = 0; | 584 const int kNumImportantPackets = 0; |
| 598 const bool kUseUnequalProtection = false; | 585 const bool kUseUnequalProtection = false; |
| 599 const int kNumMediaPackets = 5; | 586 const int kNumMediaPackets = 5; |
| 600 uint8_t kProtectionFactor = 60; | 587 uint8_t kProtectionFactor = 60; |
| 601 | 588 |
| 602 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 589 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
| 603 | 590 |
| 604 // Create a new temporary packet list for generating FEC packets. | 591 // Create a new temporary packet list for generating FEC packets. |
| 605 // This list should have every other packet removed. | 592 // This list should have every other packet removed. |
| 606 PacketList protected_media_packets; | 593 PacketList protected_media_packets; |
| 607 int i = 0; | 594 DeepCopyEveryNthPacket(media_packet_list_, 2, &protected_media_packets); |
| 608 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); | |
| 609 ++it, ++i) { | |
| 610 if (i % 2 == 0) protected_media_packets.push_back(*it); | |
| 611 } | |
| 612 | 595 |
| 613 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, | 596 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, |
| 614 kNumImportantPackets, kUseUnequalProtection, | 597 kNumImportantPackets, kUseUnequalProtection, |
| 615 webrtc::kFecMaskBursty, &fec_packet_list_)); | 598 webrtc::kFecMaskBursty, &fec_packet_list_)); |
| 616 | 599 |
| 617 // Expect 1 FEC packet. | 600 // Expect 1 FEC packet. |
| 618 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 601 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
| 619 | 602 |
| 620 // 1 protected media packet lost | 603 // 1 protected media packet lost |
| 621 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 604 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 622 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 605 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 623 media_loss_mask_[2] = 1; | 606 media_loss_mask_[2] = 1; |
| 624 NetworkReceivedPackets(); | 607 NetworkReceivedPackets(); |
| 625 | 608 |
| 626 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 609 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 627 &recovered_packet_list_)); | 610 &recovered_packet_list_)); |
| 628 | 611 |
| 629 // One packet lost, one FEC packet, expect complete recovery. | 612 // One packet lost, one FEC packet, expect complete recovery. |
| 630 EXPECT_TRUE(IsRecoveryComplete()); | 613 EXPECT_TRUE(IsRecoveryComplete()); |
| 631 FreeRecoveredPacketList(); | 614 recovered_packet_list_.clear(); |
| 632 | 615 |
| 633 // Unprotected packet lost. | 616 // Unprotected packet lost. |
| 634 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 617 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 635 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 618 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 636 media_loss_mask_[1] = 1; | 619 media_loss_mask_[1] = 1; |
| 637 NetworkReceivedPackets(); | 620 NetworkReceivedPackets(); |
| 638 | 621 |
| 639 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 622 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 640 &recovered_packet_list_)); | 623 &recovered_packet_list_)); |
| 641 | 624 |
| 642 // Unprotected packet lost. Recovery not possible. | 625 // Unprotected packet lost. Recovery not possible. |
| 643 EXPECT_FALSE(IsRecoveryComplete()); | 626 EXPECT_FALSE(IsRecoveryComplete()); |
| 644 FreeRecoveredPacketList(); | 627 recovered_packet_list_.clear(); |
| 645 | 628 |
| 646 // 2 media packets lost. | 629 // 2 media packets lost. |
| 647 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 630 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 648 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 631 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 649 media_loss_mask_[0] = 1; | 632 media_loss_mask_[0] = 1; |
| 650 media_loss_mask_[2] = 1; | 633 media_loss_mask_[2] = 1; |
| 651 NetworkReceivedPackets(); | 634 NetworkReceivedPackets(); |
| 652 | 635 |
| 653 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 636 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 654 &recovered_packet_list_)); | 637 &recovered_packet_list_)); |
| 655 | 638 |
| 656 // 2 protected packets lost, one FEC packet, cannot get complete recovery. | 639 // 2 protected packets lost, one FEC packet, cannot get complete recovery. |
| 657 EXPECT_FALSE(IsRecoveryComplete()); | 640 EXPECT_FALSE(IsRecoveryComplete()); |
| 658 } | 641 } |
| 659 | 642 |
| 660 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { | 643 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { |
| 661 const int kNumImportantPackets = 0; | 644 const int kNumImportantPackets = 0; |
| 662 const bool kUseUnequalProtection = false; | 645 const bool kUseUnequalProtection = false; |
| 663 const int kNumMediaPackets = 21; | 646 const int kNumMediaPackets = 21; |
| 664 uint8_t kProtectionFactor = 127; | 647 uint8_t kProtectionFactor = 127; |
| 665 | 648 |
| 666 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 649 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
| 667 | 650 |
| 668 // Create a new temporary packet list for generating FEC packets. | 651 // Create a new temporary packet list for generating FEC packets. |
| 669 // This list should have every other packet removed. | 652 // This list should have every other packet removed. |
| 670 PacketList protected_media_packets; | 653 PacketList protected_media_packets; |
| 671 int i = 0; | 654 DeepCopyEveryNthPacket(media_packet_list_, 2, &protected_media_packets); |
| 672 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); | |
| 673 ++it, ++i) { | |
| 674 if (i % 2 == 0) protected_media_packets.push_back(*it); | |
| 675 } | |
| 676 | 655 |
| 677 // Zero column insertion will have to extend the size of the packet | 656 // Zero column insertion will have to extend the size of the packet |
| 678 // mask since the number of actual packets are 21, while the number | 657 // mask since the number of actual packets are 21, while the number |
| 679 // of protected packets are 11. | 658 // of protected packets are 11. |
| 680 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, | 659 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, |
| 681 kNumImportantPackets, kUseUnequalProtection, | 660 kNumImportantPackets, kUseUnequalProtection, |
| 682 webrtc::kFecMaskBursty, &fec_packet_list_)); | 661 webrtc::kFecMaskBursty, &fec_packet_list_)); |
| 683 | 662 |
| 684 // Expect 5 FEC packet. | 663 // Expect 5 FEC packet. |
| 685 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); | 664 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); |
| 686 | 665 |
| 687 // Last protected media packet lost | 666 // Last protected media packet lost |
| 688 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 667 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 689 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 668 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 690 media_loss_mask_[kNumMediaPackets - 1] = 1; | 669 media_loss_mask_[kNumMediaPackets - 1] = 1; |
| 691 NetworkReceivedPackets(); | 670 NetworkReceivedPackets(); |
| 692 | 671 |
| 693 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 672 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 694 &recovered_packet_list_)); | 673 &recovered_packet_list_)); |
| 695 | 674 |
| 696 // One packet lost, one FEC packet, expect complete recovery. | 675 // One packet lost, one FEC packet, expect complete recovery. |
| 697 EXPECT_TRUE(IsRecoveryComplete()); | 676 EXPECT_TRUE(IsRecoveryComplete()); |
| 698 FreeRecoveredPacketList(); | 677 recovered_packet_list_.clear(); |
| 699 | 678 |
| 700 // Last unprotected packet lost. | 679 // Last unprotected packet lost. |
| 701 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 680 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 702 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 681 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 703 media_loss_mask_[kNumMediaPackets - 2] = 1; | 682 media_loss_mask_[kNumMediaPackets - 2] = 1; |
| 704 NetworkReceivedPackets(); | 683 NetworkReceivedPackets(); |
| 705 | 684 |
| 706 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 685 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 707 &recovered_packet_list_)); | 686 &recovered_packet_list_)); |
| 708 | 687 |
| 709 // Unprotected packet lost. Recovery not possible. | 688 // Unprotected packet lost. Recovery not possible. |
| 710 EXPECT_FALSE(IsRecoveryComplete()); | 689 EXPECT_FALSE(IsRecoveryComplete()); |
| 711 FreeRecoveredPacketList(); | 690 recovered_packet_list_.clear(); |
| 712 | 691 |
| 713 // 6 media packets lost. | 692 // 6 media packets lost. |
| 714 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 693 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 715 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 694 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 716 media_loss_mask_[kNumMediaPackets - 11] = 1; | 695 media_loss_mask_[kNumMediaPackets - 11] = 1; |
| 717 media_loss_mask_[kNumMediaPackets - 9] = 1; | 696 media_loss_mask_[kNumMediaPackets - 9] = 1; |
| 718 media_loss_mask_[kNumMediaPackets - 7] = 1; | 697 media_loss_mask_[kNumMediaPackets - 7] = 1; |
| 719 media_loss_mask_[kNumMediaPackets - 5] = 1; | 698 media_loss_mask_[kNumMediaPackets - 5] = 1; |
| 720 media_loss_mask_[kNumMediaPackets - 3] = 1; | 699 media_loss_mask_[kNumMediaPackets - 3] = 1; |
| 721 media_loss_mask_[kNumMediaPackets - 1] = 1; | 700 media_loss_mask_[kNumMediaPackets - 1] = 1; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 732 const int kNumImportantPackets = 0; | 711 const int kNumImportantPackets = 0; |
| 733 const bool kUseUnequalProtection = false; | 712 const bool kUseUnequalProtection = false; |
| 734 const int kNumMediaPackets = 21; | 713 const int kNumMediaPackets = 21; |
| 735 uint8_t kProtectionFactor = 127; | 714 uint8_t kProtectionFactor = 127; |
| 736 | 715 |
| 737 fec_seq_num_ = ConstructMediaPacketsSeqNum(kNumMediaPackets, 0xFFFF - 5); | 716 fec_seq_num_ = ConstructMediaPacketsSeqNum(kNumMediaPackets, 0xFFFF - 5); |
| 738 | 717 |
| 739 // Create a new temporary packet list for generating FEC packets. | 718 // Create a new temporary packet list for generating FEC packets. |
| 740 // This list should have every other packet removed. | 719 // This list should have every other packet removed. |
| 741 PacketList protected_media_packets; | 720 PacketList protected_media_packets; |
| 742 int i = 0; | 721 DeepCopyEveryNthPacket(media_packet_list_, 2, &protected_media_packets); |
| 743 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); | |
| 744 ++it, ++i) { | |
| 745 if (i % 2 == 0) protected_media_packets.push_back(*it); | |
| 746 } | |
| 747 | 722 |
| 748 // Zero column insertion will have to extend the size of the packet | 723 // Zero column insertion will have to extend the size of the packet |
| 749 // mask since the number of actual packets are 21, while the number | 724 // mask since the number of actual packets are 21, while the number |
| 750 // of protected packets are 11. | 725 // of protected packets are 11. |
| 751 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, | 726 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, |
| 752 kNumImportantPackets, kUseUnequalProtection, | 727 kNumImportantPackets, kUseUnequalProtection, |
| 753 webrtc::kFecMaskBursty, &fec_packet_list_)); | 728 webrtc::kFecMaskBursty, &fec_packet_list_)); |
| 754 | 729 |
| 755 // Expect 5 FEC packet. | 730 // Expect 5 FEC packet. |
| 756 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); | 731 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); |
| 757 | 732 |
| 758 // Last protected media packet lost | 733 // Last protected media packet lost |
| 759 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 734 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 760 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 735 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 761 media_loss_mask_[kNumMediaPackets - 1] = 1; | 736 media_loss_mask_[kNumMediaPackets - 1] = 1; |
| 762 NetworkReceivedPackets(); | 737 NetworkReceivedPackets(); |
| 763 | 738 |
| 764 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 739 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 765 &recovered_packet_list_)); | 740 &recovered_packet_list_)); |
| 766 | 741 |
| 767 // One packet lost, one FEC packet, expect complete recovery. | 742 // One packet lost, one FEC packet, expect complete recovery. |
| 768 EXPECT_TRUE(IsRecoveryComplete()); | 743 EXPECT_TRUE(IsRecoveryComplete()); |
| 769 FreeRecoveredPacketList(); | 744 recovered_packet_list_.clear(); |
| 770 | 745 |
| 771 // Last unprotected packet lost. | 746 // Last unprotected packet lost. |
| 772 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 747 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 773 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 748 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 774 media_loss_mask_[kNumMediaPackets - 2] = 1; | 749 media_loss_mask_[kNumMediaPackets - 2] = 1; |
| 775 NetworkReceivedPackets(); | 750 NetworkReceivedPackets(); |
| 776 | 751 |
| 777 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 752 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 778 &recovered_packet_list_)); | 753 &recovered_packet_list_)); |
| 779 | 754 |
| 780 // Unprotected packet lost. Recovery not possible. | 755 // Unprotected packet lost. Recovery not possible. |
| 781 EXPECT_FALSE(IsRecoveryComplete()); | 756 EXPECT_FALSE(IsRecoveryComplete()); |
| 782 FreeRecoveredPacketList(); | 757 recovered_packet_list_.clear(); |
| 783 | 758 |
| 784 // 6 media packets lost. | 759 // 6 media packets lost. |
| 785 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 760 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
| 786 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 761 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
| 787 media_loss_mask_[kNumMediaPackets - 11] = 1; | 762 media_loss_mask_[kNumMediaPackets - 11] = 1; |
| 788 media_loss_mask_[kNumMediaPackets - 9] = 1; | 763 media_loss_mask_[kNumMediaPackets - 9] = 1; |
| 789 media_loss_mask_[kNumMediaPackets - 7] = 1; | 764 media_loss_mask_[kNumMediaPackets - 7] = 1; |
| 790 media_loss_mask_[kNumMediaPackets - 5] = 1; | 765 media_loss_mask_[kNumMediaPackets - 5] = 1; |
| 791 media_loss_mask_[kNumMediaPackets - 3] = 1; | 766 media_loss_mask_[kNumMediaPackets - 3] = 1; |
| 792 media_loss_mask_[kNumMediaPackets - 1] = 1; | 767 media_loss_mask_[kNumMediaPackets - 1] = 1; |
| 793 NetworkReceivedPackets(); | 768 NetworkReceivedPackets(); |
| 794 | 769 |
| 795 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 770 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
| 796 &recovered_packet_list_)); | 771 &recovered_packet_list_)); |
| 797 | 772 |
| 798 // 5 protected packets lost, one FEC packet, cannot get complete recovery. | 773 // 5 protected packets lost, one FEC packet, cannot get complete recovery. |
| 799 EXPECT_FALSE(IsRecoveryComplete()); | 774 EXPECT_FALSE(IsRecoveryComplete()); |
| 800 } | 775 } |
| 801 | 776 |
| 802 void RtpFecTest::TearDown() { | 777 void RtpFecTest::TearDown() { |
| 803 fec_->ResetState(&recovered_packet_list_); | 778 fec_->ResetState(&recovered_packet_list_); |
| 804 delete fec_; | 779 delete fec_; |
| 805 FreeRecoveredPacketList(); | 780 recovered_packet_list_.clear(); |
| 806 ClearList(&media_packet_list_); | 781 media_packet_list_.clear(); |
| 807 EXPECT_TRUE(media_packet_list_.empty()); | 782 EXPECT_TRUE(media_packet_list_.empty()); |
| 808 } | 783 } |
| 809 | 784 |
| 810 void RtpFecTest::FreeRecoveredPacketList() { | |
| 811 ClearList(&recovered_packet_list_); | |
| 812 } | |
| 813 | |
| 814 bool RtpFecTest::IsRecoveryComplete() { | 785 bool RtpFecTest::IsRecoveryComplete() { |
| 815 // We must have equally many recovered packets as original packets. | 786 // We must have equally many recovered packets as original packets. |
| 816 if (recovered_packet_list_.size() != media_packet_list_.size()) { | 787 if (recovered_packet_list_.size() != media_packet_list_.size()) { |
| 817 return false; | 788 return false; |
| 818 } | 789 } |
| 819 | 790 |
| 820 // All recovered packets must be identical to the corresponding | 791 // All recovered packets must be identical to the corresponding |
| 821 // original packets. | 792 // original packets. |
| 822 auto cmp = [](ForwardErrorCorrection::Packet* media_packet, | 793 using PacketPtr = std::unique_ptr<ForwardErrorCorrection::Packet>; |
| 823 ForwardErrorCorrection::RecoveredPacket* recovered_packet) { | 794 using RecoveredPacketPtr = |
| 795 std::unique_ptr<ForwardErrorCorrection::RecoveredPacket>; | |
| 796 auto cmp = [](const PacketPtr& media_packet, | |
| 797 const RecoveredPacketPtr& recovered_packet) { | |
| 824 if (media_packet->length != recovered_packet->pkt->length) { | 798 if (media_packet->length != recovered_packet->pkt->length) { |
| 825 return false; | 799 return false; |
| 826 } | 800 } |
| 827 if (memcmp(media_packet->data, | 801 if (memcmp(media_packet->data, |
| 828 recovered_packet->pkt->data, | 802 recovered_packet->pkt->data, |
| 829 media_packet->length) != 0) { | 803 media_packet->length) != 0) { |
| 830 return false; | 804 return false; |
| 831 } | 805 } |
| 832 return true; | 806 return true; |
| 833 }; | 807 }; |
| 834 return std::equal(media_packet_list_.cbegin(), media_packet_list_.cend(), | 808 return std::equal(media_packet_list_.cbegin(), media_packet_list_.cend(), |
| 835 recovered_packet_list_.cbegin(), cmp); | 809 recovered_packet_list_.cbegin(), cmp); |
| 836 } | 810 } |
| 837 | 811 |
| 838 void RtpFecTest::NetworkReceivedPackets() { | 812 void RtpFecTest::NetworkReceivedPackets() { |
| 839 const bool kFecPacket = true; | 813 const bool kFecPacket = true; |
| 840 ReceivedPackets(media_packet_list_, media_loss_mask_, !kFecPacket); | 814 ReceivedPackets(media_packet_list_, media_loss_mask_, !kFecPacket); |
| 841 ReceivedPackets(fec_packet_list_, fec_loss_mask_, kFecPacket); | 815 ReceivedPackets(fec_packet_list_, fec_loss_mask_, kFecPacket); |
| 842 } | 816 } |
| 843 | 817 |
| 844 void RtpFecTest::ReceivedPackets(const PacketList& packet_list, int* loss_mask, | 818 template <typename T> |
| 819 void RtpFecTest::ReceivedPackets(const T& packet_list, int* loss_mask, | |
| 845 bool is_fec) { | 820 bool is_fec) { |
| 846 int seq_num = fec_seq_num_; | 821 int seq_num = fec_seq_num_; |
| 847 int packet_idx = 0; | 822 int packet_idx = 0; |
| 848 | 823 |
| 849 for (const auto* packet : packet_list) { | 824 for (const auto& packet : packet_list) { |
| 850 if (loss_mask[packet_idx] == 0) { | 825 if (loss_mask[packet_idx] == 0) { |
| 851 auto received_packet = new ForwardErrorCorrection::ReceivedPacket(); | 826 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> received_packet( |
| 827 new ForwardErrorCorrection::ReceivedPacket()); | |
| 852 received_packet->pkt = new ForwardErrorCorrection::Packet(); | 828 received_packet->pkt = new ForwardErrorCorrection::Packet(); |
| 853 received_packet_list_.push_back(received_packet); | |
| 854 received_packet->pkt->length = packet->length; | 829 received_packet->pkt->length = packet->length; |
| 855 memcpy(received_packet->pkt->data, packet->data, packet->length); | 830 memcpy(received_packet->pkt->data, packet->data, packet->length); |
| 856 received_packet->is_fec = is_fec; | 831 received_packet->is_fec = is_fec; |
| 857 if (!is_fec) { | 832 if (!is_fec) { |
| 858 // For media packets, the sequence number and marker bit is | 833 // For media packets, the sequence number and marker bit is |
| 859 // obtained from RTP header. These were set in ConstructMediaPackets(). | 834 // obtained from RTP header. These were set in ConstructMediaPackets(). |
| 860 received_packet->seq_num = | 835 received_packet->seq_num = |
| 861 webrtc::ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]); | 836 webrtc::ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]); |
| 862 } else { | 837 } else { |
| 863 // The sequence number, marker bit, and ssrc number are defined in the | 838 // The sequence number, marker bit, and ssrc number are defined in the |
| 864 // RTP header of the FEC packet, which is not constructed in this test. | 839 // RTP header of the FEC packet, which is not constructed in this test. |
| 865 // So we set these values below based on the values generated in | 840 // So we set these values below based on the values generated in |
| 866 // ConstructMediaPackets(). | 841 // ConstructMediaPackets(). |
| 867 received_packet->seq_num = seq_num; | 842 received_packet->seq_num = seq_num; |
| 868 // The ssrc value for FEC packets is set to the one used for the | 843 // The ssrc value for FEC packets is set to the one used for the |
| 869 // media packets in ConstructMediaPackets(). | 844 // media packets in ConstructMediaPackets(). |
| 870 received_packet->ssrc = ssrc_; | 845 received_packet->ssrc = ssrc_; |
| 871 } | 846 } |
| 847 received_packet_list_.push_back(std::move(received_packet)); | |
| 872 } | 848 } |
| 873 packet_idx++; | 849 packet_idx++; |
| 874 // Sequence number of FEC packets are defined as increment by 1 from | 850 // Sequence number of FEC packets are defined as increment by 1 from |
| 875 // last media packet in frame. | 851 // last media packet in frame. |
| 876 if (is_fec) seq_num++; | 852 if (is_fec) seq_num++; |
| 877 } | 853 } |
| 878 } | 854 } |
| 879 | 855 |
| 880 int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, | 856 int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, |
| 881 int start_seq_num) { | 857 int start_seq_num) { |
| 882 RTC_DCHECK_GT(num_media_packets, 0); | 858 RTC_DCHECK_GT(num_media_packets, 0); |
| 883 ForwardErrorCorrection::Packet* media_packet = NULL; | |
| 884 int sequence_number = start_seq_num; | 859 int sequence_number = start_seq_num; |
| 885 int time_stamp = random_.Rand<int>(); | 860 int time_stamp = random_.Rand<int>(); |
| 886 | 861 |
| 887 for (int i = 0; i < num_media_packets; ++i) { | 862 for (int i = 0; i < num_media_packets; ++i) { |
| 888 media_packet = new ForwardErrorCorrection::Packet(); | 863 std::unique_ptr<ForwardErrorCorrection::Packet> media_packet( |
| 889 media_packet_list_.push_back(media_packet); | 864 new ForwardErrorCorrection::Packet()); |
| 890 const uint32_t kMinPacketSize = kRtpHeaderSize; | 865 const uint32_t kMinPacketSize = kRtpHeaderSize; |
| 891 const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize - | 866 const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize - |
| 892 kTransportOverhead - | 867 kTransportOverhead - |
| 893 ForwardErrorCorrection::PacketOverhead(); | 868 ForwardErrorCorrection::PacketOverhead(); |
| 894 media_packet->length = random_.Rand(kMinPacketSize, kMaxPacketSize); | 869 media_packet->length = random_.Rand(kMinPacketSize, kMaxPacketSize); |
| 895 | 870 |
| 896 // Generate random values for the first 2 bytes | 871 // Generate random values for the first 2 bytes |
| 897 media_packet->data[0] = random_.Rand<uint8_t>(); | 872 media_packet->data[0] = random_.Rand<uint8_t>(); |
| 898 media_packet->data[1] = random_.Rand<uint8_t>(); | 873 media_packet->data[1] = random_.Rand<uint8_t>(); |
| 899 | 874 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 914 sequence_number); | 889 sequence_number); |
| 915 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], | 890 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], |
| 916 time_stamp); | 891 time_stamp); |
| 917 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc_); | 892 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc_); |
| 918 | 893 |
| 919 // Generate random values for payload. | 894 // Generate random values for payload. |
| 920 for (size_t j = 12; j < media_packet->length; ++j) { | 895 for (size_t j = 12; j < media_packet->length; ++j) { |
| 921 media_packet->data[j] = random_.Rand<uint8_t>(); | 896 media_packet->data[j] = random_.Rand<uint8_t>(); |
| 922 } | 897 } |
| 923 sequence_number++; | 898 sequence_number++; |
| 899 media_packet_list_.push_back(std::move(media_packet)); | |
| 924 } | 900 } |
| 925 // Last packet, set marker bit. | 901 // Last packet, set marker bit. |
| 902 ForwardErrorCorrection::Packet* media_packet = | |
| 903 media_packet_list_.back().get(); | |
| 926 RTC_DCHECK(media_packet); | 904 RTC_DCHECK(media_packet); |
| 927 media_packet->data[1] |= 0x80; | 905 media_packet->data[1] |= 0x80; |
| 928 return sequence_number; | 906 return sequence_number; |
| 929 } | 907 } |
| 930 | 908 |
| 931 int RtpFecTest::ConstructMediaPackets(int num_media_packets) { | 909 int RtpFecTest::ConstructMediaPackets(int num_media_packets) { |
| 932 return ConstructMediaPacketsSeqNum(num_media_packets, random_.Rand<int>()); | 910 return ConstructMediaPacketsSeqNum(num_media_packets, random_.Rand<int>()); |
| 933 } | 911 } |
| 912 | |
| 913 void RtpFecTest::DeepCopyEveryNthPacket(const PacketList& src, int n, | |
| 914 PacketList* dst) { | |
| 915 RTC_DCHECK_GT(n, 0); | |
| 916 int i = 0; | |
| 917 for (const auto& packet : src) { | |
| 918 if (i % n == 0) { | |
|
stefan-webrtc
2016/08/01 11:29:51
Remove {}
| |
| 919 dst->emplace_back(new ForwardErrorCorrection::Packet(*packet)); | |
| 920 } | |
| 921 ++i; | |
| 922 } | |
| 923 } | |
| OLD | NEW |