blob: 4aa32202d023a9ca90cae5e96eedc9ed95bb01f2 [file] [log] [blame]
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
kwiberg2bb3afa2016-03-16 15:58:08 -070011#include <memory>
12
Henrik Kjellanderdca1e092017-07-01 16:42:22 +020013#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020014#include "webrtc/modules/desktop_capture/desktop_capturer.h"
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +000015#include "webrtc/modules/desktop_capture/desktop_frame.h"
16#include "webrtc/modules/desktop_capture/desktop_region.h"
zijiehe372719b2016-11-11 17:18:34 -080017#include "webrtc/modules/desktop_capture/mock_desktop_capturer_callback.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020018#include "webrtc/rtc_base/constructormagic.h"
19#include "webrtc/rtc_base/logging.h"
zijiehe98903d22016-11-10 21:57:10 -080020#include "webrtc/test/gmock.h"
21#include "webrtc/test/gtest.h"
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +000022
zijiehe82dda1a2016-08-15 19:53:31 -070023#if defined(WEBRTC_WIN)
24#include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
25#endif // defined(WEBRTC_WIN)
26
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +000027using ::testing::_;
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +000028
29const int kTestSharedMemoryId = 123;
30
31namespace webrtc {
32
33class ScreenCapturerTest : public testing::Test {
34 public:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000035 void SetUp() override {
zijiehe30455892016-11-09 16:37:48 -080036 capturer_ = DesktopCapturer::CreateScreenCapturer(
37 DesktopCaptureOptions::CreateDefault());
sergeyu@chromium.org894e6fe2013-10-12 22:40:05 +000038 }
39
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +000040 protected:
zijiehe0f49dac2016-09-07 11:52:25 -070041#if defined(WEBRTC_WIN)
zijiehee9a3c7f2016-09-16 00:03:15 -070042 // Enable allow_directx_capturer in DesktopCaptureOptions, but let
zijiehe30455892016-11-09 16:37:48 -080043 // DesktopCapturer::CreateScreenCapturer to decide whether a DirectX capturer
44 // should be used.
zijiehee9a3c7f2016-09-16 00:03:15 -070045 void MaybeCreateDirectxCapturer() {
46 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
47 options.set_allow_directx_capturer(true);
zijiehe30455892016-11-09 16:37:48 -080048 capturer_ = DesktopCapturer::CreateScreenCapturer(options);
zijiehee9a3c7f2016-09-16 00:03:15 -070049 }
50
zijiehe8295c932016-09-14 10:21:57 -070051 bool CreateDirectxCapturer() {
zijiehe0f49dac2016-09-07 11:52:25 -070052 if (!ScreenCapturerWinDirectx::IsSupported()) {
53 LOG(LS_WARNING) << "Directx capturer is not supported";
54 return false;
55 }
56
zijiehee9a3c7f2016-09-16 00:03:15 -070057 MaybeCreateDirectxCapturer();
zijiehe0f49dac2016-09-07 11:52:25 -070058 return true;
59 }
zijiehe8295c932016-09-14 10:21:57 -070060
61 void CreateMagnifierCapturer() {
62 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
63 options.set_allow_use_magnification_api(true);
zijiehe30455892016-11-09 16:37:48 -080064 capturer_ = DesktopCapturer::CreateScreenCapturer(options);
zijiehe8295c932016-09-14 10:21:57 -070065 }
zijiehe0f49dac2016-09-07 11:52:25 -070066#endif // defined(WEBRTC_WIN)
67
zijiehe30455892016-11-09 16:37:48 -080068 std::unique_ptr<DesktopCapturer> capturer_;
zijiehe372719b2016-11-11 17:18:34 -080069 MockDesktopCapturerCallback callback_;
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +000070};
71
72class FakeSharedMemory : public SharedMemory {
73 public:
74 FakeSharedMemory(char* buffer, size_t size)
75 : SharedMemory(buffer, size, 0, kTestSharedMemoryId),
76 buffer_(buffer) {
77 }
78 virtual ~FakeSharedMemory() {
79 delete[] buffer_;
80 }
81 private:
82 char* buffer_;
henrikg3c089d72015-09-16 05:37:44 -070083 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemory);
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +000084};
85
sergeyucc9669c2016-02-09 15:13:26 -080086class FakeSharedMemoryFactory : public SharedMemoryFactory {
87 public:
88 FakeSharedMemoryFactory() {}
89 ~FakeSharedMemoryFactory() override {}
90
kwiberg84be5112016-04-27 01:19:58 -070091 std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
92 return std::unique_ptr<SharedMemory>(
kwiberg2bb3afa2016-03-16 15:58:08 -070093 new FakeSharedMemory(new char[size], size));
sergeyucc9669c2016-02-09 15:13:26 -080094 }
95
96 private:
97 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory);
98};
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +000099
zijiehe6be0a652016-10-27 16:50:35 -0700100ACTION_P(SaveUniquePtrArg, dest) {
101 *dest = std::move(*arg1);
102}
103
jiayl@webrtc.org49859272014-01-17 17:19:16 +0000104TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
zijiehe30455892016-11-09 16:37:48 -0800105 webrtc::DesktopCapturer::SourceList screens;
106 EXPECT_TRUE(capturer_->GetSourceList(&screens));
107 for (const auto& screen : screens) {
108 EXPECT_TRUE(capturer_->SelectSource(screen.id));
jiayl@webrtc.org49859272014-01-17 17:19:16 +0000109 }
110}
111
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000112TEST_F(ScreenCapturerTest, StartCapturer) {
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000113 capturer_->Start(&callback_);
114}
115
116TEST_F(ScreenCapturerTest, Capture) {
117 // Assume that Start() treats the screen as invalid initially.
sergeyu5d910282016-06-07 16:41:58 -0700118 std::unique_ptr<DesktopFrame> frame;
119 EXPECT_CALL(callback_,
120 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
121 .WillOnce(SaveUniquePtrArg(&frame));
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000122
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000123 capturer_->Start(&callback_);
zijiehe91902cb2016-10-13 16:47:49 -0700124 capturer_->CaptureFrame();
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000125
126 ASSERT_TRUE(frame);
127 EXPECT_GT(frame->size().width(), 0);
128 EXPECT_GT(frame->size().height(), 0);
129 EXPECT_GE(frame->stride(),
130 frame->size().width() * DesktopFrame::kBytesPerPixel);
131 EXPECT_TRUE(frame->shared_memory() == NULL);
132
133 // Verify that the region contains whole screen.
134 EXPECT_FALSE(frame->updated_region().is_empty());
135 DesktopRegion::Iterator it(frame->updated_region());
136 ASSERT_TRUE(!it.IsAtEnd());
137 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
138 it.Advance();
139 EXPECT_TRUE(it.IsAtEnd());
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000140}
141
jiayl@webrtc.org42204342014-05-05 16:08:47 +0000142#if defined(WEBRTC_WIN)
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000143
144TEST_F(ScreenCapturerTest, UseSharedBuffers) {
sergeyu5d910282016-06-07 16:41:58 -0700145 std::unique_ptr<DesktopFrame> frame;
146 EXPECT_CALL(callback_,
147 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
148 .WillOnce(SaveUniquePtrArg(&frame));
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000149
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000150 capturer_->Start(&callback_);
sergeyucc9669c2016-02-09 15:13:26 -0800151 capturer_->SetSharedMemoryFactory(
kwiberg84be5112016-04-27 01:19:58 -0700152 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
zijiehe91902cb2016-10-13 16:47:49 -0700153 capturer_->CaptureFrame();
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000154
155 ASSERT_TRUE(frame);
156 ASSERT_TRUE(frame->shared_memory());
157 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000158}
159
jiayl@webrtc.org42204342014-05-05 16:08:47 +0000160TEST_F(ScreenCapturerTest, UseMagnifier) {
zijiehe8295c932016-09-14 10:21:57 -0700161 CreateMagnifierCapturer();
sergeyu5d910282016-06-07 16:41:58 -0700162 std::unique_ptr<DesktopFrame> frame;
163 EXPECT_CALL(callback_,
164 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
165 .WillOnce(SaveUniquePtrArg(&frame));
jiayl@webrtc.org42204342014-05-05 16:08:47 +0000166
167 capturer_->Start(&callback_);
zijiehe91902cb2016-10-13 16:47:49 -0700168 capturer_->CaptureFrame();
jiayl@webrtc.org42204342014-05-05 16:08:47 +0000169 ASSERT_TRUE(frame);
jiayl@webrtc.org42204342014-05-05 16:08:47 +0000170}
171
zijiehe2d618de2016-08-08 17:50:21 -0700172TEST_F(ScreenCapturerTest, UseDirectxCapturer) {
zijiehe8295c932016-09-14 10:21:57 -0700173 if (!CreateDirectxCapturer()) {
zijiehe82dda1a2016-08-15 19:53:31 -0700174 return;
175 }
176
zijiehe2d618de2016-08-08 17:50:21 -0700177 std::unique_ptr<DesktopFrame> frame;
178 EXPECT_CALL(callback_,
179 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
180 .WillOnce(SaveUniquePtrArg(&frame));
181
182 capturer_->Start(&callback_);
zijiehe91902cb2016-10-13 16:47:49 -0700183 capturer_->CaptureFrame();
zijiehe2d618de2016-08-08 17:50:21 -0700184 ASSERT_TRUE(frame);
185}
186
187TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) {
zijiehe8295c932016-09-14 10:21:57 -0700188 if (!CreateDirectxCapturer()) {
zijiehe82dda1a2016-08-15 19:53:31 -0700189 return;
190 }
191
zijiehe2d618de2016-08-08 17:50:21 -0700192 std::unique_ptr<DesktopFrame> frame;
193 EXPECT_CALL(callback_,
194 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
195 .WillOnce(SaveUniquePtrArg(&frame));
196
197 capturer_->Start(&callback_);
198 capturer_->SetSharedMemoryFactory(
199 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
zijiehe91902cb2016-10-13 16:47:49 -0700200 capturer_->CaptureFrame();
zijiehe2d618de2016-08-08 17:50:21 -0700201 ASSERT_TRUE(frame);
202 ASSERT_TRUE(frame->shared_memory());
203 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
204}
205
jiayl@webrtc.org42204342014-05-05 16:08:47 +0000206#endif // defined(WEBRTC_WIN)
sergeyu@chromium.org3d34f662013-06-04 18:51:23 +0000207
208} // namespace webrtc