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 | 
| 11 #include <algorithm> | 11 #include <algorithm> | 
| 12 #include <list> | 12 #include <list> | 
| 13 #include <memory> | 13 #include <memory> | 
| 14 | 14 | 
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" | 
| 16 #include "webrtc/base/basictypes.h" | 16 #include "webrtc/base/basictypes.h" | 
| 17 #include "webrtc/base/random.h" | 17 #include "webrtc/base/random.h" | 
| 18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 
| 19 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h" | 19 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h" | 
| 20 #include "webrtc/modules/rtp_rtcp/source/flexfec_header_reader_writer.h" | |
| 20 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" | 21 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" | 
| 21 #include "webrtc/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h" | 22 #include "webrtc/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h" | 
| 22 | 23 | 
| 23 namespace webrtc { | 24 namespace webrtc { | 
| 24 | 25 | 
| 25 namespace { | 26 namespace { | 
| 26 | 27 | 
| 27 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. | 28 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. | 
| 28 constexpr size_t kTransportOverhead = 28; | 29 constexpr size_t kTransportOverhead = 28; | 
| 29 | 30 | 
| 30 constexpr uint32_t kMediaSsrc = 83542; | 31 constexpr uint32_t kMediaSsrc = 83542; | 
| 32 constexpr uint32_t kFlexfecSsrc = 43245; | |
| 31 | 33 | 
| 32 // Deep copies |src| to |dst|, but only keeps every Nth packet. | 34 // Deep copies |src| to |dst|, but only keeps every Nth packet. | 
| 33 void DeepCopyEveryNthPacket(const ForwardErrorCorrection::PacketList& src, | 35 void DeepCopyEveryNthPacket(const ForwardErrorCorrection::PacketList& src, | 
| 34 int n, | 36 int n, | 
| 35 ForwardErrorCorrection::PacketList* dst) { | 37 ForwardErrorCorrection::PacketList* dst) { | 
| 36 RTC_DCHECK_GT(n, 0); | 38 RTC_DCHECK_GT(n, 0); | 
| 37 int i = 0; | 39 int i = 0; | 
| 38 for (const auto& packet : src) { | 40 for (const auto& packet : src) { | 
| 39 if (i % n == 0) { | 41 if (i % n == 0) { | 
| 40 dst->emplace_back(new ForwardErrorCorrection::Packet(*packet)); | 42 dst->emplace_back(new ForwardErrorCorrection::Packet(*packet)); | 
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 146 bool RtpFecTest<ForwardErrorCorrectionType>::IsRecoveryComplete() { | 148 bool RtpFecTest<ForwardErrorCorrectionType>::IsRecoveryComplete() { | 
| 147 // We must have equally many recovered packets as original packets. | 149 // We must have equally many recovered packets as original packets. | 
| 148 if (recovered_packets_.size() != media_packets_.size()) { | 150 if (recovered_packets_.size() != media_packets_.size()) { | 
| 149 return false; | 151 return false; | 
| 150 } | 152 } | 
| 151 | 153 | 
| 152 // All recovered packets must be identical to the corresponding | 154 // All recovered packets must be identical to the corresponding | 
| 153 // original packets. | 155 // original packets. | 
| 154 using PacketPtr = std::unique_ptr<ForwardErrorCorrection::Packet>; | 156 using PacketPtr = std::unique_ptr<ForwardErrorCorrection::Packet>; | 
| 155 using RecoveredPacketPtr = | 157 using RecoveredPacketPtr = | 
| 156 std::unique_ptr<ForwardErrorCorrection::RecoveredPacket>; | 158 std::unique_ptr<ForwardErrorCorrection::RecoveredPacket>; | 
| 
 
stefan-webrtc
2016/09/28 07:53:29
nit: Not sure I see the value of using here. You o
 
brandtr
2016/09/28 09:11:32
Yep, no huge value. Removed.
 
 | |
| 157 auto cmp = [](const PacketPtr& media_packet, | 159 auto cmp = [](const PacketPtr& media_packet, | 
| 158 const RecoveredPacketPtr& recovered_packet) { | 160 const RecoveredPacketPtr& recovered_packet) { | 
| 159 if (media_packet->length != recovered_packet->pkt->length) { | 161 if (media_packet->length != recovered_packet->pkt->length) { | 
| 160 return false; | 162 return false; | 
| 161 } | 163 } | 
| 162 if (memcmp(media_packet->data, | 164 if (memcmp(media_packet->data, recovered_packet->pkt->data, | 
| 163 recovered_packet->pkt->data, | |
| 164 media_packet->length) != 0) { | 165 media_packet->length) != 0) { | 
| 165 return false; | 166 return false; | 
| 166 } | 167 } | 
| 167 return true; | 168 return true; | 
| 168 }; | 169 }; | 
| 169 return std::equal(media_packets_.cbegin(), media_packets_.cend(), | 170 return std::equal(media_packets_.cbegin(), media_packets_.cend(), | 
| 170 recovered_packets_.cbegin(), cmp); | 171 recovered_packets_.cbegin(), cmp); | 
| 171 } | 172 } | 
| 172 | 173 | 
| 173 // Define gTest typed test to loop over both ULPFEC and FlexFEC. | 174 // Define gTest typed test to loop over both ULPFEC and FlexFEC. | 
| 174 // Since the tests now are parameterized, we need to access | 175 // Since the tests now are parameterized, we need to access | 
| 175 // member variables using |this|, thereby enforcing runtime | 176 // member variables using |this|, thereby enforcing runtime | 
| 176 // resolution. | 177 // resolution. | 
| 177 | 178 | 
| 179 class FlexfecForwardErrorCorrection : public ForwardErrorCorrection { | |
| 180 public: | |
| 181 FlexfecForwardErrorCorrection() | |
| 182 : ForwardErrorCorrection( | |
| 183 std::unique_ptr<FecHeaderReader>(new FlexfecHeaderReader()), | |
| 184 std::unique_ptr<FecHeaderWriter>(new FlexfecHeaderWriter())) {} | |
| 185 }; | |
| 186 | |
| 178 class UlpfecForwardErrorCorrection : public ForwardErrorCorrection { | 187 class UlpfecForwardErrorCorrection : public ForwardErrorCorrection { | 
| 179 public: | 188 public: | 
| 180 UlpfecForwardErrorCorrection() | 189 UlpfecForwardErrorCorrection() | 
| 181 : ForwardErrorCorrection( | 190 : ForwardErrorCorrection( | 
| 182 std::unique_ptr<FecHeaderReader>(new UlpfecHeaderReader()), | 191 std::unique_ptr<FecHeaderReader>(new UlpfecHeaderReader()), | 
| 183 std::unique_ptr<FecHeaderWriter>(new UlpfecHeaderWriter())) {} | 192 std::unique_ptr<FecHeaderWriter>(new UlpfecHeaderWriter())) {} | 
| 184 }; | 193 }; | 
| 185 | 194 | 
| 186 using FecTypes = Types<UlpfecForwardErrorCorrection>; | 195 using FecTypes = | 
| 196 Types<FlexfecForwardErrorCorrection, UlpfecForwardErrorCorrection>; | |
| 187 TYPED_TEST_CASE(RtpFecTest, FecTypes); | 197 TYPED_TEST_CASE(RtpFecTest, FecTypes); | 
| 188 | 198 | 
| 189 TYPED_TEST(RtpFecTest, FecRecoveryNoLoss) { | 199 TYPED_TEST(RtpFecTest, FecRecoveryNoLoss) { | 
| 190 constexpr int kNumImportantPackets = 0; | 200 constexpr int kNumImportantPackets = 0; | 
| 191 constexpr bool kUseUnequalProtection = false; | 201 constexpr bool kUseUnequalProtection = false; | 
| 192 constexpr int kNumMediaPackets = 4; | 202 constexpr int kNumMediaPackets = 4; | 
| 193 constexpr uint8_t kProtectionFactor = 60; | 203 constexpr uint8_t kProtectionFactor = 60; | 
| 194 | 204 | 
| 195 this->media_packets_ = | 205 this->media_packets_ = | 
| 196 this->media_packet_generator_.ConstructMediaPackets(kNumMediaPackets); | 206 this->media_packet_generator_.ConstructMediaPackets(kNumMediaPackets); | 
| (...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 this->media_loss_mask_[kNumMediaPackets - 1] = 1; | 952 this->media_loss_mask_[kNumMediaPackets - 1] = 1; | 
| 943 this->NetworkReceivedPackets(this->media_loss_mask_, this->fec_loss_mask_); | 953 this->NetworkReceivedPackets(this->media_loss_mask_, this->fec_loss_mask_); | 
| 944 | 954 | 
| 945 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_, | 955 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_, | 
| 946 &this->recovered_packets_)); | 956 &this->recovered_packets_)); | 
| 947 | 957 | 
| 948 // 5 protected packets lost, one FEC packet, cannot get complete recovery. | 958 // 5 protected packets lost, one FEC packet, cannot get complete recovery. | 
| 949 EXPECT_FALSE(this->IsRecoveryComplete()); | 959 EXPECT_FALSE(this->IsRecoveryComplete()); | 
| 950 } | 960 } | 
| 951 | 961 | 
| 962 // 'using' directive needed for compiler to be happy. | |
| 963 using RtpFecTestWithFlexfec = RtpFecTest<FlexfecForwardErrorCorrection>; | |
| 964 TEST_F(RtpFecTestWithFlexfec, | |
| 965 FecRecoveryWithLossAndDifferentMediaAndFlexfecSsrcs) { | |
| 966 constexpr int kNumImportantPackets = 0; | |
| 967 constexpr bool kUseUnequalProtection = false; | |
| 968 constexpr int kNumMediaPackets = 4; | |
| 969 constexpr uint8_t kProtectionFactor = 60; | |
| 970 | |
| 971 media_packets_ = | |
| 972 media_packet_generator_.ConstructMediaPackets(kNumMediaPackets); | |
| 973 | |
| 974 EXPECT_EQ(0, fec_.EncodeFec(media_packets_, kProtectionFactor, | |
| 975 kNumImportantPackets, kUseUnequalProtection, | |
| 976 kFecMaskBursty, &generated_fec_packets_)); | |
| 977 | |
| 978 // Expect 1 FEC packet. | |
| 979 EXPECT_EQ(1u, generated_fec_packets_.size()); | |
| 980 | |
| 981 // 1 media packet lost | |
| 982 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | |
| 983 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | |
| 984 media_loss_mask_[3] = 1; | |
| 985 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); | |
| 986 | |
| 987 // Simulate FlexFEC packet received on different SSRC. | |
| 988 auto it = received_packets_.begin(); | |
| 989 it++; | |
| 
 
stefan-webrtc
2016/09/28 07:53:29
++it
 
brandtr
2016/09/28 09:11:32
Done.
 
 | |
| 990 it++; | |
| 991 it++; // Now at the FEC packet. | |
| 992 (*it)->ssrc = kFlexfecSsrc; | |
| 993 | |
| 994 EXPECT_EQ(0, fec_.DecodeFec(&received_packets_, &recovered_packets_)); | |
| 995 | |
| 996 // One packet lost, one FEC packet, expect complete recovery. | |
| 997 EXPECT_TRUE(IsRecoveryComplete()); | |
| 998 } | |
| 999 | |
| 952 } // namespace webrtc | 1000 } // namespace webrtc | 
| OLD | NEW |