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 27 matching lines...) Expand all Loading... | |
38 using Packet = ::webrtc::ForwardErrorCorrection::Packet; | 38 using Packet = ::webrtc::ForwardErrorCorrection::Packet; |
39 using ::webrtc::test::fec::UlpfecPacketGenerator; | 39 using ::webrtc::test::fec::UlpfecPacketGenerator; |
40 | 40 |
41 class ReceiverFecTest : public ::testing::Test { | 41 class ReceiverFecTest : public ::testing::Test { |
42 protected: | 42 protected: |
43 ReceiverFecTest() | 43 ReceiverFecTest() |
44 : fec_(ForwardErrorCorrection::CreateUlpfec()), | 44 : fec_(ForwardErrorCorrection::CreateUlpfec()), |
45 receiver_fec_(FecReceiver::Create(&rtp_data_callback_)), | 45 receiver_fec_(FecReceiver::Create(&rtp_data_callback_)), |
46 packet_generator_(kMediaSsrc) {} | 46 packet_generator_(kMediaSsrc) {} |
47 | 47 |
48 // Generates |num_fec_packets| FEC packets, given |media_packets|. | |
48 void EncodeFec(const ForwardErrorCorrection::PacketList& media_packets, | 49 void EncodeFec(const ForwardErrorCorrection::PacketList& media_packets, |
49 size_t num_fec_packets, | 50 size_t num_fec_packets, |
50 std::list<ForwardErrorCorrection::Packet*>* fec_packets) { | 51 std::list<ForwardErrorCorrection::Packet*>* fec_packets); |
51 uint8_t protection_factor = num_fec_packets * 255 / media_packets.size(); | |
52 constexpr int kNumImportantPackets = | |
53 0; // Irrelevant, since unequal protection is turned off. | |
54 constexpr bool kUseUnequalProtection = false; | |
55 constexpr FecMaskType kFecMaskType = kFecMaskBursty; | |
56 EXPECT_EQ(0, fec_->EncodeFec(media_packets, protection_factor, | |
57 kNumImportantPackets, kUseUnequalProtection, | |
58 kFecMaskType, fec_packets)); | |
59 ASSERT_EQ(num_fec_packets, fec_packets->size()); | |
60 } | |
61 | 52 |
62 void GenerateFrame(size_t num_media_packets, | 53 // Generates |num_media_packets| corresponding to a single frame. |
63 size_t frame_offset, | 54 void PacketizeFrame(size_t num_media_packets, |
64 std::list<AugmentedPacket*>* augmented_packets, | 55 size_t frame_offset, |
65 ForwardErrorCorrection::PacketList* media_packets) { | 56 std::list<AugmentedPacket*>* augmented_packets, |
66 packet_generator_.NewFrame(num_media_packets); | 57 ForwardErrorCorrection::PacketList* packets); |
67 for (size_t i = 0; i < num_media_packets; ++i) { | |
68 std::unique_ptr<AugmentedPacket> next_packet( | |
69 packet_generator_.NextPacket(frame_offset + i, kRtpHeaderSize + 10)); | |
70 augmented_packets->push_back(next_packet.get()); | |
71 media_packets->push_back(std::move(next_packet)); | |
72 } | |
73 } | |
74 | 58 |
59 // Build a media packet using |packet_generator_| and add it | |
60 // to the receiver. | |
61 void BuildAndAddRedMediaPacket(AugmentedPacket* packet); | |
62 | |
63 // Build a FEC packet using |packet_generator_| and add it | |
64 // to the receiver. | |
65 void BuildAndAddRedFecPacket(Packet* packet); | |
66 | |
67 // Ensure that |rtp_data_callback_| will be called correctly | |
68 // and that the recovered packet will be identical to the lost packet. | |
75 void VerifyReconstructedMediaPacket(const AugmentedPacket* packet, | 69 void VerifyReconstructedMediaPacket(const AugmentedPacket* packet, |
76 size_t times) { | 70 size_t times); |
77 // Verify that the content of the reconstructed packet is equal to the | |
78 // content of |packet|, and that the same content is received |times| number | |
79 // of times in a row. | |
80 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet->length)) | |
81 .With(Args<0, 1>(ElementsAreArray(packet->data, | |
82 packet->length))) | |
83 .Times(times).WillRepeatedly(Return(true)); | |
84 } | |
85 | |
86 void BuildAndAddRedMediaPacket(AugmentedPacket* packet) { | |
87 std::unique_ptr<AugmentedPacket> red_packet( | |
88 packet_generator_.BuildMediaRedPacket(*packet)); | |
89 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( | |
90 red_packet->header.header, red_packet->data, | |
91 red_packet->length, kFecPayloadType)); | |
92 } | |
93 | |
94 void BuildAndAddRedFecPacket(Packet* packet) { | |
95 std::unique_ptr<AugmentedPacket> red_packet( | |
96 packet_generator_.BuildUlpfecRedPacket(*packet)); | |
97 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( | |
98 red_packet->header.header, red_packet->data, | |
99 red_packet->length, kFecPayloadType)); | |
100 } | |
101 | 71 |
102 void InjectGarbagePacketLength(size_t fec_garbage_offset); | 72 void InjectGarbagePacketLength(size_t fec_garbage_offset); |
73 | |
103 static void SurvivesMaliciousPacket(const uint8_t* data, | 74 static void SurvivesMaliciousPacket(const uint8_t* data, |
104 size_t length, | 75 size_t length, |
105 uint8_t ulpfec_payload_type); | 76 uint8_t ulpfec_payload_type); |
106 | 77 |
107 MockRtpData rtp_data_callback_; | 78 MockRtpData rtp_data_callback_; |
108 std::unique_ptr<ForwardErrorCorrection> fec_; | 79 std::unique_ptr<ForwardErrorCorrection> fec_; |
109 std::unique_ptr<FecReceiver> receiver_fec_; | 80 std::unique_ptr<FecReceiver> receiver_fec_; |
110 UlpfecPacketGenerator packet_generator_; | 81 UlpfecPacketGenerator packet_generator_; |
111 }; | 82 }; |
112 | 83 |
113 TEST_F(ReceiverFecTest, TwoMediaOneFec) { | 84 void ReceiverFecTest::EncodeFec( |
114 constexpr size_t kNumFecPackets = 1u; | 85 const ForwardErrorCorrection::PacketList& media_packets, |
115 std::list<AugmentedPacket*> augmented_media_packets; | 86 size_t num_fec_packets, |
116 ForwardErrorCorrection::PacketList media_packets; | 87 std::list<ForwardErrorCorrection::Packet*>* fec_packets) { |
117 GenerateFrame(2, 0, &augmented_media_packets, &media_packets); | 88 const uint8_t protection_factor = |
118 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 89 num_fec_packets * 255 / media_packets.size(); |
119 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 90 constexpr int kNumImportantPackets = |
91 0; // Irrelevant, since unequal protection is turned off. | |
philipel
2016/09/05 13:55:58
Move comment to its own line.
brandtr
2016/09/05 14:38:48
Done.
| |
92 constexpr bool kUseUnequalProtection = false; | |
93 constexpr FecMaskType kFecMaskType = kFecMaskBursty; | |
94 EXPECT_EQ( | |
95 0, fec_->EncodeFec(media_packets, protection_factor, kNumImportantPackets, | |
96 kUseUnequalProtection, kFecMaskType, fec_packets)); | |
97 ASSERT_EQ(num_fec_packets, fec_packets->size()); | |
98 } | |
120 | 99 |
121 // Recovery | 100 void ReceiverFecTest::PacketizeFrame( |
122 auto it = augmented_media_packets.begin(); | 101 size_t num_media_packets, |
123 BuildAndAddRedMediaPacket(*it); | 102 size_t frame_offset, |
124 VerifyReconstructedMediaPacket(*it, 1); | 103 std::list<AugmentedPacket*>* augmented_packets, |
125 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 104 ForwardErrorCorrection::PacketList* packets) { |
126 // Drop one media packet. | 105 packet_generator_.NewFrame(num_media_packets); |
127 auto fec_it = fec_packets.begin(); | 106 for (size_t i = 0; i < num_media_packets; ++i) { |
128 BuildAndAddRedFecPacket(*fec_it); | 107 std::unique_ptr<AugmentedPacket> next_packet( |
129 ++it; | 108 packet_generator_.NextPacket(frame_offset + i, kRtpHeaderSize + 10)); |
130 VerifyReconstructedMediaPacket(*it, 1); | 109 augmented_packets->push_back(next_packet.get()); |
131 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 110 packets->push_back(std::move(next_packet)); |
111 } | |
112 } | |
132 | 113 |
133 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); | 114 void ReceiverFecTest::BuildAndAddRedMediaPacket(AugmentedPacket* packet) { |
134 EXPECT_EQ(2u, counter.num_packets); | 115 std::unique_ptr<AugmentedPacket> red_packet( |
135 EXPECT_EQ(1u, counter.num_fec_packets); | 116 packet_generator_.BuildMediaRedPacket(*packet)); |
136 EXPECT_EQ(1u, counter.num_recovered_packets); | 117 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( |
118 red_packet->header.header, red_packet->data, | |
119 red_packet->length, kFecPayloadType)); | |
120 } | |
121 | |
122 void ReceiverFecTest::BuildAndAddRedFecPacket(Packet* packet) { | |
123 std::unique_ptr<AugmentedPacket> red_packet( | |
124 packet_generator_.BuildUlpfecRedPacket(*packet)); | |
125 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( | |
126 red_packet->header.header, red_packet->data, | |
127 red_packet->length, kFecPayloadType)); | |
128 } | |
129 | |
130 void ReceiverFecTest::VerifyReconstructedMediaPacket( | |
131 const AugmentedPacket* packet, | |
132 size_t times) { | |
133 // Verify that the content of the reconstructed packet is equal to the | |
134 // content of |packet|, and that the same content is received |times| number | |
135 // of times in a row. | |
136 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet->length)) | |
137 .With(Args<0, 1>(ElementsAreArray(packet->data, packet->length))) | |
138 .Times(times) | |
139 .WillRepeatedly(Return(true)); | |
137 } | 140 } |
138 | 141 |
139 void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { | 142 void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { |
140 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 143 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
141 .WillRepeatedly(Return(true)); | 144 .WillRepeatedly(Return(true)); |
142 | 145 |
143 constexpr size_t kNumFecPackets = 1u; | 146 constexpr size_t kNumFecPackets = 1u; |
144 std::list<AugmentedPacket*> augmented_media_packets; | 147 std::list<AugmentedPacket*> augmented_media_packets; |
145 ForwardErrorCorrection::PacketList media_packets; | 148 ForwardErrorCorrection::PacketList media_packets; |
146 GenerateFrame(2, 0, &augmented_media_packets, &media_packets); | 149 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); |
147 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 150 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
148 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 151 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
149 ByteWriter<uint16_t>::WriteBigEndian( | 152 ByteWriter<uint16_t>::WriteBigEndian( |
150 &fec_packets.front()->data[fec_garbage_offset], 0x4711); | 153 &fec_packets.front()->data[fec_garbage_offset], 0x4711); |
151 | 154 |
152 // Inject first media packet, then first FEC packet, skipping the second media | 155 // Inject first media packet, then first FEC packet, skipping the second media |
153 // packet to cause a recovery from the FEC packet. | 156 // packet to cause a recovery from the FEC packet. |
154 BuildAndAddRedMediaPacket(augmented_media_packets.front()); | 157 BuildAndAddRedMediaPacket(augmented_media_packets.front()); |
155 BuildAndAddRedFecPacket(fec_packets.front()); | 158 BuildAndAddRedFecPacket(fec_packets.front()); |
156 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 159 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
157 | 160 |
158 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); | 161 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); |
159 EXPECT_EQ(2u, counter.num_packets); | 162 EXPECT_EQ(2u, counter.num_packets); |
160 EXPECT_EQ(1u, counter.num_fec_packets); | 163 EXPECT_EQ(1u, counter.num_fec_packets); |
161 EXPECT_EQ(0u, counter.num_recovered_packets); | 164 EXPECT_EQ(0u, counter.num_recovered_packets); |
162 } | 165 } |
163 | 166 |
167 void ReceiverFecTest::SurvivesMaliciousPacket(const uint8_t* data, | |
168 size_t length, | |
169 uint8_t ulpfec_payload_type) { | |
170 webrtc::RTPHeader header; | |
171 std::unique_ptr<webrtc::RtpHeaderParser> parser( | |
172 webrtc::RtpHeaderParser::Create()); | |
173 ASSERT_TRUE(parser->Parse(data, length, &header)); | |
174 | |
175 webrtc::NullRtpData null_callback; | |
176 std::unique_ptr<webrtc::FecReceiver> receiver_fec( | |
177 webrtc::FecReceiver::Create(&null_callback)); | |
178 | |
179 receiver_fec->AddReceivedRedPacket(header, data, length, ulpfec_payload_type); | |
180 } | |
181 | |
182 TEST_F(ReceiverFecTest, TwoMediaOneFec) { | |
183 constexpr size_t kNumFecPackets = 1u; | |
184 std::list<AugmentedPacket*> augmented_media_packets; | |
185 ForwardErrorCorrection::PacketList media_packets; | |
186 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); | |
187 std::list<ForwardErrorCorrection::Packet*> fec_packets; | |
188 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | |
189 | |
190 // Recovery | |
191 auto it = augmented_media_packets.begin(); | |
192 BuildAndAddRedMediaPacket(*it); | |
193 VerifyReconstructedMediaPacket(*it, 1); | |
194 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | |
195 // Drop one media packet. | |
196 auto fec_it = fec_packets.begin(); | |
197 BuildAndAddRedFecPacket(*fec_it); | |
198 ++it; | |
199 VerifyReconstructedMediaPacket(*it, 1); | |
200 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | |
201 | |
202 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); | |
203 EXPECT_EQ(2u, counter.num_packets); | |
204 EXPECT_EQ(1u, counter.num_fec_packets); | |
205 EXPECT_EQ(1u, counter.num_recovered_packets); | |
206 } | |
207 | |
164 TEST_F(ReceiverFecTest, InjectGarbageFecHeaderLengthRecovery) { | 208 TEST_F(ReceiverFecTest, InjectGarbageFecHeaderLengthRecovery) { |
165 // Byte offset 8 is the 'length recovery' field of the FEC header. | 209 // Byte offset 8 is the 'length recovery' field of the FEC header. |
166 InjectGarbagePacketLength(8); | 210 InjectGarbagePacketLength(8); |
167 } | 211 } |
168 | 212 |
169 TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) { | 213 TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) { |
170 // Byte offset 10 is the 'protection length' field in the first FEC level | 214 // Byte offset 10 is the 'protection length' field in the first FEC level |
171 // header. | 215 // header. |
172 InjectGarbagePacketLength(10); | 216 InjectGarbagePacketLength(10); |
173 } | 217 } |
174 | 218 |
175 TEST_F(ReceiverFecTest, TwoMediaTwoFec) { | 219 TEST_F(ReceiverFecTest, TwoMediaTwoFec) { |
176 constexpr size_t kNumFecPackets = 2u; | 220 constexpr size_t kNumFecPackets = 2u; |
177 std::list<AugmentedPacket*> augmented_media_packets; | 221 std::list<AugmentedPacket*> augmented_media_packets; |
178 ForwardErrorCorrection::PacketList media_packets; | 222 ForwardErrorCorrection::PacketList media_packets; |
179 GenerateFrame(2, 0, &augmented_media_packets, &media_packets); | 223 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); |
180 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 224 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
181 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 225 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
182 | 226 |
183 // Recovery | 227 // Recovery |
184 // Drop both media packets. | 228 // Drop both media packets. |
185 auto it = augmented_media_packets.begin(); | 229 auto it = augmented_media_packets.begin(); |
186 auto fec_it = fec_packets.begin(); | 230 auto fec_it = fec_packets.begin(); |
187 BuildAndAddRedFecPacket(*fec_it); | 231 BuildAndAddRedFecPacket(*fec_it); |
188 VerifyReconstructedMediaPacket(*it, 1); | 232 VerifyReconstructedMediaPacket(*it, 1); |
189 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 233 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
190 ++fec_it; | 234 ++fec_it; |
191 BuildAndAddRedFecPacket(*fec_it); | 235 BuildAndAddRedFecPacket(*fec_it); |
192 ++it; | 236 ++it; |
193 VerifyReconstructedMediaPacket(*it, 1); | 237 VerifyReconstructedMediaPacket(*it, 1); |
194 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 238 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
195 } | 239 } |
196 | 240 |
197 TEST_F(ReceiverFecTest, TwoFramesOneFec) { | 241 TEST_F(ReceiverFecTest, TwoFramesOneFec) { |
198 constexpr size_t kNumFecPackets = 1u; | 242 constexpr size_t kNumFecPackets = 1u; |
199 std::list<AugmentedPacket*> augmented_media_packets; | 243 std::list<AugmentedPacket*> augmented_media_packets; |
200 ForwardErrorCorrection::PacketList media_packets; | 244 ForwardErrorCorrection::PacketList media_packets; |
201 GenerateFrame(1, 0, &augmented_media_packets, &media_packets); | 245 PacketizeFrame(1, 0, &augmented_media_packets, &media_packets); |
202 GenerateFrame(1, 1, &augmented_media_packets, &media_packets); | 246 PacketizeFrame(1, 1, &augmented_media_packets, &media_packets); |
203 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 247 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
204 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 248 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
205 | 249 |
206 // Recovery | 250 // Recovery |
207 auto it = augmented_media_packets.begin(); | 251 auto it = augmented_media_packets.begin(); |
208 BuildAndAddRedMediaPacket(augmented_media_packets.front()); | 252 BuildAndAddRedMediaPacket(augmented_media_packets.front()); |
209 VerifyReconstructedMediaPacket(*it, 1); | 253 VerifyReconstructedMediaPacket(*it, 1); |
210 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 254 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
211 // Drop one media packet. | 255 // Drop one media packet. |
212 BuildAndAddRedFecPacket(fec_packets.front()); | 256 BuildAndAddRedFecPacket(fec_packets.front()); |
213 ++it; | 257 ++it; |
214 VerifyReconstructedMediaPacket(*it, 1); | 258 VerifyReconstructedMediaPacket(*it, 1); |
215 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 259 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
216 } | 260 } |
217 | 261 |
218 TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) { | 262 TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) { |
219 constexpr size_t kNumFecPackets = 1u; | 263 constexpr size_t kNumFecPackets = 1u; |
220 std::list<AugmentedPacket*> augmented_media_packets; | 264 std::list<AugmentedPacket*> augmented_media_packets; |
221 ForwardErrorCorrection::PacketList media_packets; | 265 ForwardErrorCorrection::PacketList media_packets; |
222 GenerateFrame(1, 0, &augmented_media_packets, &media_packets); | 266 PacketizeFrame(1, 0, &augmented_media_packets, &media_packets); |
223 GenerateFrame(2, 1, &augmented_media_packets, &media_packets); | 267 PacketizeFrame(2, 1, &augmented_media_packets, &media_packets); |
224 | 268 |
225 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 269 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
226 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 270 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
227 | 271 |
228 // Recovery | 272 // Recovery |
229 auto it = augmented_media_packets.begin(); | 273 auto it = augmented_media_packets.begin(); |
230 BuildAndAddRedMediaPacket(*it); // First frame: one packet. | 274 BuildAndAddRedMediaPacket(*it); // First frame: one packet. |
231 VerifyReconstructedMediaPacket(*it, 1); | 275 VerifyReconstructedMediaPacket(*it, 1); |
232 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 276 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
233 ++it; | 277 ++it; |
234 BuildAndAddRedMediaPacket(*it); // First packet of second frame. | 278 BuildAndAddRedMediaPacket(*it); // First packet of second frame. |
235 VerifyReconstructedMediaPacket(*it, 1); | 279 VerifyReconstructedMediaPacket(*it, 1); |
236 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 280 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
237 } | 281 } |
238 | 282 |
239 TEST_F(ReceiverFecTest, MaxFramesOneFec) { | 283 TEST_F(ReceiverFecTest, MaxFramesOneFec) { |
240 constexpr size_t kNumFecPackets = 1u; | 284 constexpr size_t kNumFecPackets = 1u; |
241 constexpr size_t kNumMediaPackets = 48u; | 285 constexpr size_t kNumMediaPackets = 48u; |
242 std::list<AugmentedPacket*> augmented_media_packets; | 286 std::list<AugmentedPacket*> augmented_media_packets; |
243 ForwardErrorCorrection::PacketList media_packets; | 287 ForwardErrorCorrection::PacketList media_packets; |
244 for (size_t i = 0; i < kNumMediaPackets; ++i) { | 288 for (size_t i = 0; i < kNumMediaPackets; ++i) { |
245 GenerateFrame(1, i, &augmented_media_packets, &media_packets); | 289 PacketizeFrame(1, i, &augmented_media_packets, &media_packets); |
246 } | 290 } |
247 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 291 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
248 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 292 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
249 | 293 |
250 // Recovery | 294 // Recovery |
251 auto it = augmented_media_packets.begin(); | 295 auto it = augmented_media_packets.begin(); |
252 ++it; // Drop first packet. | 296 ++it; // Drop first packet. |
253 for (; it != augmented_media_packets.end(); ++it) { | 297 for (; it != augmented_media_packets.end(); ++it) { |
254 BuildAndAddRedMediaPacket(*it); | 298 BuildAndAddRedMediaPacket(*it); |
255 VerifyReconstructedMediaPacket(*it, 1); | 299 VerifyReconstructedMediaPacket(*it, 1); |
256 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 300 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
257 } | 301 } |
258 BuildAndAddRedFecPacket(fec_packets.front()); | 302 BuildAndAddRedFecPacket(fec_packets.front()); |
259 it = augmented_media_packets.begin(); | 303 it = augmented_media_packets.begin(); |
260 VerifyReconstructedMediaPacket(*it, 1); | 304 VerifyReconstructedMediaPacket(*it, 1); |
261 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 305 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
262 } | 306 } |
263 | 307 |
264 TEST_F(ReceiverFecTest, TooManyFrames) { | 308 TEST_F(ReceiverFecTest, TooManyFrames) { |
265 constexpr size_t kNumFecPackets = 1u; | 309 constexpr size_t kNumFecPackets = 1u; |
266 constexpr size_t kNumMediaPackets = 49u; | 310 constexpr size_t kNumMediaPackets = 49u; |
267 std::list<AugmentedPacket*> augmented_media_packets; | 311 std::list<AugmentedPacket*> augmented_media_packets; |
268 ForwardErrorCorrection::PacketList media_packets; | 312 ForwardErrorCorrection::PacketList media_packets; |
269 for (size_t i = 0; i < kNumMediaPackets; ++i) { | 313 for (size_t i = 0; i < kNumMediaPackets; ++i) { |
270 GenerateFrame(1, i, &augmented_media_packets, &media_packets); | 314 PacketizeFrame(1, i, &augmented_media_packets, &media_packets); |
271 } | 315 } |
272 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 316 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
273 EXPECT_EQ(-1, fec_->EncodeFec(media_packets, | 317 EXPECT_EQ(-1, fec_->EncodeFec(media_packets, |
274 kNumFecPackets * 255 / kNumMediaPackets, 0, | 318 kNumFecPackets * 255 / kNumMediaPackets, 0, |
275 false, kFecMaskBursty, &fec_packets)); | 319 false, kFecMaskBursty, &fec_packets)); |
276 } | 320 } |
277 | 321 |
278 TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { | 322 TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { |
279 // 1 frame with 2 media packets and one FEC packet. One media packet missing. | 323 // 1 frame with 2 media packets and one FEC packet. One media packet missing. |
280 // Delay the FEC packet. | 324 // Delay the FEC packet. |
281 Packet* delayed_fec = NULL; | 325 Packet* delayed_fec = NULL; |
282 constexpr size_t kNumFecPacketsBatch1 = 1u; | 326 constexpr size_t kNumFecPacketsBatch1 = 1u; |
283 constexpr size_t kNumMediaPacketsBatch1 = 2u; | 327 constexpr size_t kNumMediaPacketsBatch1 = 2u; |
284 std::list<AugmentedPacket*> augmented_media_packets_batch1; | 328 std::list<AugmentedPacket*> augmented_media_packets_batch1; |
285 ForwardErrorCorrection::PacketList media_packets_batch1; | 329 ForwardErrorCorrection::PacketList media_packets_batch1; |
286 GenerateFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, | 330 PacketizeFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, |
287 &media_packets_batch1); | 331 &media_packets_batch1); |
288 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 332 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
289 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); | 333 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); |
290 | 334 |
291 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); | 335 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); |
292 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 336 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
293 .Times(1).WillRepeatedly(Return(true)); | 337 .Times(1).WillRepeatedly(Return(true)); |
294 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 338 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
295 delayed_fec = fec_packets.front(); | 339 delayed_fec = fec_packets.front(); |
296 | 340 |
297 // Fill the FEC decoder. No packets should be dropped. | 341 // Fill the FEC decoder. No packets should be dropped. |
298 constexpr size_t kNumMediaPacketsBatch2 = 46u; | 342 constexpr size_t kNumMediaPacketsBatch2 = 46u; |
299 std::list<AugmentedPacket*> augmented_media_packets_batch2; | 343 std::list<AugmentedPacket*> augmented_media_packets_batch2; |
300 ForwardErrorCorrection::PacketList media_packets_batch2; | 344 ForwardErrorCorrection::PacketList media_packets_batch2; |
301 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { | 345 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { |
302 GenerateFrame(1, i, &augmented_media_packets_batch2, &media_packets_batch2); | 346 PacketizeFrame(1, i, &augmented_media_packets_batch2, |
347 &media_packets_batch2); | |
303 } | 348 } |
304 for (auto it = augmented_media_packets_batch2.begin(); | 349 for (auto it = augmented_media_packets_batch2.begin(); |
305 it != augmented_media_packets_batch2.end(); ++it) { | 350 it != augmented_media_packets_batch2.end(); ++it) { |
306 BuildAndAddRedMediaPacket(*it); | 351 BuildAndAddRedMediaPacket(*it); |
307 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 352 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
308 .Times(1).WillRepeatedly(Return(true)); | 353 .Times(1).WillRepeatedly(Return(true)); |
309 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 354 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
310 } | 355 } |
311 | 356 |
312 // Add the delayed FEC packet. One packet should be reconstructed. | 357 // Add the delayed FEC packet. One packet should be reconstructed. |
313 BuildAndAddRedFecPacket(delayed_fec); | 358 BuildAndAddRedFecPacket(delayed_fec); |
314 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 359 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
315 .Times(1).WillRepeatedly(Return(true)); | 360 .Times(1).WillRepeatedly(Return(true)); |
316 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 361 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
317 } | 362 } |
318 | 363 |
319 TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { | 364 TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { |
320 // 1 frame with 2 media packets and one FEC packet. One media packet missing. | 365 // 1 frame with 2 media packets and one FEC packet. One media packet missing. |
321 // Delay the FEC packet. | 366 // Delay the FEC packet. |
322 Packet* delayed_fec = nullptr; | 367 Packet* delayed_fec = nullptr; |
323 constexpr size_t kNumFecPacketsBatch1 = 1u; | 368 constexpr size_t kNumFecPacketsBatch1 = 1u; |
324 constexpr size_t kNumMediaPacketsBatch1 = 2u; | 369 constexpr size_t kNumMediaPacketsBatch1 = 2u; |
325 std::list<AugmentedPacket*> augmented_media_packets_batch1; | 370 std::list<AugmentedPacket*> augmented_media_packets_batch1; |
326 ForwardErrorCorrection::PacketList media_packets_batch1; | 371 ForwardErrorCorrection::PacketList media_packets_batch1; |
327 GenerateFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, | 372 PacketizeFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, |
328 &media_packets_batch1); | 373 &media_packets_batch1); |
329 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 374 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
330 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); | 375 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); |
331 | 376 |
332 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); | 377 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); |
333 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 378 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
334 .Times(1).WillRepeatedly(Return(true)); | 379 .Times(1).WillRepeatedly(Return(true)); |
335 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 380 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
336 delayed_fec = fec_packets.front(); | 381 delayed_fec = fec_packets.front(); |
337 | 382 |
338 // Fill the FEC decoder and force the last packet to be dropped. | 383 // Fill the FEC decoder and force the last packet to be dropped. |
339 constexpr size_t kNumMediaPacketsBatch2 = 48u; | 384 constexpr size_t kNumMediaPacketsBatch2 = 48u; |
340 std::list<AugmentedPacket*> augmented_media_packets_batch2; | 385 std::list<AugmentedPacket*> augmented_media_packets_batch2; |
341 ForwardErrorCorrection::PacketList media_packets_batch2; | 386 ForwardErrorCorrection::PacketList media_packets_batch2; |
342 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { | 387 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { |
343 GenerateFrame(1, i, &augmented_media_packets_batch2, &media_packets_batch2); | 388 PacketizeFrame(1, i, &augmented_media_packets_batch2, |
389 &media_packets_batch2); | |
344 } | 390 } |
345 for (auto it = augmented_media_packets_batch2.begin(); | 391 for (auto it = augmented_media_packets_batch2.begin(); |
346 it != augmented_media_packets_batch2.end(); ++it) { | 392 it != augmented_media_packets_batch2.end(); ++it) { |
347 BuildAndAddRedMediaPacket(*it); | 393 BuildAndAddRedMediaPacket(*it); |
348 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 394 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
349 .Times(1).WillRepeatedly(Return(true)); | 395 .Times(1).WillRepeatedly(Return(true)); |
350 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 396 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
351 } | 397 } |
352 | 398 |
353 // Add the delayed FEC packet. No packet should be reconstructed since the | 399 // Add the delayed FEC packet. No packet should be reconstructed since the |
354 // first media packet of that frame has been dropped due to being too old. | 400 // first media packet of that frame has been dropped due to being too old. |
355 BuildAndAddRedFecPacket(delayed_fec); | 401 BuildAndAddRedFecPacket(delayed_fec); |
356 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 402 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
357 .Times(0); | 403 .Times(0); |
358 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 404 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
359 } | 405 } |
360 | 406 |
361 TEST_F(ReceiverFecTest, OldFecPacketDropped) { | 407 TEST_F(ReceiverFecTest, OldFecPacketDropped) { |
362 // 49 frames with 2 media packets and one FEC packet. All media packets | 408 // 49 frames with 2 media packets and one FEC packet. All media packets |
363 // missing. | 409 // missing. |
364 constexpr size_t kNumMediaPackets = 49 * 2; | 410 constexpr size_t kNumMediaPackets = 49 * 2; |
365 std::list<AugmentedPacket*> augmented_media_packets; | 411 std::list<AugmentedPacket*> augmented_media_packets; |
366 ForwardErrorCorrection::PacketList media_packets; | 412 ForwardErrorCorrection::PacketList media_packets; |
367 for (size_t i = 0; i < kNumMediaPackets / 2; ++i) { | 413 for (size_t i = 0; i < kNumMediaPackets / 2; ++i) { |
368 std::list<AugmentedPacket*> frame_augmented_media_packets; | 414 std::list<AugmentedPacket*> frame_augmented_media_packets; |
369 ForwardErrorCorrection::PacketList frame_media_packets; | 415 ForwardErrorCorrection::PacketList frame_media_packets; |
370 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 416 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
371 GenerateFrame(2, 0, &frame_augmented_media_packets, &frame_media_packets); | 417 PacketizeFrame(2, 0, &frame_augmented_media_packets, &frame_media_packets); |
372 EncodeFec(frame_media_packets, 1, &fec_packets); | 418 EncodeFec(frame_media_packets, 1, &fec_packets); |
373 for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { | 419 for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { |
374 // Only FEC packets inserted. No packets recoverable at this time. | 420 // Only FEC packets inserted. No packets recoverable at this time. |
375 BuildAndAddRedFecPacket(*it); | 421 BuildAndAddRedFecPacket(*it); |
376 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 422 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
377 .Times(0); | 423 .Times(0); |
378 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 424 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
379 } | 425 } |
380 // Move unique_ptr's to media_packets for lifetime management. | 426 // Move unique_ptr's to media_packets for lifetime management. |
381 media_packets.insert(media_packets.end(), | 427 media_packets.insert(media_packets.end(), |
382 std::make_move_iterator(frame_media_packets.begin()), | 428 std::make_move_iterator(frame_media_packets.begin()), |
383 std::make_move_iterator(frame_media_packets.end())); | 429 std::make_move_iterator(frame_media_packets.end())); |
384 augmented_media_packets.insert(augmented_media_packets.end(), | 430 augmented_media_packets.insert(augmented_media_packets.end(), |
385 frame_augmented_media_packets.begin(), | 431 frame_augmented_media_packets.begin(), |
386 frame_augmented_media_packets.end()); | 432 frame_augmented_media_packets.end()); |
387 } | 433 } |
388 // Insert the oldest media packet. The corresponding FEC packet is too old | 434 // Insert the oldest media packet. The corresponding FEC packet is too old |
389 // and should have been dropped. Only the media packet we inserted will be | 435 // and should have been dropped. Only the media packet we inserted will be |
390 // returned. | 436 // returned. |
391 BuildAndAddRedMediaPacket(augmented_media_packets.front()); | 437 BuildAndAddRedMediaPacket(augmented_media_packets.front()); |
392 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 438 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
393 .Times(1).WillRepeatedly(Return(true)); | 439 .Times(1).WillRepeatedly(Return(true)); |
394 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 440 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
395 } | 441 } |
396 | 442 |
397 void ReceiverFecTest::SurvivesMaliciousPacket(const uint8_t* data, | |
398 size_t length, | |
399 uint8_t ulpfec_payload_type) { | |
400 webrtc::RTPHeader header; | |
401 std::unique_ptr<webrtc::RtpHeaderParser> parser( | |
402 webrtc::RtpHeaderParser::Create()); | |
403 ASSERT_TRUE(parser->Parse(data, length, &header)); | |
404 | |
405 webrtc::NullRtpData null_callback; | |
406 std::unique_ptr<webrtc::FecReceiver> receiver_fec( | |
407 webrtc::FecReceiver::Create(&null_callback)); | |
408 | |
409 receiver_fec->AddReceivedRedPacket(header, data, length, ulpfec_payload_type); | |
410 } | |
411 | |
412 TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSet) { | 443 TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSet) { |
413 const uint8_t kTruncatedPacket[] = {0x80, | 444 const uint8_t kTruncatedPacket[] = {0x80, |
414 0x2a, | 445 0x2a, |
415 0x68, | 446 0x68, |
416 0x71, | 447 0x71, |
417 0x29, | 448 0x29, |
418 0xa1, | 449 0xa1, |
419 0x27, | 450 0x27, |
420 0x3a, | 451 0x3a, |
421 0x29, | 452 0x29, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
516 0x27, | 547 0x27, |
517 0xc4, | 548 0xc4, |
518 0x2a, | 549 0x2a, |
519 0x21, | 550 0x21, |
520 0x2a, | 551 0x2a, |
521 0x28}; | 552 0x28}; |
522 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); | 553 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); |
523 } | 554 } |
524 | 555 |
525 } // namespace webrtc | 556 } // namespace webrtc |
OLD | NEW |