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.
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"
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);
23 typedef std::map
<uint32
, size_t> MissingPacketsMap
;
25 class NackFeedbackVerification
: public RtpPayloadFeedback
{
27 NackFeedbackVerification()
28 : triggered_(false), missing_packets_(), last_frame_acked_(0) {}
30 virtual void CastFeedback(const RtcpCastMessage
& cast_feedback
) OVERRIDE
{
31 EXPECT_EQ(kSsrc
, cast_feedback
.media_ssrc_
);
33 last_frame_acked_
= cast_feedback
.ack_frame_id_
;
35 MissingFramesAndPacketsMap::const_iterator frame_it
=
36 cast_feedback
.missing_frames_and_packets_
.begin();
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
));
47 missing_packets_
.insert(
48 std::make_pair(frame_it
->first
, frame_it
->second
.size()));
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())
64 // Holds value for one call.
66 bool ret_val
= triggered_
;
71 uint32
last_frame_acked() { return last_frame_acked_
; }
75 MissingPacketsMap missing_packets_
; // Missing packets per frame.
76 uint32 last_frame_acked_
;
78 DISALLOW_COPY_AND_ASSIGN(NackFeedbackVerification
);
82 class CastMessageBuilderTest
: public ::testing::Test
{
84 CastMessageBuilderTest()
85 : cast_msg_builder_(new CastMessageBuilder(&testing_clock_
,
91 rtp_header_
.sender_ssrc
= kSsrc
;
92 rtp_header_
.is_key_frame
= false;
93 testing_clock_
.Advance(
94 base::TimeDelta::FromMilliseconds(kStartMillisecond
));
97 virtual ~CastMessageBuilderTest() {}
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
;
104 void SetPacketId(uint16 packet_id
) { rtp_header_
.packet_id
= packet_id
; }
106 void SetMaxPacketId(uint16 max_packet_id
) {
107 rtp_header_
.max_packet_id
= max_packet_id
;
110 void SetKeyFrame(bool is_key
) { rtp_header_
.is_key_frame
= is_key
; }
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
);
118 cast_msg_builder_
->UpdateCastMessage();
121 void SetDecoderSlowerThanMaxFrameRate(int max_unacked_frames
) {
122 cast_msg_builder_
.reset(new CastMessageBuilder(&testing_clock_
,
127 max_unacked_frames
));
130 NackFeedbackVerification feedback_
;
131 scoped_ptr
<CastMessageBuilder
> cast_msg_builder_
;
132 RtpCastHeader rtp_header_
;
133 FrameIdMap frame_id_map_
;
134 base::SimpleTestTickClock testing_clock_
;
136 DISALLOW_COPY_AND_ASSIGN(CastMessageBuilderTest
);
139 TEST_F(CastMessageBuilderTest
, StartWithAKeyFrame
) {
144 // Should not trigger ack.
145 EXPECT_FALSE(feedback_
.triggered());
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());
159 TEST_F(CastMessageBuilderTest
, OneFrameNackList
) {
164 testing_clock_
.Advance(
165 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs
));
166 EXPECT_FALSE(feedback_
.triggered());
167 testing_clock_
.Advance(
168 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
171 EXPECT_TRUE(feedback_
.triggered());
172 EXPECT_EQ(4u, feedback_
.num_missing_packets(0));
175 TEST_F(CastMessageBuilderTest
, CompleteFrameMissing
) {
180 testing_clock_
.Advance(
181 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
186 EXPECT_TRUE(feedback_
.triggered());
187 EXPECT_EQ(kRtcpCastAllPacketsLost
, feedback_
.num_missing_packets(1));
190 TEST_F(CastMessageBuilderTest
, FastForwardAck
) {
195 EXPECT_FALSE(feedback_
.triggered());
196 testing_clock_
.Advance(
197 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
202 EXPECT_TRUE(feedback_
.triggered());
203 EXPECT_EQ(kStartFrameId
, feedback_
.last_frame_acked());
204 testing_clock_
.Advance(
205 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
211 EXPECT_TRUE(feedback_
.triggered());
212 EXPECT_EQ(2u, feedback_
.last_frame_acked());
215 TEST_F(CastMessageBuilderTest
, RemoveOldFrames
) {
220 EXPECT_FALSE(feedback_
.triggered());
221 testing_clock_
.Advance(
222 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
227 EXPECT_TRUE(feedback_
.triggered());
228 testing_clock_
.Advance(
229 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
234 EXPECT_TRUE(feedback_
.triggered());
235 EXPECT_EQ(kStartFrameId
, feedback_
.last_frame_acked());
236 testing_clock_
.Advance(
237 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
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
));
255 EXPECT_FALSE(feedback_
.triggered());
256 testing_clock_
.Advance(
257 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
259 EXPECT_TRUE(feedback_
.triggered());
260 EXPECT_EQ(5u, feedback_
.last_frame_acked());
263 TEST_F(CastMessageBuilderTest
, WrapFastForward
) {
264 SetFrameIds(254, 254);
269 EXPECT_FALSE(feedback_
.triggered());
270 testing_clock_
.Advance(
271 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
272 SetFrameIds(255, 254);
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);
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);
295 EXPECT_TRUE(feedback_
.triggered());
296 EXPECT_EQ(256u, feedback_
.last_frame_acked());
299 TEST_F(CastMessageBuilderTest
, NackUntilMaxReceivedPacket
) {
305 testing_clock_
.Advance(
306 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
309 EXPECT_TRUE(feedback_
.triggered());
310 EXPECT_EQ(4u, feedback_
.num_missing_packets(0));
313 TEST_F(CastMessageBuilderTest
, NackUntilMaxReceivedPacketNextFrame
) {
319 testing_clock_
.Advance(
320 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
323 testing_clock_
.Advance(
324 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
325 EXPECT_TRUE(feedback_
.triggered());
326 EXPECT_EQ(4u, feedback_
.num_missing_packets(0));
332 testing_clock_
.Advance(
333 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
334 EXPECT_TRUE(feedback_
.triggered());
335 EXPECT_EQ(19u, feedback_
.num_missing_packets(0));
338 TEST_F(CastMessageBuilderTest
, NackUntilMaxReceivedPacketNextKey
) {
344 testing_clock_
.Advance(
345 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
348 testing_clock_
.Advance(
349 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
350 EXPECT_TRUE(feedback_
.triggered());
351 EXPECT_EQ(4u, feedback_
.num_missing_packets(0));
357 testing_clock_
.Advance(
358 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
359 EXPECT_TRUE(feedback_
.triggered());
360 EXPECT_EQ(0u, feedback_
.num_missing_packets(0));
363 TEST_F(CastMessageBuilderTest
, Reset
) {
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));
375 TEST_F(CastMessageBuilderTest
, DeltaAfterReset
) {
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();
390 EXPECT_FALSE(feedback_
.triggered());
393 TEST_F(CastMessageBuilderTest
, BasicRps
) {
399 testing_clock_
.Advance(
400 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs
));
401 EXPECT_TRUE(feedback_
.triggered());
402 EXPECT_EQ(0u, feedback_
.last_frame_acked());
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());
416 TEST_F(CastMessageBuilderTest
, InOrderRps
) {
417 // Create a pattern - skip to rps, and don't look back.
423 testing_clock_
.Advance(
424 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs
));
425 EXPECT_TRUE(feedback_
.triggered());
426 EXPECT_EQ(0u, feedback_
.last_frame_acked());
432 testing_clock_
.Advance(
433 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs
));
434 EXPECT_FALSE(feedback_
.triggered());
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.
454 testing_clock_
.Advance(
455 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs
));
456 EXPECT_FALSE(feedback_
.triggered());
457 EXPECT_EQ(3u, feedback_
.last_frame_acked());
460 TEST_F(CastMessageBuilderTest
, SlowDownAck
) {
461 SetDecoderSlowerThanMaxFrameRate(3);
469 testing_clock_
.Advance(
470 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs
));
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);
477 testing_clock_
.Advance(
478 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs
));
480 // We should now have entered the slowdown ACK state.
481 uint32 expected_frame_id
= 1;
482 for (; frame_id
< 10; ++frame_id
) {
485 EXPECT_TRUE(feedback_
.triggered());
486 EXPECT_EQ(expected_frame_id
, feedback_
.last_frame_acked());
487 SetFrameIds(frame_id
, frame_id
- 1);
489 testing_clock_
.Advance(
490 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs
));
492 EXPECT_TRUE(feedback_
.triggered());
493 EXPECT_EQ(expected_frame_id
, feedback_
.last_frame_acked());
495 // Simulate frame_id being pulled for rendering.
496 frame_id_map_
.RemoveOldFrames(frame_id
);
497 // We should now leave the slowdown ACK state.
499 SetFrameIds(frame_id
, frame_id
- 1);
501 testing_clock_
.Advance(
502 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs
));
503 EXPECT_TRUE(feedback_
.triggered());
504 EXPECT_EQ(frame_id
, feedback_
.last_frame_acked());