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.
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/net/rtcp/rtcp_receiver.h"
19 #include "media/cast/sender/video_sender.h"
20 #include "media/cast/test/fake_single_thread_task_runner.h"
21 #include "media/cast/test/fake_video_encode_accelerator.h"
22 #include "media/cast/test/utility/default_config.h"
23 #include "media/cast/test/utility/video_utility.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
31 static const uint8 kPixelValue = 123;
32 static const int kWidth = 320;
33 static const int kHeight = 240;
36 using testing::AtLeast;
38 void CreateVideoEncodeAccelerator(
39 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
40 scoped_ptr<VideoEncodeAccelerator> fake_vea,
41 const ReceiveVideoEncodeAcceleratorCallback& callback) {
42 callback.Run(task_runner, fake_vea.Pass());
45 void CreateSharedMemory(
46 size_t size, const ReceiveVideoEncodeMemoryCallback& callback) {
47 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory());
48 if (!shm->CreateAndMapAnonymous(size)) {
52 callback.Run(shm.Pass());
55 class TestPacketSender : public PacketSender {
58 : number_of_rtp_packets_(0),
59 number_of_rtcp_packets_(0),
62 // A singular packet implies a RTCP packet.
63 virtual bool SendPacket(PacketRef packet,
64 const base::Closure& cb) OVERRIDE {
66 stored_packet_ = packet;
70 if (RtcpReceiver::IsRtcpPacket(&packet->data[0], packet->data.size())) {
71 ++number_of_rtcp_packets_;
73 // Check that at least one RTCP packet was sent before the first RTP
74 // packet. This confirms that the receiver will have the necessary lip
75 // sync info before it has to calculate the playout time of the first
77 if (number_of_rtp_packets_ == 0)
78 EXPECT_LE(1, number_of_rtcp_packets_);
79 ++number_of_rtp_packets_;
84 int number_of_rtp_packets() const { return number_of_rtp_packets_; }
86 int number_of_rtcp_packets() const { return number_of_rtcp_packets_; }
88 void SetPause(bool paused) {
90 if (!paused && stored_packet_) {
91 SendPacket(stored_packet_, callback_);
97 int number_of_rtp_packets_;
98 int number_of_rtcp_packets_;
100 base::Closure callback_;
101 PacketRef stored_packet_;
103 DISALLOW_COPY_AND_ASSIGN(TestPacketSender);
106 class PeerVideoSender : public VideoSender {
109 scoped_refptr<CastEnvironment> cast_environment,
110 const VideoSenderConfig& video_config,
111 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
112 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
113 CastTransportSender* const transport_sender)
114 : VideoSender(cast_environment,
117 create_video_encode_mem_cb,
119 using VideoSender::OnReceivedCastFeedback;
123 class VideoSenderTest : public ::testing::Test {
126 testing_clock_ = new base::SimpleTestTickClock();
127 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
128 task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_);
130 new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(),
134 last_pixel_value_ = kPixelValue;
135 net::IPEndPoint dummy_endpoint;
136 transport_sender_.reset(new CastTransportSenderImpl(
140 base::Bind(&UpdateCastTransportStatus),
141 BulkRawEventsCallback(),
147 virtual ~VideoSenderTest() {}
149 virtual void TearDown() OVERRIDE {
150 video_sender_.reset();
151 task_runner_->RunTasks();
154 static void UpdateCastTransportStatus(CastTransportStatus status) {
155 EXPECT_EQ(TRANSPORT_VIDEO_INITIALIZED, status);
158 void InitEncoder(bool external) {
159 VideoSenderConfig video_config;
160 video_config.ssrc = 1;
161 video_config.incoming_feedback_ssrc = 2;
162 video_config.rtp_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 = CODEC_VIDEO_VP8;
176 scoped_ptr<VideoEncodeAccelerator> fake_vea(
177 new test::FakeVideoEncodeAccelerator(task_runner_,
180 new PeerVideoSender(cast_environment_,
182 base::Bind(&CreateVideoEncodeAccelerator,
184 base::Passed(&fake_vea)),
185 base::Bind(&CreateSharedMemory),
186 transport_sender_.get()));
189 new PeerVideoSender(cast_environment_,
191 CreateDefaultVideoEncodeAcceleratorCallback(),
192 CreateDefaultVideoEncodeMemoryCallback(),
193 transport_sender_.get()));
195 ASSERT_EQ(STATUS_VIDEO_INITIALIZED, video_sender_->InitializationResult());
198 scoped_refptr<media::VideoFrame> GetNewVideoFrame() {
199 gfx::Size size(kWidth, kHeight);
200 scoped_refptr<media::VideoFrame> video_frame =
201 media::VideoFrame::CreateFrame(
202 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta());
203 PopulateVideoFrame(video_frame, last_pixel_value_++);
207 scoped_refptr<media::VideoFrame> GetLargeNewVideoFrame() {
208 gfx::Size size(kWidth, kHeight);
209 scoped_refptr<media::VideoFrame> video_frame =
210 media::VideoFrame::CreateFrame(
211 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta());
212 PopulateVideoFrameWithNoise(video_frame);
216 void RunTasks(int during_ms) {
217 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(during_ms));
220 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment.
221 TestPacketSender transport_;
222 scoped_ptr<CastTransportSenderImpl> transport_sender_;
223 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
224 scoped_ptr<PeerVideoSender> video_sender_;
225 std::vector<uint32> stored_bitrates_;
226 scoped_refptr<CastEnvironment> cast_environment_;
227 int last_pixel_value_;
229 DISALLOW_COPY_AND_ASSIGN(VideoSenderTest);
232 TEST_F(VideoSenderTest, BuiltInEncoder) {
234 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
236 const base::TimeTicks capture_time = testing_clock_->NowTicks();
237 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
239 task_runner_->RunTasks();
240 EXPECT_LE(1, transport_.number_of_rtp_packets());
241 EXPECT_LE(1, transport_.number_of_rtcp_packets());
244 TEST_F(VideoSenderTest, ExternalEncoder) {
246 task_runner_->RunTasks();
248 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
250 const base::TimeTicks capture_time = testing_clock_->NowTicks();
251 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
252 task_runner_->RunTasks();
253 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
254 task_runner_->RunTasks();
255 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
256 task_runner_->RunTasks();
258 // Fixed bitrate is used for external encoder. Bitrate is only once
260 EXPECT_EQ(1u, stored_bitrates_.size());
262 // We need to run the task to cleanup the GPU instance.
263 video_sender_.reset(NULL);
264 task_runner_->RunTasks();
267 TEST_F(VideoSenderTest, RtcpTimer) {
270 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
272 const base::TimeTicks capture_time = testing_clock_->NowTicks();
273 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
275 // Make sure that we send at least one RTCP packet.
276 base::TimeDelta max_rtcp_timeout =
277 base::TimeDelta::FromMilliseconds(1 + kDefaultRtcpIntervalMs * 3 / 2);
279 RunTasks(max_rtcp_timeout.InMilliseconds());
280 EXPECT_LE(1, transport_.number_of_rtp_packets());
281 EXPECT_LE(1, transport_.number_of_rtcp_packets());
282 // Build Cast msg and expect RTCP packet.
283 RtcpCastMessage cast_feedback(1);
284 cast_feedback.media_ssrc = 2;
285 cast_feedback.ack_frame_id = 0;
286 video_sender_->OnReceivedCastFeedback(cast_feedback);
287 RunTasks(max_rtcp_timeout.InMilliseconds());
288 EXPECT_LE(1, transport_.number_of_rtcp_packets());
291 TEST_F(VideoSenderTest, ResendTimer) {
294 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
296 const base::TimeTicks capture_time = testing_clock_->NowTicks();
297 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
299 // ACK the key frame.
300 RtcpCastMessage cast_feedback(1);
301 cast_feedback.media_ssrc = 2;
302 cast_feedback.ack_frame_id = 0;
303 video_sender_->OnReceivedCastFeedback(cast_feedback);
305 video_frame = GetNewVideoFrame();
306 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
308 base::TimeDelta max_resend_timeout =
309 base::TimeDelta::FromMilliseconds(1 + kDefaultRtpMaxDelayMs);
311 // Make sure that we do a re-send.
312 RunTasks(max_resend_timeout.InMilliseconds());
313 // Should have sent at least 3 packets.
316 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
319 TEST_F(VideoSenderTest, LogAckReceivedEvent) {
321 SimpleEventSubscriber event_subscriber;
322 cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber);
325 for (int i = 0; i < num_frames; i++) {
326 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
328 const base::TimeTicks capture_time = testing_clock_->NowTicks();
329 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
333 task_runner_->RunTasks();
335 RtcpCastMessage cast_feedback(1);
336 cast_feedback.ack_frame_id = num_frames - 1;
338 video_sender_->OnReceivedCastFeedback(cast_feedback);
340 std::vector<FrameEvent> frame_events;
341 event_subscriber.GetFrameEventsAndReset(&frame_events);
343 ASSERT_TRUE(!frame_events.empty());
344 EXPECT_EQ(FRAME_ACK_RECEIVED, frame_events.rbegin()->type);
345 EXPECT_EQ(VIDEO_EVENT, frame_events.rbegin()->media_type);
346 EXPECT_EQ(num_frames - 1u, frame_events.rbegin()->frame_id);
348 cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber);
351 TEST_F(VideoSenderTest, StopSendingInTheAbsenceOfAck) {
353 // Send a stream of frames and don't ACK; by default we shouldn't have more
354 // than 4 frames in flight.
355 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
356 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
359 // Send 3 more frames and record the number of packets sent.
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());
365 const int number_of_packets_sent = transport_.number_of_rtp_packets();
367 // Send 3 more frames - they should not be encoded, as we have not received
369 for (int i = 0; i < 3; ++i) {
370 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
371 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
375 // We expect a frame to be retransmitted because of duplicated ACKs.
376 // Only one packet of the frame is re-transmitted.
377 EXPECT_EQ(number_of_packets_sent + 1,
378 transport_.number_of_rtp_packets());
380 // Start acking and make sure we're back to steady-state.
381 RtcpCastMessage cast_feedback(1);
382 cast_feedback.media_ssrc = 2;
383 cast_feedback.ack_frame_id = 0;
384 video_sender_->OnReceivedCastFeedback(cast_feedback);
387 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
389 // Empty the pipeline.
391 // Should have sent at least 7 packets.
394 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
397 TEST_F(VideoSenderTest, DuplicateAckRetransmit) {
399 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
400 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
402 RtcpCastMessage cast_feedback(1);
403 cast_feedback.media_ssrc = 2;
404 cast_feedback.ack_frame_id = 0;
406 // Send 3 more frames but don't ACK.
407 for (int i = 0; i < 3; ++i) {
408 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
409 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
412 const int number_of_packets_sent = transport_.number_of_rtp_packets();
414 // Send duplicated ACKs and mix some invalid NACKs.
415 for (int i = 0; i < 10; ++i) {
416 RtcpCastMessage ack_feedback(1);
417 ack_feedback.media_ssrc = 2;
418 ack_feedback.ack_frame_id = 0;
419 RtcpCastMessage nack_feedback(1);
420 nack_feedback.media_ssrc = 2;
421 nack_feedback.missing_frames_and_packets[255] = PacketIdSet();
422 video_sender_->OnReceivedCastFeedback(ack_feedback);
423 video_sender_->OnReceivedCastFeedback(nack_feedback);
425 EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets());
427 // Re-transmit one packet because of duplicated ACKs.
428 for (int i = 0; i < 3; ++i) {
429 RtcpCastMessage ack_feedback(1);
430 ack_feedback.media_ssrc = 2;
431 ack_feedback.ack_frame_id = 0;
432 video_sender_->OnReceivedCastFeedback(ack_feedback);
434 EXPECT_EQ(number_of_packets_sent + 1, transport_.number_of_rtp_packets());
437 TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) {
439 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
440 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
442 RtcpCastMessage cast_feedback(1);
443 cast_feedback.media_ssrc = 2;
444 cast_feedback.ack_frame_id = 0;
446 // Send 2 more frames but don't ACK.
447 for (int i = 0; i < 2; ++i) {
448 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
449 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
452 // Pause the transport
453 transport_.SetPause(true);
455 // Insert one more video frame.
456 video_frame = GetLargeNewVideoFrame();
457 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
460 const int number_of_packets_sent = transport_.number_of_rtp_packets();
462 // Send duplicated ACKs and mix some invalid NACKs.
463 for (int i = 0; i < 10; ++i) {
464 RtcpCastMessage ack_feedback(1);
465 ack_feedback.media_ssrc = 2;
466 ack_feedback.ack_frame_id = 0;
467 RtcpCastMessage nack_feedback(1);
468 nack_feedback.media_ssrc = 2;
469 nack_feedback.missing_frames_and_packets[255] = PacketIdSet();
470 video_sender_->OnReceivedCastFeedback(ack_feedback);
471 video_sender_->OnReceivedCastFeedback(nack_feedback);
473 EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets());
475 // Re-transmit one packet because of duplicated ACKs.
476 for (int i = 0; i < 3; ++i) {
477 RtcpCastMessage ack_feedback(1);
478 ack_feedback.media_ssrc = 2;
479 ack_feedback.ack_frame_id = 0;
480 video_sender_->OnReceivedCastFeedback(ack_feedback);
483 transport_.SetPause(false);
485 EXPECT_LT(number_of_packets_sent + 1, transport_.number_of_rtp_packets());
488 TEST_F(VideoSenderTest, AcksCancelRetransmits) {
490 transport_.SetPause(true);
491 scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame();
492 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
495 // Frame should be in buffer, waiting. Now let's ack it.
496 RtcpCastMessage cast_feedback(1);
497 cast_feedback.media_ssrc = 2;
498 cast_feedback.ack_frame_id = 0;
499 video_sender_->OnReceivedCastFeedback(cast_feedback);
501 transport_.SetPause(false);
503 EXPECT_EQ(0, transport_.number_of_rtp_packets());
506 TEST_F(VideoSenderTest, NAcksCancelRetransmits) {
508 transport_.SetPause(true);
509 // Send two video frames.
510 scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame();
511 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
513 video_frame = GetLargeNewVideoFrame();
514 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
517 // Frames should be in buffer, waiting. Now let's ack the first one and nack
518 // one packet in the second one.
519 RtcpCastMessage cast_feedback(1);
520 cast_feedback.media_ssrc = 2;
521 cast_feedback.ack_frame_id = 0;
522 PacketIdSet missing_packets;
523 missing_packets.insert(0);
524 cast_feedback.missing_frames_and_packets[1] = missing_packets;
525 video_sender_->OnReceivedCastFeedback(cast_feedback);
527 transport_.SetPause(false);
529 // Only one packet should be retransmitted.
530 EXPECT_EQ(1, transport_.number_of_rtp_packets());