Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / media / cast / sender / video_sender_unittest.cc
blob89a9c4fa497ffea88c1198a09fe29f82c1bf7f04
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.
5 #include <stdint.h>
7 #include <vector>
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/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"
28 namespace media {
29 namespace cast {
31 namespace {
32 static const uint8 kPixelValue = 123;
33 static const int kWidth = 320;
34 static const int kHeight = 240;
36 using testing::_;
37 using testing::AtLeast;
40 void SaveOperationalStatus(OperationalStatus* out_status,
41 OperationalStatus in_status) {
42 DVLOG(1) << "OperationalStatus transitioning from " << *out_status << " to "
43 << in_status;
44 *out_status = in_status;
47 class TestPacketSender : public PacketSender {
48 public:
49 TestPacketSender()
50 : number_of_rtp_packets_(0),
51 number_of_rtcp_packets_(0),
52 paused_(false) {}
54 // A singular packet implies a RTCP packet.
55 bool SendPacket(PacketRef packet, const base::Closure& cb) override {
56 if (paused_) {
57 stored_packet_ = packet;
58 callback_ = cb;
59 return false;
61 if (Rtcp::IsRtcpPacket(&packet->data[0], packet->data.size())) {
62 ++number_of_rtcp_packets_;
63 } else {
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
67 // frame.
68 if (number_of_rtp_packets_ == 0)
69 EXPECT_LE(1, number_of_rtcp_packets_);
70 ++number_of_rtp_packets_;
72 return true;
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) {
82 paused_ = paused;
83 if (!paused && stored_packet_.get()) {
84 SendPacket(stored_packet_, callback_);
85 callback_.Run();
89 private:
90 int number_of_rtp_packets_;
91 int number_of_rtcp_packets_;
92 bool paused_;
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 {
103 public:
104 PeerVideoSender(
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,
112 video_config,
113 status_change_cb,
114 create_vea_cb,
115 create_video_encode_mem_cb,
116 transport_sender,
117 base::Bind(&IgnorePlayoutDelayChanges)) {}
118 using VideoSender::OnReceivedCastFeedback;
120 } // namespace
122 class VideoSenderTest : public ::testing::Test {
123 protected:
124 VideoSenderTest()
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(),
129 task_runner_,
130 task_runner_,
131 task_runner_)),
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(
139 NULL,
140 testing_clock_,
141 dummy_endpoint,
142 dummy_endpoint,
143 make_scoped_ptr(new base::DictionaryValue),
144 base::Bind(&UpdateCastTransportStatus),
145 BulkRawEventsCallback(),
146 base::TimeDelta(),
147 task_runner_,
148 PacketReceiverCallback(),
149 &transport_));
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);
182 if (external) {
183 vea_factory_.SetInitializationWillSucceed(expect_init_success);
184 video_sender_.reset(new PeerVideoSender(
185 cast_environment_,
186 video_config,
187 base::Bind(&SaveOperationalStatus, &operational_status_),
188 base::Bind(
189 &FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator,
190 base::Unretained(&vea_factory_)),
191 base::Bind(&FakeVideoEncodeAcceleratorFactory::CreateSharedMemory,
192 base::Unretained(&vea_factory_)),
193 transport_sender_.get()));
194 } else {
195 video_sender_.reset(new PeerVideoSender(
196 cast_environment_,
197 video_config,
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_++);
215 return video_frame;
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());
227 return video_frame;
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_);
276 RunTasks(33);
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);
288 RunTasks(33);
289 // VideoSender re-created the encoder for the 320x240 frames we're
290 // providing.
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.
368 EXPECT_LE(
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);
380 int num_frames = 10;
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);
386 RunTasks(33);
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());
415 RunTasks(33);
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());
421 RunTasks(33);
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
426 // any acks.
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());
430 RunTasks(33);
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);
443 EXPECT_LE(
445 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
447 // Empty the pipeline.
448 RunTasks(100);
449 // Should have sent at least 7 packets.
450 EXPECT_LE(
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());
461 RunTasks(33);
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());
470 RunTasks(33);
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());
503 RunTasks(33);
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());
512 RunTasks(33);
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());
520 RunTasks(33);
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);
546 RunTasks(100);
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());
557 RunTasks(33);
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);
566 RunTasks(33);
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());
577 } // namespace cast
578 } // namespace media