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/sender/fake_video_encode_accelerator_factory.h"
19 #include "media/cast/sender/video_frame_factory.h"
20 #include "media/cast/sender/video_sender.h"
21 #include "media/cast/test/fake_single_thread_task_runner.h"
22 #include "media/cast/test/utility/default_config.h"
23 #include "media/cast/test/utility/video_utility.h"
24 #include "media/video/fake_video_encode_accelerator.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
32 static const uint8 kPixelValue
= 123;
33 static const int kWidth
= 320;
34 static const int kHeight
= 240;
37 using testing::AtLeast
;
40 void SaveOperationalStatus(OperationalStatus
* out_status
,
41 OperationalStatus in_status
) {
42 DVLOG(1) << "OperationalStatus transitioning from " << *out_status
<< " to "
44 *out_status
= in_status
;
47 class TestPacketSender
: public PacketSender
{
50 : number_of_rtp_packets_(0),
51 number_of_rtcp_packets_(0),
54 // A singular packet implies a RTCP packet.
55 bool SendPacket(PacketRef packet
, const base::Closure
& cb
) override
{
57 stored_packet_
= packet
;
61 if (Rtcp::IsRtcpPacket(&packet
->data
[0], packet
->data
.size())) {
62 ++number_of_rtcp_packets_
;
64 // Check that at least one RTCP packet was sent before the first RTP
65 // packet. This confirms that the receiver will have the necessary lip
66 // sync info before it has to calculate the playout time of the first
68 if (number_of_rtp_packets_
== 0)
69 EXPECT_LE(1, number_of_rtcp_packets_
);
70 ++number_of_rtp_packets_
;
75 int64
GetBytesSent() override
{ return 0; }
77 int number_of_rtp_packets() const { return number_of_rtp_packets_
; }
79 int number_of_rtcp_packets() const { return number_of_rtcp_packets_
; }
81 void SetPause(bool paused
) {
83 if (!paused
&& stored_packet_
.get()) {
84 SendPacket(stored_packet_
, callback_
);
90 int number_of_rtp_packets_
;
91 int number_of_rtcp_packets_
;
93 base::Closure callback_
;
94 PacketRef stored_packet_
;
96 DISALLOW_COPY_AND_ASSIGN(TestPacketSender
);
99 void IgnorePlayoutDelayChanges(base::TimeDelta unused_playout_delay
) {
102 class PeerVideoSender
: public VideoSender
{
105 scoped_refptr
<CastEnvironment
> cast_environment
,
106 const VideoSenderConfig
& video_config
,
107 const StatusChangeCallback
& status_change_cb
,
108 const CreateVideoEncodeAcceleratorCallback
& create_vea_cb
,
109 const CreateVideoEncodeMemoryCallback
& create_video_encode_mem_cb
,
110 CastTransportSender
* const transport_sender
)
111 : VideoSender(cast_environment
,
115 create_video_encode_mem_cb
,
117 base::Bind(&IgnorePlayoutDelayChanges
)) {}
118 using VideoSender::OnReceivedCastFeedback
;
122 class VideoSenderTest
: public ::testing::Test
{
125 : testing_clock_(new base::SimpleTestTickClock()),
126 task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_
)),
127 cast_environment_(new CastEnvironment(
128 scoped_ptr
<base::TickClock
>(testing_clock_
).Pass(),
132 operational_status_(STATUS_UNINITIALIZED
),
133 vea_factory_(task_runner_
) {
134 testing_clock_
->Advance(base::TimeTicks::Now() - base::TimeTicks());
135 vea_factory_
.SetAutoRespond(true);
136 last_pixel_value_
= kPixelValue
;
137 net::IPEndPoint dummy_endpoint
;
138 transport_sender_
.reset(new CastTransportSenderImpl(
143 make_scoped_ptr(new base::DictionaryValue
),
144 base::Bind(&UpdateCastTransportStatus
),
145 BulkRawEventsCallback(),
148 PacketReceiverCallback(),
152 ~VideoSenderTest() override
{}
154 void TearDown() override
{
155 video_sender_
.reset();
156 task_runner_
->RunTasks();
159 static void UpdateCastTransportStatus(CastTransportStatus status
) {
160 EXPECT_EQ(TRANSPORT_VIDEO_INITIALIZED
, status
);
163 // If |external| is true then external video encoder (VEA) is used.
164 // |expect_init_sucess| is true if initialization is expected to succeed.
165 void InitEncoder(bool external
, bool expect_init_success
) {
166 VideoSenderConfig video_config
;
167 video_config
.ssrc
= 1;
168 video_config
.receiver_ssrc
= 2;
169 video_config
.rtp_payload_type
= 127;
170 video_config
.use_external_encoder
= external
;
171 video_config
.max_bitrate
= 5000000;
172 video_config
.min_bitrate
= 1000000;
173 video_config
.start_bitrate
= 1000000;
174 video_config
.max_qp
= 56;
175 video_config
.min_qp
= 0;
176 video_config
.max_frame_rate
= 30;
177 video_config
.max_number_of_video_buffers_used
= 1;
178 video_config
.codec
= CODEC_VIDEO_VP8
;
180 ASSERT_EQ(operational_status_
, STATUS_UNINITIALIZED
);
183 vea_factory_
.SetInitializationWillSucceed(expect_init_success
);
184 video_sender_
.reset(new PeerVideoSender(
187 base::Bind(&SaveOperationalStatus
, &operational_status_
),
189 &FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator
,
190 base::Unretained(&vea_factory_
)),
191 base::Bind(&FakeVideoEncodeAcceleratorFactory::CreateSharedMemory
,
192 base::Unretained(&vea_factory_
)),
193 transport_sender_
.get()));
195 video_sender_
.reset(new PeerVideoSender(
198 base::Bind(&SaveOperationalStatus
, &operational_status_
),
199 CreateDefaultVideoEncodeAcceleratorCallback(),
200 CreateDefaultVideoEncodeMemoryCallback(),
201 transport_sender_
.get()));
203 task_runner_
->RunTasks();
206 scoped_refptr
<media::VideoFrame
> GetNewVideoFrame() {
207 if (first_frame_timestamp_
.is_null())
208 first_frame_timestamp_
= testing_clock_
->NowTicks();
209 gfx::Size
size(kWidth
, kHeight
);
210 scoped_refptr
<media::VideoFrame
> video_frame
=
211 media::VideoFrame::CreateFrame(
212 VideoFrame::I420
, size
, gfx::Rect(size
), size
,
213 testing_clock_
->NowTicks() - first_frame_timestamp_
);
214 PopulateVideoFrame(video_frame
.get(), last_pixel_value_
++);
218 scoped_refptr
<media::VideoFrame
> GetLargeNewVideoFrame() {
219 if (first_frame_timestamp_
.is_null())
220 first_frame_timestamp_
= testing_clock_
->NowTicks();
221 gfx::Size
size(kWidth
, kHeight
);
222 scoped_refptr
<media::VideoFrame
> video_frame
=
223 media::VideoFrame::CreateFrame(
224 VideoFrame::I420
, size
, gfx::Rect(size
), size
,
225 testing_clock_
->NowTicks() - first_frame_timestamp_
);
226 PopulateVideoFrameWithNoise(video_frame
.get());
230 void RunTasks(int during_ms
) {
231 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(during_ms
));
234 base::SimpleTestTickClock
* const testing_clock_
; // Owned by CastEnvironment.
235 const scoped_refptr
<test::FakeSingleThreadTaskRunner
> task_runner_
;
236 const scoped_refptr
<CastEnvironment
> cast_environment_
;
237 OperationalStatus operational_status_
;
238 FakeVideoEncodeAcceleratorFactory vea_factory_
;
239 TestPacketSender transport_
;
240 scoped_ptr
<CastTransportSenderImpl
> transport_sender_
;
241 scoped_ptr
<PeerVideoSender
> video_sender_
;
242 int last_pixel_value_
;
243 base::TimeTicks first_frame_timestamp_
;
245 DISALLOW_COPY_AND_ASSIGN(VideoSenderTest
);
248 TEST_F(VideoSenderTest
, BuiltInEncoder
) {
249 InitEncoder(false, true);
250 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
252 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
254 const base::TimeTicks reference_time
= testing_clock_
->NowTicks();
255 video_sender_
->InsertRawVideoFrame(video_frame
, reference_time
);
257 task_runner_
->RunTasks();
258 EXPECT_LE(1, transport_
.number_of_rtp_packets());
259 EXPECT_LE(1, transport_
.number_of_rtcp_packets());
262 TEST_F(VideoSenderTest
, ExternalEncoder
) {
263 InitEncoder(true, true);
264 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
266 // The SizeAdaptableExternalVideoEncoder initally reports STATUS_INITIALIZED
267 // so that frames will be sent to it. Therefore, no encoder activity should
268 // have occurred at this point. Send a frame to spurn creation of the
269 // underlying ExternalVideoEncoder instance.
270 if (vea_factory_
.vea_response_count() == 0) {
271 video_sender_
->InsertRawVideoFrame(GetNewVideoFrame(),
272 testing_clock_
->NowTicks());
273 task_runner_
->RunTasks();
275 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
278 // VideoSender created an encoder for 1280x720 frames, in order to provide the
279 // INITIALIZED status.
280 EXPECT_EQ(1, vea_factory_
.vea_response_count());
281 EXPECT_EQ(3, vea_factory_
.shm_response_count());
283 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
285 for (int i
= 0; i
< 3; ++i
) {
286 const base::TimeTicks reference_time
= testing_clock_
->NowTicks();
287 video_sender_
->InsertRawVideoFrame(video_frame
, reference_time
);
289 // VideoSender re-created the encoder for the 320x240 frames we're
291 EXPECT_EQ(1, vea_factory_
.vea_response_count());
292 EXPECT_EQ(3, vea_factory_
.shm_response_count());
295 video_sender_
.reset(NULL
);
296 task_runner_
->RunTasks();
297 EXPECT_EQ(1, vea_factory_
.vea_response_count());
298 EXPECT_EQ(3, vea_factory_
.shm_response_count());
301 TEST_F(VideoSenderTest
, ExternalEncoderInitFails
) {
302 InitEncoder(true, false);
304 // The SizeAdaptableExternalVideoEncoder initally reports STATUS_INITIALIZED
305 // so that frames will be sent to it. Send a frame to spurn creation of the
306 // underlying ExternalVideoEncoder instance, which should result in failure.
307 if (operational_status_
== STATUS_INITIALIZED
||
308 operational_status_
== STATUS_CODEC_REINIT_PENDING
) {
309 video_sender_
->InsertRawVideoFrame(GetNewVideoFrame(),
310 testing_clock_
->NowTicks());
311 task_runner_
->RunTasks();
313 EXPECT_EQ(STATUS_CODEC_INIT_FAILED
, operational_status_
);
315 video_sender_
.reset(NULL
);
316 task_runner_
->RunTasks();
319 TEST_F(VideoSenderTest
, RtcpTimer
) {
320 InitEncoder(false, true);
321 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
323 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
325 const base::TimeTicks reference_time
= testing_clock_
->NowTicks();
326 video_sender_
->InsertRawVideoFrame(video_frame
, reference_time
);
328 // Make sure that we send at least one RTCP packet.
329 base::TimeDelta max_rtcp_timeout
=
330 base::TimeDelta::FromMilliseconds(1 + kDefaultRtcpIntervalMs
* 3 / 2);
332 RunTasks(max_rtcp_timeout
.InMilliseconds());
333 EXPECT_LE(1, transport_
.number_of_rtp_packets());
334 EXPECT_LE(1, transport_
.number_of_rtcp_packets());
335 // Build Cast msg and expect RTCP packet.
336 RtcpCastMessage
cast_feedback(1);
337 cast_feedback
.media_ssrc
= 2;
338 cast_feedback
.ack_frame_id
= 0;
339 video_sender_
->OnReceivedCastFeedback(cast_feedback
);
340 RunTasks(max_rtcp_timeout
.InMilliseconds());
341 EXPECT_LE(1, transport_
.number_of_rtcp_packets());
344 TEST_F(VideoSenderTest
, ResendTimer
) {
345 InitEncoder(false, true);
346 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
348 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
350 const base::TimeTicks reference_time
= testing_clock_
->NowTicks();
351 video_sender_
->InsertRawVideoFrame(video_frame
, reference_time
);
353 // ACK the key frame.
354 RtcpCastMessage
cast_feedback(1);
355 cast_feedback
.media_ssrc
= 2;
356 cast_feedback
.ack_frame_id
= 0;
357 video_sender_
->OnReceivedCastFeedback(cast_feedback
);
359 video_frame
= GetNewVideoFrame();
360 video_sender_
->InsertRawVideoFrame(video_frame
, reference_time
);
362 base::TimeDelta max_resend_timeout
=
363 base::TimeDelta::FromMilliseconds(1 + kDefaultRtpMaxDelayMs
);
365 // Make sure that we do a re-send.
366 RunTasks(max_resend_timeout
.InMilliseconds());
367 // Should have sent at least 3 packets.
370 transport_
.number_of_rtp_packets() + transport_
.number_of_rtcp_packets());
373 TEST_F(VideoSenderTest
, LogAckReceivedEvent
) {
374 InitEncoder(false, true);
375 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
377 SimpleEventSubscriber event_subscriber
;
378 cast_environment_
->Logging()->AddRawEventSubscriber(&event_subscriber
);
381 for (int i
= 0; i
< num_frames
; i
++) {
382 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
384 const base::TimeTicks reference_time
= testing_clock_
->NowTicks();
385 video_sender_
->InsertRawVideoFrame(video_frame
, reference_time
);
389 task_runner_
->RunTasks();
391 RtcpCastMessage
cast_feedback(1);
392 cast_feedback
.ack_frame_id
= num_frames
- 1;
394 video_sender_
->OnReceivedCastFeedback(cast_feedback
);
396 std::vector
<FrameEvent
> frame_events
;
397 event_subscriber
.GetFrameEventsAndReset(&frame_events
);
399 ASSERT_TRUE(!frame_events
.empty());
400 EXPECT_EQ(FRAME_ACK_RECEIVED
, frame_events
.rbegin()->type
);
401 EXPECT_EQ(VIDEO_EVENT
, frame_events
.rbegin()->media_type
);
402 EXPECT_EQ(num_frames
- 1u, frame_events
.rbegin()->frame_id
);
404 cast_environment_
->Logging()->RemoveRawEventSubscriber(&event_subscriber
);
407 TEST_F(VideoSenderTest
, StopSendingInTheAbsenceOfAck
) {
408 InitEncoder(false, true);
409 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
411 // Send a stream of frames and don't ACK; by default we shouldn't have more
412 // than 4 frames in flight.
413 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
414 video_sender_
->InsertRawVideoFrame(video_frame
, testing_clock_
->NowTicks());
417 // Send 3 more frames and record the number of packets sent.
418 for (int i
= 0; i
< 3; ++i
) {
419 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
420 video_sender_
->InsertRawVideoFrame(video_frame
, testing_clock_
->NowTicks());
423 const int number_of_packets_sent
= transport_
.number_of_rtp_packets();
425 // Send 3 more frames - they should not be encoded, as we have not received
427 for (int i
= 0; i
< 3; ++i
) {
428 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
429 video_sender_
->InsertRawVideoFrame(video_frame
, testing_clock_
->NowTicks());
433 // We expect a frame to be retransmitted because of duplicated ACKs.
434 // Only one packet of the frame is re-transmitted.
435 EXPECT_EQ(number_of_packets_sent
+ 1,
436 transport_
.number_of_rtp_packets());
438 // Start acking and make sure we're back to steady-state.
439 RtcpCastMessage
cast_feedback(1);
440 cast_feedback
.media_ssrc
= 2;
441 cast_feedback
.ack_frame_id
= 0;
442 video_sender_
->OnReceivedCastFeedback(cast_feedback
);
445 transport_
.number_of_rtp_packets() + transport_
.number_of_rtcp_packets());
447 // Empty the pipeline.
449 // Should have sent at least 7 packets.
452 transport_
.number_of_rtp_packets() + transport_
.number_of_rtcp_packets());
455 TEST_F(VideoSenderTest
, DuplicateAckRetransmit
) {
456 InitEncoder(false, true);
457 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
459 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
460 video_sender_
->InsertRawVideoFrame(video_frame
, testing_clock_
->NowTicks());
462 RtcpCastMessage
cast_feedback(1);
463 cast_feedback
.media_ssrc
= 2;
464 cast_feedback
.ack_frame_id
= 0;
466 // Send 3 more frames but don't ACK.
467 for (int i
= 0; i
< 3; ++i
) {
468 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
469 video_sender_
->InsertRawVideoFrame(video_frame
, testing_clock_
->NowTicks());
472 const int number_of_packets_sent
= transport_
.number_of_rtp_packets();
474 // Send duplicated ACKs and mix some invalid NACKs.
475 for (int i
= 0; i
< 10; ++i
) {
476 RtcpCastMessage
ack_feedback(1);
477 ack_feedback
.media_ssrc
= 2;
478 ack_feedback
.ack_frame_id
= 0;
479 RtcpCastMessage
nack_feedback(1);
480 nack_feedback
.media_ssrc
= 2;
481 nack_feedback
.missing_frames_and_packets
[255] = PacketIdSet();
482 video_sender_
->OnReceivedCastFeedback(ack_feedback
);
483 video_sender_
->OnReceivedCastFeedback(nack_feedback
);
485 EXPECT_EQ(number_of_packets_sent
, transport_
.number_of_rtp_packets());
487 // Re-transmit one packet because of duplicated ACKs.
488 for (int i
= 0; i
< 3; ++i
) {
489 RtcpCastMessage
ack_feedback(1);
490 ack_feedback
.media_ssrc
= 2;
491 ack_feedback
.ack_frame_id
= 0;
492 video_sender_
->OnReceivedCastFeedback(ack_feedback
);
494 EXPECT_EQ(number_of_packets_sent
+ 1, transport_
.number_of_rtp_packets());
497 TEST_F(VideoSenderTest
, DuplicateAckRetransmitDoesNotCancelRetransmits
) {
498 InitEncoder(false, true);
499 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
501 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
502 video_sender_
->InsertRawVideoFrame(video_frame
, testing_clock_
->NowTicks());
504 RtcpCastMessage
cast_feedback(1);
505 cast_feedback
.media_ssrc
= 2;
506 cast_feedback
.ack_frame_id
= 0;
508 // Send 2 more frames but don't ACK.
509 for (int i
= 0; i
< 2; ++i
) {
510 scoped_refptr
<media::VideoFrame
> video_frame
= GetNewVideoFrame();
511 video_sender_
->InsertRawVideoFrame(video_frame
, testing_clock_
->NowTicks());
514 // Pause the transport
515 transport_
.SetPause(true);
517 // Insert one more video frame.
518 video_frame
= GetLargeNewVideoFrame();
519 video_sender_
->InsertRawVideoFrame(video_frame
, testing_clock_
->NowTicks());
522 const int number_of_packets_sent
= transport_
.number_of_rtp_packets();
524 // Send duplicated ACKs and mix some invalid NACKs.
525 for (int i
= 0; i
< 10; ++i
) {
526 RtcpCastMessage
ack_feedback(1);
527 ack_feedback
.media_ssrc
= 2;
528 ack_feedback
.ack_frame_id
= 0;
529 RtcpCastMessage
nack_feedback(1);
530 nack_feedback
.media_ssrc
= 2;
531 nack_feedback
.missing_frames_and_packets
[255] = PacketIdSet();
532 video_sender_
->OnReceivedCastFeedback(ack_feedback
);
533 video_sender_
->OnReceivedCastFeedback(nack_feedback
);
535 EXPECT_EQ(number_of_packets_sent
, transport_
.number_of_rtp_packets());
537 // Re-transmit one packet because of duplicated ACKs.
538 for (int i
= 0; i
< 3; ++i
) {
539 RtcpCastMessage
ack_feedback(1);
540 ack_feedback
.media_ssrc
= 2;
541 ack_feedback
.ack_frame_id
= 0;
542 video_sender_
->OnReceivedCastFeedback(ack_feedback
);
545 transport_
.SetPause(false);
547 EXPECT_LT(number_of_packets_sent
+ 1, transport_
.number_of_rtp_packets());
550 TEST_F(VideoSenderTest
, AcksCancelRetransmits
) {
551 InitEncoder(false, true);
552 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
554 transport_
.SetPause(true);
555 scoped_refptr
<media::VideoFrame
> video_frame
= GetLargeNewVideoFrame();
556 video_sender_
->InsertRawVideoFrame(video_frame
, testing_clock_
->NowTicks());
559 // Frame should be in buffer, waiting. Now let's ack it.
560 RtcpCastMessage
cast_feedback(1);
561 cast_feedback
.media_ssrc
= 2;
562 cast_feedback
.ack_frame_id
= 0;
563 video_sender_
->OnReceivedCastFeedback(cast_feedback
);
565 transport_
.SetPause(false);
567 EXPECT_EQ(0, transport_
.number_of_rtp_packets());
570 TEST_F(VideoSenderTest
, CheckVideoFrameFactoryIsNull
) {
571 InitEncoder(false, true);
572 ASSERT_EQ(STATUS_INITIALIZED
, operational_status_
);
574 EXPECT_EQ(nullptr, video_sender_
->CreateVideoFrameFactory().get());