1 // Copyright 2015 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_frame_pump.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "remoting/base/auto_thread.h"
12 #include "remoting/base/auto_thread_task_runner.h"
13 #include "remoting/codec/video_encoder.h"
14 #include "remoting/codec/video_encoder_verbatim.h"
15 #include "remoting/host/desktop_capturer_proxy.h"
16 #include "remoting/host/fake_desktop_capturer.h"
17 #include "remoting/host/host_mock_objects.h"
18 #include "remoting/proto/control.pb.h"
19 #include "remoting/proto/video.pb.h"
20 #include "remoting/protocol/protocol_mock_objects.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
24 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
26 using ::remoting::protocol::MockVideoStub
;
29 using ::testing::DoAll
;
30 using ::testing::Expectation
;
31 using ::testing::InvokeWithoutArgs
;
43 static const int kWidth
= 640;
44 static const int kHeight
= 480;
46 class ThreadCheckVideoEncoder
: public VideoEncoderVerbatim
{
48 ThreadCheckVideoEncoder(
49 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
)
50 : task_runner_(task_runner
) {
52 ~ThreadCheckVideoEncoder() override
{
53 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
56 scoped_ptr
<VideoPacket
> Encode(const webrtc::DesktopFrame
& frame
) override
{
57 return make_scoped_ptr(new VideoPacket());
61 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner_
;
63 DISALLOW_COPY_AND_ASSIGN(ThreadCheckVideoEncoder
);
66 class ThreadCheckDesktopCapturer
: public webrtc::DesktopCapturer
{
68 ThreadCheckDesktopCapturer(
69 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
)
70 : task_runner_(task_runner
), callback_(nullptr) {}
71 ~ThreadCheckDesktopCapturer() override
{
72 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
75 void Start(Callback
* callback
) override
{
76 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
77 EXPECT_FALSE(callback_
);
78 EXPECT_TRUE(callback
);
83 void Capture(const webrtc::DesktopRegion
& rect
) override
{
84 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
86 scoped_ptr
<webrtc::DesktopFrame
> frame(
87 new webrtc::BasicDesktopFrame(webrtc::DesktopSize(kWidth
, kHeight
)));
88 frame
->mutable_updated_region()->SetRect(
89 webrtc::DesktopRect::MakeXYWH(0, 0, 10, 10));
90 callback_
->OnCaptureCompleted(frame
.release());
94 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner_
;
95 webrtc::DesktopCapturer::Callback
* callback_
;
97 DISALLOW_COPY_AND_ASSIGN(ThreadCheckDesktopCapturer
);
100 class VideoFramePumpTest
: public testing::Test
{
102 void SetUp() override
;
103 void TearDown() override
;
105 void StartVideoFramePump(
106 scoped_ptr
<webrtc::DesktopCapturer
> capturer
,
107 scoped_ptr
<VideoEncoder
> encoder
);
110 base::MessageLoop message_loop_
;
111 base::RunLoop run_loop_
;
112 scoped_refptr
<AutoThreadTaskRunner
> capture_task_runner_
;
113 scoped_refptr
<AutoThreadTaskRunner
> encode_task_runner_
;
114 scoped_refptr
<AutoThreadTaskRunner
> main_task_runner_
;
115 scoped_ptr
<VideoFramePump
> pump_
;
117 MockVideoStub video_stub_
;
120 void VideoFramePumpTest::SetUp() {
121 main_task_runner_
= new AutoThreadTaskRunner(
122 message_loop_
.message_loop_proxy(), run_loop_
.QuitClosure());
123 capture_task_runner_
= AutoThread::Create("capture", main_task_runner_
);
124 encode_task_runner_
= AutoThread::Create("encode", main_task_runner_
);
127 void VideoFramePumpTest::TearDown() {
130 // Release the task runners, so that the test can quit.
131 capture_task_runner_
= nullptr;
132 encode_task_runner_
= nullptr;
133 main_task_runner_
= nullptr;
135 // Run the MessageLoop until everything has torn down.
139 // This test mocks capturer, encoder and network layer to simulate one capture
141 TEST_F(VideoFramePumpTest
, StartAndStop
) {
142 scoped_ptr
<ThreadCheckDesktopCapturer
> capturer(
143 new ThreadCheckDesktopCapturer(capture_task_runner_
));
144 scoped_ptr
<ThreadCheckVideoEncoder
> encoder(
145 new ThreadCheckVideoEncoder(encode_task_runner_
));
147 base::RunLoop run_loop
;
149 // When the first ProcessVideoPacket is received we stop the VideoFramePump.
150 EXPECT_CALL(video_stub_
, ProcessVideoPacketPtr(_
, _
))
153 InvokeWithoutArgs(&run_loop
, &base::RunLoop::Quit
)))
154 .RetiresOnSaturation();
156 // Start video frame capture.
157 pump_
.reset(new VideoFramePump(encode_task_runner_
,
158 make_scoped_ptr(new DesktopCapturerProxy(
159 capture_task_runner_
, capturer
.Pass())),
160 encoder
.Pass(), &video_stub_
));
162 // Run MessageLoop until the first frame is received..
166 } // namespace remoting