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());