| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
| 6 #include "base/test/simple_test_tick_clock.h" | 6 #include "base/test/simple_test_tick_clock.h" |
| 7 #include "media/cast/framer/cast_message_builder.h" | 7 #include "media/cast/framer/cast_message_builder.h" |
| 8 #include "media/cast/rtcp/rtcp.h" | 8 #include "media/cast/rtcp/rtcp.h" |
| 9 #include "media/cast/rtp_receiver/rtp_receiver_defines.h" | 9 #include "media/cast/rtp_receiver/rtp_receiver_defines.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 | 11 |
| 12 namespace media { | 12 namespace media { |
| 13 namespace cast { | 13 namespace cast { |
| 14 | 14 |
| 15 namespace { |
| 15 static const uint32 kSsrc = 0x1234; | 16 static const uint32 kSsrc = 0x1234; |
| 16 static const uint32 kShortTimeIncrementMs = 10; | 17 static const uint32 kShortTimeIncrementMs = 10; |
| 17 static const uint32 kLongTimeIncrementMs = 40; | 18 static const uint32 kLongTimeIncrementMs = 40; |
| 18 static const int64 kStartMillisecond = GG_INT64_C(12345678900000); | 19 static const int64 kStartMillisecond = GG_INT64_C(12345678900000); |
| 19 | 20 |
| 20 namespace { | |
| 21 typedef std::map<uint32, size_t> MissingPacketsMap; | 21 typedef std::map<uint32, size_t> MissingPacketsMap; |
| 22 | 22 |
| 23 class NackFeedbackVerification : public RtpPayloadFeedback { | 23 class NackFeedbackVerification : public RtpPayloadFeedback { |
| 24 public: | 24 public: |
| 25 NackFeedbackVerification() | 25 NackFeedbackVerification() |
| 26 : triggered_(false), | 26 : triggered_(false), missing_packets_(), last_frame_acked_(0) {} |
| 27 missing_packets_(), | |
| 28 last_frame_acked_(0) {} | |
| 29 | |
| 30 | 27 |
| 31 virtual void CastFeedback(const RtcpCastMessage& cast_feedback) OVERRIDE { | 28 virtual void CastFeedback(const RtcpCastMessage& cast_feedback) OVERRIDE { |
| 32 EXPECT_EQ(kSsrc, cast_feedback.media_ssrc_); | 29 EXPECT_EQ(kSsrc, cast_feedback.media_ssrc_); |
| 33 | 30 |
| 34 last_frame_acked_ = cast_feedback.ack_frame_id_; | 31 last_frame_acked_ = cast_feedback.ack_frame_id_; |
| 35 | 32 |
| 36 MissingFramesAndPacketsMap::const_iterator frame_it = | 33 MissingFramesAndPacketsMap::const_iterator frame_it = |
| 37 cast_feedback.missing_frames_and_packets_.begin(); | 34 cast_feedback.missing_frames_and_packets_.begin(); |
| 38 | 35 |
| 39 // Keep track of the number of missing packets per frame. | 36 // Keep track of the number of missing packets per frame. |
| 40 missing_packets_.clear(); | 37 missing_packets_.clear(); |
| 41 while (frame_it != cast_feedback.missing_frames_and_packets_.end()) { | 38 while (frame_it != cast_feedback.missing_frames_and_packets_.end()) { |
| 42 // Check for complete frame lost. | 39 // Check for complete frame lost. |
| 43 if ((frame_it->second.size() == 1) && | 40 if ((frame_it->second.size() == 1) && |
| 44 (*frame_it->second.begin() == kRtcpCastAllPacketsLost)) { | 41 (*frame_it->second.begin() == kRtcpCastAllPacketsLost)) { |
| 45 missing_packets_.insert( | 42 missing_packets_.insert( |
| 46 std::make_pair(frame_it->first, kRtcpCastAllPacketsLost)); | 43 std::make_pair(frame_it->first, kRtcpCastAllPacketsLost)); |
| 47 } else { | 44 } else { |
| 48 missing_packets_.insert( | 45 missing_packets_.insert( |
| 49 std::make_pair(frame_it->first, frame_it->second.size())); | 46 std::make_pair(frame_it->first, frame_it->second.size())); |
| 50 } | 47 } |
| 51 ++frame_it; | 48 ++frame_it; |
| 52 } | 49 } |
| 53 triggered_ = true; | 50 triggered_ = true; |
| 54 } | 51 } |
| 55 | 52 |
| 56 size_t num_missing_packets(uint32 frame_id) { | 53 size_t num_missing_packets(uint32 frame_id) { |
| 57 MissingPacketsMap::iterator it; | 54 MissingPacketsMap::iterator it; |
| 58 it = missing_packets_.find(frame_id); | 55 it = missing_packets_.find(frame_id); |
| 59 if (it == missing_packets_.end()) return 0; | 56 if (it == missing_packets_.end()) |
| 57 return 0; |
| 60 | 58 |
| 61 return it->second; | 59 return it->second; |
| 62 } | 60 } |
| 63 | 61 |
| 64 // Holds value for one call. | 62 // Holds value for one call. |
| 65 bool triggered() { | 63 bool triggered() { |
| 66 bool ret_val = triggered_; | 64 bool ret_val = triggered_; |
| 67 triggered_ = false; | 65 triggered_ = false; |
| 68 return ret_val; | 66 return ret_val; |
| 69 } | 67 } |
| 70 | 68 |
| 71 uint32 last_frame_acked() { return last_frame_acked_; } | 69 uint32 last_frame_acked() { return last_frame_acked_; } |
| 72 | 70 |
| 73 private: | 71 private: |
| 74 bool triggered_; | 72 bool triggered_; |
| 75 MissingPacketsMap missing_packets_; // Missing packets per frame. | 73 MissingPacketsMap missing_packets_; // Missing packets per frame. |
| 76 uint32 last_frame_acked_; | 74 uint32 last_frame_acked_; |
| 75 |
| 76 DISALLOW_COPY_AND_ASSIGN(NackFeedbackVerification); |
| 77 }; | 77 }; |
| 78 } // namespace | 78 } // namespace |
| 79 | 79 |
| 80 class CastMessageBuilderTest : public ::testing::Test { | 80 class CastMessageBuilderTest : public ::testing::Test { |
| 81 protected: | 81 protected: |
| 82 CastMessageBuilderTest() | 82 CastMessageBuilderTest() |
| 83 : cast_msg_builder_(new CastMessageBuilder(&testing_clock_, | 83 : cast_msg_builder_(new CastMessageBuilder(&testing_clock_, |
| 84 &feedback_, | 84 &feedback_, |
| 85 &frame_id_map_, | 85 &frame_id_map_, |
| 86 kSsrc, | 86 kSsrc, |
| 87 true, | 87 true, |
| 88 0)) { | 88 0)) { |
| 89 rtp_header_.webrtc.header.ssrc = kSsrc; | 89 rtp_header_.webrtc.header.ssrc = kSsrc; |
| 90 rtp_header_.is_key_frame = false; | 90 rtp_header_.is_key_frame = false; |
| 91 testing_clock_.Advance( | 91 testing_clock_.Advance( |
| 92 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 92 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
| 93 } | 93 } |
| 94 | 94 |
| 95 virtual ~CastMessageBuilderTest() {} | 95 virtual ~CastMessageBuilderTest() {} |
| 96 | 96 |
| 97 void SetFrameId(uint32 frame_id) { | 97 void SetFrameId(uint32 frame_id) { rtp_header_.frame_id = frame_id; } |
| 98 rtp_header_.frame_id = frame_id; | |
| 99 } | |
| 100 | 98 |
| 101 void SetPacketId(uint16 packet_id) { | 99 void SetPacketId(uint16 packet_id) { rtp_header_.packet_id = packet_id; } |
| 102 rtp_header_.packet_id = packet_id; | |
| 103 } | |
| 104 | 100 |
| 105 void SetMaxPacketId(uint16 max_packet_id) { | 101 void SetMaxPacketId(uint16 max_packet_id) { |
| 106 rtp_header_.max_packet_id = max_packet_id; | 102 rtp_header_.max_packet_id = max_packet_id; |
| 107 } | 103 } |
| 108 | 104 |
| 109 void SetKeyFrame(bool is_key) { | 105 void SetKeyFrame(bool is_key) { rtp_header_.is_key_frame = is_key; } |
| 110 rtp_header_.is_key_frame = is_key; | |
| 111 } | |
| 112 | 106 |
| 113 void SetReferenceFrameId(uint32 reference_frame_id) { | 107 void SetReferenceFrameId(uint32 reference_frame_id) { |
| 114 rtp_header_.is_reference = true; | 108 rtp_header_.is_reference = true; |
| 115 rtp_header_.reference_frame_id = reference_frame_id; | 109 rtp_header_.reference_frame_id = reference_frame_id; |
| 116 } | 110 } |
| 117 | 111 |
| 118 void InsertPacket() { | 112 void InsertPacket() { |
| 119 PacketType packet_type = frame_id_map_.InsertPacket(rtp_header_); | 113 PacketType packet_type = frame_id_map_.InsertPacket(rtp_header_); |
| 120 if (packet_type == kNewPacketCompletingFrame) { | 114 if (packet_type == kNewPacketCompletingFrame) { |
| 121 cast_msg_builder_->CompleteFrameReceived(rtp_header_.frame_id, | 115 cast_msg_builder_->CompleteFrameReceived(rtp_header_.frame_id, |
| 122 rtp_header_.is_key_frame); | 116 rtp_header_.is_key_frame); |
| 123 } | 117 } |
| 124 cast_msg_builder_->UpdateCastMessage(); | 118 cast_msg_builder_->UpdateCastMessage(); |
| 125 } | 119 } |
| 126 | 120 |
| 127 void SetDecoderSlowerThanMaxFrameRate(int max_unacked_frames) { | 121 void SetDecoderSlowerThanMaxFrameRate(int max_unacked_frames) { |
| 128 cast_msg_builder_.reset(new CastMessageBuilder(&testing_clock_, | 122 cast_msg_builder_.reset(new CastMessageBuilder(&testing_clock_, |
| 129 &feedback_, | 123 &feedback_, |
| 130 &frame_id_map_, | 124 &frame_id_map_, |
| 131 kSsrc, | 125 kSsrc, |
| 132 false, | 126 false, |
| 133 max_unacked_frames)); | 127 max_unacked_frames)); |
| 134 } | 128 } |
| 135 | 129 |
| 136 NackFeedbackVerification feedback_; | 130 NackFeedbackVerification feedback_; |
| 137 scoped_ptr<CastMessageBuilder> cast_msg_builder_; | 131 scoped_ptr<CastMessageBuilder> cast_msg_builder_; |
| 138 RtpCastHeader rtp_header_; | 132 RtpCastHeader rtp_header_; |
| 139 FrameIdMap frame_id_map_; | 133 FrameIdMap frame_id_map_; |
| 140 base::SimpleTestTickClock testing_clock_; | 134 base::SimpleTestTickClock testing_clock_; |
| 135 |
| 136 DISALLOW_COPY_AND_ASSIGN(CastMessageBuilderTest); |
| 141 }; | 137 }; |
| 142 | 138 |
| 143 TEST_F(CastMessageBuilderTest, StartWithAKeyFrame) { | 139 TEST_F(CastMessageBuilderTest, StartWithAKeyFrame) { |
| 144 SetFrameId(3); | 140 SetFrameId(3); |
| 145 SetPacketId(0); | 141 SetPacketId(0); |
| 146 SetMaxPacketId(0); | 142 SetMaxPacketId(0); |
| 147 InsertPacket(); | 143 InsertPacket(); |
| 148 // Should not trigger ack. | 144 // Should not trigger ack. |
| 149 EXPECT_FALSE(feedback_.triggered()); | 145 EXPECT_FALSE(feedback_.triggered()); |
| 150 SetFrameId(5); | 146 SetFrameId(5); |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 uint32 frame_id; | 470 uint32 frame_id; |
| 475 testing_clock_.Advance( | 471 testing_clock_.Advance( |
| 476 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | 472 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); |
| 477 SetKeyFrame(false); | 473 SetKeyFrame(false); |
| 478 for (frame_id = 1; frame_id < 3; ++frame_id) { | 474 for (frame_id = 1; frame_id < 3; ++frame_id) { |
| 479 EXPECT_TRUE(feedback_.triggered()); | 475 EXPECT_TRUE(feedback_.triggered()); |
| 480 EXPECT_EQ(frame_id - 1, feedback_.last_frame_acked()); | 476 EXPECT_EQ(frame_id - 1, feedback_.last_frame_acked()); |
| 481 SetFrameId(frame_id); | 477 SetFrameId(frame_id); |
| 482 InsertPacket(); | 478 InsertPacket(); |
| 483 testing_clock_.Advance( | 479 testing_clock_.Advance( |
| 484 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | 480 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); |
| 485 } | 481 } |
| 486 // We should now have entered the slowdown ACK state. | 482 // We should now have entered the slowdown ACK state. |
| 487 uint32 expected_frame_id = 1; | 483 uint32 expected_frame_id = 1; |
| 488 for (; frame_id < 10; ++frame_id) { | 484 for (; frame_id < 10; ++frame_id) { |
| 489 if (frame_id % 2) ++expected_frame_id; | 485 if (frame_id % 2) |
| 486 ++expected_frame_id; |
| 490 EXPECT_TRUE(feedback_.triggered()); | 487 EXPECT_TRUE(feedback_.triggered()); |
| 491 EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked()); | 488 EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked()); |
| 492 SetFrameId(frame_id); | 489 SetFrameId(frame_id); |
| 493 InsertPacket(); | 490 InsertPacket(); |
| 494 testing_clock_.Advance( | 491 testing_clock_.Advance( |
| 495 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | 492 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); |
| 496 } | 493 } |
| 497 EXPECT_TRUE(feedback_.triggered()); | 494 EXPECT_TRUE(feedback_.triggered()); |
| 498 EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked()); | 495 EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked()); |
| 499 | 496 |
| 500 // Simulate frame_id being pulled for rendering. | 497 // Simulate frame_id being pulled for rendering. |
| 501 frame_id_map_.RemoveOldFrames(frame_id); | 498 frame_id_map_.RemoveOldFrames(frame_id); |
| 502 // We should now leave the slowdown ACK state. | 499 // We should now leave the slowdown ACK state. |
| 503 ++frame_id; | 500 ++frame_id; |
| 504 SetFrameId(frame_id); | 501 SetFrameId(frame_id); |
| 505 InsertPacket(); | 502 InsertPacket(); |
| 506 testing_clock_.Advance( | 503 testing_clock_.Advance( |
| 507 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); | 504 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); |
| 508 EXPECT_TRUE(feedback_.triggered()); | 505 EXPECT_TRUE(feedback_.triggered()); |
| 509 EXPECT_EQ(frame_id, feedback_.last_frame_acked()); | 506 EXPECT_EQ(frame_id, feedback_.last_frame_acked()); |
| 510 } | 507 } |
| 511 | 508 |
| 512 } // namespace cast | 509 } // namespace cast |
| 513 } // namespace media | 510 } // namespace media |
| OLD | NEW |