OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <gtest/gtest.h> | 5 #include <gtest/gtest.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/test/simple_test_tick_clock.h" | 11 #include "base/test/simple_test_tick_clock.h" |
12 #include "media/cast/cast_config.h" | 12 #include "media/cast/cast_config.h" |
13 #include "media/cast/net/cast_transport_config.h" | 13 #include "media/cast/net/cast_transport_config.h" |
14 #include "media/cast/net/cast_transport_sender_impl.h" | 14 #include "media/cast/net/cast_transport_sender_impl.h" |
15 #include "media/cast/net/rtcp/rtcp.h" | 15 #include "media/cast/net/rtcp/rtcp.h" |
16 #include "media/cast/test/fake_single_thread_task_runner.h" | 16 #include "media/cast/test/fake_single_thread_task_runner.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 | 18 |
19 namespace media { | 19 namespace media { |
20 namespace cast { | 20 namespace cast { |
21 | 21 |
22 static const int64 kStartMillisecond = INT64_C(12345678900000); | 22 namespace { |
| 23 const int64 kStartMillisecond = INT64_C(12345678900000); |
| 24 const uint32 kVideoSsrc = 1; |
| 25 } // namespace |
23 | 26 |
24 class FakePacketSender : public PacketSender { | 27 class FakePacketSender : public PacketSender { |
25 public: | 28 public: |
26 FakePacketSender() {} | 29 FakePacketSender() |
| 30 : paused_(false), packets_sent_(0) {} |
27 | 31 |
28 virtual bool SendPacket(PacketRef packet, const base::Closure& cb) OVERRIDE { | 32 virtual bool SendPacket(PacketRef packet, const base::Closure& cb) OVERRIDE { |
| 33 if (paused_) { |
| 34 stored_packet_ = packet; |
| 35 callback_ = cb; |
| 36 return false; |
| 37 } |
| 38 ++packets_sent_; |
29 return true; | 39 return true; |
30 } | 40 } |
| 41 |
| 42 void SetPaused(bool paused) { |
| 43 paused_ = paused; |
| 44 if (!paused && stored_packet_) { |
| 45 SendPacket(stored_packet_, callback_); |
| 46 callback_.Run(); |
| 47 } |
| 48 } |
| 49 |
| 50 int packets_sent() const { return packets_sent_; } |
| 51 |
| 52 private: |
| 53 bool paused_; |
| 54 base::Closure callback_; |
| 55 PacketRef stored_packet_; |
| 56 int packets_sent_; |
| 57 |
| 58 DISALLOW_COPY_AND_ASSIGN(FakePacketSender); |
31 }; | 59 }; |
32 | 60 |
33 class CastTransportSenderImplTest : public ::testing::Test { | 61 class CastTransportSenderImplTest : public ::testing::Test { |
34 protected: | 62 protected: |
35 CastTransportSenderImplTest() | 63 CastTransportSenderImplTest() |
36 : num_times_callback_called_(0) { | 64 : num_times_callback_called_(0) { |
37 testing_clock_.Advance( | 65 testing_clock_.Advance( |
38 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 66 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
39 task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_); | 67 task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_); |
40 } | 68 } |
(...skipping 20 matching lines...) Expand all Loading... |
61 net::IPEndPoint(), | 89 net::IPEndPoint(), |
62 base::Bind(&UpdateCastTransportStatus), | 90 base::Bind(&UpdateCastTransportStatus), |
63 base::Bind(&CastTransportSenderImplTest::LogRawEvents, | 91 base::Bind(&CastTransportSenderImplTest::LogRawEvents, |
64 base::Unretained(this)), | 92 base::Unretained(this)), |
65 base::TimeDelta::FromMilliseconds(10), | 93 base::TimeDelta::FromMilliseconds(10), |
66 task_runner_, | 94 task_runner_, |
67 &transport_)); | 95 &transport_)); |
68 task_runner_->RunTasks(); | 96 task_runner_->RunTasks(); |
69 } | 97 } |
70 | 98 |
| 99 void InitializeVideo() { |
| 100 CastTransportRtpConfig rtp_config; |
| 101 rtp_config.ssrc = kVideoSsrc; |
| 102 rtp_config.feedback_ssrc = 2; |
| 103 rtp_config.rtp_payload_type = 3; |
| 104 rtp_config.stored_frames = 10; |
| 105 transport_sender_->InitializeVideo(rtp_config, |
| 106 RtcpCastMessageCallback(), |
| 107 RtcpRttCallback()); |
| 108 |
| 109 } |
| 110 |
71 void LogRawEvents(const std::vector<PacketEvent>& packet_events, | 111 void LogRawEvents(const std::vector<PacketEvent>& packet_events, |
72 const std::vector<FrameEvent>& frame_events) { | 112 const std::vector<FrameEvent>& frame_events) { |
73 num_times_callback_called_++; | 113 num_times_callback_called_++; |
74 } | 114 } |
75 | 115 |
76 static void UpdateCastTransportStatus(CastTransportStatus status) { | 116 static void UpdateCastTransportStatus(CastTransportStatus status) { |
77 } | 117 } |
78 | 118 |
79 base::SimpleTestTickClock testing_clock_; | 119 base::SimpleTestTickClock testing_clock_; |
80 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; | 120 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; |
81 scoped_ptr<CastTransportSenderImpl> transport_sender_; | 121 scoped_ptr<CastTransportSenderImpl> transport_sender_; |
82 FakePacketSender transport_; | 122 FakePacketSender transport_; |
83 int num_times_callback_called_; | 123 int num_times_callback_called_; |
84 }; | 124 }; |
85 | 125 |
86 TEST_F(CastTransportSenderImplTest, InitWithoutLogging) { | 126 TEST_F(CastTransportSenderImplTest, InitWithoutLogging) { |
87 InitWithoutLogging(); | 127 InitWithoutLogging(); |
88 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); | 128 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); |
89 EXPECT_EQ(0, num_times_callback_called_); | 129 EXPECT_EQ(0, num_times_callback_called_); |
90 } | 130 } |
91 | 131 |
92 TEST_F(CastTransportSenderImplTest, InitWithLogging) { | 132 TEST_F(CastTransportSenderImplTest, InitWithLogging) { |
93 InitWithLogging(); | 133 InitWithLogging(); |
94 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); | 134 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); |
95 EXPECT_EQ(5, num_times_callback_called_); | 135 EXPECT_EQ(5, num_times_callback_called_); |
96 } | 136 } |
97 | 137 |
| 138 TEST_F(CastTransportSenderImplTest, NacksCancelRetransmits) { |
| 139 InitWithoutLogging(); |
| 140 InitializeVideo(); |
| 141 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); |
| 142 |
| 143 // A fake frame that will be decomposed into 4 packets. |
| 144 EncodedFrame fake_frame; |
| 145 fake_frame.frame_id = 1; |
| 146 fake_frame.rtp_timestamp = 1; |
| 147 fake_frame.dependency = EncodedFrame::KEY; |
| 148 fake_frame.data.resize(5000, ' '); |
| 149 |
| 150 transport_sender_->InsertCodedVideoFrame(fake_frame); |
| 151 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
| 152 EXPECT_EQ(4, transport_.packets_sent()); |
| 153 |
| 154 // Resend packet 0. |
| 155 MissingFramesAndPacketsMap missing_packets; |
| 156 missing_packets[1].insert(0); |
| 157 missing_packets[1].insert(1); |
| 158 missing_packets[1].insert(2); |
| 159 |
| 160 transport_.SetPaused(true); |
| 161 transport_sender_->ResendPackets( |
| 162 kVideoSsrc, missing_packets, true, |
| 163 base::TimeDelta::FromMilliseconds(10)); |
| 164 |
| 165 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
| 166 |
| 167 RtcpCastMessage cast_message; |
| 168 cast_message.media_ssrc = kVideoSsrc; |
| 169 cast_message.ack_frame_id = 1; |
| 170 cast_message.missing_frames_and_packets[1].insert(3); |
| 171 transport_sender_->OnReceivedCastMessage(kVideoSsrc, |
| 172 RtcpCastMessageCallback(), |
| 173 cast_message); |
| 174 transport_.SetPaused(false); |
| 175 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
| 176 |
| 177 // Resend one packet in the socket when unpaused. |
| 178 // Resend one more packet from NACK. |
| 179 EXPECT_EQ(6, transport_.packets_sent()); |
| 180 } |
| 181 |
| 182 TEST_F(CastTransportSenderImplTest, CancelRetransmits) { |
| 183 InitWithoutLogging(); |
| 184 InitializeVideo(); |
| 185 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); |
| 186 |
| 187 // A fake frame that will be decomposed into 4 packets. |
| 188 EncodedFrame fake_frame; |
| 189 fake_frame.frame_id = 1; |
| 190 fake_frame.rtp_timestamp = 1; |
| 191 fake_frame.dependency = EncodedFrame::KEY; |
| 192 fake_frame.data.resize(5000, ' '); |
| 193 |
| 194 transport_sender_->InsertCodedVideoFrame(fake_frame); |
| 195 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
| 196 EXPECT_EQ(4, transport_.packets_sent()); |
| 197 |
| 198 // Resend all packets for frame 1. |
| 199 MissingFramesAndPacketsMap missing_packets; |
| 200 missing_packets[1].insert(kRtcpCastAllPacketsLost); |
| 201 |
| 202 transport_.SetPaused(true); |
| 203 transport_sender_->ResendPackets( |
| 204 kVideoSsrc, missing_packets, true, |
| 205 base::TimeDelta::FromMilliseconds(10)); |
| 206 |
| 207 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
| 208 std::vector<uint32> cancel_sending_frames; |
| 209 cancel_sending_frames.push_back(1); |
| 210 transport_sender_->CancelSendingFrames(kVideoSsrc, |
| 211 cancel_sending_frames); |
| 212 transport_.SetPaused(false); |
| 213 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
| 214 |
| 215 // Resend one packet in the socket when unpaused. |
| 216 EXPECT_EQ(5, transport_.packets_sent()); |
| 217 } |
| 218 |
| 219 TEST_F(CastTransportSenderImplTest, Kickstart) { |
| 220 InitWithoutLogging(); |
| 221 InitializeVideo(); |
| 222 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); |
| 223 |
| 224 // A fake frame that will be decomposed into 4 packets. |
| 225 EncodedFrame fake_frame; |
| 226 fake_frame.frame_id = 1; |
| 227 fake_frame.rtp_timestamp = 1; |
| 228 fake_frame.dependency = EncodedFrame::KEY; |
| 229 fake_frame.data.resize(5000, ' '); |
| 230 |
| 231 transport_.SetPaused(true); |
| 232 transport_sender_->InsertCodedVideoFrame(fake_frame); |
| 233 transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1); |
| 234 transport_.SetPaused(false); |
| 235 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
| 236 EXPECT_EQ(4, transport_.packets_sent()); |
| 237 |
| 238 // Resend 2 packets for frame 1. |
| 239 MissingFramesAndPacketsMap missing_packets; |
| 240 missing_packets[1].insert(0); |
| 241 missing_packets[1].insert(1); |
| 242 |
| 243 transport_.SetPaused(true); |
| 244 transport_sender_->ResendPackets( |
| 245 kVideoSsrc, missing_packets, true, |
| 246 base::TimeDelta::FromMilliseconds(10)); |
| 247 transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1); |
| 248 transport_.SetPaused(false); |
| 249 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
| 250 |
| 251 // Resend one packet in the socket when unpaused. |
| 252 // Two more retransmission packets sent. |
| 253 EXPECT_EQ(7, transport_.packets_sent()); |
| 254 } |
| 255 |
98 } // namespace cast | 256 } // namespace cast |
99 } // namespace media | 257 } // namespace media |
OLD | NEW |