Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / media / cast / video_sender / video_sender_unittest.cc
blobd8b074047d99a764ec3426bc9b9d088df173b99a
1 // Copyright 2013 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/test/fake_single_thread_task_runner.h"
16 #include "media/cast/test/fake_video_encode_accelerator.h"
17 #include "media/cast/test/utility/default_config.h"
18 #include "media/cast/test/utility/video_utility.h"
19 #include "media/cast/transport/cast_transport_config.h"
20 #include "media/cast/transport/cast_transport_sender_impl.h"
21 #include "media/cast/transport/pacing/paced_sender.h"
22 #include "media/cast/video_sender/video_sender.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 namespace media {
27 namespace cast {
29 namespace {
30 static const int64 kStartMillisecond = INT64_C(12345678900000);
31 static const uint8 kPixelValue = 123;
32 static const int kWidth = 320;
33 static const int kHeight = 240;
35 using testing::_;
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)) {
49 NOTREACHED();
50 return;
52 callback.Run(shm.Pass());
55 class TestPacketSender : public transport::PacketSender {
56 public:
57 TestPacketSender() : number_of_rtp_packets_(0), number_of_rtcp_packets_(0) {}
59 // A singular packet implies a RTCP packet.
60 virtual bool SendPacket(transport::PacketRef packet,
61 const base::Closure& cb) OVERRIDE {
62 if (Rtcp::IsRtcpPacket(&packet->data[0], packet->data.size())) {
63 ++number_of_rtcp_packets_;
64 } else {
65 ++number_of_rtp_packets_;
67 return true;
70 int number_of_rtp_packets() const { return number_of_rtp_packets_; }
72 int number_of_rtcp_packets() const { return number_of_rtcp_packets_; }
74 private:
75 int number_of_rtp_packets_;
76 int number_of_rtcp_packets_;
78 DISALLOW_COPY_AND_ASSIGN(TestPacketSender);
81 class PeerVideoSender : public VideoSender {
82 public:
83 PeerVideoSender(
84 scoped_refptr<CastEnvironment> cast_environment,
85 const VideoSenderConfig& video_config,
86 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
87 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
88 const CastInitializationCallback& cast_initialization_cb,
89 transport::CastTransportSender* const transport_sender)
90 : VideoSender(cast_environment,
91 video_config,
92 create_vea_cb,
93 create_video_encode_mem_cb,
94 cast_initialization_cb,
95 transport_sender) {}
96 using VideoSender::OnReceivedCastFeedback;
98 } // namespace
100 class VideoSenderTest : public ::testing::Test {
101 protected:
102 VideoSenderTest() {
103 testing_clock_ = new base::SimpleTestTickClock();
104 testing_clock_->Advance(
105 base::TimeDelta::FromMilliseconds(kStartMillisecond));
106 task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_);
107 cast_environment_ =
108 new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(),
109 task_runner_,
110 task_runner_,
111 task_runner_);
112 net::IPEndPoint dummy_endpoint;
113 transport_sender_.reset(new transport::CastTransportSenderImpl(
114 NULL,
115 testing_clock_,
116 dummy_endpoint,
117 base::Bind(&UpdateCastTransportStatus),
118 transport::BulkRawEventsCallback(),
119 base::TimeDelta(),
120 task_runner_,
121 &transport_));
124 virtual ~VideoSenderTest() {}
126 virtual void TearDown() OVERRIDE {
127 video_sender_.reset();
128 task_runner_->RunTasks();
131 static void UpdateCastTransportStatus(transport::CastTransportStatus status) {
132 EXPECT_EQ(status, transport::TRANSPORT_VIDEO_INITIALIZED);
135 void InitEncoder(bool external) {
136 VideoSenderConfig video_config;
137 video_config.rtp_config.ssrc = 1;
138 video_config.incoming_feedback_ssrc = 2;
139 video_config.rtcp_c_name = "video_test@10.1.1.1";
140 video_config.rtp_config.payload_type = 127;
141 video_config.use_external_encoder = external;
142 video_config.width = kWidth;
143 video_config.height = kHeight;
144 video_config.max_bitrate = 5000000;
145 video_config.min_bitrate = 1000000;
146 video_config.start_bitrate = 1000000;
147 video_config.max_qp = 56;
148 video_config.min_qp = 0;
149 video_config.max_frame_rate = 30;
150 video_config.max_number_of_video_buffers_used = 1;
151 video_config.codec = transport::kVp8;
153 if (external) {
154 scoped_ptr<VideoEncodeAccelerator> fake_vea(
155 new test::FakeVideoEncodeAccelerator(task_runner_));
156 video_sender_.reset(
157 new PeerVideoSender(cast_environment_,
158 video_config,
159 base::Bind(&CreateVideoEncodeAccelerator,
160 task_runner_,
161 base::Passed(&fake_vea)),
162 base::Bind(&CreateSharedMemory),
163 base::Bind(&VideoSenderTest::InitializationResult,
164 base::Unretained(this)),
165 transport_sender_.get()));
166 } else {
167 video_sender_.reset(
168 new PeerVideoSender(cast_environment_,
169 video_config,
170 CreateDefaultVideoEncodeAcceleratorCallback(),
171 CreateDefaultVideoEncodeMemoryCallback(),
172 base::Bind(&VideoSenderTest::InitializationResult,
173 base::Unretained(this)),
174 transport_sender_.get()));
178 scoped_refptr<media::VideoFrame> GetNewVideoFrame() {
179 gfx::Size size(kWidth, kHeight);
180 scoped_refptr<media::VideoFrame> video_frame =
181 media::VideoFrame::CreateFrame(
182 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta());
183 PopulateVideoFrame(video_frame, kPixelValue);
184 return video_frame;
187 void RunTasks(int during_ms) {
188 for (int i = 0; i < during_ms; ++i) {
189 // Call process the timers every 1 ms.
190 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(1));
191 task_runner_->RunTasks();
195 void InitializationResult(CastInitializationStatus result) {
196 EXPECT_EQ(result, STATUS_VIDEO_INITIALIZED);
199 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment.
200 TestPacketSender transport_;
201 scoped_ptr<transport::CastTransportSenderImpl> transport_sender_;
202 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
203 scoped_ptr<PeerVideoSender> video_sender_;
204 scoped_refptr<CastEnvironment> cast_environment_;
206 DISALLOW_COPY_AND_ASSIGN(VideoSenderTest);
209 TEST_F(VideoSenderTest, BuiltInEncoder) {
210 InitEncoder(false);
211 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
213 base::TimeTicks capture_time;
214 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
216 task_runner_->RunTasks();
217 EXPECT_GE(
218 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets(),
222 TEST_F(VideoSenderTest, ExternalEncoder) {
223 InitEncoder(true);
224 task_runner_->RunTasks();
226 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
228 base::TimeTicks capture_time;
229 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
231 task_runner_->RunTasks();
233 // We need to run the task to cleanup the GPU instance.
234 video_sender_.reset(NULL);
235 task_runner_->RunTasks();
238 TEST_F(VideoSenderTest, RtcpTimer) {
239 InitEncoder(false);
241 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
243 base::TimeTicks capture_time;
244 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
246 // Make sure that we send at least one RTCP packet.
247 base::TimeDelta max_rtcp_timeout =
248 base::TimeDelta::FromMilliseconds(1 + kDefaultRtcpIntervalMs * 3 / 2);
250 RunTasks(max_rtcp_timeout.InMilliseconds());
251 EXPECT_GE(transport_.number_of_rtp_packets(), 1);
252 // Don't send RTCP prior to receiving an ACK.
253 EXPECT_GE(transport_.number_of_rtcp_packets(), 0);
254 // Build Cast msg and expect RTCP packet.
255 RtcpCastMessage cast_feedback(1);
256 cast_feedback.media_ssrc_ = 2;
257 cast_feedback.ack_frame_id_ = 0;
258 video_sender_->OnReceivedCastFeedback(cast_feedback);
259 RunTasks(max_rtcp_timeout.InMilliseconds());
260 EXPECT_GE(transport_.number_of_rtcp_packets(), 1);
263 TEST_F(VideoSenderTest, ResendTimer) {
264 InitEncoder(false);
266 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
268 base::TimeTicks capture_time;
269 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
271 // ACK the key frame.
272 RtcpCastMessage cast_feedback(1);
273 cast_feedback.media_ssrc_ = 2;
274 cast_feedback.ack_frame_id_ = 0;
275 video_sender_->OnReceivedCastFeedback(cast_feedback);
277 video_frame = GetNewVideoFrame();
278 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
280 base::TimeDelta max_resend_timeout =
281 base::TimeDelta::FromMilliseconds(1 + kDefaultRtpMaxDelayMs);
283 // Make sure that we do a re-send.
284 RunTasks(max_resend_timeout.InMilliseconds());
285 // Should have sent at least 3 packets.
286 EXPECT_GE(
287 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets(),
291 TEST_F(VideoSenderTest, LogAckReceivedEvent) {
292 InitEncoder(false);
293 SimpleEventSubscriber event_subscriber;
294 cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber);
296 int num_frames = 10;
297 for (int i = 0; i < num_frames; i++) {
298 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
300 base::TimeTicks capture_time;
301 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
302 RunTasks(33);
305 task_runner_->RunTasks();
307 RtcpCastMessage cast_feedback(1);
308 cast_feedback.ack_frame_id_ = num_frames - 1;
310 video_sender_->OnReceivedCastFeedback(cast_feedback);
312 std::vector<FrameEvent> frame_events;
313 event_subscriber.GetFrameEventsAndReset(&frame_events);
315 ASSERT_TRUE(!frame_events.empty());
316 EXPECT_EQ(kVideoAckReceived, frame_events.rbegin()->type);
317 EXPECT_EQ(num_frames - 1u, frame_events.rbegin()->frame_id);
319 cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber);
322 TEST_F(VideoSenderTest, StopSendingIntheAbsenceOfAck) {
323 InitEncoder(false);
324 // Send a stream of frames and don't ACK; by default we shouldn't have more
325 // than 4 frames in flight.
326 // Store size in packets of frame 0, as it should be resent sue to timeout.
327 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
328 base::TimeTicks capture_time;
329 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
330 RunTasks(33);
331 const int size_of_frame0 = transport_.number_of_rtp_packets();
333 for (int i = 1; i < 4; ++i) {
334 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
335 base::TimeTicks capture_time;
336 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
337 RunTasks(33);
340 const int number_of_packets_sent = transport_.number_of_rtp_packets();
341 // Send 4 more frames - they should not be sent to the transport, as we have
342 // received any acks.
343 for (int i = 0; i < 3; ++i) {
344 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
345 base::TimeTicks capture_time;
346 video_sender_->InsertRawVideoFrame(video_frame, capture_time);
347 RunTasks(33);
350 EXPECT_EQ(number_of_packets_sent + size_of_frame0,
351 transport_.number_of_rtp_packets());
353 // Start acking and make sure we're back to steady-state.
354 RtcpCastMessage cast_feedback(1);
355 cast_feedback.media_ssrc_ = 2;
356 cast_feedback.ack_frame_id_ = 0;
357 video_sender_->OnReceivedCastFeedback(cast_feedback);
358 EXPECT_GE(
359 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets(),
362 // Empty the pipeline.
363 RunTasks(100);
364 // Should have sent at least 7 packets.
365 EXPECT_GE(
366 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets(),
370 } // namespace cast
371 } // namespace media