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 <vector> 8 9 #include "base/bind.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/test/simple_test_tick_clock.h" 12 #include "media/base/video_frame.h" 13 #include "media/cast/cast_environment.h" 14 #include "media/cast/logging/simple_event_subscriber.h" 15 #include "media/cast/test/fake_single_thread_task_runner.h" 16 #include "media/cast/test/fake_video_encode_accelerator.h" 17 #include "media/cast/test/utility/default_config.h" 18 #include "media/cast/test/utility/video_utility.h" 19 #include "media/cast/transport/cast_transport_config.h" 20 #include "media/cast/transport/cast_transport_sender_impl.h" 21 #include "media/cast/transport/pacing/paced_sender.h" 22 #include "media/cast/video_sender/video_sender.h" 23 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gtest/include/gtest/gtest.h" 25 26 namespace media { 27 namespace cast { 28 29 namespace { 30 static const uint8 kPixelValue = 123; 31 static const int kWidth = 320; 32 static const int kHeight = 240; 33 34 using testing::_; 35 using testing::AtLeast; 36 37 void CreateVideoEncodeAccelerator( 38 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 39 scoped_ptr<VideoEncodeAccelerator> fake_vea, 40 const ReceiveVideoEncodeAcceleratorCallback& callback) { 41 callback.Run(task_runner, fake_vea.Pass()); 42 } 43 44 void CreateSharedMemory( 45 size_t size, const ReceiveVideoEncodeMemoryCallback& callback) { 46 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory()); 47 if (!shm->CreateAndMapAnonymous(size)) { 48 NOTREACHED(); 49 return; 50 } 51 callback.Run(shm.Pass()); 52 } 53 54 class TestPacketSender : public transport::PacketSender { 55 public: 56 TestPacketSender() 57 : number_of_rtp_packets_(0), 58 number_of_rtcp_packets_(0), 59 paused_(false) {} 60 61 // A singular packet implies a RTCP packet. 62 virtual bool SendPacket(transport::PacketRef packet, 63 const base::Closure& cb) OVERRIDE { 64 if (paused_) { 65 stored_packet_ = packet; 66 callback_ = cb; 67 return false; 68 } 69 if (Rtcp::IsRtcpPacket(&packet->data[0], packet->data.size())) { 70 ++number_of_rtcp_packets_; 71 } else { 72 // Check that at least one RTCP packet was sent before the first RTP 73 // packet. This confirms that the receiver will have the necessary lip 74 // sync info before it has to calculate the playout time of the first 75 // frame. 76 if (number_of_rtp_packets_ == 0) 77 EXPECT_LE(1, number_of_rtcp_packets_); 78 ++number_of_rtp_packets_; 79 } 80 return true; 81 } 82 83 int number_of_rtp_packets() const { return number_of_rtp_packets_; } 84 85 int number_of_rtcp_packets() const { return number_of_rtcp_packets_; } 86 87 void SetPause(bool paused) { 88 paused_ = paused; 89 if (!paused && stored_packet_) { 90 SendPacket(stored_packet_, callback_); 91 callback_.Run(); 92 } 93 } 94 95 private: 96 int number_of_rtp_packets_; 97 int number_of_rtcp_packets_; 98 bool paused_; 99 base::Closure callback_; 100 transport::PacketRef stored_packet_; 101 102 DISALLOW_COPY_AND_ASSIGN(TestPacketSender); 103 }; 104 105 class PeerVideoSender : public VideoSender { 106 public: 107 PeerVideoSender( 108 scoped_refptr<CastEnvironment> cast_environment, 109 const VideoSenderConfig& video_config, 110 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, 111 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, 112 transport::CastTransportSender* const transport_sender) 113 : VideoSender(cast_environment, 114 video_config, 115 create_vea_cb, 116 create_video_encode_mem_cb, 117 transport_sender) {} 118 using VideoSender::OnReceivedCastFeedback; 119 }; 120 } // namespace 121 122 class VideoSenderTest : public ::testing::Test { 123 protected: 124 VideoSenderTest() { 125 testing_clock_ = new base::SimpleTestTickClock(); 126 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); 127 task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_); 128 cast_environment_ = 129 new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(), 130 task_runner_, 131 task_runner_, 132 task_runner_); 133 last_pixel_value_ = kPixelValue; 134 net::IPEndPoint dummy_endpoint; 135 transport_sender_.reset(new transport::CastTransportSenderImpl( 136 NULL, 137 testing_clock_, 138 dummy_endpoint, 139 base::Bind(&UpdateCastTransportStatus), 140 transport::BulkRawEventsCallback(), 141 base::TimeDelta(), 142 task_runner_, 143 &transport_)); 144 } 145 146 virtual ~VideoSenderTest() {} 147 148 virtual void TearDown() OVERRIDE { 149 video_sender_.reset(); 150 task_runner_->RunTasks(); 151 } 152 153 static void UpdateCastTransportStatus(transport::CastTransportStatus status) { 154 EXPECT_EQ(transport::TRANSPORT_VIDEO_INITIALIZED, status); 155 } 156 157 void InitEncoder(bool external) { 158 VideoSenderConfig video_config; 159 video_config.rtp_config.ssrc = 1; 160 video_config.incoming_feedback_ssrc = 2; 161 video_config.rtcp_c_name = "video_test (at) 10.1.1.1"; 162 video_config.rtp_config.payload_type = 127; 163 video_config.use_external_encoder = external; 164 video_config.width = kWidth; 165 video_config.height = kHeight; 166 video_config.max_bitrate = 5000000; 167 video_config.min_bitrate = 1000000; 168 video_config.start_bitrate = 1000000; 169 video_config.max_qp = 56; 170 video_config.min_qp = 0; 171 video_config.max_frame_rate = 30; 172 video_config.max_number_of_video_buffers_used = 1; 173 video_config.codec = transport::kVp8; 174 175 if (external) { 176 scoped_ptr<VideoEncodeAccelerator> fake_vea( 177 new test::FakeVideoEncodeAccelerator(task_runner_)); 178 video_sender_.reset( 179 new PeerVideoSender(cast_environment_, 180 video_config, 181 base::Bind(&CreateVideoEncodeAccelerator, 182 task_runner_, 183 base::Passed(&fake_vea)), 184 base::Bind(&CreateSharedMemory), 185 transport_sender_.get())); 186 } else { 187 video_sender_.reset( 188 new PeerVideoSender(cast_environment_, 189 video_config, 190 CreateDefaultVideoEncodeAcceleratorCallback(), 191 CreateDefaultVideoEncodeMemoryCallback(), 192 transport_sender_.get())); 193 } 194 ASSERT_EQ(STATUS_VIDEO_INITIALIZED, video_sender_->InitializationResult()); 195 } 196 197 scoped_refptr<media::VideoFrame> GetNewVideoFrame() { 198 gfx::Size size(kWidth, kHeight); 199 scoped_refptr<media::VideoFrame> video_frame = 200 media::VideoFrame::CreateFrame( 201 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); 202 PopulateVideoFrame(video_frame, last_pixel_value_++); 203 return video_frame; 204 } 205 206 scoped_refptr<media::VideoFrame> GetLargeNewVideoFrame() { 207 gfx::Size size(kWidth, kHeight); 208 scoped_refptr<media::VideoFrame> video_frame = 209 media::VideoFrame::CreateFrame( 210 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); 211 PopulateVideoFrameWithNoise(video_frame); 212 return video_frame; 213 } 214 215 void RunTasks(int during_ms) { 216 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(during_ms)); 217 } 218 219 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. 220 TestPacketSender transport_; 221 scoped_ptr<transport::CastTransportSenderImpl> transport_sender_; 222 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; 223 scoped_ptr<PeerVideoSender> video_sender_; 224 scoped_refptr<CastEnvironment> cast_environment_; 225 int last_pixel_value_; 226 227 DISALLOW_COPY_AND_ASSIGN(VideoSenderTest); 228 }; 229 230 TEST_F(VideoSenderTest, BuiltInEncoder) { 231 InitEncoder(false); 232 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 233 234 const base::TimeTicks capture_time = testing_clock_->NowTicks(); 235 video_sender_->InsertRawVideoFrame(video_frame, capture_time); 236 237 task_runner_->RunTasks(); 238 EXPECT_LE(1, transport_.number_of_rtp_packets()); 239 EXPECT_LE(1, transport_.number_of_rtcp_packets()); 240 } 241 242 TEST_F(VideoSenderTest, ExternalEncoder) { 243 InitEncoder(true); 244 task_runner_->RunTasks(); 245 246 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 247 248 const base::TimeTicks capture_time = testing_clock_->NowTicks(); 249 video_sender_->InsertRawVideoFrame(video_frame, capture_time); 250 251 task_runner_->RunTasks(); 252 253 // We need to run the task to cleanup the GPU instance. 254 video_sender_.reset(NULL); 255 task_runner_->RunTasks(); 256 } 257 258 TEST_F(VideoSenderTest, RtcpTimer) { 259 InitEncoder(false); 260 261 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 262 263 const base::TimeTicks capture_time = testing_clock_->NowTicks(); 264 video_sender_->InsertRawVideoFrame(video_frame, capture_time); 265 266 // Make sure that we send at least one RTCP packet. 267 base::TimeDelta max_rtcp_timeout = 268 base::TimeDelta::FromMilliseconds(1 + kDefaultRtcpIntervalMs * 3 / 2); 269 270 RunTasks(max_rtcp_timeout.InMilliseconds()); 271 EXPECT_LE(1, transport_.number_of_rtp_packets()); 272 EXPECT_LE(1, transport_.number_of_rtcp_packets()); 273 // Build Cast msg and expect RTCP packet. 274 RtcpCastMessage cast_feedback(1); 275 cast_feedback.media_ssrc_ = 2; 276 cast_feedback.ack_frame_id_ = 0; 277 video_sender_->OnReceivedCastFeedback(cast_feedback); 278 RunTasks(max_rtcp_timeout.InMilliseconds()); 279 EXPECT_LE(1, transport_.number_of_rtcp_packets()); 280 } 281 282 TEST_F(VideoSenderTest, ResendTimer) { 283 InitEncoder(false); 284 285 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 286 287 const base::TimeTicks capture_time = testing_clock_->NowTicks(); 288 video_sender_->InsertRawVideoFrame(video_frame, capture_time); 289 290 // ACK the key frame. 291 RtcpCastMessage cast_feedback(1); 292 cast_feedback.media_ssrc_ = 2; 293 cast_feedback.ack_frame_id_ = 0; 294 video_sender_->OnReceivedCastFeedback(cast_feedback); 295 296 video_frame = GetNewVideoFrame(); 297 video_sender_->InsertRawVideoFrame(video_frame, capture_time); 298 299 base::TimeDelta max_resend_timeout = 300 base::TimeDelta::FromMilliseconds(1 + kDefaultRtpMaxDelayMs); 301 302 // Make sure that we do a re-send. 303 RunTasks(max_resend_timeout.InMilliseconds()); 304 // Should have sent at least 3 packets. 305 EXPECT_LE( 306 3, 307 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets()); 308 } 309 310 TEST_F(VideoSenderTest, LogAckReceivedEvent) { 311 InitEncoder(false); 312 SimpleEventSubscriber event_subscriber; 313 cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber); 314 315 int num_frames = 10; 316 for (int i = 0; i < num_frames; i++) { 317 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 318 319 const base::TimeTicks capture_time = testing_clock_->NowTicks(); 320 video_sender_->InsertRawVideoFrame(video_frame, capture_time); 321 RunTasks(33); 322 } 323 324 task_runner_->RunTasks(); 325 326 RtcpCastMessage cast_feedback(1); 327 cast_feedback.ack_frame_id_ = num_frames - 1; 328 329 video_sender_->OnReceivedCastFeedback(cast_feedback); 330 331 std::vector<FrameEvent> frame_events; 332 event_subscriber.GetFrameEventsAndReset(&frame_events); 333 334 ASSERT_TRUE(!frame_events.empty()); 335 EXPECT_EQ(FRAME_ACK_RECEIVED, frame_events.rbegin()->type); 336 EXPECT_EQ(VIDEO_EVENT, frame_events.rbegin()->media_type); 337 EXPECT_EQ(num_frames - 1u, frame_events.rbegin()->frame_id); 338 339 cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber); 340 } 341 342 TEST_F(VideoSenderTest, StopSendingInTheAbsenceOfAck) { 343 InitEncoder(false); 344 // Send a stream of frames and don't ACK; by default we shouldn't have more 345 // than 4 frames in flight. 346 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 347 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 348 RunTasks(33); 349 350 // Send 3 more frames and record the number of packets sent. 351 for (int i = 0; i < 3; ++i) { 352 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 353 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 354 RunTasks(33); 355 } 356 const int number_of_packets_sent = transport_.number_of_rtp_packets(); 357 358 // Send 3 more frames - they should not be encoded, as we have not received 359 // any acks. 360 for (int i = 0; i < 3; ++i) { 361 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 362 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 363 RunTasks(33); 364 } 365 366 // We expect a frame to be retransmitted because of duplicated ACKs. 367 // Only one packet of the frame is re-transmitted. 368 EXPECT_EQ(number_of_packets_sent + 1, 369 transport_.number_of_rtp_packets()); 370 371 // Start acking and make sure we're back to steady-state. 372 RtcpCastMessage cast_feedback(1); 373 cast_feedback.media_ssrc_ = 2; 374 cast_feedback.ack_frame_id_ = 0; 375 video_sender_->OnReceivedCastFeedback(cast_feedback); 376 EXPECT_LE( 377 4, 378 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets()); 379 380 // Empty the pipeline. 381 RunTasks(100); 382 // Should have sent at least 7 packets. 383 EXPECT_LE( 384 7, 385 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets()); 386 } 387 388 TEST_F(VideoSenderTest, DuplicateAckRetransmit) { 389 InitEncoder(false); 390 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 391 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 392 RunTasks(33); 393 RtcpCastMessage cast_feedback(1); 394 cast_feedback.media_ssrc_ = 2; 395 cast_feedback.ack_frame_id_ = 0; 396 397 // Send 3 more frames but don't ACK. 398 for (int i = 0; i < 3; ++i) { 399 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 400 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 401 RunTasks(33); 402 } 403 const int number_of_packets_sent = transport_.number_of_rtp_packets(); 404 405 // Send duplicated ACKs and mix some invalid NACKs. 406 for (int i = 0; i < 10; ++i) { 407 RtcpCastMessage ack_feedback(1); 408 ack_feedback.media_ssrc_ = 2; 409 ack_feedback.ack_frame_id_ = 0; 410 RtcpCastMessage nack_feedback(1); 411 nack_feedback.media_ssrc_ = 2; 412 nack_feedback.missing_frames_and_packets_[255] = PacketIdSet(); 413 video_sender_->OnReceivedCastFeedback(ack_feedback); 414 video_sender_->OnReceivedCastFeedback(nack_feedback); 415 } 416 EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets()); 417 418 // Re-transmit one packet because of duplicated ACKs. 419 for (int i = 0; i < 3; ++i) { 420 RtcpCastMessage ack_feedback(1); 421 ack_feedback.media_ssrc_ = 2; 422 ack_feedback.ack_frame_id_ = 0; 423 video_sender_->OnReceivedCastFeedback(ack_feedback); 424 } 425 EXPECT_EQ(number_of_packets_sent + 1, transport_.number_of_rtp_packets()); 426 } 427 428 TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) { 429 InitEncoder(false); 430 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 431 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 432 RunTasks(33); 433 RtcpCastMessage cast_feedback(1); 434 cast_feedback.media_ssrc_ = 2; 435 cast_feedback.ack_frame_id_ = 0; 436 437 // Send 2 more frames but don't ACK. 438 for (int i = 0; i < 2; ++i) { 439 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); 440 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 441 RunTasks(33); 442 } 443 // Pause the transport 444 transport_.SetPause(true); 445 446 // Insert one more video frame. 447 video_frame = GetLargeNewVideoFrame(); 448 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 449 RunTasks(33); 450 451 const int number_of_packets_sent = transport_.number_of_rtp_packets(); 452 453 // Send duplicated ACKs and mix some invalid NACKs. 454 for (int i = 0; i < 10; ++i) { 455 RtcpCastMessage ack_feedback(1); 456 ack_feedback.media_ssrc_ = 2; 457 ack_feedback.ack_frame_id_ = 0; 458 RtcpCastMessage nack_feedback(1); 459 nack_feedback.media_ssrc_ = 2; 460 nack_feedback.missing_frames_and_packets_[255] = PacketIdSet(); 461 video_sender_->OnReceivedCastFeedback(ack_feedback); 462 video_sender_->OnReceivedCastFeedback(nack_feedback); 463 } 464 EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets()); 465 466 // Re-transmit one packet because of duplicated ACKs. 467 for (int i = 0; i < 3; ++i) { 468 RtcpCastMessage ack_feedback(1); 469 ack_feedback.media_ssrc_ = 2; 470 ack_feedback.ack_frame_id_ = 0; 471 video_sender_->OnReceivedCastFeedback(ack_feedback); 472 } 473 474 transport_.SetPause(false); 475 RunTasks(100); 476 EXPECT_LT(number_of_packets_sent + 1, transport_.number_of_rtp_packets()); 477 } 478 479 TEST_F(VideoSenderTest, AcksCancelRetransmits) { 480 InitEncoder(false); 481 transport_.SetPause(true); 482 scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame(); 483 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 484 RunTasks(33); 485 486 // Frame should be in buffer, waiting. Now let's ack it. 487 RtcpCastMessage cast_feedback(1); 488 cast_feedback.media_ssrc_ = 2; 489 cast_feedback.ack_frame_id_ = 0; 490 video_sender_->OnReceivedCastFeedback(cast_feedback); 491 492 transport_.SetPause(false); 493 RunTasks(33); 494 EXPECT_EQ(0, transport_.number_of_rtp_packets()); 495 } 496 497 TEST_F(VideoSenderTest, NAcksCancelRetransmits) { 498 InitEncoder(false); 499 transport_.SetPause(true); 500 // Send two video frames. 501 scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame(); 502 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 503 RunTasks(33); 504 video_frame = GetLargeNewVideoFrame(); 505 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); 506 RunTasks(33); 507 508 // Frames should be in buffer, waiting. Now let's ack the first one and nack 509 // one packet in the second one. 510 RtcpCastMessage cast_feedback(1); 511 cast_feedback.media_ssrc_ = 2; 512 cast_feedback.ack_frame_id_ = 0; 513 PacketIdSet missing_packets; 514 missing_packets.insert(0); 515 cast_feedback.missing_frames_and_packets_[1] = missing_packets; 516 video_sender_->OnReceivedCastFeedback(cast_feedback); 517 518 transport_.SetPause(false); 519 RunTasks(33); 520 // Only one packet should be retransmitted. 521 EXPECT_EQ(1, transport_.number_of_rtp_packets()); 522 } 523 524 } // namespace cast 525 } // namespace media 526