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.
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"
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);
21 typedef std::map<uint32, size_t> MissingPacketsMap;
23 class NackFeedbackVerification : public RtpPayloadFeedback {
25 NackFeedbackVerification()
26 : triggered_(false), missing_packets_(), last_frame_acked_(0) {}
28 virtual void CastFeedback(const RtcpCastMessage& cast_feedback) OVERRIDE {
29 EXPECT_EQ(kSsrc, cast_feedback.media_ssrc_);
31 last_frame_acked_ = cast_feedback.ack_frame_id_;
33 MissingFramesAndPacketsMap::const_iterator frame_it =
34 cast_feedback.missing_frames_and_packets_.begin();
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));
45 missing_packets_.insert(
46 std::make_pair(frame_it->first, frame_it->second.size()));
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())
62 // Holds value for one call.
64 bool ret_val = triggered_;
69 uint32 last_frame_acked() { return last_frame_acked_; }
73 MissingPacketsMap missing_packets_; // Missing packets per frame.
74 uint32 last_frame_acked_;
76 DISALLOW_COPY_AND_ASSIGN(NackFeedbackVerification);
80 class CastMessageBuilderTest : public ::testing::Test {
82 CastMessageBuilderTest()
83 : cast_msg_builder_(new CastMessageBuilder(&testing_clock_,
89 rtp_header_.webrtc.header.ssrc = kSsrc;
90 rtp_header_.is_key_frame = false;
91 testing_clock_.Advance(
92 base::TimeDelta::FromMilliseconds(kStartMillisecond));
95 virtual ~CastMessageBuilderTest() {}
97 void SetFrameId(uint32 frame_id) { rtp_header_.frame_id = frame_id; }
99 void SetPacketId(uint16 packet_id) { rtp_header_.packet_id = packet_id; }
101 void SetMaxPacketId(uint16 max_packet_id) {
102 rtp_header_.max_packet_id = max_packet_id;
105 void SetKeyFrame(bool is_key) { rtp_header_.is_key_frame = is_key; }
107 void SetReferenceFrameId(uint32 reference_frame_id) {
108 rtp_header_.is_reference = true;
109 rtp_header_.reference_frame_id = reference_frame_id;
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) {
269 EXPECT_FALSE(feedback_.triggered());
270 testing_clock_.Advance(
271 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
277 EXPECT_TRUE(feedback_.triggered());
278 EXPECT_EQ(253u, feedback_.last_frame_acked());
279 testing_clock_.Advance(
280 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
286 EXPECT_TRUE(feedback_.triggered());
287 EXPECT_EQ(253u, feedback_.last_frame_acked());
288 testing_clock_.Advance(
289 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
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());
405 SetReferenceFrameId(0);
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());
417 TEST_F(CastMessageBuilderTest, InOrderRps) {
418 // Create a pattern - skip to rps, and don't look back.
424 testing_clock_.Advance(
425 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
426 EXPECT_TRUE(feedback_.triggered());
427 EXPECT_EQ(0u, feedback_.last_frame_acked());
433 testing_clock_.Advance(
434 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
435 EXPECT_FALSE(feedback_.triggered());
440 SetReferenceFrameId(0);
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.
456 testing_clock_.Advance(
457 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
458 EXPECT_FALSE(feedback_.triggered());
459 EXPECT_EQ(3u, feedback_.last_frame_acked());
462 TEST_F(CastMessageBuilderTest, SlowDownAck) {
463 SetDecoderSlowerThanMaxFrameRate(3);
471 testing_clock_.Advance(
472 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
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);
479 testing_clock_.Advance(
480 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
482 // We should now have entered the slowdown ACK state.
483 uint32 expected_frame_id = 1;
484 for (; frame_id < 10; ++frame_id) {
487 EXPECT_TRUE(feedback_.triggered());
488 EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
489 SetFrameId(frame_id);
491 testing_clock_.Advance(
492 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
494 EXPECT_TRUE(feedback_.triggered());
495 EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
497 // Simulate frame_id being pulled for rendering.
498 frame_id_map_.RemoveOldFrames(frame_id);
499 // We should now leave the slowdown ACK state.
501 SetFrameId(frame_id);
503 testing_clock_.Advance(
504 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
505 EXPECT_TRUE(feedback_.triggered());
506 EXPECT_EQ(frame_id, feedback_.last_frame_acked());