| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include <stdint.h> | |
| 6 | |
| 7 #include "base/big_endian.h" | |
| 8 #include "base/test/simple_test_tick_clock.h" | |
| 9 #include "media/cast/logging/simple_event_subscriber.h" | |
| 10 #include "media/cast/test/fake_single_thread_task_runner.h" | |
| 11 #include "media/cast/transport/pacing/paced_sender.h" | |
| 12 #include "testing/gmock/include/gmock/gmock.h" | |
| 13 | |
| 14 namespace media { | |
| 15 namespace cast { | |
| 16 namespace transport { | |
| 17 | |
| 18 using testing::_; | |
| 19 | |
| 20 static const uint8 kValue = 123; | |
| 21 static const size_t kSize1 = 100; | |
| 22 static const size_t kSize2 = 101; | |
| 23 static const size_t kSize3 = 102; | |
| 24 static const size_t kSize4 = 103; | |
| 25 static const size_t kNackSize = 104; | |
| 26 static const int64 kStartMillisecond = INT64_C(12345678900000); | |
| 27 static const uint32 kVideoSsrc = 0x1234; | |
| 28 static const uint32 kAudioSsrc = 0x5678; | |
| 29 | |
| 30 class TestPacketSender : public PacketSender { | |
| 31 public: | |
| 32 TestPacketSender() {} | |
| 33 | |
| 34 virtual bool SendPacket(PacketRef packet, const base::Closure& cb) OVERRIDE { | |
| 35 EXPECT_FALSE(expected_packet_size_.empty()); | |
| 36 size_t expected_packet_size = expected_packet_size_.front(); | |
| 37 expected_packet_size_.pop_front(); | |
| 38 EXPECT_EQ(expected_packet_size, packet->data.size()); | |
| 39 return true; | |
| 40 } | |
| 41 | |
| 42 void AddExpectedSize(int expected_packet_size, int repeat_count) { | |
| 43 for (int i = 0; i < repeat_count; ++i) { | |
| 44 expected_packet_size_.push_back(expected_packet_size); | |
| 45 } | |
| 46 } | |
| 47 | |
| 48 public: | |
| 49 std::list<int> expected_packet_size_; | |
| 50 | |
| 51 DISALLOW_COPY_AND_ASSIGN(TestPacketSender); | |
| 52 }; | |
| 53 | |
| 54 class PacedSenderTest : public ::testing::Test { | |
| 55 protected: | |
| 56 PacedSenderTest() { | |
| 57 logging_.AddRawEventSubscriber(&subscriber_); | |
| 58 testing_clock_.Advance( | |
| 59 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | |
| 60 task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_); | |
| 61 paced_sender_.reset(new PacedSender( | |
| 62 &testing_clock_, &logging_, &mock_transport_, task_runner_)); | |
| 63 paced_sender_->RegisterAudioSsrc(kAudioSsrc); | |
| 64 paced_sender_->RegisterVideoSsrc(kVideoSsrc); | |
| 65 } | |
| 66 | |
| 67 virtual ~PacedSenderTest() { | |
| 68 logging_.RemoveRawEventSubscriber(&subscriber_); | |
| 69 } | |
| 70 | |
| 71 static void UpdateCastTransportStatus(transport::CastTransportStatus status) { | |
| 72 NOTREACHED(); | |
| 73 } | |
| 74 | |
| 75 SendPacketVector CreateSendPacketVector(size_t packet_size, | |
| 76 int num_of_packets_in_frame, | |
| 77 bool audio) { | |
| 78 DCHECK_GE(packet_size, 12u); | |
| 79 SendPacketVector packets; | |
| 80 base::TimeTicks frame_tick = testing_clock_.NowTicks(); | |
| 81 // Advance the clock so that we don't get the same frame_tick | |
| 82 // next time this function is called. | |
| 83 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); | |
| 84 for (int i = 0; i < num_of_packets_in_frame; ++i) { | |
| 85 PacketKey key = PacedPacketSender::MakePacketKey( | |
| 86 frame_tick, | |
| 87 audio ? kAudioSsrc : kVideoSsrc, // ssrc | |
| 88 i); | |
| 89 | |
| 90 PacketRef packet(new base::RefCountedData<Packet>); | |
| 91 packet->data.resize(packet_size, kValue); | |
| 92 // Write ssrc to packet so that it can be recognized as a | |
| 93 // "video frame" for logging purposes. | |
| 94 base::BigEndianWriter writer( | |
| 95 reinterpret_cast<char*>(&packet->data[8]), 4); | |
| 96 bool success = writer.WriteU32(audio ? kAudioSsrc : kVideoSsrc); | |
| 97 DCHECK(success); | |
| 98 packets.push_back(std::make_pair(key, packet)); | |
| 99 } | |
| 100 return packets; | |
| 101 } | |
| 102 | |
| 103 // Use this function to drain the packet list in PacedSender without having | |
| 104 // to test the pacing implementation details. | |
| 105 bool RunUntilEmpty(int max_tries) { | |
| 106 for (int i = 0; i < max_tries; i++) { | |
| 107 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); | |
| 108 task_runner_->RunTasks(); | |
| 109 if (mock_transport_.expected_packet_size_.empty()) | |
| 110 return true; | |
| 111 i++; | |
| 112 } | |
| 113 | |
| 114 return mock_transport_.expected_packet_size_.empty(); | |
| 115 } | |
| 116 | |
| 117 LoggingImpl logging_; | |
| 118 SimpleEventSubscriber subscriber_; | |
| 119 base::SimpleTestTickClock testing_clock_; | |
| 120 TestPacketSender mock_transport_; | |
| 121 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; | |
| 122 scoped_ptr<PacedSender> paced_sender_; | |
| 123 | |
| 124 DISALLOW_COPY_AND_ASSIGN(PacedSenderTest); | |
| 125 }; | |
| 126 | |
| 127 TEST_F(PacedSenderTest, PassThroughRtcp) { | |
| 128 mock_transport_.AddExpectedSize(kSize1, 2); | |
| 129 SendPacketVector packets = CreateSendPacketVector(kSize1, 1, true); | |
| 130 | |
| 131 EXPECT_TRUE(paced_sender_->SendPackets(packets)); | |
| 132 EXPECT_TRUE(paced_sender_->ResendPackets(packets, base::TimeDelta())); | |
| 133 | |
| 134 mock_transport_.AddExpectedSize(kSize2, 1); | |
| 135 Packet tmp(kSize2, kValue); | |
| 136 EXPECT_TRUE(paced_sender_->SendRtcpPacket( | |
| 137 1, | |
| 138 new base::RefCountedData<Packet>(tmp))); | |
| 139 } | |
| 140 | |
| 141 TEST_F(PacedSenderTest, BasicPace) { | |
| 142 int num_of_packets = 27; | |
| 143 SendPacketVector packets = CreateSendPacketVector(kSize1, | |
| 144 num_of_packets, | |
| 145 false); | |
| 146 | |
| 147 mock_transport_.AddExpectedSize(kSize1, 10); | |
| 148 EXPECT_TRUE(paced_sender_->SendPackets(packets)); | |
| 149 | |
| 150 // Check that we get the next burst. | |
| 151 mock_transport_.AddExpectedSize(kSize1, 10); | |
| 152 | |
| 153 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(10); | |
| 154 testing_clock_.Advance(timeout); | |
| 155 task_runner_->RunTasks(); | |
| 156 | |
| 157 // If we call process too early make sure we don't send any packets. | |
| 158 timeout = base::TimeDelta::FromMilliseconds(5); | |
| 159 testing_clock_.Advance(timeout); | |
| 160 task_runner_->RunTasks(); | |
| 161 | |
| 162 // Check that we get the next burst. | |
| 163 mock_transport_.AddExpectedSize(kSize1, 7); | |
| 164 testing_clock_.Advance(timeout); | |
| 165 task_runner_->RunTasks(); | |
| 166 | |
| 167 // Check that we don't get any more packets. | |
| 168 EXPECT_TRUE(RunUntilEmpty(3)); | |
| 169 | |
| 170 std::vector<PacketEvent> packet_events; | |
| 171 subscriber_.GetPacketEventsAndReset(&packet_events); | |
| 172 EXPECT_EQ(num_of_packets, static_cast<int>(packet_events.size())); | |
| 173 int sent_to_network_event_count = 0; | |
| 174 for (std::vector<PacketEvent>::iterator it = packet_events.begin(); | |
| 175 it != packet_events.end(); | |
| 176 ++it) { | |
| 177 if (it->type == PACKET_SENT_TO_NETWORK) | |
| 178 sent_to_network_event_count++; | |
| 179 else | |
| 180 FAIL() << "Got unexpected event type " << CastLoggingToString(it->type); | |
| 181 } | |
| 182 EXPECT_EQ(num_of_packets, sent_to_network_event_count); | |
| 183 } | |
| 184 | |
| 185 TEST_F(PacedSenderTest, PaceWithNack) { | |
| 186 // Testing what happen when we get multiple NACK requests for a fully lost | |
| 187 // frames just as we sent the first packets in a frame. | |
| 188 int num_of_packets_in_frame = 12; | |
| 189 int num_of_packets_in_nack = 12; | |
| 190 | |
| 191 SendPacketVector nack_packets = | |
| 192 CreateSendPacketVector(kNackSize, num_of_packets_in_nack, false); | |
| 193 | |
| 194 SendPacketVector first_frame_packets = | |
| 195 CreateSendPacketVector(kSize1, num_of_packets_in_frame, false); | |
| 196 | |
| 197 SendPacketVector second_frame_packets = | |
| 198 CreateSendPacketVector(kSize2, num_of_packets_in_frame, true); | |
| 199 | |
| 200 // Check that the first burst of the frame go out on the wire. | |
| 201 mock_transport_.AddExpectedSize(kSize1, 10); | |
| 202 EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets)); | |
| 203 | |
| 204 // Add first NACK request. | |
| 205 EXPECT_TRUE(paced_sender_->ResendPackets(nack_packets, base::TimeDelta())); | |
| 206 | |
| 207 // Check that we get the first NACK burst. | |
| 208 mock_transport_.AddExpectedSize(kNackSize, 10); | |
| 209 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(10); | |
| 210 testing_clock_.Advance(timeout); | |
| 211 task_runner_->RunTasks(); | |
| 212 | |
| 213 // Add second NACK request. | |
| 214 EXPECT_TRUE(paced_sender_->ResendPackets(nack_packets, base::TimeDelta())); | |
| 215 | |
| 216 // Check that we get the next NACK burst. | |
| 217 mock_transport_.AddExpectedSize(kNackSize, 10); | |
| 218 testing_clock_.Advance(timeout); | |
| 219 task_runner_->RunTasks(); | |
| 220 | |
| 221 // End of NACK plus two packets from the oldest frame. | |
| 222 // Note that two of the NACKs have been de-duped. | |
| 223 mock_transport_.AddExpectedSize(kNackSize, 2); | |
| 224 mock_transport_.AddExpectedSize(kSize1, 2); | |
| 225 testing_clock_.Advance(timeout); | |
| 226 task_runner_->RunTasks(); | |
| 227 | |
| 228 // Add second frame. | |
| 229 // Make sure we don't delay the second frame due to the previous packets. | |
| 230 mock_transport_.AddExpectedSize(kSize2, 10); | |
| 231 EXPECT_TRUE(paced_sender_->SendPackets(second_frame_packets)); | |
| 232 | |
| 233 // Last packets of frame 2. | |
| 234 mock_transport_.AddExpectedSize(kSize2, 2); | |
| 235 testing_clock_.Advance(timeout); | |
| 236 task_runner_->RunTasks(); | |
| 237 | |
| 238 // No more packets. | |
| 239 EXPECT_TRUE(RunUntilEmpty(5)); | |
| 240 | |
| 241 std::vector<PacketEvent> packet_events; | |
| 242 subscriber_.GetPacketEventsAndReset(&packet_events); | |
| 243 int expected_video_network_event_count = num_of_packets_in_frame; | |
| 244 int expected_video_retransmitted_event_count = 2 * num_of_packets_in_nack; | |
| 245 expected_video_retransmitted_event_count -= 2; // 2 packets deduped | |
| 246 int expected_audio_network_event_count = num_of_packets_in_frame; | |
| 247 EXPECT_EQ(expected_video_network_event_count + | |
| 248 expected_video_retransmitted_event_count + | |
| 249 expected_audio_network_event_count, | |
| 250 static_cast<int>(packet_events.size())); | |
| 251 int audio_network_event_count = 0; | |
| 252 int video_network_event_count = 0; | |
| 253 int video_retransmitted_event_count = 0; | |
| 254 for (std::vector<PacketEvent>::iterator it = packet_events.begin(); | |
| 255 it != packet_events.end(); | |
| 256 ++it) { | |
| 257 if (it->type == PACKET_SENT_TO_NETWORK) { | |
| 258 if (it->media_type == VIDEO_EVENT) | |
| 259 video_network_event_count++; | |
| 260 else | |
| 261 audio_network_event_count++; | |
| 262 } else if (it->type == PACKET_RETRANSMITTED) { | |
| 263 if (it->media_type == VIDEO_EVENT) | |
| 264 video_retransmitted_event_count++; | |
| 265 } else { | |
| 266 FAIL() << "Got unexpected event type " << CastLoggingToString(it->type); | |
| 267 } | |
| 268 } | |
| 269 EXPECT_EQ(expected_audio_network_event_count, audio_network_event_count); | |
| 270 EXPECT_EQ(expected_video_network_event_count, video_network_event_count); | |
| 271 EXPECT_EQ(expected_video_retransmitted_event_count, | |
| 272 video_retransmitted_event_count); | |
| 273 } | |
| 274 | |
| 275 TEST_F(PacedSenderTest, PaceWith60fps) { | |
| 276 // Testing what happen when we get multiple NACK requests for a fully lost | |
| 277 // frames just as we sent the first packets in a frame. | |
| 278 int num_of_packets_in_frame = 17; | |
| 279 | |
| 280 SendPacketVector first_frame_packets = | |
| 281 CreateSendPacketVector(kSize1, num_of_packets_in_frame, false); | |
| 282 | |
| 283 SendPacketVector second_frame_packets = | |
| 284 CreateSendPacketVector(kSize2, num_of_packets_in_frame, false); | |
| 285 | |
| 286 SendPacketVector third_frame_packets = | |
| 287 CreateSendPacketVector(kSize3, num_of_packets_in_frame, false); | |
| 288 | |
| 289 SendPacketVector fourth_frame_packets = | |
| 290 CreateSendPacketVector(kSize4, num_of_packets_in_frame, false); | |
| 291 | |
| 292 base::TimeDelta timeout_10ms = base::TimeDelta::FromMilliseconds(10); | |
| 293 | |
| 294 // Check that the first burst of the frame go out on the wire. | |
| 295 mock_transport_.AddExpectedSize(kSize1, 10); | |
| 296 EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets)); | |
| 297 | |
| 298 mock_transport_.AddExpectedSize(kSize1, 7); | |
| 299 testing_clock_.Advance(timeout_10ms); | |
| 300 task_runner_->RunTasks(); | |
| 301 | |
| 302 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(6)); | |
| 303 | |
| 304 // Add second frame, after 16 ms. | |
| 305 mock_transport_.AddExpectedSize(kSize2, 3); | |
| 306 EXPECT_TRUE(paced_sender_->SendPackets(second_frame_packets)); | |
| 307 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(4)); | |
| 308 | |
| 309 mock_transport_.AddExpectedSize(kSize2, 10); | |
| 310 testing_clock_.Advance(timeout_10ms); | |
| 311 task_runner_->RunTasks(); | |
| 312 | |
| 313 mock_transport_.AddExpectedSize(kSize2, 4); | |
| 314 testing_clock_.Advance(timeout_10ms); | |
| 315 task_runner_->RunTasks(); | |
| 316 | |
| 317 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(3)); | |
| 318 | |
| 319 // Add third frame, after 33 ms. | |
| 320 mock_transport_.AddExpectedSize(kSize3, 6); | |
| 321 EXPECT_TRUE(paced_sender_->SendPackets(third_frame_packets)); | |
| 322 | |
| 323 mock_transport_.AddExpectedSize(kSize3, 10); | |
| 324 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(7)); | |
| 325 task_runner_->RunTasks(); | |
| 326 | |
| 327 // Add fourth frame, after 50 ms. | |
| 328 EXPECT_TRUE(paced_sender_->SendPackets(fourth_frame_packets)); | |
| 329 | |
| 330 mock_transport_.AddExpectedSize(kSize3, 1); | |
| 331 mock_transport_.AddExpectedSize(kSize4, 9); | |
| 332 testing_clock_.Advance(timeout_10ms); | |
| 333 task_runner_->RunTasks(); | |
| 334 | |
| 335 mock_transport_.AddExpectedSize(kSize4, 8); | |
| 336 testing_clock_.Advance(timeout_10ms); | |
| 337 task_runner_->RunTasks(); | |
| 338 | |
| 339 testing_clock_.Advance(timeout_10ms); | |
| 340 task_runner_->RunTasks(); | |
| 341 | |
| 342 testing_clock_.Advance(timeout_10ms); | |
| 343 task_runner_->RunTasks(); | |
| 344 | |
| 345 // No more packets. | |
| 346 EXPECT_TRUE(RunUntilEmpty(5)); | |
| 347 } | |
| 348 | |
| 349 } // namespace transport | |
| 350 } // namespace cast | |
| 351 } // namespace media | |
| OLD | NEW |