Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / cast / framer / cast_message_builder_unittest.cc
1 // Copyright 2013 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/framer/cast_message_builder.h"
10 #include "media/cast/rtcp/rtcp.h"
11 #include "media/cast/rtp_receiver/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                                                rtp_header_.is_key_frame);
117     }
118     cast_msg_builder_->UpdateCastMessage();
119   }
120
121   void SetDecoderSlowerThanMaxFrameRate(int max_unacked_frames) {
122     cast_msg_builder_.reset(new CastMessageBuilder(&testing_clock_,
123                                                    &feedback_,
124                                                    &frame_id_map_,
125                                                    kSsrc,
126                                                    false,
127                                                    max_unacked_frames));
128   }
129
130   NackFeedbackVerification feedback_;
131   scoped_ptr<CastMessageBuilder> cast_msg_builder_;
132   RtpCastHeader rtp_header_;
133   FrameIdMap frame_id_map_;
134   base::SimpleTestTickClock testing_clock_;
135
136   DISALLOW_COPY_AND_ASSIGN(CastMessageBuilderTest);
137 };
138
139 TEST_F(CastMessageBuilderTest, StartWithAKeyFrame) {
140   SetFrameIds(3, 2);
141   SetPacketId(0);
142   SetMaxPacketId(0);
143   InsertPacket();
144   // Should not trigger ack.
145   EXPECT_FALSE(feedback_.triggered());
146   SetFrameIds(5, 5);
147   SetPacketId(0);
148   SetMaxPacketId(0);
149   SetKeyFrame(true);
150   InsertPacket();
151   frame_id_map_.RemoveOldFrames(5);  // Simulate 5 being pulled for rendering.
152   testing_clock_.Advance(
153       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
154   cast_msg_builder_->UpdateCastMessage();
155   EXPECT_TRUE(feedback_.triggered());
156   EXPECT_EQ(5u, feedback_.last_frame_acked());
157 }
158
159 TEST_F(CastMessageBuilderTest, OneFrameNackList) {
160   SetFrameIds(0, 0);
161   SetPacketId(4);
162   SetMaxPacketId(10);
163   InsertPacket();
164   testing_clock_.Advance(
165       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
166   EXPECT_FALSE(feedback_.triggered());
167   testing_clock_.Advance(
168       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
169   SetPacketId(5);
170   InsertPacket();
171   EXPECT_TRUE(feedback_.triggered());
172   EXPECT_EQ(4u, feedback_.num_missing_packets(0));
173 }
174
175 TEST_F(CastMessageBuilderTest, CompleteFrameMissing) {
176   SetFrameIds(0, 0);
177   SetPacketId(2);
178   SetMaxPacketId(5);
179   InsertPacket();
180   testing_clock_.Advance(
181       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
182   SetFrameIds(2, 1);
183   SetPacketId(2);
184   SetMaxPacketId(5);
185   InsertPacket();
186   EXPECT_TRUE(feedback_.triggered());
187   EXPECT_EQ(kRtcpCastAllPacketsLost, feedback_.num_missing_packets(1));
188 }
189
190 TEST_F(CastMessageBuilderTest, FastForwardAck) {
191   SetFrameIds(1, 0);
192   SetPacketId(0);
193   SetMaxPacketId(0);
194   InsertPacket();
195   EXPECT_FALSE(feedback_.triggered());
196   testing_clock_.Advance(
197       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
198   SetFrameIds(2, 1);
199   SetPacketId(0);
200   SetMaxPacketId(0);
201   InsertPacket();
202   EXPECT_TRUE(feedback_.triggered());
203   EXPECT_EQ(kStartFrameId, feedback_.last_frame_acked());
204   testing_clock_.Advance(
205       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
206   SetFrameIds(0, 0);
207   SetPacketId(0);
208   SetMaxPacketId(0);
209   SetKeyFrame(true);
210   InsertPacket();
211   EXPECT_TRUE(feedback_.triggered());
212   EXPECT_EQ(2u, feedback_.last_frame_acked());
213 }
214
215 TEST_F(CastMessageBuilderTest, RemoveOldFrames) {
216   SetFrameIds(1, 0);
217   SetPacketId(0);
218   SetMaxPacketId(1);
219   InsertPacket();
220   EXPECT_FALSE(feedback_.triggered());
221   testing_clock_.Advance(
222       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
223   SetFrameIds(2, 1);
224   SetPacketId(0);
225   SetMaxPacketId(0);
226   InsertPacket();
227   EXPECT_TRUE(feedback_.triggered());
228   testing_clock_.Advance(
229       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
230   SetFrameIds(3, 2);
231   SetPacketId(0);
232   SetMaxPacketId(5);
233   InsertPacket();
234   EXPECT_TRUE(feedback_.triggered());
235   EXPECT_EQ(kStartFrameId, feedback_.last_frame_acked());
236   testing_clock_.Advance(
237       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
238   SetFrameIds(5, 5);
239   SetPacketId(0);
240   SetMaxPacketId(0);
241   SetKeyFrame(true);
242   InsertPacket();
243   testing_clock_.Advance(
244       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
245   frame_id_map_.RemoveOldFrames(5);  // Simulate 5 being pulled for rendering.
246   cast_msg_builder_->UpdateCastMessage();
247   EXPECT_TRUE(feedback_.triggered());
248   EXPECT_EQ(5u, feedback_.last_frame_acked());
249   testing_clock_.Advance(
250       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
251   SetFrameIds(1, 0);
252   SetPacketId(1);
253   SetMaxPacketId(1);
254   InsertPacket();
255   EXPECT_FALSE(feedback_.triggered());
256   testing_clock_.Advance(
257       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
258   InsertPacket();
259   EXPECT_TRUE(feedback_.triggered());
260   EXPECT_EQ(5u, feedback_.last_frame_acked());
261 }
262
263 TEST_F(CastMessageBuilderTest, WrapFastForward) {
264   SetFrameIds(254, 254);
265   SetPacketId(0);
266   SetMaxPacketId(1);
267   SetKeyFrame(true);
268   InsertPacket();
269   EXPECT_FALSE(feedback_.triggered());
270   testing_clock_.Advance(
271       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
272   SetFrameIds(255, 254);
273   SetPacketId(0);
274   SetMaxPacketId(0);
275   SetKeyFrame(false);
276   InsertPacket();
277   EXPECT_TRUE(feedback_.triggered());
278   EXPECT_EQ(253u, feedback_.last_frame_acked());
279   testing_clock_.Advance(
280       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
281   SetFrameIds(256, 255);
282   SetPacketId(0);
283   SetMaxPacketId(0);
284   SetKeyFrame(false);
285   InsertPacket();
286   EXPECT_TRUE(feedback_.triggered());
287   EXPECT_EQ(253u, feedback_.last_frame_acked());
288   testing_clock_.Advance(
289       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
290   SetFrameIds(254, 254);
291   SetPacketId(1);
292   SetMaxPacketId(1);
293   SetKeyFrame(true);
294   InsertPacket();
295   EXPECT_TRUE(feedback_.triggered());
296   EXPECT_EQ(256u, feedback_.last_frame_acked());
297 }
298
299 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacket) {
300   SetFrameIds(0, 0);
301   SetPacketId(0);
302   SetMaxPacketId(20);
303   SetKeyFrame(true);
304   InsertPacket();
305   testing_clock_.Advance(
306       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
307   SetPacketId(5);
308   InsertPacket();
309   EXPECT_TRUE(feedback_.triggered());
310   EXPECT_EQ(4u, feedback_.num_missing_packets(0));
311 }
312
313 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextFrame) {
314   SetFrameIds(0, 0);
315   SetPacketId(0);
316   SetMaxPacketId(20);
317   SetKeyFrame(true);
318   InsertPacket();
319   testing_clock_.Advance(
320       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
321   SetPacketId(5);
322   InsertPacket();
323   testing_clock_.Advance(
324       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
325   EXPECT_TRUE(feedback_.triggered());
326   EXPECT_EQ(4u, feedback_.num_missing_packets(0));
327   SetFrameIds(1, 0);
328   SetMaxPacketId(2);
329   SetPacketId(0);
330   SetKeyFrame(false);
331   InsertPacket();
332   testing_clock_.Advance(
333       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
334   EXPECT_TRUE(feedback_.triggered());
335   EXPECT_EQ(19u, feedback_.num_missing_packets(0));
336 }
337
338 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextKey) {
339   SetFrameIds(0, 0);
340   SetPacketId(0);
341   SetMaxPacketId(20);
342   SetKeyFrame(true);
343   InsertPacket();
344   testing_clock_.Advance(
345       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
346   SetPacketId(5);
347   InsertPacket();
348   testing_clock_.Advance(
349       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
350   EXPECT_TRUE(feedback_.triggered());
351   EXPECT_EQ(4u, feedback_.num_missing_packets(0));
352   SetFrameIds(1, 1);
353   SetMaxPacketId(0);
354   SetPacketId(0);
355   SetKeyFrame(true);
356   InsertPacket();
357   testing_clock_.Advance(
358       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
359   EXPECT_TRUE(feedback_.triggered());
360   EXPECT_EQ(0u, feedback_.num_missing_packets(0));
361 }
362
363 TEST_F(CastMessageBuilderTest, Reset) {
364   InsertPacket();
365   testing_clock_.Advance(
366       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
367   cast_msg_builder_->Reset();
368   frame_id_map_.Clear();
369   // Should reset nack list state and request a key frame.
370   cast_msg_builder_->UpdateCastMessage();
371   EXPECT_TRUE(feedback_.triggered());
372   EXPECT_EQ(0u, feedback_.num_missing_packets(0));
373 }
374
375 TEST_F(CastMessageBuilderTest, DeltaAfterReset) {
376   SetFrameIds(0, 0);
377   SetPacketId(0);
378   SetMaxPacketId(0);
379   SetKeyFrame(true);
380   InsertPacket();
381   EXPECT_TRUE(feedback_.triggered());
382   EXPECT_EQ(0u, feedback_.num_missing_packets(0));
383   testing_clock_.Advance(
384       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
385   cast_msg_builder_->Reset();
386   SetFrameIds(1, 0);
387   SetPacketId(0);
388   SetMaxPacketId(0);
389   SetKeyFrame(true);
390   EXPECT_FALSE(feedback_.triggered());
391 }
392
393 TEST_F(CastMessageBuilderTest, BasicRps) {
394   SetFrameIds(0, 0);
395   SetPacketId(0);
396   SetMaxPacketId(0);
397   SetKeyFrame(true);
398   InsertPacket();
399   testing_clock_.Advance(
400       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
401   EXPECT_TRUE(feedback_.triggered());
402   EXPECT_EQ(0u, feedback_.last_frame_acked());
403   SetFrameIds(3, 0);
404   SetKeyFrame(false);
405   InsertPacket();
406   EXPECT_TRUE(feedback_.triggered());
407   EXPECT_EQ(0u, feedback_.last_frame_acked());
408   testing_clock_.Advance(
409       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
410   frame_id_map_.RemoveOldFrames(3);  // Simulate 3 being pulled for rendering.
411   cast_msg_builder_->UpdateCastMessage();
412   EXPECT_TRUE(feedback_.triggered());
413   EXPECT_EQ(3u, feedback_.last_frame_acked());
414 }
415
416 TEST_F(CastMessageBuilderTest, InOrderRps) {
417   // Create a pattern - skip to rps, and don't look back.
418   SetFrameIds(0, 0);
419   SetPacketId(0);
420   SetMaxPacketId(0);
421   SetKeyFrame(true);
422   InsertPacket();
423   testing_clock_.Advance(
424       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
425   EXPECT_TRUE(feedback_.triggered());
426   EXPECT_EQ(0u, feedback_.last_frame_acked());
427   SetFrameIds(1, 0);
428   SetPacketId(0);
429   SetMaxPacketId(1);
430   SetKeyFrame(false);
431   InsertPacket();
432   testing_clock_.Advance(
433       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
434   EXPECT_FALSE(feedback_.triggered());
435   SetFrameIds(3, 0);
436   SetPacketId(0);
437   SetMaxPacketId(0);
438   SetKeyFrame(false);
439   InsertPacket();
440   testing_clock_.Advance(
441       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
442   frame_id_map_.RemoveOldFrames(3);  // Simulate 3 being pulled for rendering.
443   testing_clock_.Advance(
444       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
445   cast_msg_builder_->UpdateCastMessage();
446   EXPECT_TRUE(feedback_.triggered());
447   EXPECT_EQ(3u, feedback_.last_frame_acked());
448   // Make an old frame complete - should not trigger an ack.
449   SetFrameIds(1, 0);
450   SetPacketId(1);
451   SetMaxPacketId(1);
452   SetKeyFrame(false);
453   InsertPacket();
454   testing_clock_.Advance(
455       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
456   EXPECT_FALSE(feedback_.triggered());
457   EXPECT_EQ(3u, feedback_.last_frame_acked());
458 }
459
460 TEST_F(CastMessageBuilderTest, SlowDownAck) {
461   SetDecoderSlowerThanMaxFrameRate(3);
462   SetFrameIds(0, 0);
463   SetPacketId(0);
464   SetMaxPacketId(0);
465   SetKeyFrame(true);
466   InsertPacket();
467
468   uint32 frame_id;
469   testing_clock_.Advance(
470       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
471   SetKeyFrame(false);
472   for (frame_id = 1; frame_id < 3; ++frame_id) {
473     EXPECT_TRUE(feedback_.triggered());
474     EXPECT_EQ(frame_id - 1, feedback_.last_frame_acked());
475     SetFrameIds(frame_id, frame_id - 1);
476     InsertPacket();
477     testing_clock_.Advance(
478         base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
479   }
480   // We should now have entered the slowdown ACK state.
481   uint32 expected_frame_id = 1;
482   for (; frame_id < 10; ++frame_id) {
483     if (frame_id % 2)
484       ++expected_frame_id;
485     EXPECT_TRUE(feedback_.triggered());
486     EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
487     SetFrameIds(frame_id, frame_id - 1);
488     InsertPacket();
489     testing_clock_.Advance(
490         base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
491   }
492   EXPECT_TRUE(feedback_.triggered());
493   EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
494
495   // Simulate frame_id being pulled for rendering.
496   frame_id_map_.RemoveOldFrames(frame_id);
497   // We should now leave the slowdown ACK state.
498   ++frame_id;
499   SetFrameIds(frame_id, frame_id - 1);
500   InsertPacket();
501   testing_clock_.Advance(
502       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
503   EXPECT_TRUE(feedback_.triggered());
504   EXPECT_EQ(frame_id, feedback_.last_frame_acked());
505 }
506
507 }  // namespace cast
508 }  // namespace media