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