OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <algorithm> | |
12 #include <memory> | |
13 | |
14 #include "webrtc/base/basictypes.h" | |
15 #include "webrtc/modules/rtp_rtcp/include/flexfec_receiver.h" | |
16 #include "webrtc/modules/rtp_rtcp/mocks/mock_recovered_packet_receiver.h" | |
17 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h" | |
18 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" | |
19 #include "webrtc/test/gmock.h" | |
20 #include "webrtc/test/gtest.h" | |
21 | |
22 namespace webrtc { | |
23 | |
24 namespace { | |
25 | |
26 using ::testing::_; | |
27 using ::testing::Args; | |
28 using ::testing::ElementsAreArray; | |
29 using ::testing::Return; | |
30 | |
31 using test::fec::FlexfecPacketGenerator; | |
32 using Packet = ForwardErrorCorrection::Packet; | |
33 using PacketList = ForwardErrorCorrection::PacketList; | |
34 | |
35 constexpr size_t kPayloadLength = 500; | |
36 constexpr uint32_t kFlexfecSsrc = 42984; | |
37 constexpr uint32_t kMediaSsrc = 8353; | |
38 | |
39 } // namespace | |
40 | |
41 class FlexfecReceiverTest : public ::testing::Test { | |
42 protected: | |
43 FlexfecReceiverTest() | |
44 : receiver_(FlexfecReceiver::Create(kFlexfecSsrc, | |
45 kMediaSsrc, | |
46 &recovered_packet_receiver_)), | |
47 erasure_code_(ForwardErrorCorrection::CreateFlexfec()), | |
48 packet_generator_(kMediaSsrc, kFlexfecSsrc) {} | |
49 | |
50 // Generates |num_media_packets| corresponding to a single frame. | |
51 void PacketizeFrame(size_t num_media_packets, | |
52 size_t frame_offset, | |
53 PacketList* media_packets); | |
54 | |
55 // Generates |num_fec_packets| FEC packets, given |media_packets|. | |
56 std::list<Packet*> EncodeFec(const PacketList& media_packets, | |
57 size_t num_fec_packets); | |
58 | |
59 std::unique_ptr<FlexfecReceiver> receiver_; | |
60 std::unique_ptr<ForwardErrorCorrection> erasure_code_; | |
61 | |
62 FlexfecPacketGenerator packet_generator_; | |
63 testing::StrictMock<MockRecoveredPacketReceiver> recovered_packet_receiver_; | |
64 }; | |
65 | |
66 void FlexfecReceiverTest::PacketizeFrame(size_t num_media_packets, | |
67 size_t frame_offset, | |
68 PacketList* media_packets) { | |
69 packet_generator_.NewFrame(num_media_packets); | |
70 for (size_t i = 0; i < num_media_packets; ++i) { | |
71 std::unique_ptr<Packet> next_packet( | |
72 packet_generator_.NextPacket(frame_offset + i, kPayloadLength)); | |
73 media_packets->push_back(std::move(next_packet)); | |
74 } | |
75 } | |
76 | |
77 std::list<Packet*> FlexfecReceiverTest::EncodeFec( | |
78 const PacketList& media_packets, | |
79 size_t num_fec_packets) { | |
80 const uint8_t protection_factor = | |
81 num_fec_packets * 255 / media_packets.size(); | |
82 constexpr int kNumImportantPackets = 0; | |
83 constexpr bool kUseUnequalProtection = false; | |
84 constexpr FecMaskType kFecMaskType = kFecMaskRandom; | |
85 std::list<Packet*> fec_packets; | |
86 EXPECT_EQ(0, erasure_code_->EncodeFec( | |
87 media_packets, protection_factor, kNumImportantPackets, | |
88 kUseUnequalProtection, kFecMaskType, &fec_packets)); | |
89 EXPECT_EQ(num_fec_packets, fec_packets.size()); | |
90 return fec_packets; | |
91 } | |
92 | |
93 TEST_F(FlexfecReceiverTest, ReceivesMediaPacket) { | |
94 packet_generator_.NewFrame(1); | |
95 std::unique_ptr<Packet> media_packet( | |
96 packet_generator_.NextPacket(0, kPayloadLength)); | |
97 | |
98 EXPECT_EQ(true, receiver_->AddReceivedPacket(media_packet->data, | |
danilchap
2016/10/05 14:32:04
s/EXPECT_EQ(true,/EXPECT_TRUE(/g
brandtr
2016/10/06 08:38:57
Done.
| |
99 media_packet->length)); | |
100 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
101 } | |
102 | |
103 TEST_F(FlexfecReceiverTest, FailsOnTruncatedMediaPacket) { | |
104 const size_t kNoPayload = 0; | |
105 | |
106 packet_generator_.NewFrame(1); | |
107 std::unique_ptr<Packet> media_packet( | |
108 packet_generator_.NextPacket(0, kNoPayload)); | |
109 // Simulate truncated media packet. | |
110 media_packet->length = kRtpHeaderSize - 1; | |
111 | |
112 EXPECT_EQ(false, receiver_->AddReceivedPacket(media_packet->data, | |
danilchap
2016/10/05 14:32:04
EXPECT_FALSE(
brandtr
2016/10/06 08:38:57
Done.
| |
113 media_packet->length)); | |
114 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
115 } | |
116 | |
117 TEST_F(FlexfecReceiverTest, ReceivesFecPacket) { | |
118 const size_t kNumMediaPackets = 1; | |
119 const size_t kNumFecPackets = 1; | |
120 | |
121 PacketList media_packets; | |
122 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
123 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
124 auto media_packet = media_packets.front().get(); | |
125 auto fec_packet = packet_generator_.BuildFlexfecPacket(*fec_packets.front()); | |
126 | |
127 EXPECT_EQ(true, receiver_->AddReceivedPacket(media_packet->data, | |
128 media_packet->length)); | |
129 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
130 EXPECT_EQ(true, | |
131 receiver_->AddReceivedPacket(fec_packet->data, fec_packet->length)); | |
132 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
133 } | |
134 | |
135 TEST_F(FlexfecReceiverTest, FailsOnTruncatedFecPacket) { | |
136 const size_t kNumMediaPackets = 1; | |
137 const size_t kNumFecPackets = 1; | |
138 | |
139 PacketList media_packets; | |
140 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
141 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
142 auto media_packet = media_packets.front().get(); | |
143 // Simulate truncated FlexFEC payload. | |
144 fec_packets.front()->length = 1; | |
145 auto fec_packet = packet_generator_.BuildFlexfecPacket(*fec_packets.front()); | |
146 | |
147 EXPECT_EQ(true, receiver_->AddReceivedPacket(media_packet->data, | |
148 media_packet->length)); | |
149 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
150 EXPECT_EQ(false, | |
151 receiver_->AddReceivedPacket(fec_packet->data, fec_packet->length)); | |
152 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
153 } | |
154 | |
155 TEST_F(FlexfecReceiverTest, FailsOnUnknownMediaSsrc) { | |
156 const size_t kNumMediaPackets = 1; | |
157 | |
158 PacketList media_packets; | |
159 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
160 auto media_packet = media_packets.front().get(); | |
161 // Corrupt the SSRC. | |
162 media_packet->data[8] = 0; | |
163 media_packet->data[9] = 1; | |
164 media_packet->data[10] = 2; | |
165 media_packet->data[11] = 3; | |
166 | |
167 EXPECT_EQ(false, receiver_->AddReceivedPacket(media_packet->data, | |
168 media_packet->length)); | |
169 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
170 } | |
171 | |
172 TEST_F(FlexfecReceiverTest, FailsOnUnknownFecSsrc) { | |
173 const size_t kNumMediaPackets = 1; | |
174 const size_t kNumFecPackets = 1; | |
175 | |
176 PacketList media_packets; | |
177 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
178 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
179 auto media_packet = media_packets.front().get(); | |
180 auto fec_packet = packet_generator_.BuildFlexfecPacket(*fec_packets.front()); | |
181 // Corrupt the SSRC. | |
182 fec_packet->data[8] = 4; | |
183 fec_packet->data[9] = 5; | |
184 fec_packet->data[10] = 6; | |
185 fec_packet->data[11] = 7; | |
186 | |
187 EXPECT_EQ(true, receiver_->AddReceivedPacket(media_packet->data, | |
188 media_packet->length)); | |
189 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
190 EXPECT_EQ(false, | |
191 receiver_->AddReceivedPacket(fec_packet->data, fec_packet->length)); | |
192 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
193 } | |
194 | |
195 TEST_F(FlexfecReceiverTest, ReceivesMultiplePackets) { | |
196 const size_t kNumMediaPackets = 2; | |
197 const size_t kNumFecPackets = 1; | |
198 | |
199 PacketList media_packets; | |
200 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
201 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
202 | |
203 // Receive all media packets. | |
204 for (const auto& media_packet : media_packets) { | |
205 EXPECT_EQ(true, receiver_->AddReceivedPacket(media_packet->data, | |
206 media_packet->length)); | |
207 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
208 } | |
209 | |
210 // Receive FEC packet. | |
211 auto fec_it = fec_packets.begin(); | |
212 std::unique_ptr<Packet> packet_with_rtp_header = | |
213 packet_generator_.BuildFlexfecPacket(**fec_it); | |
214 EXPECT_EQ(true, receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
215 packet_with_rtp_header->length)); | |
216 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
217 } | |
218 | |
219 TEST_F(FlexfecReceiverTest, RecoversFromSingleMediaLoss) { | |
220 const size_t kNumMediaPackets = 2; | |
221 const size_t kNumFecPackets = 1; | |
222 | |
223 PacketList media_packets; | |
224 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
225 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
226 | |
227 // Receive first media packet but drop second. | |
228 auto media_it = media_packets.begin(); | |
229 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_it)->data, | |
230 (*media_it)->length)); | |
231 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
232 | |
233 // Receive FEC packet. | |
234 auto fec_it = fec_packets.begin(); | |
235 std::unique_ptr<Packet> packet_with_rtp_header = | |
236 packet_generator_.BuildFlexfecPacket(**fec_it); | |
237 EXPECT_EQ(true, receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
238 packet_with_rtp_header->length)); | |
239 | |
240 // Ensure recovery of lost media packet. | |
241 media_it++; | |
242 EXPECT_CALL(recovered_packet_receiver_, | |
243 OnRecoveredPacket(_, (*media_it)->length)) | |
244 .With( | |
245 Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length))) | |
246 .WillOnce(Return(true)); | |
247 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
248 } | |
249 | |
250 TEST_F(FlexfecReceiverTest, RecoversFromDoubleMediaLoss) { | |
251 const size_t kNumMediaPackets = 2; | |
252 const size_t kNumFecPackets = 2; | |
253 | |
254 PacketList media_packets; | |
255 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
256 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
257 | |
258 // Drop both media packets. | |
259 auto media_it = media_packets.begin(); | |
260 | |
261 // Receive first FEC packet. | |
262 auto fec_it = fec_packets.begin(); | |
263 std::unique_ptr<Packet> packet_with_rtp_header = | |
264 packet_generator_.BuildFlexfecPacket(**fec_it); | |
265 EXPECT_EQ(true, receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
266 packet_with_rtp_header->length)); | |
267 | |
268 // Recover first lost media packet. | |
269 EXPECT_CALL(recovered_packet_receiver_, | |
270 OnRecoveredPacket(_, (*media_it)->length)) | |
271 .With( | |
272 Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length))) | |
273 .WillOnce(Return(true)); | |
274 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
275 | |
276 // Receive second FEC packet. | |
277 fec_it++; | |
278 packet_with_rtp_header = packet_generator_.BuildFlexfecPacket(**fec_it); | |
279 EXPECT_EQ(true, receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
280 packet_with_rtp_header->length)); | |
281 | |
282 // Recover second lost media packet. | |
283 media_it++; | |
284 EXPECT_CALL(recovered_packet_receiver_, | |
285 OnRecoveredPacket(_, (*media_it)->length)) | |
286 .With( | |
287 Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length))) | |
288 .WillOnce(Return(true)); | |
289 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
290 } | |
291 | |
292 TEST_F(FlexfecReceiverTest, DoesNotRecoverFromMediaAndFecLoss) { | |
293 const size_t kNumMediaPackets = 2; | |
294 const size_t kNumFecPackets = 1; | |
295 | |
296 PacketList media_packets; | |
297 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
298 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
299 | |
300 // Receive first media packet. | |
301 auto media_it = media_packets.begin(); | |
302 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_it)->data, | |
303 (*media_it)->length)); | |
304 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
305 | |
306 // Drop second media packet and FEC packet. | |
307 } | |
308 | |
309 TEST_F(FlexfecReceiverTest, DoesNotCallbackTwice) { | |
310 const size_t kNumMediaPackets = 2; | |
311 const size_t kNumFecPackets = 1; | |
312 | |
313 PacketList media_packets; | |
314 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
315 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
316 | |
317 // Receive first media packet but drop second. | |
318 auto media_it = media_packets.begin(); | |
319 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_it)->data, | |
320 (*media_it)->length)); | |
321 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
322 | |
323 // Receive FEC packet. | |
324 auto fec_it = fec_packets.begin(); | |
325 std::unique_ptr<Packet> packet_with_rtp_header = | |
326 packet_generator_.BuildFlexfecPacket(**fec_it); | |
327 EXPECT_EQ(true, receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
328 packet_with_rtp_header->length)); | |
329 | |
330 // Ensure recovery of lost media packet. | |
331 media_it++; | |
332 EXPECT_CALL(recovered_packet_receiver_, | |
333 OnRecoveredPacket(_, (*media_it)->length)) | |
334 .With( | |
335 Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length))) | |
336 .WillOnce(Return(true)); | |
337 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
338 | |
339 // Receive FEC packet again. | |
340 EXPECT_EQ(true, receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
341 packet_with_rtp_header->length)); | |
342 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
343 } | |
344 | |
345 // Here we are implicitly assuming packet masks that are suitable for | |
346 // this type of 50% correlated loss. If we are changing our precomputed | |
347 // packet masks, this test might need to be updated. | |
348 TEST_F(FlexfecReceiverTest, RecoversFrom50PercentLoss) { | |
349 const size_t kNumFecPackets = 5; | |
350 const size_t kNumFrames = 2 * kNumFecPackets; | |
351 const size_t kNumMediaPacketsPerFrame = 1; | |
352 | |
353 PacketList media_packets; | |
354 for (size_t i = 0; i < kNumFrames; ++i) { | |
355 PacketizeFrame(kNumMediaPacketsPerFrame, i, &media_packets); | |
356 } | |
357 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
358 | |
359 // Drop every second media packet. | |
360 auto media_it = media_packets.begin(); | |
361 while (media_it != media_packets.end()) { | |
362 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_it)->data, | |
363 (*media_it)->length)); | |
364 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
365 ++media_it; | |
366 if (media_it == media_packets.end()) { | |
367 break; | |
368 } | |
369 ++media_it; | |
370 } | |
371 | |
372 // Receive all FEC packets. | |
373 media_it = media_packets.begin(); | |
374 for (const auto& fec_packet : fec_packets) { | |
375 std::unique_ptr<Packet> fec_packet_with_rtp_header = | |
376 packet_generator_.BuildFlexfecPacket(*fec_packet); | |
377 EXPECT_EQ(true, | |
378 receiver_->AddReceivedPacket(fec_packet_with_rtp_header->data, | |
379 fec_packet_with_rtp_header->length)); | |
380 ++media_it; | |
381 if (media_it == media_packets.end()) { | |
382 break; | |
383 } | |
384 EXPECT_CALL(recovered_packet_receiver_, | |
385 OnRecoveredPacket(_, (*media_it)->length)) | |
386 .With(Args<0, 1>( | |
387 ElementsAreArray((*media_it)->data, (*media_it)->length))) | |
388 .WillOnce(Return(true)); | |
389 ++media_it; | |
390 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
391 } | |
392 } | |
393 | |
394 TEST_F(FlexfecReceiverTest, DelayedFecPacketDoesHelp) { | |
395 // These values need to be updated if the underlying erasure code | |
396 // implementation changes. | |
397 const size_t kNumFrames = 48; | |
398 const size_t kNumMediaPacketsPerFrame = 1; | |
399 const size_t kNumFecPackets = 1; | |
400 | |
401 PacketList media_packets; | |
402 PacketizeFrame(kNumMediaPacketsPerFrame, 0, &media_packets); | |
403 PacketizeFrame(kNumMediaPacketsPerFrame, 1, &media_packets); | |
404 // Protect two first frames. | |
405 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
406 for (size_t i = 2; i < kNumFrames; ++i) { | |
407 PacketizeFrame(kNumMediaPacketsPerFrame, i, &media_packets); | |
408 } | |
409 | |
410 // Drop first media packet and delay FEC packet. | |
411 auto media_it = media_packets.begin(); | |
412 ++media_it; | |
413 | |
414 // Receive all other media packets. | |
415 while (media_it != media_packets.end()) { | |
416 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_it)->data, | |
417 (*media_it)->length)); | |
418 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
419 ++media_it; | |
420 } | |
421 | |
422 // Receive FEC packet. | |
423 auto fec_it = fec_packets.begin(); | |
424 std::unique_ptr<Packet> packet_with_rtp_header = | |
425 packet_generator_.BuildFlexfecPacket(**fec_it); | |
426 EXPECT_EQ(true, receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
427 packet_with_rtp_header->length)); | |
428 | |
429 // Recover first media packet. | |
430 media_it = media_packets.begin(); | |
431 EXPECT_CALL(recovered_packet_receiver_, | |
432 OnRecoveredPacket(_, (*media_it)->length)) | |
433 .With( | |
434 Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length))) | |
435 .WillOnce(Return(true)); | |
436 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
437 } | |
438 | |
439 TEST_F(FlexfecReceiverTest, TooDelayedFecPacketDoesNotHelp) { | |
440 // These values need to be updated if the underlying erasure code | |
441 // implementation changes. | |
442 const size_t kNumFrames = 49; | |
443 const size_t kNumMediaPacketsPerFrame = 1; | |
444 const size_t kNumFecPackets = 1; | |
445 | |
446 PacketList media_packets; | |
447 PacketizeFrame(kNumMediaPacketsPerFrame, 0, &media_packets); | |
448 PacketizeFrame(kNumMediaPacketsPerFrame, 1, &media_packets); | |
449 // Protect two first frames. | |
450 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
451 for (size_t i = 2; i < kNumFrames; ++i) { | |
452 PacketizeFrame(kNumMediaPacketsPerFrame, i, &media_packets); | |
453 } | |
454 | |
455 // Drop first media packet and delay FEC packet. | |
456 auto media_it = media_packets.begin(); | |
457 ++media_it; | |
458 | |
459 // Receive all other media packets. | |
460 while (media_it != media_packets.end()) { | |
461 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_it)->data, | |
462 (*media_it)->length)); | |
463 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
464 ++media_it; | |
465 } | |
466 | |
467 // Receive FEC packet. | |
468 auto fec_it = fec_packets.begin(); | |
469 std::unique_ptr<Packet> packet_with_rtp_header = | |
470 packet_generator_.BuildFlexfecPacket(**fec_it); | |
471 EXPECT_EQ(true, receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
472 packet_with_rtp_header->length)); | |
473 // Do not expect a callback. | |
474 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
475 } | |
476 | |
477 TEST_F(FlexfecReceiverTest, RecoversWithMediaPacketsOutOfOrder) { | |
478 const size_t kNumMediaPackets = 6; | |
479 const size_t kNumFecPackets = 2; | |
480 | |
481 PacketList media_packets; | |
482 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
483 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
484 | |
485 // Lose two media packets, and receive the others out of order. | |
486 auto media_it = media_packets.begin(); | |
487 auto media_packet0 = media_it++; | |
488 auto media_packet1 = media_it++; | |
489 auto media_packet2 = media_it++; | |
490 auto media_packet3 = media_it++; | |
491 auto media_packet4 = media_it++; | |
492 auto media_packet5 = media_it++; | |
493 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_packet5)->data, | |
494 (*media_packet5)->length)); | |
495 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
496 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_packet2)->data, | |
497 (*media_packet2)->length)); | |
498 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
499 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_packet3)->data, | |
500 (*media_packet3)->length)); | |
501 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
502 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_packet0)->data, | |
503 (*media_packet0)->length)); | |
504 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
505 | |
506 // Add FEC packets. | |
507 auto fec_it = fec_packets.begin(); | |
508 std::unique_ptr<Packet> packet_with_rtp_header; | |
509 while (fec_it != fec_packets.end()) { | |
510 packet_with_rtp_header = packet_generator_.BuildFlexfecPacket(**fec_it); | |
511 EXPECT_EQ(true, | |
512 receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
513 packet_with_rtp_header->length)); | |
514 ++fec_it; | |
515 } | |
516 | |
517 // Recover lost media packets. | |
518 EXPECT_CALL(recovered_packet_receiver_, | |
519 OnRecoveredPacket(_, (*media_packet1)->length)) | |
520 .With(Args<0, 1>( | |
521 ElementsAreArray((*media_packet1)->data, (*media_packet1)->length))) | |
522 .WillOnce(Return(true)); | |
523 EXPECT_CALL(recovered_packet_receiver_, | |
524 OnRecoveredPacket(_, (*media_packet4)->length)) | |
525 .With(Args<0, 1>( | |
526 ElementsAreArray((*media_packet4)->data, (*media_packet4)->length))) | |
527 .WillOnce(Return(true)); | |
528 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
529 } | |
530 | |
531 TEST_F(FlexfecReceiverTest, CalculatesNumberOfPackets) { | |
532 const size_t kNumMediaPackets = 2; | |
533 const size_t kNumFecPackets = 1; | |
534 | |
535 PacketList media_packets; | |
536 PacketizeFrame(kNumMediaPackets, 0, &media_packets); | |
537 std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets); | |
538 | |
539 // Receive first media packet but drop second. | |
540 auto media_it = media_packets.begin(); | |
541 EXPECT_EQ(true, receiver_->AddReceivedPacket((*media_it)->data, | |
542 (*media_it)->length)); | |
543 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
544 | |
545 // Receive FEC packet. | |
546 auto fec_it = fec_packets.begin(); | |
547 std::unique_ptr<Packet> packet_with_rtp_header = | |
548 packet_generator_.BuildFlexfecPacket(**fec_it); | |
549 EXPECT_EQ(true, receiver_->AddReceivedPacket(packet_with_rtp_header->data, | |
550 packet_with_rtp_header->length)); | |
551 | |
552 // Ensure recovery of lost media packet. | |
553 media_it++; | |
554 EXPECT_CALL(recovered_packet_receiver_, | |
555 OnRecoveredPacket(_, (*media_it)->length)) | |
556 .With( | |
557 Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length))) | |
558 .WillOnce(Return(true)); | |
559 EXPECT_EQ(true, receiver_->ProcessReceivedPackets()); | |
560 | |
561 // Check stats calculations. | |
562 auto packet_counter = receiver_->GetPacketCounter(); | |
563 EXPECT_EQ(2U, packet_counter.num_packets); | |
564 EXPECT_EQ(1U, packet_counter.num_fec_packets); | |
565 EXPECT_EQ(1U, packet_counter.num_recovered_packets); | |
566 } | |
567 | |
568 } // namespace webrtc | |
OLD | NEW |