Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc

Issue 2919313005: Revert of Only compare sequence numbers from the same SSRC in ForwardErrorCorrection. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 ReceivedPackets(media_packets_, media_loss_mask, !kFecPacket); 101 ReceivedPackets(media_packets_, media_loss_mask, !kFecPacket);
102 ReceivedPackets(generated_fec_packets_, fec_loss_mask, kFecPacket); 102 ReceivedPackets(generated_fec_packets_, fec_loss_mask, kFecPacket);
103 } 103 }
104 104
105 template <typename ForwardErrorCorrectionType> 105 template <typename ForwardErrorCorrectionType>
106 template <typename PacketListType> 106 template <typename PacketListType>
107 void RtpFecTest<ForwardErrorCorrectionType>::ReceivedPackets( 107 void RtpFecTest<ForwardErrorCorrectionType>::ReceivedPackets(
108 const PacketListType& packet_list, 108 const PacketListType& packet_list,
109 int* loss_mask, 109 int* loss_mask,
110 bool is_fec) { 110 bool is_fec) {
111 uint16_t fec_seq_num = ForwardErrorCorrectionType::GetFirstFecSeqNum( 111 uint16_t fec_seq_num = media_packet_generator_.GetFecSeqNum();
112 media_packet_generator_.GetNextSeqNum());
113 int packet_idx = 0; 112 int packet_idx = 0;
114 113
115 for (const auto& packet : packet_list) { 114 for (const auto& packet : packet_list) {
116 if (loss_mask[packet_idx] == 0) { 115 if (loss_mask[packet_idx] == 0) {
117 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> received_packet( 116 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> received_packet(
118 new ForwardErrorCorrection::ReceivedPacket()); 117 new ForwardErrorCorrection::ReceivedPacket());
119 received_packet->pkt = new ForwardErrorCorrection::Packet(); 118 received_packet->pkt = new ForwardErrorCorrection::Packet();
120 received_packet->pkt->length = packet->length; 119 received_packet->pkt->length = packet->length;
121 memcpy(received_packet->pkt->data, packet->data, packet->length); 120 memcpy(received_packet->pkt->data, packet->data, packet->length);
122 received_packet->is_fec = is_fec; 121 received_packet->is_fec = is_fec;
123 if (!is_fec) { 122 if (!is_fec) {
124 received_packet->ssrc = kMediaSsrc; 123 // For media packets, the sequence number and marker bit is
125 // For media packets, the sequence number is obtained from the 124 // obtained from RTP header. These were set in ConstructMediaPackets().
126 // RTP header as written by MediaPacketGenerator::ConstructMediaPackets.
127 received_packet->seq_num = 125 received_packet->seq_num =
128 ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]); 126 ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]);
129 } else { 127 } else {
130 received_packet->ssrc = ForwardErrorCorrectionType::kFecSsrc; 128 // The sequence number, marker bit, and ssrc number are defined in the
131 // For FEC packets, we simulate the sequence numbers differently 129 // RTP header of the FEC packet, which is not constructed in this test.
132 // depending on if ULPFEC or FlexFEC is used. See the definition of 130 // So we set these values below based on the values generated in
133 // ForwardErrorCorrectionType::GetFirstFecSeqNum. 131 // ConstructMediaPackets().
134 received_packet->seq_num = fec_seq_num; 132 received_packet->seq_num = fec_seq_num;
133 // The ssrc value for FEC packets is set to the one used for the
134 // media packets in ConstructMediaPackets().
135 received_packet->ssrc = kMediaSsrc;
135 } 136 }
136 received_packets_.push_back(std::move(received_packet)); 137 received_packets_.push_back(std::move(received_packet));
137 } 138 }
138 packet_idx++; 139 packet_idx++;
139 // Sequence number of FEC packets are defined as increment by 1 from 140 // Sequence number of FEC packets are defined as increment by 1 from
140 // last media packet in frame. 141 // last media packet in frame.
141 if (is_fec) 142 if (is_fec)
142 fec_seq_num++; 143 fec_seq_num++;
143 } 144 }
144 } 145 }
(...skipping 24 matching lines...) Expand all
169 recovered_packets_.cbegin(), cmp); 170 recovered_packets_.cbegin(), cmp);
170 } 171 }
171 172
172 // Define gTest typed test to loop over both ULPFEC and FlexFEC. 173 // Define gTest typed test to loop over both ULPFEC and FlexFEC.
173 // Since the tests now are parameterized, we need to access 174 // Since the tests now are parameterized, we need to access
174 // member variables using |this|, thereby enforcing runtime 175 // member variables using |this|, thereby enforcing runtime
175 // resolution. 176 // resolution.
176 177
177 class FlexfecForwardErrorCorrection : public ForwardErrorCorrection { 178 class FlexfecForwardErrorCorrection : public ForwardErrorCorrection {
178 public: 179 public:
179 static const uint32_t kFecSsrc = kFlexfecSsrc;
180
181 FlexfecForwardErrorCorrection() 180 FlexfecForwardErrorCorrection()
182 : ForwardErrorCorrection( 181 : ForwardErrorCorrection(
183 std::unique_ptr<FecHeaderReader>(new FlexfecHeaderReader()), 182 std::unique_ptr<FecHeaderReader>(new FlexfecHeaderReader()),
184 std::unique_ptr<FecHeaderWriter>(new FlexfecHeaderWriter())) {} 183 std::unique_ptr<FecHeaderWriter>(new FlexfecHeaderWriter())) {}
185
186 // For FlexFEC we let the FEC packet sequence numbers be independent of
187 // the media packet sequence numbers.
188 static uint16_t GetFirstFecSeqNum(uint16_t next_media_seq_num) {
189 Random random(0xbe110);
190 return random.Rand<uint16_t>();
191 }
192 }; 184 };
193 185
194 class UlpfecForwardErrorCorrection : public ForwardErrorCorrection { 186 class UlpfecForwardErrorCorrection : public ForwardErrorCorrection {
195 public: 187 public:
196 static const uint32_t kFecSsrc = kMediaSsrc;
197
198 UlpfecForwardErrorCorrection() 188 UlpfecForwardErrorCorrection()
199 : ForwardErrorCorrection( 189 : ForwardErrorCorrection(
200 std::unique_ptr<FecHeaderReader>(new UlpfecHeaderReader()), 190 std::unique_ptr<FecHeaderReader>(new UlpfecHeaderReader()),
201 std::unique_ptr<FecHeaderWriter>(new UlpfecHeaderWriter())) {} 191 std::unique_ptr<FecHeaderWriter>(new UlpfecHeaderWriter())) {}
202
203 // For ULPFEC we assume that the FEC packets are subsequent to the media
204 // packets in terms of sequence number.
205 static uint16_t GetFirstFecSeqNum(uint16_t next_media_seq_num) {
206 return next_media_seq_num;
207 }
208 }; 192 };
209 193
210 using FecTypes = 194 using FecTypes =
211 Types<FlexfecForwardErrorCorrection, UlpfecForwardErrorCorrection>; 195 Types<FlexfecForwardErrorCorrection, UlpfecForwardErrorCorrection>;
212 TYPED_TEST_CASE(RtpFecTest, FecTypes); 196 TYPED_TEST_CASE(RtpFecTest, FecTypes);
213 197
214 TYPED_TEST(RtpFecTest, FecRecoveryNoLoss) { 198 TYPED_TEST(RtpFecTest, FecRecoveryNoLoss) {
215 constexpr int kNumImportantPackets = 0; 199 constexpr int kNumImportantPackets = 0;
216 constexpr bool kUseUnequalProtection = false; 200 constexpr bool kUseUnequalProtection = false;
217 constexpr int kNumMediaPackets = 4; 201 constexpr int kNumMediaPackets = 4;
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 352
369 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_, 353 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_,
370 &this->recovered_packets_)); 354 &this->recovered_packets_));
371 355
372 // Expect 3 media packets in recovered list, and complete recovery. 356 // Expect 3 media packets in recovered list, and complete recovery.
373 // Wrap-around won't remove FEC packet, as it follows the wrap. 357 // Wrap-around won't remove FEC packet, as it follows the wrap.
374 EXPECT_EQ(3u, this->recovered_packets_.size()); 358 EXPECT_EQ(3u, this->recovered_packets_.size());
375 EXPECT_TRUE(this->IsRecoveryComplete()); 359 EXPECT_TRUE(this->IsRecoveryComplete());
376 } 360 }
377 361
378 // Sequence number wrap occurs within the ULPFEC packets for the frame. 362 // Sequence number wrap occurs within the FEC packets for the frame.
379 // In this case we will discard ULPFEC packet and full recovery is not expected. 363 // In this case we will discard FEC packet and full recovery is not expected.
380 // Same problem will occur if wrap is within media packets but ULPFEC packet is 364 // Same problem will occur if wrap is within media packets but FEC packet is
381 // received before the media packets. This may be improved if timing information 365 // received before the media packets. This may be improved if timing information
382 // is used to detect old ULPFEC packets. 366 // is used to detect old FEC packets.
383 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding. 367 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding.
384 using RtpFecTestUlpfecOnly = RtpFecTest<UlpfecForwardErrorCorrection>; 368 TYPED_TEST(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) {
385 TEST_F(RtpFecTestUlpfecOnly, FecRecoveryWithSeqNumGapOneFrameNoRecovery) {
386 constexpr int kNumImportantPackets = 0; 369 constexpr int kNumImportantPackets = 0;
387 constexpr bool kUseUnequalProtection = false; 370 constexpr bool kUseUnequalProtection = false;
388 constexpr uint8_t kProtectionFactor = 200; 371 constexpr uint8_t kProtectionFactor = 200;
389 372
390 // 1 frame: 3 media packets and 2 FEC packets. 373 // 1 frame: 3 media packets and 2 FEC packets.
391 // Sequence number wrap in FEC packets. 374 // Sequence number wrap in FEC packets.
392 // -----Frame 1---- 375 // -----Frame 1----
393 // #65532(media) #65533(media) #65534(media) #65535(FEC) #0(FEC). 376 // #65532(media) #65533(media) #65534(media) #65535(FEC) #0(FEC).
394 this->media_packets_ = 377 this->media_packets_ =
395 this->media_packet_generator_.ConstructMediaPackets(3, 65532); 378 this->media_packet_generator_.ConstructMediaPackets(3, 65532);
(...skipping 12 matching lines...) Expand all
408 this->media_loss_mask_[1] = 1; 391 this->media_loss_mask_[1] = 1;
409 this->media_loss_mask_[2] = 1; 392 this->media_loss_mask_[2] = 1;
410 this->ReceivedPackets(this->media_packets_, this->media_loss_mask_, false); 393 this->ReceivedPackets(this->media_packets_, this->media_loss_mask_, false);
411 this->ReceivedPackets(this->generated_fec_packets_, this->fec_loss_mask_, 394 this->ReceivedPackets(this->generated_fec_packets_, this->fec_loss_mask_,
412 true); 395 true);
413 396
414 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_, 397 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_,
415 &this->recovered_packets_)); 398 &this->recovered_packets_));
416 399
417 // The two FEC packets are received and should allow for complete recovery, 400 // The two FEC packets are received and should allow for complete recovery,
418 // but because of the wrap the first FEC packet will be discarded, and only 401 // but because of the wrap the second FEC packet will be discarded, and only
419 // one media packet is recoverable. So expect 2 media packets on recovered 402 // one media packet is recoverable. So exepct 2 media packets on recovered
420 // list and no complete recovery.
421 EXPECT_EQ(2u, this->recovered_packets_.size());
422 EXPECT_TRUE(this->recovered_packets_.size() != this->media_packets_.size());
423 EXPECT_FALSE(this->IsRecoveryComplete());
424 }
425
426 // TODO(brandtr): This test mimics the one above, ensuring that the recovery
427 // strategy of FlexFEC matches the recovery strategy of ULPFEC. Since FlexFEC
428 // does not share the sequence number space with the media, however, having a
429 // matching recovery strategy may be suboptimal. Study this further.
430 using RtpFecTestFlexfecOnly = RtpFecTest<FlexfecForwardErrorCorrection>;
431 TEST_F(RtpFecTestFlexfecOnly, FecRecoveryWithSeqNumGapOneFrameNoRecovery) {
432 constexpr int kNumImportantPackets = 0;
433 constexpr bool kUseUnequalProtection = false;
434 constexpr uint8_t kProtectionFactor = 200;
435
436 // 1 frame: 3 media packets and 2 FEC packets.
437 // Sequence number wrap in FEC packets.
438 // -----Frame 1----
439 // #65532(media) #65533(media) #65534(media) #65535(FEC) #0(FEC).
440 this->media_packets_ =
441 this->media_packet_generator_.ConstructMediaPackets(3, 65532);
442
443 EXPECT_EQ(
444 0, this->fec_.EncodeFec(this->media_packets_, kProtectionFactor,
445 kNumImportantPackets, kUseUnequalProtection,
446 kFecMaskBursty, &this->generated_fec_packets_));
447
448 // Expect 2 FEC packets.
449 EXPECT_EQ(2u, this->generated_fec_packets_.size());
450
451 // Overwrite the sequence numbers generated by ConstructMediaPackets,
452 // to make sure that we do have a wrap.
453 auto it = this->generated_fec_packets_.begin();
454 ByteWriter<uint16_t>::WriteBigEndian(&(*it)->data[2], 65535);
455 ++it;
456 ByteWriter<uint16_t>::WriteBigEndian(&(*it)->data[2], 0);
457
458 // Lose the last two media packets (seq# 65533, 65534).
459 memset(this->media_loss_mask_, 0, sizeof(this->media_loss_mask_));
460 memset(this->fec_loss_mask_, 0, sizeof(this->fec_loss_mask_));
461 this->media_loss_mask_[1] = 1;
462 this->media_loss_mask_[2] = 1;
463 this->ReceivedPackets(this->media_packets_, this->media_loss_mask_, false);
464 this->ReceivedPackets(this->generated_fec_packets_, this->fec_loss_mask_,
465 true);
466
467 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_,
468 &this->recovered_packets_));
469
470 // The two FEC packets are received and should allow for complete recovery,
471 // but because of the wrap the first FEC packet will be discarded, and only
472 // one media packet is recoverable. So expect 2 media packets on recovered
473 // list and no complete recovery. 403 // list and no complete recovery.
474 EXPECT_EQ(2u, this->recovered_packets_.size()); 404 EXPECT_EQ(2u, this->recovered_packets_.size());
475 EXPECT_TRUE(this->recovered_packets_.size() != this->media_packets_.size()); 405 EXPECT_TRUE(this->recovered_packets_.size() != this->media_packets_.size());
476 EXPECT_FALSE(this->IsRecoveryComplete()); 406 EXPECT_FALSE(this->IsRecoveryComplete());
477 } 407 }
478 408
479 // Verify we can still recover frame if media packets are reordered. 409 // Verify we can still recover frame if media packets are reordered.
480 TYPED_TEST(RtpFecTest, FecRecoveryWithMediaOutOfOrder) { 410 TYPED_TEST(RtpFecTest, FecRecoveryWithMediaOutOfOrder) {
481 constexpr int kNumImportantPackets = 0; 411 constexpr int kNumImportantPackets = 0;
482 constexpr bool kUseUnequalProtection = false; 412 constexpr bool kUseUnequalProtection = false;
(...skipping 14 matching lines...) Expand all
497 EXPECT_EQ(1u, this->generated_fec_packets_.size()); 427 EXPECT_EQ(1u, this->generated_fec_packets_.size());
498 428
499 // Lose one media packet (seq# 1). 429 // Lose one media packet (seq# 1).
500 memset(this->media_loss_mask_, 0, sizeof(this->media_loss_mask_)); 430 memset(this->media_loss_mask_, 0, sizeof(this->media_loss_mask_));
501 memset(this->fec_loss_mask_, 0, sizeof(this->fec_loss_mask_)); 431 memset(this->fec_loss_mask_, 0, sizeof(this->fec_loss_mask_));
502 this->media_loss_mask_[1] = 1; 432 this->media_loss_mask_[1] = 1;
503 this->NetworkReceivedPackets(this->media_loss_mask_, this->fec_loss_mask_); 433 this->NetworkReceivedPackets(this->media_loss_mask_, this->fec_loss_mask_);
504 434
505 // Reorder received media packets. 435 // Reorder received media packets.
506 auto it0 = this->received_packets_.begin(); 436 auto it0 = this->received_packets_.begin();
507 auto it1 = this->received_packets_.begin(); 437 auto it2 = this->received_packets_.begin();
508 it1++; 438 it2++;
509 std::swap(*it0, *it1); 439 std::swap(*it0, *it2);
510 440
511 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_, 441 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_,
512 &this->recovered_packets_)); 442 &this->recovered_packets_));
513 443
514 // Expect 3 media packets in recovered list, and complete recovery. 444 // Expect 3 media packets in recovered list, and complete recovery.
515 EXPECT_EQ(3u, this->recovered_packets_.size()); 445 EXPECT_EQ(3u, this->recovered_packets_.size());
516 EXPECT_TRUE(this->IsRecoveryComplete()); 446 EXPECT_TRUE(this->IsRecoveryComplete());
517 } 447 }
518 448
519 // Verify we can still recover frame if FEC is received before media packets. 449 // Verify we can still recover frame if FEC is received before media packets.
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 this->media_loss_mask_[kNumMediaPackets - 1] = 1; 951 this->media_loss_mask_[kNumMediaPackets - 1] = 1;
1022 this->NetworkReceivedPackets(this->media_loss_mask_, this->fec_loss_mask_); 952 this->NetworkReceivedPackets(this->media_loss_mask_, this->fec_loss_mask_);
1023 953
1024 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_, 954 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_,
1025 &this->recovered_packets_)); 955 &this->recovered_packets_));
1026 956
1027 // 5 protected packets lost, one FEC packet, cannot get complete recovery. 957 // 5 protected packets lost, one FEC packet, cannot get complete recovery.
1028 EXPECT_FALSE(this->IsRecoveryComplete()); 958 EXPECT_FALSE(this->IsRecoveryComplete());
1029 } 959 }
1030 960
961 // 'using' directive needed for compiler to be happy.
962 using RtpFecTestWithFlexfec = RtpFecTest<FlexfecForwardErrorCorrection>;
963 TEST_F(RtpFecTestWithFlexfec,
964 FecRecoveryWithLossAndDifferentMediaAndFlexfecSsrcs) {
965 constexpr int kNumImportantPackets = 0;
966 constexpr bool kUseUnequalProtection = false;
967 constexpr int kNumMediaPackets = 4;
968 constexpr uint8_t kProtectionFactor = 60;
969
970 media_packets_ =
971 media_packet_generator_.ConstructMediaPackets(kNumMediaPackets);
972
973 EXPECT_EQ(0, fec_.EncodeFec(media_packets_, kProtectionFactor,
974 kNumImportantPackets, kUseUnequalProtection,
975 kFecMaskBursty, &generated_fec_packets_));
976
977 // Expect 1 FEC packet.
978 EXPECT_EQ(1u, generated_fec_packets_.size());
979
980 // 1 media packet lost
981 memset(media_loss_mask_, 0, sizeof(media_loss_mask_));
982 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_));
983 media_loss_mask_[3] = 1;
984 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_);
985
986 // Simulate FlexFEC packet received on different SSRC.
987 auto it = received_packets_.begin();
988 ++it;
989 ++it;
990 ++it; // Now at the FEC packet.
991 (*it)->ssrc = kFlexfecSsrc;
992
993 EXPECT_EQ(0, fec_.DecodeFec(&received_packets_, &recovered_packets_));
994
995 // One packet lost, one FEC packet, expect complete recovery.
996 EXPECT_TRUE(IsRecoveryComplete());
997 }
998
1031 } // namespace webrtc 999 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/forward_error_correction.cc ('k') | webrtc/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698