Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / media / cast / net / rtp / cast_message_builder_unittest.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdint.h>
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "media/cast/net/rtcp/rtcp.h"
10 #include "media/cast/net/rtp/cast_message_builder.h"
11 #include "media/cast/net/rtp/rtp_receiver_defines.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace media {
15 namespace cast {
16
17 namespace {
18 static const uint32 kSsrc = 0x1234;
19 static const uint32 kShortTimeIncrementMs = 10;
20 static const uint32 kLongTimeIncrementMs = 40;
21 static const int64 kStartMillisecond = INT64_C(12345678900000);
22
23 typedef std::map<uint32, size_t> MissingPacketsMap;
24
25 class NackFeedbackVerification : public RtpPayloadFeedback {
26  public:
27   NackFeedbackVerification()
28       : triggered_(false), missing_packets_(), last_frame_acked_(0) {}
29
30   virtual void CastFeedback(const RtcpCastMessage& cast_feedback) OVERRIDE {
31     EXPECT_EQ(kSsrc, cast_feedback.media_ssrc);
32
33     last_frame_acked_ = cast_feedback.ack_frame_id;
34
35     MissingFramesAndPacketsMap::const_iterator frame_it =
36         cast_feedback.missing_frames_and_packets.begin();
37
38     // Keep track of the number of missing packets per frame.
39     missing_packets_.clear();
40     while (frame_it != cast_feedback.missing_frames_and_packets.end()) {
41       // Check for complete frame lost.
42       if ((frame_it->second.size() == 1) &&
43           (*frame_it->second.begin() == kRtcpCastAllPacketsLost)) {
44         missing_packets_.insert(
45             std::make_pair(frame_it->first, kRtcpCastAllPacketsLost));
46       } else {
47         missing_packets_.insert(
48             std::make_pair(frame_it->first, frame_it->second.size()));
49       }
50       ++frame_it;
51     }
52     triggered_ = true;
53   }
54
55   size_t num_missing_packets(uint32 frame_id) {
56     MissingPacketsMap::iterator it;
57     it = missing_packets_.find(frame_id);
58     if (it == missing_packets_.end())
59       return 0;
60
61     return it->second;
62   }
63
64   // Holds value for one call.
65   bool triggered() {
66     bool ret_val = triggered_;
67     triggered_ = false;
68     return ret_val;
69   }
70
71   uint32 last_frame_acked() { return last_frame_acked_; }
72
73  private:
74   bool triggered_;
75   MissingPacketsMap missing_packets_;  // Missing packets per frame.
76   uint32 last_frame_acked_;
77
78   DISALLOW_COPY_AND_ASSIGN(NackFeedbackVerification);
79 };
80 }  // namespace
81
82 class CastMessageBuilderTest : public ::testing::Test {
83  protected:
84   CastMessageBuilderTest()
85       : cast_msg_builder_(new CastMessageBuilder(&testing_clock_,
86                                                  &feedback_,
87                                                  &frame_id_map_,
88                                                  kSsrc,
89                                                  true,
90                                                  0)) {
91     rtp_header_.sender_ssrc = kSsrc;
92     rtp_header_.is_key_frame = false;
93     testing_clock_.Advance(
94         base::TimeDelta::FromMilliseconds(kStartMillisecond));
95   }
96
97   virtual ~CastMessageBuilderTest() {}
98
99   void SetFrameIds(uint32 frame_id, uint32 reference_frame_id) {
100     rtp_header_.frame_id = frame_id;
101     rtp_header_.reference_frame_id = reference_frame_id;
102   }
103
104   void SetPacketId(uint16 packet_id) { rtp_header_.packet_id = packet_id; }
105
106   void SetMaxPacketId(uint16 max_packet_id) {
107     rtp_header_.max_packet_id = max_packet_id;
108   }
109
110   void SetKeyFrame(bool is_key) { rtp_header_.is_key_frame = is_key; }
111
112   void InsertPacket() {
113     PacketType packet_type = frame_id_map_.InsertPacket(rtp_header_);
114     if (packet_type == kNewPacketCompletingFrame) {
115       cast_msg_builder_->CompleteFrameReceived(rtp_header_.frame_id);
116     }
117     cast_msg_builder_->UpdateCastMessage();
118   }
119
120   void SetDecoderSlowerThanMaxFrameRate(int max_unacked_frames) {
121     cast_msg_builder_.reset(new CastMessageBuilder(&testing_clock_,
122                                                    &feedback_,
123                                                    &frame_id_map_,
124                                                    kSsrc,
125                                                    false,
126                                                    max_unacked_frames));
127   }
128
129   NackFeedbackVerification feedback_;
130   scoped_ptr<CastMessageBuilder> cast_msg_builder_;
131   RtpCastHeader rtp_header_;
132   FrameIdMap frame_id_map_;
133   base::SimpleTestTickClock testing_clock_;
134
135   DISALLOW_COPY_AND_ASSIGN(CastMessageBuilderTest);
136 };
137
138 TEST_F(CastMessageBuilderTest, OneFrameNackList) {
139   SetFrameIds(0, 0);
140   SetPacketId(4);
141   SetMaxPacketId(10);
142   InsertPacket();
143   testing_clock_.Advance(
144       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
145   EXPECT_FALSE(feedback_.triggered());
146   testing_clock_.Advance(
147       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
148   SetPacketId(5);
149   InsertPacket();
150   EXPECT_TRUE(feedback_.triggered());
151   EXPECT_EQ(4u, feedback_.num_missing_packets(0));
152 }
153
154 TEST_F(CastMessageBuilderTest, CompleteFrameMissing) {
155   SetFrameIds(0, 0);
156   SetPacketId(2);
157   SetMaxPacketId(5);
158   InsertPacket();
159   testing_clock_.Advance(
160       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
161   SetFrameIds(2, 1);
162   SetPacketId(2);
163   SetMaxPacketId(5);
164   InsertPacket();
165   EXPECT_TRUE(feedback_.triggered());
166   EXPECT_EQ(kRtcpCastAllPacketsLost, feedback_.num_missing_packets(1));
167 }
168
169 TEST_F(CastMessageBuilderTest, RemoveOldFrames) {
170   SetFrameIds(1, 0);
171   SetPacketId(0);
172   SetMaxPacketId(1);
173   InsertPacket();
174   EXPECT_FALSE(feedback_.triggered());
175   testing_clock_.Advance(
176       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
177   SetFrameIds(2, 1);
178   SetPacketId(0);
179   SetMaxPacketId(0);
180   InsertPacket();
181   EXPECT_TRUE(feedback_.triggered());
182   testing_clock_.Advance(
183       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
184   SetFrameIds(3, 2);
185   SetPacketId(0);
186   SetMaxPacketId(5);
187   InsertPacket();
188   EXPECT_TRUE(feedback_.triggered());
189   EXPECT_EQ(2u, feedback_.last_frame_acked());
190   testing_clock_.Advance(
191       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
192   SetFrameIds(5, 5);
193   SetPacketId(0);
194   SetMaxPacketId(0);
195   SetKeyFrame(true);
196   InsertPacket();
197   testing_clock_.Advance(
198       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
199   frame_id_map_.RemoveOldFrames(5);  // Simulate 5 being pulled for rendering.
200   cast_msg_builder_->UpdateCastMessage();
201   EXPECT_TRUE(feedback_.triggered());
202   EXPECT_EQ(5u, feedback_.last_frame_acked());
203   testing_clock_.Advance(
204       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
205   SetFrameIds(1, 0);
206   SetPacketId(1);
207   SetMaxPacketId(1);
208   InsertPacket();
209   EXPECT_FALSE(feedback_.triggered());
210   testing_clock_.Advance(
211       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
212   InsertPacket();
213   EXPECT_TRUE(feedback_.triggered());
214   EXPECT_EQ(5u, feedback_.last_frame_acked());
215 }
216
217 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacket) {
218   SetFrameIds(0, 0);
219   SetPacketId(0);
220   SetMaxPacketId(20);
221   SetKeyFrame(true);
222   InsertPacket();
223   testing_clock_.Advance(
224       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
225   SetPacketId(5);
226   InsertPacket();
227   EXPECT_TRUE(feedback_.triggered());
228   EXPECT_EQ(4u, feedback_.num_missing_packets(0));
229 }
230
231 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextFrame) {
232   SetFrameIds(0, 0);
233   SetPacketId(0);
234   SetMaxPacketId(20);
235   SetKeyFrame(true);
236   InsertPacket();
237   testing_clock_.Advance(
238       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
239   SetPacketId(5);
240   InsertPacket();
241   testing_clock_.Advance(
242       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
243   EXPECT_TRUE(feedback_.triggered());
244   EXPECT_EQ(4u, feedback_.num_missing_packets(0));
245   SetFrameIds(1, 0);
246   SetMaxPacketId(2);
247   SetPacketId(0);
248   SetKeyFrame(false);
249   InsertPacket();
250   testing_clock_.Advance(
251       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
252   EXPECT_TRUE(feedback_.triggered());
253   EXPECT_EQ(19u, feedback_.num_missing_packets(0));
254 }
255
256 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextKey) {
257   SetFrameIds(0, 0);
258   SetPacketId(0);
259   SetMaxPacketId(20);
260   SetKeyFrame(true);
261   InsertPacket();
262   testing_clock_.Advance(
263       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
264   SetPacketId(5);
265   InsertPacket();
266   testing_clock_.Advance(
267       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
268   EXPECT_TRUE(feedback_.triggered());
269   EXPECT_EQ(4u, feedback_.num_missing_packets(0));
270   SetFrameIds(1, 1);
271   SetMaxPacketId(0);
272   SetPacketId(0);
273   SetKeyFrame(true);
274   InsertPacket();
275   testing_clock_.Advance(
276       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
277   EXPECT_TRUE(feedback_.triggered());
278   EXPECT_EQ(0u, feedback_.num_missing_packets(0));
279 }
280
281 TEST_F(CastMessageBuilderTest, Reset) {
282   InsertPacket();
283   testing_clock_.Advance(
284       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
285   cast_msg_builder_->Reset();
286   frame_id_map_.Clear();
287   // Should reset nack list state and request a key frame.
288   cast_msg_builder_->UpdateCastMessage();
289   EXPECT_TRUE(feedback_.triggered());
290   EXPECT_EQ(0u, feedback_.num_missing_packets(0));
291 }
292
293 TEST_F(CastMessageBuilderTest, DeltaAfterReset) {
294   SetFrameIds(0, 0);
295   SetPacketId(0);
296   SetMaxPacketId(0);
297   SetKeyFrame(true);
298   InsertPacket();
299   EXPECT_TRUE(feedback_.triggered());
300   EXPECT_EQ(0u, feedback_.num_missing_packets(0));
301   testing_clock_.Advance(
302       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
303   cast_msg_builder_->Reset();
304   SetFrameIds(1, 0);
305   SetPacketId(0);
306   SetMaxPacketId(0);
307   SetKeyFrame(true);
308   EXPECT_FALSE(feedback_.triggered());
309 }
310
311 TEST_F(CastMessageBuilderTest, BasicRps) {
312   SetFrameIds(0, 0);
313   SetPacketId(0);
314   SetMaxPacketId(0);
315   SetKeyFrame(true);
316   InsertPacket();
317   testing_clock_.Advance(
318       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
319   EXPECT_TRUE(feedback_.triggered());
320   EXPECT_EQ(0u, feedback_.last_frame_acked());
321   SetFrameIds(3, 0);
322   SetKeyFrame(false);
323   InsertPacket();
324   EXPECT_TRUE(feedback_.triggered());
325   EXPECT_EQ(3u, feedback_.last_frame_acked());
326   testing_clock_.Advance(
327       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
328   frame_id_map_.RemoveOldFrames(3);  // Simulate 3 being pulled for rendering.
329   cast_msg_builder_->UpdateCastMessage();
330   EXPECT_TRUE(feedback_.triggered());
331   EXPECT_EQ(3u, feedback_.last_frame_acked());
332 }
333
334 TEST_F(CastMessageBuilderTest, InOrderRps) {
335   // Create a pattern - skip to rps, and don't look back.
336   SetFrameIds(0, 0);
337   SetPacketId(0);
338   SetMaxPacketId(0);
339   SetKeyFrame(true);
340   InsertPacket();
341   testing_clock_.Advance(
342       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
343   EXPECT_TRUE(feedback_.triggered());
344   EXPECT_EQ(0u, feedback_.last_frame_acked());
345   SetFrameIds(1, 0);
346   SetPacketId(0);
347   SetMaxPacketId(1);
348   SetKeyFrame(false);
349   InsertPacket();
350   testing_clock_.Advance(
351       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
352   EXPECT_FALSE(feedback_.triggered());
353   SetFrameIds(3, 0);
354   SetPacketId(0);
355   SetMaxPacketId(0);
356   SetKeyFrame(false);
357   InsertPacket();
358   testing_clock_.Advance(
359       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
360   frame_id_map_.RemoveOldFrames(3);  // Simulate 3 being pulled for rendering.
361   testing_clock_.Advance(
362       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
363   cast_msg_builder_->UpdateCastMessage();
364   EXPECT_TRUE(feedback_.triggered());
365   EXPECT_EQ(3u, feedback_.last_frame_acked());
366   // Make an old frame complete - should not trigger an ack.
367   SetFrameIds(1, 0);
368   SetPacketId(1);
369   SetMaxPacketId(1);
370   SetKeyFrame(false);
371   InsertPacket();
372   testing_clock_.Advance(
373       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
374   EXPECT_FALSE(feedback_.triggered());
375   EXPECT_EQ(3u, feedback_.last_frame_acked());
376 }
377
378 TEST_F(CastMessageBuilderTest, SlowDownAck) {
379   SetDecoderSlowerThanMaxFrameRate(3);
380   SetFrameIds(0, 0);
381   SetPacketId(0);
382   SetMaxPacketId(0);
383   SetKeyFrame(true);
384   InsertPacket();
385
386   uint32 frame_id;
387   testing_clock_.Advance(
388       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
389   SetKeyFrame(false);
390   for (frame_id = 1; frame_id < 3; ++frame_id) {
391     EXPECT_TRUE(feedback_.triggered());
392     EXPECT_EQ(frame_id - 1, feedback_.last_frame_acked());
393     SetFrameIds(frame_id, frame_id - 1);
394     InsertPacket();
395     testing_clock_.Advance(
396         base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
397   }
398   // We should now have entered the slowdown ACK state.
399   uint32 expected_frame_id = 1;
400   for (; frame_id < 10; ++frame_id) {
401     if (frame_id % 2) {
402       ++expected_frame_id;
403       EXPECT_TRUE(feedback_.triggered());
404     } else {
405       EXPECT_FALSE(feedback_.triggered());
406     }
407     EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
408     SetFrameIds(frame_id, frame_id - 1);
409     InsertPacket();
410     testing_clock_.Advance(
411         base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
412   }
413   EXPECT_FALSE(feedback_.triggered());
414   EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
415
416   // Simulate frame_id being pulled for rendering.
417   frame_id_map_.RemoveOldFrames(frame_id);
418   // We should now leave the slowdown ACK state.
419   ++frame_id;
420   SetFrameIds(frame_id, frame_id - 1);
421   InsertPacket();
422   testing_clock_.Advance(
423       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
424   EXPECT_TRUE(feedback_.triggered());
425   EXPECT_EQ(frame_id, feedback_.last_frame_acked());
426 }
427
428 }  // namespace cast
429 }  // namespace media