Upstream version 9.38.198.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/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"
26
27 namespace media {
28 namespace cast {
29
30 namespace {
31 static const uint8 kPixelValue = 123;
32 static const int kWidth = 320;
33 static const int kHeight = 240;
34
35 using testing::_;
36 using testing::AtLeast;
37
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());
43 }
44
45 void CreateSharedMemory(
46     size_t size, const ReceiveVideoEncodeMemoryCallback& callback) {
47   scoped_ptr<base::SharedMemory> shm(new base::SharedMemory());
48   if (!shm->CreateAndMapAnonymous(size)) {
49     NOTREACHED();
50     return;
51   }
52   callback.Run(shm.Pass());
53 }
54
55 class TestPacketSender : public PacketSender {
56  public:
57   TestPacketSender()
58       : number_of_rtp_packets_(0),
59         number_of_rtcp_packets_(0),
60         paused_(false) {}
61
62   // A singular packet implies a RTCP packet.
63   virtual bool SendPacket(PacketRef packet,
64                           const base::Closure& cb) OVERRIDE {
65     if (paused_) {
66       stored_packet_ = packet;
67       callback_ = cb;
68       return false;
69     }
70     if (RtcpReceiver::IsRtcpPacket(&packet->data[0], packet->data.size())) {
71       ++number_of_rtcp_packets_;
72     } else {
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
76       // frame.
77       if (number_of_rtp_packets_ == 0)
78         EXPECT_LE(1, number_of_rtcp_packets_);
79       ++number_of_rtp_packets_;
80     }
81     return true;
82   }
83
84   int number_of_rtp_packets() const { return number_of_rtp_packets_; }
85
86   int number_of_rtcp_packets() const { return number_of_rtcp_packets_; }
87
88   void SetPause(bool paused) {
89     paused_ = paused;
90     if (!paused && stored_packet_) {
91       SendPacket(stored_packet_, callback_);
92       callback_.Run();
93     }
94   }
95
96  private:
97   int number_of_rtp_packets_;
98   int number_of_rtcp_packets_;
99   bool paused_;
100   base::Closure callback_;
101   PacketRef stored_packet_;
102
103   DISALLOW_COPY_AND_ASSIGN(TestPacketSender);
104 };
105
106 class PeerVideoSender : public VideoSender {
107  public:
108   PeerVideoSender(
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,
115                     video_config,
116                     create_vea_cb,
117                     create_video_encode_mem_cb,
118                     transport_sender) {}
119   using VideoSender::OnReceivedCastFeedback;
120 };
121 }  // namespace
122
123 class VideoSenderTest : public ::testing::Test {
124  protected:
125   VideoSenderTest() {
126     testing_clock_ = new base::SimpleTestTickClock();
127     testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
128     task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_);
129     cast_environment_ =
130         new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(),
131                             task_runner_,
132                             task_runner_,
133                             task_runner_);
134     last_pixel_value_ = kPixelValue;
135     net::IPEndPoint dummy_endpoint;
136     transport_sender_.reset(new CastTransportSenderImpl(
137         NULL,
138         testing_clock_,
139         dummy_endpoint,
140         base::Bind(&UpdateCastTransportStatus),
141         BulkRawEventsCallback(),
142         base::TimeDelta(),
143         task_runner_,
144         &transport_));
145   }
146
147   virtual ~VideoSenderTest() {}
148
149   virtual void TearDown() OVERRIDE {
150     video_sender_.reset();
151     task_runner_->RunTasks();
152   }
153
154   static void UpdateCastTransportStatus(CastTransportStatus status) {
155     EXPECT_EQ(TRANSPORT_VIDEO_INITIALIZED, status);
156   }
157
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;
174
175     if (external) {
176       scoped_ptr<VideoEncodeAccelerator> fake_vea(
177           new test::FakeVideoEncodeAccelerator(task_runner_,
178                                                &stored_bitrates_));
179       video_sender_.reset(
180           new PeerVideoSender(cast_environment_,
181                               video_config,
182                               base::Bind(&CreateVideoEncodeAccelerator,
183                                          task_runner_,
184                                          base::Passed(&fake_vea)),
185                               base::Bind(&CreateSharedMemory),
186                               transport_sender_.get()));
187     } else {
188       video_sender_.reset(
189           new PeerVideoSender(cast_environment_,
190                               video_config,
191                               CreateDefaultVideoEncodeAcceleratorCallback(),
192                               CreateDefaultVideoEncodeMemoryCallback(),
193                               transport_sender_.get()));
194     }
195     ASSERT_EQ(STATUS_VIDEO_INITIALIZED, video_sender_->InitializationResult());
196   }
197
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_++);
204     return video_frame;
205   }
206
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);
213     return video_frame;
214   }
215
216   void RunTasks(int during_ms) {
217     task_runner_->Sleep(base::TimeDelta::FromMilliseconds(during_ms));
218   }
219
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_;
228
229   DISALLOW_COPY_AND_ASSIGN(VideoSenderTest);
230 };
231
232 TEST_F(VideoSenderTest, BuiltInEncoder) {
233   InitEncoder(false);
234   scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
235
236   const base::TimeTicks capture_time = testing_clock_->NowTicks();
237   video_sender_->InsertRawVideoFrame(video_frame, capture_time);
238
239   task_runner_->RunTasks();
240   EXPECT_LE(1, transport_.number_of_rtp_packets());
241   EXPECT_LE(1, transport_.number_of_rtcp_packets());
242 }
243
244 TEST_F(VideoSenderTest, ExternalEncoder) {
245   InitEncoder(true);
246   task_runner_->RunTasks();
247
248   scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
249
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();
257
258   // Fixed bitrate is used for external encoder. Bitrate is only once
259   // to the encoder.
260   EXPECT_EQ(1u, stored_bitrates_.size());
261
262   // We need to run the task to cleanup the GPU instance.
263   video_sender_.reset(NULL);
264   task_runner_->RunTasks();
265 }
266
267 TEST_F(VideoSenderTest, RtcpTimer) {
268   InitEncoder(false);
269
270   scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
271
272   const base::TimeTicks capture_time = testing_clock_->NowTicks();
273   video_sender_->InsertRawVideoFrame(video_frame, capture_time);
274
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);
278
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());
289 }
290
291 TEST_F(VideoSenderTest, ResendTimer) {
292   InitEncoder(false);
293
294   scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
295
296   const base::TimeTicks capture_time = testing_clock_->NowTicks();
297   video_sender_->InsertRawVideoFrame(video_frame, capture_time);
298
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);
304
305   video_frame = GetNewVideoFrame();
306   video_sender_->InsertRawVideoFrame(video_frame, capture_time);
307
308   base::TimeDelta max_resend_timeout =
309       base::TimeDelta::FromMilliseconds(1 + kDefaultRtpMaxDelayMs);
310
311   // Make sure that we do a re-send.
312   RunTasks(max_resend_timeout.InMilliseconds());
313   // Should have sent at least 3 packets.
314   EXPECT_LE(
315       3,
316       transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
317 }
318
319 TEST_F(VideoSenderTest, LogAckReceivedEvent) {
320   InitEncoder(false);
321   SimpleEventSubscriber event_subscriber;
322   cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber);
323
324   int num_frames = 10;
325   for (int i = 0; i < num_frames; i++) {
326     scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
327
328     const base::TimeTicks capture_time = testing_clock_->NowTicks();
329     video_sender_->InsertRawVideoFrame(video_frame, capture_time);
330     RunTasks(33);
331   }
332
333   task_runner_->RunTasks();
334
335   RtcpCastMessage cast_feedback(1);
336   cast_feedback.ack_frame_id = num_frames - 1;
337
338   video_sender_->OnReceivedCastFeedback(cast_feedback);
339
340   std::vector<FrameEvent> frame_events;
341   event_subscriber.GetFrameEventsAndReset(&frame_events);
342
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);
347
348   cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber);
349 }
350
351 TEST_F(VideoSenderTest, StopSendingInTheAbsenceOfAck) {
352   InitEncoder(false);
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());
357   RunTasks(33);
358
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());
363     RunTasks(33);
364   }
365   const int number_of_packets_sent = transport_.number_of_rtp_packets();
366
367   // Send 3 more frames - they should not be encoded, as we have not received
368   // any acks.
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());
372     RunTasks(33);
373   }
374
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());
379
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);
385   EXPECT_LE(
386       4,
387       transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
388
389   // Empty the pipeline.
390   RunTasks(100);
391   // Should have sent at least 7 packets.
392   EXPECT_LE(
393       7,
394       transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
395 }
396
397 TEST_F(VideoSenderTest, DuplicateAckRetransmit) {
398   InitEncoder(false);
399   scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
400   video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
401   RunTasks(33);
402   RtcpCastMessage cast_feedback(1);
403   cast_feedback.media_ssrc = 2;
404   cast_feedback.ack_frame_id = 0;
405
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());
410     RunTasks(33);
411   }
412   const int number_of_packets_sent = transport_.number_of_rtp_packets();
413
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);
424   }
425   EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets());
426
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);
433   }
434   EXPECT_EQ(number_of_packets_sent + 1, transport_.number_of_rtp_packets());
435 }
436
437 TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) {
438   InitEncoder(false);
439   scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
440   video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
441   RunTasks(33);
442   RtcpCastMessage cast_feedback(1);
443   cast_feedback.media_ssrc = 2;
444   cast_feedback.ack_frame_id = 0;
445
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());
450     RunTasks(33);
451   }
452   // Pause the transport
453   transport_.SetPause(true);
454
455   // Insert one more video frame.
456   video_frame = GetLargeNewVideoFrame();
457   video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
458   RunTasks(33);
459
460   const int number_of_packets_sent = transport_.number_of_rtp_packets();
461
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);
472   }
473   EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets());
474
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);
481   }
482
483   transport_.SetPause(false);
484   RunTasks(100);
485   EXPECT_LT(number_of_packets_sent + 1, transport_.number_of_rtp_packets());
486 }
487
488 TEST_F(VideoSenderTest, AcksCancelRetransmits) {
489   InitEncoder(false);
490   transport_.SetPause(true);
491   scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame();
492   video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
493   RunTasks(33);
494
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);
500
501   transport_.SetPause(false);
502   RunTasks(33);
503   EXPECT_EQ(0, transport_.number_of_rtp_packets());
504 }
505
506 TEST_F(VideoSenderTest, NAcksCancelRetransmits) {
507   InitEncoder(false);
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());
512   RunTasks(33);
513   video_frame = GetLargeNewVideoFrame();
514   video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
515   RunTasks(33);
516
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);
526
527   transport_.SetPause(false);
528   RunTasks(33);
529   // Only one packet should be retransmitted.
530   EXPECT_EQ(1, transport_.number_of_rtp_packets());
531 }
532
533 }  // namespace cast
534 }  // namespace media