Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / rtp_rtcp / source / fec_receiver_unittest.cc
1 /*
2  *  Copyright (c) 2012 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 <string.h>
12
13 #include <list>
14
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
18 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
19 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
20
21 using ::testing::_;
22 using ::testing::Args;
23 using ::testing::ElementsAreArray;
24 using ::testing::Return;
25
26 namespace webrtc {
27
28 class MockRtpData : public RtpData {
29  public:
30   MOCK_METHOD3(OnReceivedPayloadData,
31       int32_t(const uint8_t* payloadData,
32               const uint16_t payloadSize,
33               const WebRtcRTPHeader* rtpHeader));
34
35   MOCK_METHOD2(OnRecoveredPacket,
36       bool(const uint8_t* packet, int packet_length));
37 };
38
39 class ReceiverFecTest : public ::testing::Test {
40  protected:
41   virtual void SetUp() {
42     fec_ = new ForwardErrorCorrection();
43     receiver_fec_ = FecReceiver::Create(&rtp_data_callback_);
44     generator_ = new FrameGenerator();
45   }
46
47   virtual void TearDown() {
48     delete fec_;
49     delete receiver_fec_;
50     delete generator_;
51   }
52
53   void GenerateFEC(std::list<Packet*>* media_packets,
54                    std::list<Packet*>* fec_packets,
55                    unsigned int num_fec_packets) {
56     uint8_t protection_factor = num_fec_packets * 255 / media_packets->size();
57     EXPECT_EQ(0, fec_->GenerateFEC(*media_packets, protection_factor,
58                                    0, false, kFecMaskBursty, fec_packets));
59     ASSERT_EQ(num_fec_packets, fec_packets->size());
60   }
61
62   void GenerateFrame(int num_media_packets, int frame_offset,
63                      std::list<RtpPacket*>* media_rtp_packets,
64                      std::list<Packet*>* media_packets) {
65     generator_->NewFrame(num_media_packets);
66     for (int i = 0; i < num_media_packets; ++i) {
67       media_rtp_packets->push_back(
68           generator_->NextPacket(frame_offset + i, kRtpHeaderSize + 10));
69       media_packets->push_back(media_rtp_packets->back());
70     }
71   }
72
73   void VerifyReconstructedMediaPacket(const RtpPacket* packet, int times) {
74     // Verify that the content of the reconstructed packet is equal to the
75     // content of |packet|, and that the same content is received |times| number
76     // of times in a row.
77     EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet->length))
78         .With(Args<0, 1>(ElementsAreArray(packet->data,
79                                           packet->length)))
80         .Times(times).WillRepeatedly(Return(true));
81   }
82
83   void BuildAndAddRedMediaPacket(RtpPacket* packet) {
84     RtpPacket* red_packet = generator_->BuildMediaRedPacket(packet);
85     EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket(
86                      red_packet->header.header, red_packet->data,
87                      red_packet->length, kFecPayloadType));
88     delete red_packet;
89   }
90
91   void BuildAndAddRedFecPacket(Packet* packet) {
92     RtpPacket* red_packet = generator_->BuildFecRedPacket(packet);
93     EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket(
94                      red_packet->header.header, red_packet->data,
95                      red_packet->length, kFecPayloadType));
96     delete red_packet;
97   }
98
99   ForwardErrorCorrection* fec_;
100   MockRtpData rtp_data_callback_;
101   FecReceiver* receiver_fec_;
102   FrameGenerator* generator_;
103 };
104
105 void DeletePackets(std::list<Packet*>* packets) {
106   while (!packets->empty()) {
107     delete packets->front();
108     packets->pop_front();
109   }
110 }
111
112 TEST_F(ReceiverFecTest, TwoMediaOneFec) {
113   const unsigned int kNumFecPackets = 1u;
114   std::list<RtpPacket*> media_rtp_packets;
115   std::list<Packet*> media_packets;
116   GenerateFrame(2, 0, &media_rtp_packets, &media_packets);
117   std::list<Packet*> fec_packets;
118   GenerateFEC(&media_packets, &fec_packets, kNumFecPackets);
119
120   // Recovery
121   std::list<RtpPacket*>::iterator it = media_rtp_packets.begin();
122   std::list<RtpPacket*>::iterator media_it = media_rtp_packets.begin();
123   BuildAndAddRedMediaPacket(*media_it);
124   VerifyReconstructedMediaPacket(*it, 1);
125   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
126   // Drop one media packet.
127   std::list<Packet*>::iterator fec_it = fec_packets.begin();
128   BuildAndAddRedFecPacket(*fec_it);
129   ++it;
130   VerifyReconstructedMediaPacket(*it, 1);
131   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
132
133   DeletePackets(&media_packets);
134 }
135
136 TEST_F(ReceiverFecTest, TwoMediaTwoFec) {
137   const unsigned int kNumFecPackets = 2u;
138   std::list<RtpPacket*> media_rtp_packets;
139   std::list<Packet*> media_packets;
140   GenerateFrame(2, 0, &media_rtp_packets, &media_packets);
141   std::list<Packet*> fec_packets;
142   GenerateFEC(&media_packets, &fec_packets, kNumFecPackets);
143
144   // Recovery
145   // Drop both media packets.
146   std::list<RtpPacket*>::iterator it = media_rtp_packets.begin();
147   std::list<Packet*>::iterator fec_it = fec_packets.begin();
148   BuildAndAddRedFecPacket(*fec_it);
149   VerifyReconstructedMediaPacket(*it, 1);
150   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
151   ++fec_it;
152   BuildAndAddRedFecPacket(*fec_it);
153   ++it;
154   VerifyReconstructedMediaPacket(*it, 1);
155   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
156
157   DeletePackets(&media_packets);
158 }
159
160 TEST_F(ReceiverFecTest, TwoFramesOneFec) {
161   const unsigned int kNumFecPackets = 1u;
162   std::list<RtpPacket*> media_rtp_packets;
163   std::list<Packet*> media_packets;
164   GenerateFrame(1, 0, &media_rtp_packets, &media_packets);
165   GenerateFrame(1, 1, &media_rtp_packets, &media_packets);
166   std::list<Packet*> fec_packets;
167   GenerateFEC(&media_packets, &fec_packets, kNumFecPackets);
168
169   // Recovery
170   std::list<RtpPacket*>::iterator it = media_rtp_packets.begin();
171   BuildAndAddRedMediaPacket(media_rtp_packets.front());
172   VerifyReconstructedMediaPacket(*it, 1);
173   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
174   // Drop one media packet.
175   BuildAndAddRedFecPacket(fec_packets.front());
176   ++it;
177   VerifyReconstructedMediaPacket(*it, 1);
178   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
179
180   DeletePackets(&media_packets);
181 }
182
183 TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) {
184   const unsigned int kNumFecPackets = 1u;
185   std::list<RtpPacket*> media_rtp_packets;
186   std::list<Packet*> media_packets;
187   GenerateFrame(1, 0, &media_rtp_packets, &media_packets);
188   GenerateFrame(2, 1, &media_rtp_packets, &media_packets);
189
190   std::list<Packet*> fec_packets;
191   GenerateFEC(&media_packets, &fec_packets, kNumFecPackets);
192
193   // Recovery
194   std::list<RtpPacket*>::iterator it = media_rtp_packets.begin();
195   BuildAndAddRedMediaPacket(*it);  // First frame: one packet.
196   VerifyReconstructedMediaPacket(*it, 1);
197   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
198   ++it;
199   BuildAndAddRedMediaPacket(*it);  // First packet of second frame.
200   VerifyReconstructedMediaPacket(*it, 1);
201   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
202
203   DeletePackets(&media_packets);
204 }
205
206 TEST_F(ReceiverFecTest, MaxFramesOneFec) {
207   const unsigned int kNumFecPackets = 1u;
208   const unsigned int kNumMediaPackets = 48u;
209   std::list<RtpPacket*> media_rtp_packets;
210   std::list<Packet*> media_packets;
211   for (unsigned int i = 0; i < kNumMediaPackets; ++i) {
212     GenerateFrame(1, i, &media_rtp_packets, &media_packets);
213   }
214   std::list<Packet*> fec_packets;
215   GenerateFEC(&media_packets, &fec_packets, kNumFecPackets);
216
217   // Recovery
218   std::list<RtpPacket*>::iterator it = media_rtp_packets.begin();
219   ++it;  // Drop first packet.
220   for (; it != media_rtp_packets.end(); ++it) {
221     BuildAndAddRedMediaPacket(*it);
222     VerifyReconstructedMediaPacket(*it, 1);
223     EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
224   }
225   BuildAndAddRedFecPacket(fec_packets.front());
226   it = media_rtp_packets.begin();
227   VerifyReconstructedMediaPacket(*it, 1);
228   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
229
230   DeletePackets(&media_packets);
231 }
232
233 TEST_F(ReceiverFecTest, TooManyFrames) {
234   const unsigned int kNumFecPackets = 1u;
235   const unsigned int kNumMediaPackets = 49u;
236   std::list<RtpPacket*> media_rtp_packets;
237   std::list<Packet*> media_packets;
238   for (unsigned int i = 0; i < kNumMediaPackets; ++i) {
239     GenerateFrame(1, i, &media_rtp_packets, &media_packets);
240   }
241   std::list<Packet*> fec_packets;
242   EXPECT_EQ(-1, fec_->GenerateFEC(media_packets,
243                                   kNumFecPackets * 255 / kNumMediaPackets, 0,
244                                   false, kFecMaskBursty, &fec_packets));
245
246   DeletePackets(&media_packets);
247 }
248
249 TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) {
250   // 1 frame with 2 media packets and one FEC packet. One media packet missing.
251   // Delay the FEC packet.
252   Packet* delayed_fec = NULL;
253   const unsigned int kNumFecPacketsBatch1 = 1u;
254   const unsigned int kNumMediaPacketsBatch1 = 2u;
255   std::list<RtpPacket*> media_rtp_packets_batch1;
256   std::list<Packet*> media_packets_batch1;
257   GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1,
258                 &media_packets_batch1);
259   std::list<Packet*> fec_packets;
260   GenerateFEC(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1);
261
262   BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front());
263   EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
264       .Times(1).WillRepeatedly(Return(true));
265   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
266   delayed_fec = fec_packets.front();
267
268   // Fill the FEC decoder. No packets should be dropped.
269   const unsigned int kNumMediaPacketsBatch2 = 46u;
270   std::list<RtpPacket*> media_rtp_packets_batch2;
271   std::list<Packet*> media_packets_batch2;
272   for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) {
273     GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2);
274   }
275   for (std::list<RtpPacket*>::iterator it = media_rtp_packets_batch2.begin();
276        it != media_rtp_packets_batch2.end(); ++it) {
277     BuildAndAddRedMediaPacket(*it);
278     EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
279         .Times(1).WillRepeatedly(Return(true));
280     EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
281   }
282
283   // Add the delayed FEC packet. One packet should be reconstructed.
284   BuildAndAddRedFecPacket(delayed_fec);
285   EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
286       .Times(1).WillRepeatedly(Return(true));
287   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
288
289   DeletePackets(&media_packets_batch1);
290   DeletePackets(&media_packets_batch2);
291 }
292
293 TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) {
294   // 1 frame with 2 media packets and one FEC packet. One media packet missing.
295   // Delay the FEC packet.
296   Packet* delayed_fec = NULL;
297   const unsigned int kNumFecPacketsBatch1 = 1u;
298   const unsigned int kNumMediaPacketsBatch1 = 2u;
299   std::list<RtpPacket*> media_rtp_packets_batch1;
300   std::list<Packet*> media_packets_batch1;
301   GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1,
302                 &media_packets_batch1);
303   std::list<Packet*> fec_packets;
304   GenerateFEC(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1);
305
306   BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front());
307   EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
308       .Times(1).WillRepeatedly(Return(true));
309   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
310   delayed_fec = fec_packets.front();
311
312   // Fill the FEC decoder and force the last packet to be dropped.
313   const unsigned int kNumMediaPacketsBatch2 = 48u;
314   std::list<RtpPacket*> media_rtp_packets_batch2;
315   std::list<Packet*> media_packets_batch2;
316   for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) {
317     GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2);
318   }
319   for (std::list<RtpPacket*>::iterator it = media_rtp_packets_batch2.begin();
320        it != media_rtp_packets_batch2.end(); ++it) {
321     BuildAndAddRedMediaPacket(*it);
322     EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
323         .Times(1).WillRepeatedly(Return(true));
324     EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
325   }
326
327   // Add the delayed FEC packet. No packet should be reconstructed since the
328   // first media packet of that frame has been dropped due to being too old.
329   BuildAndAddRedFecPacket(delayed_fec);
330   EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
331       .Times(0);
332   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
333
334   DeletePackets(&media_packets_batch1);
335   DeletePackets(&media_packets_batch2);
336 }
337
338 TEST_F(ReceiverFecTest, OldFecPacketDropped) {
339   // 49 frames with 2 media packets and one FEC packet. All media packets
340   // missing.
341   const unsigned int kNumMediaPackets = 49 * 2;
342   std::list<RtpPacket*> media_rtp_packets;
343   std::list<Packet*> media_packets;
344   for (unsigned int i = 0; i < kNumMediaPackets / 2; ++i) {
345     std::list<RtpPacket*> frame_media_rtp_packets;
346     std::list<Packet*> frame_media_packets;
347     std::list<Packet*> fec_packets;
348     GenerateFrame(2, 0, &frame_media_rtp_packets, &frame_media_packets);
349     GenerateFEC(&frame_media_packets, &fec_packets, 1);
350     for (std::list<Packet*>::iterator it = fec_packets.begin();
351          it != fec_packets.end(); ++it) {
352       // Only FEC packets inserted. No packets recoverable at this time.
353       BuildAndAddRedFecPacket(*it);
354       EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
355           .Times(0);
356       EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
357     }
358     media_packets.insert(media_packets.end(), frame_media_packets.begin(),
359                          frame_media_packets.end());
360     media_rtp_packets.insert(media_rtp_packets.end(),
361                              frame_media_rtp_packets.begin(),
362                              frame_media_rtp_packets.end());
363   }
364   // Insert the oldest media packet. The corresponding FEC packet is too old
365   // and should've been dropped. Only the media packet we inserted will be
366   // returned.
367   BuildAndAddRedMediaPacket(media_rtp_packets.front());
368   EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
369       .Times(1).WillRepeatedly(Return(true));
370   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
371
372   DeletePackets(&media_packets);
373 }
374
375 }  // namespace webrtc