Chromium Code Reviews| 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/big_endian.h" | |
| 5 #include "base/test/simple_test_tick_clock.h" | 6 #include "base/test/simple_test_tick_clock.h" |
| 7 #include "media/cast/logging/simple_event_subscriber.h" | |
| 6 #include "media/cast/test/fake_single_thread_task_runner.h" | 8 #include "media/cast/test/fake_single_thread_task_runner.h" |
| 7 #include "media/cast/transport/pacing/paced_sender.h" | 9 #include "media/cast/transport/pacing/paced_sender.h" |
| 8 #include "testing/gmock/include/gmock/gmock.h" | 10 #include "testing/gmock/include/gmock/gmock.h" |
| 9 | 11 |
| 10 namespace media { | 12 namespace media { |
| 11 namespace cast { | 13 namespace cast { |
| 12 namespace transport { | 14 namespace transport { |
| 13 | 15 |
| 14 using testing::_; | 16 using testing::_; |
| 15 | 17 |
| 16 static const uint8 kValue = 123; | 18 static const uint8 kValue = 123; |
| 17 static const size_t kSize1 = 100; | 19 static const size_t kSize1 = 100; |
| 18 static const size_t kSize2 = 101; | 20 static const size_t kSize2 = 101; |
| 19 static const size_t kSize3 = 102; | 21 static const size_t kSize3 = 102; |
| 20 static const size_t kSize4 = 103; | 22 static const size_t kSize4 = 103; |
| 21 static const size_t kNackSize = 104; | 23 static const size_t kNackSize = 104; |
| 22 static const int64 kStartMillisecond = GG_INT64_C(12345678900000); | 24 static const int64 kStartMillisecond = GG_INT64_C(12345678900000); |
| 25 static const uint32 kVideoSsrc = 0x1234; | |
| 26 static const uint32 kAudioSsrc = 0x5678; | |
| 23 | 27 |
| 24 class TestPacketSender : public PacketSender { | 28 class TestPacketSender : public PacketSender { |
| 25 public: | 29 public: |
| 26 TestPacketSender() {} | 30 TestPacketSender() {} |
| 27 | 31 |
| 28 virtual bool SendPacket(const Packet& packet) OVERRIDE { | 32 virtual bool SendPacket(const Packet& packet) OVERRIDE { |
| 29 EXPECT_FALSE(expected_packet_size_.empty()); | 33 EXPECT_FALSE(expected_packet_size_.empty()); |
| 30 size_t expected_packet_size = expected_packet_size_.front(); | 34 size_t expected_packet_size = expected_packet_size_.front(); |
| 31 expected_packet_size_.pop_front(); | 35 expected_packet_size_.pop_front(); |
| 32 EXPECT_EQ(expected_packet_size, packet.size()); | 36 EXPECT_EQ(expected_packet_size, packet.size()); |
| 33 return true; | 37 return true; |
| 34 } | 38 } |
| 35 | 39 |
| 36 void AddExpectedSize(int expected_packet_size, int repeat_count) { | 40 void AddExpectedSize(int expected_packet_size, int repeat_count) { |
| 37 for (int i = 0; i < repeat_count; ++i) { | 41 for (int i = 0; i < repeat_count; ++i) { |
| 38 expected_packet_size_.push_back(expected_packet_size); | 42 expected_packet_size_.push_back(expected_packet_size); |
| 39 } | 43 } |
| 40 } | 44 } |
| 41 | 45 |
| 42 private: | 46 public: |
| 43 std::list<int> expected_packet_size_; | 47 std::list<int> expected_packet_size_; |
| 44 | 48 |
| 45 DISALLOW_COPY_AND_ASSIGN(TestPacketSender); | 49 DISALLOW_COPY_AND_ASSIGN(TestPacketSender); |
| 46 }; | 50 }; |
| 47 | 51 |
| 48 class PacedSenderTest : public ::testing::Test { | 52 class PacedSenderTest : public ::testing::Test { |
| 49 protected: | 53 protected: |
| 50 PacedSenderTest() { | 54 PacedSenderTest() : logging_(GetLoggingConfigWithRawEventsAndStatsEnabled()) { |
| 55 logging_.AddRawEventSubscriber(&subscriber_); | |
| 51 testing_clock_.Advance( | 56 testing_clock_.Advance( |
| 52 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 57 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
| 53 task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_); | 58 task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_); |
| 54 paced_sender_.reset( | 59 paced_sender_.reset(new PacedSender( |
| 55 new PacedSender(&testing_clock_, &mock_transport_, task_runner_)); | 60 &testing_clock_, &logging_, &mock_transport_, task_runner_)); |
| 61 paced_sender_->RegisterAudioSsrc(kAudioSsrc); | |
| 62 paced_sender_->RegisterVideoSsrc(kVideoSsrc); | |
| 56 } | 63 } |
| 57 | 64 |
| 58 virtual ~PacedSenderTest() {} | 65 virtual ~PacedSenderTest() { |
| 66 logging_.RemoveRawEventSubscriber(&subscriber_); | |
| 67 } | |
| 59 | 68 |
| 60 static void UpdateCastTransportStatus(transport::CastTransportStatus status) { | 69 static void UpdateCastTransportStatus(transport::CastTransportStatus status) { |
| 61 NOTREACHED(); | 70 NOTREACHED(); |
| 62 } | 71 } |
| 63 | 72 |
| 64 PacketList CreatePacketList(size_t packet_size, int num_of_packets_in_frame) { | 73 PacketList CreatePacketList(size_t packet_size, |
| 74 int num_of_packets_in_frame, | |
| 75 bool audio) { | |
| 76 DCHECK_GE(packet_size, 12u); | |
| 65 PacketList packets; | 77 PacketList packets; |
| 66 for (int i = 0; i < num_of_packets_in_frame; ++i) { | 78 for (int i = 0; i < num_of_packets_in_frame; ++i) { |
| 67 packets.push_back(Packet(packet_size, kValue)); | 79 Packet packet(packet_size, kValue); |
| 80 // Write ssrc to packet so that it can be recognized as a | |
| 81 // "video frame" for logging purposes. | |
| 82 base::BigEndianWriter writer(reinterpret_cast<char*>(&packet[8]), 4); | |
| 83 bool success = writer.WriteU32(audio ? kAudioSsrc : kVideoSsrc); | |
| 84 DCHECK(success); | |
| 85 packets.push_back(packet); | |
| 68 } | 86 } |
| 69 return packets; | 87 return packets; |
| 70 } | 88 } |
| 71 | 89 |
| 90 // Use this function to drain the packet list in PacedSender without having | |
| 91 // to test the pacing implementation details. | |
| 92 bool RunUntilEmpty(int max_tries) { | |
| 93 for (int i = 0; i < max_tries; i++) { | |
| 94 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); | |
| 95 task_runner_->RunTasks(); | |
| 96 if (mock_transport_.expected_packet_size_.empty()) | |
| 97 return true; | |
| 98 i++; | |
|
Nico
2016/01/05 18:56:13
Is this intentional? A new warning I'm testing say
imcheng
2016/01/05 19:18:09
Looks like a mistake. It should be removed.
| |
| 99 } | |
| 100 | |
| 101 return mock_transport_.expected_packet_size_.empty(); | |
| 102 } | |
| 103 | |
| 104 LoggingImpl logging_; | |
| 105 SimpleEventSubscriber subscriber_; | |
| 72 base::SimpleTestTickClock testing_clock_; | 106 base::SimpleTestTickClock testing_clock_; |
| 73 TestPacketSender mock_transport_; | 107 TestPacketSender mock_transport_; |
| 74 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; | 108 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; |
| 75 scoped_ptr<PacedSender> paced_sender_; | 109 scoped_ptr<PacedSender> paced_sender_; |
| 76 | 110 |
| 77 DISALLOW_COPY_AND_ASSIGN(PacedSenderTest); | 111 DISALLOW_COPY_AND_ASSIGN(PacedSenderTest); |
| 78 }; | 112 }; |
| 79 | 113 |
| 80 TEST_F(PacedSenderTest, PassThroughRtcp) { | 114 TEST_F(PacedSenderTest, PassThroughRtcp) { |
| 81 mock_transport_.AddExpectedSize(kSize1, 1); | 115 mock_transport_.AddExpectedSize(kSize1, 1); |
| 82 PacketList packets = CreatePacketList(kSize1, 1); | 116 PacketList packets = CreatePacketList(kSize1, 1, true); |
| 83 | 117 |
| 84 EXPECT_TRUE(paced_sender_->SendPackets(packets)); | 118 EXPECT_TRUE(paced_sender_->SendPackets(packets)); |
| 85 EXPECT_TRUE(paced_sender_->ResendPackets(packets)); | 119 EXPECT_TRUE(paced_sender_->ResendPackets(packets)); |
| 86 | 120 |
| 87 mock_transport_.AddExpectedSize(kSize2, 1); | 121 mock_transport_.AddExpectedSize(kSize2, 1); |
| 88 EXPECT_TRUE(paced_sender_->SendRtcpPacket(Packet(kSize2, kValue))); | 122 EXPECT_TRUE(paced_sender_->SendRtcpPacket(Packet(kSize2, kValue))); |
| 89 } | 123 } |
| 90 | 124 |
| 91 TEST_F(PacedSenderTest, BasicPace) { | 125 TEST_F(PacedSenderTest, BasicPace) { |
| 92 int num_of_packets = 9; | 126 int num_of_packets = 9; |
| 93 PacketList packets = CreatePacketList(kSize1, num_of_packets); | 127 PacketList packets = CreatePacketList(kSize1, num_of_packets, false); |
| 94 | 128 |
| 95 mock_transport_.AddExpectedSize(kSize1, 3); | 129 mock_transport_.AddExpectedSize(kSize1, 3); |
| 96 EXPECT_TRUE(paced_sender_->SendPackets(packets)); | 130 EXPECT_TRUE(paced_sender_->SendPackets(packets)); |
| 97 | 131 |
| 98 // Check that we get the next burst. | 132 // Check that we get the next burst. |
| 99 mock_transport_.AddExpectedSize(kSize1, 3); | 133 mock_transport_.AddExpectedSize(kSize1, 3); |
| 100 | 134 |
| 101 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(10); | 135 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(10); |
| 102 testing_clock_.Advance(timeout); | 136 testing_clock_.Advance(timeout); |
| 103 task_runner_->RunTasks(); | 137 task_runner_->RunTasks(); |
| 104 | 138 |
| 105 // If we call process too early make sure we don't send any packets. | 139 // If we call process too early make sure we don't send any packets. |
| 106 timeout = base::TimeDelta::FromMilliseconds(5); | 140 timeout = base::TimeDelta::FromMilliseconds(5); |
| 107 testing_clock_.Advance(timeout); | 141 testing_clock_.Advance(timeout); |
| 108 task_runner_->RunTasks(); | 142 task_runner_->RunTasks(); |
| 109 | 143 |
| 110 // Check that we get the next burst. | 144 // Check that we get the next burst. |
| 111 mock_transport_.AddExpectedSize(kSize1, 3); | 145 mock_transport_.AddExpectedSize(kSize1, 3); |
| 112 testing_clock_.Advance(timeout); | 146 testing_clock_.Advance(timeout); |
| 113 task_runner_->RunTasks(); | 147 task_runner_->RunTasks(); |
| 114 | 148 |
| 115 // Check that we don't get any more packets. | 149 // Check that we don't get any more packets. |
| 116 testing_clock_.Advance(timeout); | 150 EXPECT_TRUE(RunUntilEmpty(3)); |
| 117 task_runner_->RunTasks(); | 151 |
| 152 std::vector<PacketEvent> packet_events; | |
| 153 subscriber_.GetPacketEventsAndReset(&packet_events); | |
| 154 EXPECT_EQ(num_of_packets, static_cast<int>(packet_events.size())); | |
| 155 int sent_to_network_event_count = 0; | |
| 156 for (std::vector<PacketEvent>::iterator it = packet_events.begin(); | |
| 157 it != packet_events.end(); | |
| 158 ++it) { | |
| 159 if (it->type == kVideoPacketSentToNetwork) | |
| 160 sent_to_network_event_count++; | |
| 161 else | |
| 162 FAIL() << "Got unexpected event type " << CastLoggingToString(it->type); | |
| 163 } | |
| 164 EXPECT_EQ(num_of_packets, sent_to_network_event_count); | |
| 118 } | 165 } |
| 119 | 166 |
| 120 TEST_F(PacedSenderTest, PaceWithNack) { | 167 TEST_F(PacedSenderTest, PaceWithNack) { |
| 121 // Testing what happen when we get multiple NACK requests for a fully lost | 168 // Testing what happen when we get multiple NACK requests for a fully lost |
| 122 // frames just as we sent the first packets in a frame. | 169 // frames just as we sent the first packets in a frame. |
| 123 int num_of_packets_in_frame = 9; | 170 int num_of_packets_in_frame = 9; |
| 124 int num_of_packets_in_nack = 9; | 171 int num_of_packets_in_nack = 9; |
| 125 | 172 |
| 126 PacketList first_frame_packets = | 173 PacketList first_frame_packets = |
| 127 CreatePacketList(kSize1, num_of_packets_in_frame); | 174 CreatePacketList(kSize1, num_of_packets_in_frame, false); |
| 128 | 175 |
| 129 PacketList second_frame_packets = | 176 PacketList second_frame_packets = |
| 130 CreatePacketList(kSize2, num_of_packets_in_frame); | 177 CreatePacketList(kSize2, num_of_packets_in_frame, true); |
| 131 | 178 |
| 132 PacketList nack_packets = CreatePacketList(kNackSize, num_of_packets_in_nack); | 179 PacketList nack_packets = |
| 180 CreatePacketList(kNackSize, num_of_packets_in_nack, false); | |
| 133 | 181 |
| 134 // Check that the first burst of the frame go out on the wire. | 182 // Check that the first burst of the frame go out on the wire. |
| 135 mock_transport_.AddExpectedSize(kSize1, 3); | 183 mock_transport_.AddExpectedSize(kSize1, 3); |
| 136 EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets)); | 184 EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets)); |
| 137 | 185 |
| 138 // Add first NACK request. | 186 // Add first NACK request. |
| 139 EXPECT_TRUE(paced_sender_->ResendPackets(nack_packets)); | 187 EXPECT_TRUE(paced_sender_->ResendPackets(nack_packets)); |
| 140 | 188 |
| 141 // Check that we get the first NACK burst. | 189 // Check that we get the first NACK burst. |
| 142 mock_transport_.AddExpectedSize(kNackSize, 5); | 190 mock_transport_.AddExpectedSize(kNackSize, 5); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 167 mock_transport_.AddExpectedSize(kSize2, 2); | 215 mock_transport_.AddExpectedSize(kSize2, 2); |
| 168 testing_clock_.Advance(timeout); | 216 testing_clock_.Advance(timeout); |
| 169 task_runner_->RunTasks(); | 217 task_runner_->RunTasks(); |
| 170 | 218 |
| 171 // Last packets of frame 2. | 219 // Last packets of frame 2. |
| 172 mock_transport_.AddExpectedSize(kSize2, 7); | 220 mock_transport_.AddExpectedSize(kSize2, 7); |
| 173 testing_clock_.Advance(timeout); | 221 testing_clock_.Advance(timeout); |
| 174 task_runner_->RunTasks(); | 222 task_runner_->RunTasks(); |
| 175 | 223 |
| 176 // No more packets. | 224 // No more packets. |
| 177 testing_clock_.Advance(timeout); | 225 EXPECT_TRUE(RunUntilEmpty(5)); |
| 178 task_runner_->RunTasks(); | 226 |
| 227 std::vector<PacketEvent> packet_events; | |
| 228 subscriber_.GetPacketEventsAndReset(&packet_events); | |
| 229 int expected_video_network_event_count = num_of_packets_in_frame; | |
| 230 int expected_video_retransmitted_event_count = 2 * num_of_packets_in_nack; | |
| 231 int expected_audio_network_event_count = num_of_packets_in_frame; | |
| 232 EXPECT_EQ(expected_video_network_event_count + | |
| 233 expected_video_retransmitted_event_count + | |
| 234 expected_audio_network_event_count, | |
| 235 static_cast<int>(packet_events.size())); | |
| 236 int audio_network_event_count = 0; | |
| 237 int video_network_event_count = 0; | |
| 238 int video_retransmitted_event_count = 0; | |
| 239 for (std::vector<PacketEvent>::iterator it = packet_events.begin(); | |
| 240 it != packet_events.end(); | |
| 241 ++it) { | |
| 242 if (it->type == kVideoPacketSentToNetwork) | |
| 243 video_network_event_count++; | |
| 244 else if (it->type == kVideoPacketRetransmitted) | |
| 245 video_retransmitted_event_count++; | |
| 246 else if (it->type == kAudioPacketSentToNetwork) | |
| 247 audio_network_event_count++; | |
| 248 else | |
| 249 FAIL() << "Got unexpected event type " << CastLoggingToString(it->type); | |
| 250 } | |
| 251 EXPECT_EQ(expected_audio_network_event_count, audio_network_event_count); | |
| 252 EXPECT_EQ(expected_video_network_event_count, video_network_event_count); | |
| 253 EXPECT_EQ(expected_video_retransmitted_event_count, | |
| 254 video_retransmitted_event_count); | |
| 179 } | 255 } |
| 180 | 256 |
| 181 TEST_F(PacedSenderTest, PaceWith60fps) { | 257 TEST_F(PacedSenderTest, PaceWith60fps) { |
| 182 // Testing what happen when we get multiple NACK requests for a fully lost | 258 // Testing what happen when we get multiple NACK requests for a fully lost |
| 183 // frames just as we sent the first packets in a frame. | 259 // frames just as we sent the first packets in a frame. |
| 184 int num_of_packets_in_frame = 9; | 260 int num_of_packets_in_frame = 9; |
| 185 | 261 |
| 186 PacketList first_frame_packets = | 262 PacketList first_frame_packets = |
| 187 CreatePacketList(kSize1, num_of_packets_in_frame); | 263 CreatePacketList(kSize1, num_of_packets_in_frame, false); |
| 188 | 264 |
| 189 PacketList second_frame_packets = | 265 PacketList second_frame_packets = |
| 190 CreatePacketList(kSize2, num_of_packets_in_frame); | 266 CreatePacketList(kSize2, num_of_packets_in_frame, false); |
| 191 | 267 |
| 192 PacketList third_frame_packets = | 268 PacketList third_frame_packets = |
| 193 CreatePacketList(kSize3, num_of_packets_in_frame); | 269 CreatePacketList(kSize3, num_of_packets_in_frame, false); |
| 194 | 270 |
| 195 PacketList fourth_frame_packets = | 271 PacketList fourth_frame_packets = |
| 196 CreatePacketList(kSize4, num_of_packets_in_frame); | 272 CreatePacketList(kSize4, num_of_packets_in_frame, false); |
| 197 | 273 |
| 198 base::TimeDelta timeout_10ms = base::TimeDelta::FromMilliseconds(10); | 274 base::TimeDelta timeout_10ms = base::TimeDelta::FromMilliseconds(10); |
| 199 | 275 |
| 200 // Check that the first burst of the frame go out on the wire. | 276 // Check that the first burst of the frame go out on the wire. |
| 201 mock_transport_.AddExpectedSize(kSize1, 3); | 277 mock_transport_.AddExpectedSize(kSize1, 3); |
| 202 EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets)); | 278 EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets)); |
| 203 | 279 |
| 204 mock_transport_.AddExpectedSize(kSize1, 3); | 280 mock_transport_.AddExpectedSize(kSize1, 3); |
| 205 testing_clock_.Advance(timeout_10ms); | 281 testing_clock_.Advance(timeout_10ms); |
| 206 task_runner_->RunTasks(); | 282 task_runner_->RunTasks(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 mock_transport_.AddExpectedSize(kSize4, 4); | 317 mock_transport_.AddExpectedSize(kSize4, 4); |
| 242 testing_clock_.Advance(timeout_10ms); | 318 testing_clock_.Advance(timeout_10ms); |
| 243 task_runner_->RunTasks(); | 319 task_runner_->RunTasks(); |
| 244 | 320 |
| 245 mock_transport_.AddExpectedSize(kSize4, 5); | 321 mock_transport_.AddExpectedSize(kSize4, 5); |
| 246 testing_clock_.Advance(timeout_10ms); | 322 testing_clock_.Advance(timeout_10ms); |
| 247 task_runner_->RunTasks(); | 323 task_runner_->RunTasks(); |
| 248 | 324 |
| 249 testing_clock_.Advance(timeout_10ms); | 325 testing_clock_.Advance(timeout_10ms); |
| 250 task_runner_->RunTasks(); | 326 task_runner_->RunTasks(); |
| 327 | |
| 328 // No more packets. | |
| 329 EXPECT_TRUE(RunUntilEmpty(5)); | |
| 251 } | 330 } |
| 252 | 331 |
| 253 } // namespace transport | 332 } // namespace transport |
| 254 } // namespace cast | 333 } // namespace cast |
| 255 } // namespace media | 334 } // namespace media |
| OLD | NEW |