Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / rtp_rtcp / source / nack_rtx_unittest.cc
1 /*
2 *  Copyright (c) 2013 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 <iterator>
13 #include <list>
14 #include <set>
15
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "webrtc/common_types.h"
18 #include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
19 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
20 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
21 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
22 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
23 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
24 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
25
26 using namespace webrtc;
27
28 const int kVideoNackListSize = 30;
29 const int kTestId = 123;
30 const uint32_t kTestSsrc = 3456;
31 const uint16_t kTestSequenceNumber = 2345;
32 const uint32_t kTestNumberOfPackets = 1350;
33 const int kTestNumberOfRtxPackets = 149;
34 const int kNumFrames = 30;
35
36 class VerifyingRtxReceiver : public NullRtpData
37 {
38  public:
39   VerifyingRtxReceiver() {}
40
41   virtual int32_t OnReceivedPayloadData(
42       const uint8_t* data,
43       const uint16_t size,
44       const webrtc::WebRtcRTPHeader* rtp_header) OVERRIDE {
45     if (!sequence_numbers_.empty())
46       EXPECT_EQ(kTestSsrc, rtp_header->header.ssrc);
47     sequence_numbers_.push_back(rtp_header->header.sequenceNumber);
48     return 0;
49   }
50   std::list<uint16_t> sequence_numbers_;
51 };
52
53 class TestRtpFeedback : public NullRtpFeedback {
54  public:
55   TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
56   virtual ~TestRtpFeedback() {}
57
58   virtual void OnIncomingSSRCChanged(const int32_t id,
59                                      const uint32_t ssrc) OVERRIDE {
60     rtp_rtcp_->SetRemoteSSRC(ssrc);
61   }
62
63  private:
64   RtpRtcp* rtp_rtcp_;
65 };
66
67 class RtxLoopBackTransport : public webrtc::Transport {
68  public:
69   explicit RtxLoopBackTransport(uint32_t rtx_ssrc)
70       : count_(0),
71         packet_loss_(0),
72         consecutive_drop_start_(0),
73         consecutive_drop_end_(0),
74         rtx_ssrc_(rtx_ssrc),
75         count_rtx_ssrc_(0),
76         rtp_payload_registry_(NULL),
77         rtp_receiver_(NULL),
78         module_(NULL) {}
79
80   void SetSendModule(RtpRtcp* rtpRtcpModule,
81                      RTPPayloadRegistry* rtp_payload_registry,
82                      RtpReceiver* receiver) {
83     module_ = rtpRtcpModule;
84     rtp_payload_registry_ = rtp_payload_registry;
85     rtp_receiver_ = receiver;
86   }
87
88   void DropEveryNthPacket(int n) {
89     packet_loss_ = n;
90   }
91
92   void DropConsecutivePackets(int start, int total) {
93     consecutive_drop_start_ = start;
94     consecutive_drop_end_ = start + total;
95     packet_loss_ = 0;
96   }
97
98   virtual int SendPacket(int channel, const void *data, int len) OVERRIDE {
99     count_++;
100     const unsigned char* ptr = static_cast<const unsigned  char*>(data);
101     uint32_t ssrc = (ptr[8] << 24) + (ptr[9] << 16) + (ptr[10] << 8) + ptr[11];
102     if (ssrc == rtx_ssrc_) count_rtx_ssrc_++;
103     uint16_t sequence_number = (ptr[2] << 8) + ptr[3];
104     expected_sequence_numbers_.insert(expected_sequence_numbers_.end(),
105         sequence_number);
106     if (packet_loss_ > 0) {
107       if ((count_ % packet_loss_) == 0) {
108         return len;
109       }
110     } else if (count_ >= consecutive_drop_start_ &&
111         count_ < consecutive_drop_end_) {
112       return len;
113     }
114     int packet_length = len;
115     // TODO(pbos): Figure out why this needs to be initialized. Likely this
116     // is hiding a bug either in test setup or other code.
117     // https://code.google.com/p/webrtc/issues/detail?id=3183
118     uint8_t restored_packet[1500] = {0};
119     uint8_t* restored_packet_ptr = restored_packet;
120     RTPHeader header;
121     scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
122     if (!parser->Parse(ptr, len, &header)) {
123       return -1;
124     }
125     if (rtp_payload_registry_->IsRtx(header)) {
126       // Remove the RTX header and parse the original RTP header.
127       EXPECT_TRUE(rtp_payload_registry_->RestoreOriginalPacket(
128           &restored_packet_ptr, ptr, &packet_length, rtp_receiver_->SSRC(),
129           header));
130       if (!parser->Parse(restored_packet_ptr, packet_length, &header)) {
131         return -1;
132       }
133     }
134     restored_packet_ptr += header.headerLength;
135     packet_length -= header.headerLength;
136     PayloadUnion payload_specific;
137     if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
138                                                     &payload_specific)) {
139       return -1;
140     }
141     if (!rtp_receiver_->IncomingRtpPacket(header, restored_packet_ptr,
142                                           packet_length, payload_specific,
143                                           true)) {
144       return -1;
145     }
146     return len;
147   }
148
149   virtual int SendRTCPPacket(int channel, const void *data, int len) OVERRIDE {
150     if (module_->IncomingRtcpPacket((const uint8_t*)data, len) == 0) {
151       return len;
152     }
153     return -1;
154   }
155   int count_;
156   int packet_loss_;
157   int consecutive_drop_start_;
158   int consecutive_drop_end_;
159   uint32_t rtx_ssrc_;
160   int count_rtx_ssrc_;
161   RTPPayloadRegistry* rtp_payload_registry_;
162   RtpReceiver* rtp_receiver_;
163   RtpRtcp* module_;
164   std::set<uint16_t> expected_sequence_numbers_;
165 };
166
167 class RtpRtcpRtxNackTest : public ::testing::Test {
168  protected:
169   RtpRtcpRtxNackTest()
170       : rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)),
171         rtp_rtcp_module_(NULL),
172         transport_(kTestSsrc + 1),
173         receiver_(),
174         payload_data_length(sizeof(payload_data)),
175         fake_clock(123456) {}
176   ~RtpRtcpRtxNackTest() {}
177
178   virtual void SetUp() OVERRIDE {
179     RtpRtcp::Configuration configuration;
180     configuration.id = kTestId;
181     configuration.audio = false;
182     configuration.clock = &fake_clock;
183     receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock));
184     configuration.receive_statistics = receive_statistics_.get();
185     configuration.outgoing_transport = &transport_;
186     rtp_rtcp_module_ = RtpRtcp::CreateRtpRtcp(configuration);
187
188     rtp_feedback_.reset(new TestRtpFeedback(rtp_rtcp_module_));
189
190     rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
191         kTestId, &fake_clock, &receiver_, rtp_feedback_.get(),
192         &rtp_payload_registry_));
193
194     rtp_rtcp_module_->SetSSRC(kTestSsrc);
195     EXPECT_EQ(0, rtp_rtcp_module_->SetRTCPStatus(kRtcpCompound));
196     rtp_receiver_->SetNACKStatus(kNackRtcp);
197     EXPECT_EQ(0, rtp_rtcp_module_->SetStorePacketsStatus(true, 600));
198     EXPECT_EQ(0, rtp_rtcp_module_->SetSendingStatus(true));
199     EXPECT_EQ(0, rtp_rtcp_module_->SetSequenceNumber(kTestSequenceNumber));
200     EXPECT_EQ(0, rtp_rtcp_module_->SetStartTimestamp(111111));
201
202     transport_.SetSendModule(rtp_rtcp_module_, &rtp_payload_registry_,
203                              rtp_receiver_.get());
204
205     VideoCodec video_codec;
206     memset(&video_codec, 0, sizeof(video_codec));
207     video_codec.plType = 123;
208     memcpy(video_codec.plName, "I420", 5);
209
210     EXPECT_EQ(0, rtp_rtcp_module_->RegisterSendPayload(video_codec));
211     EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName,
212                                                        video_codec.plType,
213                                                        90000,
214                                                        0,
215                                                        video_codec.maxBitrate));
216
217     for (int n = 0; n < payload_data_length; n++) {
218       payload_data[n] = n % 10;
219     }
220   }
221
222   int BuildNackList(uint16_t* nack_list) {
223     receiver_.sequence_numbers_.sort();
224     std::list<uint16_t> missing_sequence_numbers;
225     std::list<uint16_t>::iterator it =
226         receiver_.sequence_numbers_.begin();
227
228     while (it != receiver_.sequence_numbers_.end()) {
229       uint16_t sequence_number_1 = *it;
230       ++it;
231       if (it != receiver_.sequence_numbers_.end()) {
232         uint16_t sequence_number_2 = *it;
233         // Add all missing sequence numbers to list
234         for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2;
235             ++i) {
236           missing_sequence_numbers.push_back(i);
237         }
238       }
239     }
240     int n = 0;
241     for (it = missing_sequence_numbers.begin();
242         it != missing_sequence_numbers.end(); ++it) {
243       nack_list[n++] = (*it);
244     }
245     return n;
246   }
247
248   bool ExpectedPacketsReceived() {
249     std::list<uint16_t> received_sorted;
250     std::copy(receiver_.sequence_numbers_.begin(),
251               receiver_.sequence_numbers_.end(),
252               std::back_inserter(received_sorted));
253     received_sorted.sort();
254     return std::equal(received_sorted.begin(), received_sorted.end(),
255                       transport_.expected_sequence_numbers_.begin());
256   }
257
258   void RunRtxTest(RtxMode rtx_method, int loss) {
259     rtp_payload_registry_.SetRtxSsrc(kTestSsrc + 1);
260     rtp_rtcp_module_->SetRTXSendStatus(rtx_method);
261     rtp_rtcp_module_->SetRtxSsrc(kTestSsrc + 1);
262     transport_.DropEveryNthPacket(loss);
263     uint32_t timestamp = 3000;
264     uint16_t nack_list[kVideoNackListSize];
265     for (int frame = 0; frame < kNumFrames; ++frame) {
266       EXPECT_EQ(0, rtp_rtcp_module_->SendOutgoingData(webrtc::kVideoFrameDelta,
267                                                       123,
268                                                       timestamp,
269                                                       timestamp / 90,
270                                                       payload_data,
271                                                       payload_data_length));
272       int length = BuildNackList(nack_list);
273       if (length > 0)
274         rtp_rtcp_module_->SendNACK(nack_list, length);
275       fake_clock.AdvanceTimeMilliseconds(33);
276       rtp_rtcp_module_->Process();
277       // Prepare next frame.
278       timestamp += 3000;
279     }
280     receiver_.sequence_numbers_.sort();
281   }
282
283   virtual void TearDown() OVERRIDE {
284     delete rtp_rtcp_module_;
285   }
286
287   scoped_ptr<ReceiveStatistics> receive_statistics_;
288   RTPPayloadRegistry rtp_payload_registry_;
289   scoped_ptr<RtpReceiver> rtp_receiver_;
290   RtpRtcp* rtp_rtcp_module_;
291   scoped_ptr<TestRtpFeedback> rtp_feedback_;
292   RtxLoopBackTransport transport_;
293   VerifyingRtxReceiver receiver_;
294   uint8_t  payload_data[65000];
295   int payload_data_length;
296   SimulatedClock fake_clock;
297 };
298
299 TEST_F(RtpRtcpRtxNackTest, LongNackList) {
300   const int kNumPacketsToDrop = 900;
301   const int kNumRequiredRtcp = 4;
302   uint32_t timestamp = 3000;
303   uint16_t nack_list[kNumPacketsToDrop];
304   // Disable StorePackets to be able to set a larger packet history.
305   EXPECT_EQ(0, rtp_rtcp_module_->SetStorePacketsStatus(false, 0));
306   // Enable StorePackets with a packet history of 2000 packets.
307   EXPECT_EQ(0, rtp_rtcp_module_->SetStorePacketsStatus(true, 2000));
308   // Drop 900 packets from the second one so that we get a NACK list which is
309   // big enough to require 4 RTCP packets to be fully transmitted to the sender.
310   transport_.DropConsecutivePackets(2, kNumPacketsToDrop);
311   // Send 30 frames which at the default size is roughly what we need to get
312   // enough packets.
313   for (int frame = 0; frame < kNumFrames; ++frame) {
314     EXPECT_EQ(0, rtp_rtcp_module_->SendOutgoingData(webrtc::kVideoFrameDelta,
315                                                     123,
316                                                     timestamp,
317                                                     timestamp / 90,
318                                                     payload_data,
319                                                     payload_data_length));
320     // Prepare next frame.
321     timestamp += 3000;
322     fake_clock.AdvanceTimeMilliseconds(33);
323     rtp_rtcp_module_->Process();
324   }
325   EXPECT_FALSE(transport_.expected_sequence_numbers_.empty());
326   EXPECT_FALSE(receiver_.sequence_numbers_.empty());
327   size_t last_receive_count = receiver_.sequence_numbers_.size();
328   int length = BuildNackList(nack_list);
329   for (int i = 0; i < kNumRequiredRtcp - 1; ++i) {
330     rtp_rtcp_module_->SendNACK(nack_list, length);
331     EXPECT_GT(receiver_.sequence_numbers_.size(), last_receive_count);
332     last_receive_count = receiver_.sequence_numbers_.size();
333     EXPECT_FALSE(ExpectedPacketsReceived());
334   }
335   rtp_rtcp_module_->SendNACK(nack_list, length);
336   EXPECT_GT(receiver_.sequence_numbers_.size(), last_receive_count);
337   EXPECT_TRUE(ExpectedPacketsReceived());
338 }
339
340 TEST_F(RtpRtcpRtxNackTest, RtxNack) {
341   RunRtxTest(kRtxRetransmitted, 10);
342   EXPECT_EQ(kTestSequenceNumber, *(receiver_.sequence_numbers_.begin()));
343   EXPECT_EQ(kTestSequenceNumber + kTestNumberOfPackets - 1,
344       *(receiver_.sequence_numbers_.rbegin()));
345   EXPECT_EQ(kTestNumberOfPackets, receiver_.sequence_numbers_.size());
346   EXPECT_EQ(kTestNumberOfRtxPackets, transport_.count_rtx_ssrc_);
347   EXPECT_TRUE(ExpectedPacketsReceived());
348 }