1 // Copyright (c) 2012 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 "remoting/host/video_scheduler.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "remoting/base/auto_thread_task_runner.h"
11 #include "remoting/codec/video_encoder.h"
12 #include "remoting/proto/video.pb.h"
13 #include "remoting/protocol/protocol_mock_objects.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
17 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
19 using ::remoting::protocol::MockClientStub
;
20 using ::remoting::protocol::MockVideoStub
;
23 using ::testing::AtLeast
;
24 using ::testing::AnyNumber
;
25 using ::testing::DeleteArg
;
26 using ::testing::DoAll
;
27 using ::testing::Expectation
;
28 using ::testing::InSequence
;
29 using ::testing::InvokeWithoutArgs
;
30 using ::testing::Return
;
31 using ::testing::ReturnRef
;
32 using ::testing::SaveArg
;
38 ACTION(FinishEncode
) {
39 scoped_ptr
<VideoPacket
> packet(new VideoPacket());
40 return packet
.release();
49 static const int kWidth
= 640;
50 static const int kHeight
= 480;
52 class MockVideoEncoder
: public VideoEncoder
{
55 virtual ~MockVideoEncoder();
57 scoped_ptr
<VideoPacket
> Encode(
58 const webrtc::DesktopFrame
& frame
) {
59 return scoped_ptr
<VideoPacket
>(EncodePtr(frame
));
61 MOCK_METHOD1(EncodePtr
, VideoPacket
*(const webrtc::DesktopFrame
& frame
));
64 DISALLOW_COPY_AND_ASSIGN(MockVideoEncoder
);
67 MockVideoEncoder::MockVideoEncoder() {}
69 MockVideoEncoder::~MockVideoEncoder() {}
71 class VideoSchedulerTest
: public testing::Test
{
75 virtual void SetUp() OVERRIDE
;
77 void StartVideoScheduler(scoped_ptr
<webrtc::ScreenCapturer
> capturer
);
78 void StopVideoScheduler();
80 // webrtc::ScreenCapturer mocks.
81 void OnCapturerStart(webrtc::ScreenCapturer::Callback
* callback
);
82 void OnCaptureFrame(const webrtc::DesktopRegion
& region
);
85 base::MessageLoop message_loop_
;
86 base::RunLoop run_loop_
;
87 scoped_refptr
<AutoThreadTaskRunner
> task_runner_
;
88 scoped_refptr
<VideoScheduler
> scheduler_
;
90 MockClientStub client_stub_
;
91 MockVideoStub video_stub_
;
93 // The following mock objects are owned by VideoScheduler.
94 MockVideoEncoder
* encoder_
;
96 scoped_ptr
<webrtc::DesktopFrame
> frame_
;
98 // Points to the callback passed to webrtc::ScreenCapturer::Start().
99 webrtc::ScreenCapturer::Callback
* capturer_callback_
;
102 DISALLOW_COPY_AND_ASSIGN(VideoSchedulerTest
);
105 VideoSchedulerTest::VideoSchedulerTest()
107 capturer_callback_(NULL
) {
110 void VideoSchedulerTest::SetUp() {
111 task_runner_
= new AutoThreadTaskRunner(
112 message_loop_
.message_loop_proxy(), run_loop_
.QuitClosure());
114 encoder_
= new MockVideoEncoder();
117 void VideoSchedulerTest::StartVideoScheduler(
118 scoped_ptr
<webrtc::ScreenCapturer
> capturer
) {
119 scheduler_
= new VideoScheduler(
120 task_runner_
, // Capture
121 task_runner_
, // Encode
122 task_runner_
, // Network
124 scoped_ptr
<VideoEncoder
>(encoder_
),
130 void VideoSchedulerTest::StopVideoScheduler() {
135 void VideoSchedulerTest::OnCapturerStart(
136 webrtc::ScreenCapturer::Callback
* callback
) {
137 EXPECT_FALSE(capturer_callback_
);
138 EXPECT_TRUE(callback
);
140 capturer_callback_
= callback
;
143 void VideoSchedulerTest::OnCaptureFrame(const webrtc::DesktopRegion
& region
) {
144 frame_
->mutable_updated_region()->SetRect(
145 webrtc::DesktopRect::MakeXYWH(0, 0, 10, 10));
146 capturer_callback_
->OnCaptureCompleted(frame_
.release());
149 // This test mocks capturer, encoder and network layer to simulate one capture
150 // cycle. When the first encoded packet is submitted to the network
151 // VideoScheduler is instructed to come to a complete stop. We expect the stop
152 // sequence to be executed successfully.
153 TEST_F(VideoSchedulerTest
, StartAndStop
) {
154 scoped_ptr
<webrtc::MockScreenCapturer
> capturer(
155 new webrtc::MockScreenCapturer());
156 Expectation capturer_start
=
157 EXPECT_CALL(*capturer
, Start(_
))
158 .WillOnce(Invoke(this, &VideoSchedulerTest::OnCapturerStart
));
160 frame_
.reset(new webrtc::BasicDesktopFrame(
161 webrtc::DesktopSize(kWidth
, kHeight
)));
163 // First the capturer is called.
164 Expectation capturer_capture
= EXPECT_CALL(*capturer
, Capture(_
))
165 .After(capturer_start
)
166 .WillRepeatedly(Invoke(this, &VideoSchedulerTest::OnCaptureFrame
));
168 // Expect the encoder be called.
169 EXPECT_CALL(*encoder_
, EncodePtr(_
))
170 .WillRepeatedly(FinishEncode());
172 // By default delete the arguments when ProcessVideoPacket is received.
173 EXPECT_CALL(video_stub_
, ProcessVideoPacketPtr(_
, _
))
174 .WillRepeatedly(FinishSend());
176 // For the first time when ProcessVideoPacket is received we stop the
178 EXPECT_CALL(video_stub_
, ProcessVideoPacketPtr(_
, _
))
181 InvokeWithoutArgs(this, &VideoSchedulerTest::StopVideoScheduler
)))
182 .RetiresOnSaturation();
184 // Start video frame capture.
185 StartVideoScheduler(capturer
.PassAs
<webrtc::ScreenCapturer
>());
191 } // namespace remoting