Upstream version 5.34.104.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 "base/memory/scoped_ptr.h"
6 #include "base/test/simple_test_tick_clock.h"
7 #include "media/cast/framer/cast_message_builder.h"
8 #include "media/cast/rtcp/rtcp.h"
9 #include "media/cast/rtp_receiver/rtp_receiver_defines.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace media {
13 namespace cast {
14
15 namespace {
16 static const uint32 kSsrc = 0x1234;
17 static const uint32 kShortTimeIncrementMs = 10;
18 static const uint32 kLongTimeIncrementMs = 40;
19 static const int64 kStartMillisecond = GG_INT64_C(12345678900000);
20
21 typedef std::map<uint32, size_t> MissingPacketsMap;
22
23 class NackFeedbackVerification : public RtpPayloadFeedback {
24  public:
25   NackFeedbackVerification()
26       : triggered_(false), missing_packets_(), last_frame_acked_(0) {}
27
28   virtual void CastFeedback(const RtcpCastMessage& cast_feedback) OVERRIDE {
29     EXPECT_EQ(kSsrc, cast_feedback.media_ssrc_);
30
31     last_frame_acked_ = cast_feedback.ack_frame_id_;
32
33     MissingFramesAndPacketsMap::const_iterator frame_it =
34         cast_feedback.missing_frames_and_packets_.begin();
35
36     // Keep track of the number of missing packets per frame.
37     missing_packets_.clear();
38     while (frame_it != cast_feedback.missing_frames_and_packets_.end()) {
39       // Check for complete frame lost.
40       if ((frame_it->second.size() == 1) &&
41           (*frame_it->second.begin() == kRtcpCastAllPacketsLost)) {
42         missing_packets_.insert(
43             std::make_pair(frame_it->first, kRtcpCastAllPacketsLost));
44       } else {
45         missing_packets_.insert(
46             std::make_pair(frame_it->first, frame_it->second.size()));
47       }
48       ++frame_it;
49     }
50     triggered_ = true;
51   }
52
53   size_t num_missing_packets(uint32 frame_id) {
54     MissingPacketsMap::iterator it;
55     it = missing_packets_.find(frame_id);
56     if (it == missing_packets_.end())
57       return 0;
58
59     return it->second;
60   }
61
62   // Holds value for one call.
63   bool triggered() {
64     bool ret_val = triggered_;
65     triggered_ = false;
66     return ret_val;
67   }
68
69   uint32 last_frame_acked() { return last_frame_acked_; }
70
71  private:
72   bool triggered_;
73   MissingPacketsMap missing_packets_;  // Missing packets per frame.
74   uint32 last_frame_acked_;
75
76   DISALLOW_COPY_AND_ASSIGN(NackFeedbackVerification);
77 };
78 }  // namespace
79
80 class CastMessageBuilderTest : public ::testing::Test {
81  protected:
82   CastMessageBuilderTest()
83       : cast_msg_builder_(new CastMessageBuilder(&testing_clock_,
84                                                  &feedback_,
85                                                  &frame_id_map_,
86                                                  kSsrc,
87                                                  true,
88                                                  0)) {
89     rtp_header_.webrtc.header.ssrc = kSsrc;
90     rtp_header_.is_key_frame = false;
91     testing_clock_.Advance(
92         base::TimeDelta::FromMilliseconds(kStartMillisecond));
93   }
94
95   virtual ~CastMessageBuilderTest() {}
96
97   void SetFrameId(uint32 frame_id) { rtp_header_.frame_id = frame_id; }
98
99   void SetPacketId(uint16 packet_id) { rtp_header_.packet_id = packet_id; }
100
101   void SetMaxPacketId(uint16 max_packet_id) {
102     rtp_header_.max_packet_id = max_packet_id;
103   }
104
105   void SetKeyFrame(bool is_key) { rtp_header_.is_key_frame = is_key; }
106
107   void SetReferenceFrameId(uint32 reference_frame_id) {
108     rtp_header_.is_reference = true;
109     rtp_header_.reference_frame_id = reference_frame_id;
110   }
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   SetFrameId(3);
141   SetPacketId(0);
142   SetMaxPacketId(0);
143   InsertPacket();
144   // Should not trigger ack.
145   EXPECT_FALSE(feedback_.triggered());
146   SetFrameId(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   SetFrameId(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   SetFrameId(0);
177   SetPacketId(2);
178   SetMaxPacketId(5);
179   InsertPacket();
180   testing_clock_.Advance(
181       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
182   SetFrameId(2);
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   SetFrameId(1);
192   SetPacketId(0);
193   SetMaxPacketId(0);
194   InsertPacket();
195   EXPECT_FALSE(feedback_.triggered());
196   testing_clock_.Advance(
197       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
198   SetFrameId(2);
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   SetFrameId(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   SetFrameId(1);
217   SetPacketId(0);
218   SetMaxPacketId(1);
219   InsertPacket();
220   EXPECT_FALSE(feedback_.triggered());
221   testing_clock_.Advance(
222       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
223   SetFrameId(2);
224   SetPacketId(0);
225   SetMaxPacketId(0);
226   InsertPacket();
227   EXPECT_TRUE(feedback_.triggered());
228   testing_clock_.Advance(
229       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
230   SetFrameId(3);
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   SetFrameId(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   SetFrameId(1);
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   SetFrameId(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   SetFrameId(255);
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   SetFrameId(256);
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   SetFrameId(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   SetFrameId(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   SetFrameId(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   SetFrameId(1);
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   SetFrameId(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   SetFrameId(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   SetFrameId(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   SetFrameId(1);
387   SetPacketId(0);
388   SetMaxPacketId(0);
389   SetKeyFrame(true);
390   EXPECT_FALSE(feedback_.triggered());
391 }
392
393 TEST_F(CastMessageBuilderTest, BasicRps) {
394   SetFrameId(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   SetFrameId(3);
404   SetKeyFrame(false);
405   SetReferenceFrameId(0);
406   InsertPacket();
407   EXPECT_TRUE(feedback_.triggered());
408   EXPECT_EQ(0u, feedback_.last_frame_acked());
409   testing_clock_.Advance(
410       base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
411   frame_id_map_.RemoveOldFrames(3);  // Simulate 3 being pulled for rendering.
412   cast_msg_builder_->UpdateCastMessage();
413   EXPECT_TRUE(feedback_.triggered());
414   EXPECT_EQ(3u, feedback_.last_frame_acked());
415 }
416
417 TEST_F(CastMessageBuilderTest, InOrderRps) {
418   // Create a pattern - skip to rps, and don't look back.
419   SetFrameId(0);
420   SetPacketId(0);
421   SetMaxPacketId(0);
422   SetKeyFrame(true);
423   InsertPacket();
424   testing_clock_.Advance(
425       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
426   EXPECT_TRUE(feedback_.triggered());
427   EXPECT_EQ(0u, feedback_.last_frame_acked());
428   SetFrameId(1);
429   SetPacketId(0);
430   SetMaxPacketId(1);
431   SetKeyFrame(false);
432   InsertPacket();
433   testing_clock_.Advance(
434       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
435   EXPECT_FALSE(feedback_.triggered());
436   SetFrameId(3);
437   SetPacketId(0);
438   SetMaxPacketId(0);
439   SetKeyFrame(false);
440   SetReferenceFrameId(0);
441   InsertPacket();
442   testing_clock_.Advance(
443       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
444   frame_id_map_.RemoveOldFrames(3);  // Simulate 3 being pulled for rendering.
445   testing_clock_.Advance(
446       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
447   cast_msg_builder_->UpdateCastMessage();
448   EXPECT_TRUE(feedback_.triggered());
449   EXPECT_EQ(3u, feedback_.last_frame_acked());
450   // Make an old frame complete - should not trigger an ack.
451   SetFrameId(1);
452   SetPacketId(1);
453   SetMaxPacketId(1);
454   SetKeyFrame(false);
455   InsertPacket();
456   testing_clock_.Advance(
457       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
458   EXPECT_FALSE(feedback_.triggered());
459   EXPECT_EQ(3u, feedback_.last_frame_acked());
460 }
461
462 TEST_F(CastMessageBuilderTest, SlowDownAck) {
463   SetDecoderSlowerThanMaxFrameRate(3);
464   SetFrameId(0);
465   SetPacketId(0);
466   SetMaxPacketId(0);
467   SetKeyFrame(true);
468   InsertPacket();
469
470   uint32 frame_id;
471   testing_clock_.Advance(
472       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
473   SetKeyFrame(false);
474   for (frame_id = 1; frame_id < 3; ++frame_id) {
475     EXPECT_TRUE(feedback_.triggered());
476     EXPECT_EQ(frame_id - 1, feedback_.last_frame_acked());
477     SetFrameId(frame_id);
478     InsertPacket();
479     testing_clock_.Advance(
480         base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
481   }
482   // We should now have entered the slowdown ACK state.
483   uint32 expected_frame_id = 1;
484   for (; frame_id < 10; ++frame_id) {
485     if (frame_id % 2)
486       ++expected_frame_id;
487     EXPECT_TRUE(feedback_.triggered());
488     EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
489     SetFrameId(frame_id);
490     InsertPacket();
491     testing_clock_.Advance(
492         base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
493   }
494   EXPECT_TRUE(feedback_.triggered());
495   EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
496
497   // Simulate frame_id being pulled for rendering.
498   frame_id_map_.RemoveOldFrames(frame_id);
499   // We should now leave the slowdown ACK state.
500   ++frame_id;
501   SetFrameId(frame_id);
502   InsertPacket();
503   testing_clock_.Advance(
504       base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
505   EXPECT_TRUE(feedback_.triggered());
506   EXPECT_EQ(frame_id, feedback_.last_frame_acked());
507 }
508
509 }  // namespace cast
510 }  // namespace media