Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: webrtc/modules/desktop_capture/screen_capturer_unittest.cc

Issue 2268093002: [WebRTC] A real ScreenCapturer test (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Remove DirectX capturer changes Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <string.h>
12
13 #include <algorithm>
14 #include <initializer_list>
11 #include <memory> 15 #include <memory>
12 #include <utility> 16 #include <utility>
13 17
14 #include "webrtc/modules/desktop_capture/screen_capturer.h" 18 #include "webrtc/modules/desktop_capture/screen_capturer.h"
15 19
16 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "webrtc/base/checks.h"
18 #include "webrtc/base/constructormagic.h" 23 #include "webrtc/base/constructormagic.h"
19 #include "webrtc/base/logging.h" 24 #include "webrtc/base/logging.h"
25 #include "webrtc/modules/desktop_capture/color.h"
20 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" 26 #include "webrtc/modules/desktop_capture/desktop_capture_options.h"
21 #include "webrtc/modules/desktop_capture/desktop_frame.h" 27 #include "webrtc/modules/desktop_capture/desktop_frame.h"
22 #include "webrtc/modules/desktop_capture/desktop_region.h" 28 #include "webrtc/modules/desktop_capture/desktop_region.h"
23 #include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h" 29 #include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
30 #include "webrtc/modules/desktop_capture/screen_drawer.h"
31 #include "webrtc/system_wrappers/include/sleep.h"
24 32
25 #if defined(WEBRTC_WIN) 33 #if defined(WEBRTC_WIN)
26 #include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h" 34 #include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
27 #endif // defined(WEBRTC_WIN) 35 #endif // defined(WEBRTC_WIN)
28 36
29 using ::testing::_; 37 using ::testing::_;
30 using ::testing::AnyNumber; 38 using ::testing::AnyNumber;
31 using ::testing::Return; 39 using ::testing::Return;
32 40
33 const int kTestSharedMemoryId = 123; 41 const int kTestSharedMemoryId = 123;
34 42
35 namespace webrtc { 43 namespace webrtc {
36 44
45 namespace {
46
47 ACTION_P(SaveUniquePtrArg, dest) {
48 *dest = std::move(*arg1);
49 }
50
51 // Expects |capturer| to successfully capture a frame, and returns it.
52 std::unique_ptr<DesktopFrame> CaptureFrame(
53 ScreenCapturer* capturer,
54 MockScreenCapturerCallback* callback) {
55 std::unique_ptr<DesktopFrame> frame;
56 EXPECT_CALL(*callback,
57 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
58 .WillOnce(SaveUniquePtrArg(&frame));
59 capturer->Capture(DesktopRegion());
60 EXPECT_TRUE(frame);
61 return frame;
62 }
63
64 // Expects color in |rect| of |frame| is |color|.
65 void ExpectPixelsAreColoredBy(const DesktopFrame& frame,
66 DesktopRect rect,
67 Color color) {
68 // updated_region() should cover the painted area.
69 DesktopRegion updated_region(frame.updated_region());
70 updated_region.IntersectWith(rect);
71 ASSERT_TRUE(updated_region.Equals(DesktopRegion(rect)));
72
73 // Color in the |rect| should be |color|.
74 uint8_t* row = frame.GetFrameDataAtPos(rect.top_left());
75 for (int i = 0; i < rect.height(); i++) {
76 uint8_t* column = row;
77 for (int j = 0; j < rect.width(); j++) {
78 ASSERT_EQ(color, column);
79 column += DesktopFrame::kBytesPerPixel;
80 }
81 row += frame.stride();
82 }
83 }
84
85 } // namespace
86
37 class ScreenCapturerTest : public testing::Test { 87 class ScreenCapturerTest : public testing::Test {
38 public: 88 public:
39 void SetUp() override { 89 void SetUp() override {
40 capturer_.reset( 90 capturer_.reset(
41 ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault())); 91 ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault()));
42 } 92 }
43 93
44 protected: 94 protected:
95 void TestCaptureUpdatedRegion(
96 std::initializer_list<ScreenCapturer*> capturers) {
97 // A large enough area for the tests, which should be able to fulfill by
98 // most of systems.
99 const int kTestArea = 512;
100 const int kRectSize = 32;
101 std::unique_ptr<ScreenDrawer> drawer = ScreenDrawer::Create();
102 if (!drawer || drawer->DrawableRegion().is_empty()) {
103 LOG(LS_WARNING) << "No ScreenDrawer implementation for current platform.";
104 return;
105 }
106 if (drawer->DrawableRegion().width() < kTestArea ||
107 drawer->DrawableRegion().height() < kTestArea) {
108 LOG(LS_WARNING) << "ScreenDrawer::DrawableRegion() is too small for the "
109 "CaptureUpdatedRegion tests.";
110 return;
111 }
112
113 for (ScreenCapturer* capturer : capturers) {
114 capturer->Start(&callback_);
115 }
116
117 #if defined(WEBRTC_LINUX)
118 // TODO(zijiehe): ScreenCapturerX11 won't be able to capture correct images
119 // in the first several capture attempts.
120 for (int i = 0; i < 10; i++) {
121 for (ScreenCapturer* capturer : capturers) {
122 std::unique_ptr<DesktopFrame> frame =
123 CaptureFrame(capturer, &callback_);
124 if (!frame) {
125 return;
126 }
127 }
128 }
129 #endif
130
131 for (int c = 0; c < 3; c++) {
132 for (int i = 0; i < kTestArea - kRectSize; i += 16) {
133 DesktopRect rect = DesktopRect::MakeXYWH(i, i, kRectSize, kRectSize);
134 rect.Translate(drawer->DrawableRegion().top_left());
135 Color color((c == 0 ? (i & 0xff) : 0x7f), (c == 1 ? (i & 0xff) : 0x7f),
136 (c == 2 ? (i & 0xff) : 0x7f));
137 drawer->Clear();
138 drawer->DrawRectangle(rect, color);
139 drawer->WaitForPendingDraws();
140
141 for (ScreenCapturer* capturer : capturers) {
142 std::unique_ptr<DesktopFrame> frame =
143 CaptureFrame(capturer, &callback_);
144 if (!frame) {
145 return;
146 }
147
148 ExpectPixelsAreColoredBy(*frame, rect, color);
149 }
150 }
151 }
152 }
153
154 void TestCaptureUpdatedRegion() {
155 TestCaptureUpdatedRegion({capturer_.get()});
156 }
157
158 #if defined(WEBRTC_WIN)
159 bool SetDirectxCapturerMode() {
160 if (!ScreenCapturerWinDirectx::IsSupported()) {
161 LOG(LS_WARNING) << "Directx capturer is not supported";
162 return false;
163 }
164
165 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
166 options.set_allow_directx_capturer(true);
167 capturer_.reset(ScreenCapturer::Create(options));
168 return true;
169 }
170 #endif // defined(WEBRTC_WIN)
171
45 std::unique_ptr<ScreenCapturer> capturer_; 172 std::unique_ptr<ScreenCapturer> capturer_;
46 MockScreenCapturerCallback callback_; 173 MockScreenCapturerCallback callback_;
47 }; 174 };
48 175
49 class FakeSharedMemory : public SharedMemory { 176 class FakeSharedMemory : public SharedMemory {
50 public: 177 public:
51 FakeSharedMemory(char* buffer, size_t size) 178 FakeSharedMemory(char* buffer, size_t size)
52 : SharedMemory(buffer, size, 0, kTestSharedMemoryId), 179 : SharedMemory(buffer, size, 0, kTestSharedMemoryId),
53 buffer_(buffer) { 180 buffer_(buffer) {
54 } 181 }
(...skipping 12 matching lines...) Expand all
67 194
68 std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override { 195 std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
69 return std::unique_ptr<SharedMemory>( 196 return std::unique_ptr<SharedMemory>(
70 new FakeSharedMemory(new char[size], size)); 197 new FakeSharedMemory(new char[size], size));
71 } 198 }
72 199
73 private: 200 private:
74 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory); 201 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory);
75 }; 202 };
76 203
77 ACTION_P(SaveUniquePtrArg, dest) {
78 *dest = std::move(*arg1);
79 }
80
81 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) { 204 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
82 webrtc::ScreenCapturer::ScreenList screens; 205 webrtc::ScreenCapturer::ScreenList screens;
83 EXPECT_TRUE(capturer_->GetScreenList(&screens)); 206 EXPECT_TRUE(capturer_->GetScreenList(&screens));
84 for (webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin(); 207 for (webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin();
85 it != screens.end(); ++it) { 208 it != screens.end(); ++it) {
86 EXPECT_TRUE(capturer_->SelectScreen(it->id)); 209 EXPECT_TRUE(capturer_->SelectScreen(it->id));
87 } 210 }
88 } 211 }
89 212
90 TEST_F(ScreenCapturerTest, StartCapturer) { 213 TEST_F(ScreenCapturerTest, StartCapturer) {
(...skipping 19 matching lines...) Expand all
110 233
111 // Verify that the region contains whole screen. 234 // Verify that the region contains whole screen.
112 EXPECT_FALSE(frame->updated_region().is_empty()); 235 EXPECT_FALSE(frame->updated_region().is_empty());
113 DesktopRegion::Iterator it(frame->updated_region()); 236 DesktopRegion::Iterator it(frame->updated_region());
114 ASSERT_TRUE(!it.IsAtEnd()); 237 ASSERT_TRUE(!it.IsAtEnd());
115 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size()))); 238 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
116 it.Advance(); 239 it.Advance();
117 EXPECT_TRUE(it.IsAtEnd()); 240 EXPECT_TRUE(it.IsAtEnd());
118 } 241 }
119 242
243 TEST_F(ScreenCapturerTest, CaptureUpdatedRegion) {
244 TestCaptureUpdatedRegion();
245 }
246
120 #if defined(WEBRTC_WIN) 247 #if defined(WEBRTC_WIN)
121 248
122 TEST_F(ScreenCapturerTest, UseSharedBuffers) { 249 TEST_F(ScreenCapturerTest, UseSharedBuffers) {
123 std::unique_ptr<DesktopFrame> frame; 250 std::unique_ptr<DesktopFrame> frame;
124 EXPECT_CALL(callback_, 251 EXPECT_CALL(callback_,
125 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 252 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
126 .WillOnce(SaveUniquePtrArg(&frame)); 253 .WillOnce(SaveUniquePtrArg(&frame));
127 254
128 capturer_->Start(&callback_); 255 capturer_->Start(&callback_);
129 capturer_->SetSharedMemoryFactory( 256 capturer_->SetSharedMemoryFactory(
(...skipping 14 matching lines...) Expand all
144 EXPECT_CALL(callback_, 271 EXPECT_CALL(callback_,
145 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 272 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
146 .WillOnce(SaveUniquePtrArg(&frame)); 273 .WillOnce(SaveUniquePtrArg(&frame));
147 274
148 capturer_->Start(&callback_); 275 capturer_->Start(&callback_);
149 capturer_->Capture(DesktopRegion()); 276 capturer_->Capture(DesktopRegion());
150 ASSERT_TRUE(frame); 277 ASSERT_TRUE(frame);
151 } 278 }
152 279
153 TEST_F(ScreenCapturerTest, UseDirectxCapturer) { 280 TEST_F(ScreenCapturerTest, UseDirectxCapturer) {
154 if (!ScreenCapturerWinDirectx::IsSupported()) { 281 if (!SetDirectxCapturerMode()) {
155 LOG(LS_WARNING) << "Directx capturer is not supported";
156 return; 282 return;
157 } 283 }
158 284
159 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
160 options.set_allow_directx_capturer(true);
161 capturer_.reset(ScreenCapturer::Create(options));
162
163 std::unique_ptr<DesktopFrame> frame; 285 std::unique_ptr<DesktopFrame> frame;
164 EXPECT_CALL(callback_, 286 EXPECT_CALL(callback_,
165 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 287 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
166 .WillOnce(SaveUniquePtrArg(&frame)); 288 .WillOnce(SaveUniquePtrArg(&frame));
167 289
168 capturer_->Start(&callback_); 290 capturer_->Start(&callback_);
169 capturer_->Capture(DesktopRegion()); 291 capturer_->Capture(DesktopRegion());
170 ASSERT_TRUE(frame); 292 ASSERT_TRUE(frame);
171 } 293 }
172 294
173 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { 295 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) {
174 if (!ScreenCapturerWinDirectx::IsSupported()) { 296 if (!SetDirectxCapturerMode()) {
175 LOG(LS_WARNING) << "Directx capturer is not supported";
176 return; 297 return;
177 } 298 }
178 299
179 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
180 options.set_allow_directx_capturer(true);
181 capturer_.reset(ScreenCapturer::Create(options));
182
183 std::unique_ptr<DesktopFrame> frame; 300 std::unique_ptr<DesktopFrame> frame;
184 EXPECT_CALL(callback_, 301 EXPECT_CALL(callback_,
185 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 302 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
186 .WillOnce(SaveUniquePtrArg(&frame)); 303 .WillOnce(SaveUniquePtrArg(&frame));
187 304
188 capturer_->Start(&callback_); 305 capturer_->Start(&callback_);
189 capturer_->SetSharedMemoryFactory( 306 capturer_->SetSharedMemoryFactory(
190 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); 307 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
191 capturer_->Capture(DesktopRegion()); 308 capturer_->Capture(DesktopRegion());
192 ASSERT_TRUE(frame); 309 ASSERT_TRUE(frame);
193 ASSERT_TRUE(frame->shared_memory()); 310 ASSERT_TRUE(frame->shared_memory());
194 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); 311 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
195 } 312 }
196 313
314 TEST_F(ScreenCapturerTest, CaptureUpdatedRegionWithDirectxCapturer) {
315 if (!SetDirectxCapturerMode()) {
316 return;
317 }
318
319 TestCaptureUpdatedRegion();
320 }
321
322 // TODO(zijiehe): Enable this test after CL 2299663003 has been submitted.
323 TEST_F(ScreenCapturerTest, DISABLED_TwoDirectxCapturers) {
324 if (!SetDirectxCapturerMode()) {
325 return;
326 }
327
328 std::unique_ptr<ScreenCapturer> capturer2(capturer_.release());
329 RTC_CHECK(SetDirectxCapturerMode());
330 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()});
331 }
332
197 #endif // defined(WEBRTC_WIN) 333 #endif // defined(WEBRTC_WIN)
198 334
199 } // namespace webrtc 335 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698