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