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

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: Merge from 2313653003 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/rgba_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 // Returns true if color in |rect| of |frame| is |color|.
65 bool ArePixelsColoredBy(const DesktopFrame& frame,
66 DesktopRect rect,
67 RgbaColor color) {
68 // updated_region() should cover the painted area.
69 DesktopRegion updated_region(frame.updated_region());
70 updated_region.IntersectWith(rect);
71 if (!updated_region.Equals(DesktopRegion(rect))) {
72 return false;
73 }
74
75 // Color in the |rect| should be |color|.
76 uint8_t* row = frame.GetFrameDataAtPos(rect.top_left());
77 for (int i = 0; i < rect.height(); i++) {
78 uint8_t* column = row;
79 for (int j = 0; j < rect.width(); j++) {
80 if (color != RgbaColor(column)) {
81 return false;
82 }
83 column += DesktopFrame::kBytesPerPixel;
84 }
85 row += frame.stride();
86 }
87 return true;
88 }
89
90 } // namespace
91
37 class ScreenCapturerTest : public testing::Test { 92 class ScreenCapturerTest : public testing::Test {
38 public: 93 public:
39 void SetUp() override { 94 void SetUp() override {
40 capturer_.reset( 95 capturer_.reset(
41 ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault())); 96 ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault()));
42 } 97 }
43 98
44 protected: 99 protected:
100 void TestCaptureUpdatedRegion(
101 std::initializer_list<ScreenCapturer*> capturers) {
102 RTC_DCHECK(capturers.size() > 0);
103 // A large enough area for the tests, which should be able to fulfill by
104 // most of systems.
105 const int kTestArea = 512;
106 const int kRectSize = 32;
107 std::unique_ptr<ScreenDrawer> drawer = ScreenDrawer::Create();
108 if (!drawer || drawer->DrawableRegion().is_empty()) {
109 LOG(LS_WARNING) << "No ScreenDrawer implementation for current platform.";
110 return;
111 }
112 if (drawer->DrawableRegion().width() < kTestArea ||
113 drawer->DrawableRegion().height() < kTestArea) {
114 LOG(LS_WARNING) << "ScreenDrawer::DrawableRegion() is too small for the "
115 "CaptureUpdatedRegion tests.";
116 return;
117 }
118
119 for (ScreenCapturer* capturer : capturers) {
120 capturer->Start(&callback_);
121 }
122
123 for (int c = 0; c < 3; c++) {
124 for (int i = 0; i < kTestArea - kRectSize; i += 16) {
125 DesktopRect rect = DesktopRect::MakeXYWH(i, i, kRectSize, kRectSize);
126 rect.Translate(drawer->DrawableRegion().top_left());
127 RgbaColor color((c == 0 ? (i & 0xff) : 0x7f),
128 (c == 1 ? (i & 0xff) : 0x7f),
129 (c == 2 ? (i & 0xff) : 0x7f));
130 drawer->Clear();
131 drawer->DrawRectangle(rect, color);
132
133 const int wait_first_capture_round = 20;
134 for (int j = 0; j < wait_first_capture_round; j++) {
135 drawer->WaitForPendingDraws();
136 std::unique_ptr<DesktopFrame> frame =
137 CaptureFrame(*capturers.begin(), &callback_);
138 if (!frame) {
139 return;
140 }
141
142 if (ArePixelsColoredBy(*frame, rect, color)) {
143 // The first capturer successfully captured the frame we expected.
144 // So the others should also be able to capture it.
145 break;
146 } else {
147 ASSERT_LT(j, wait_first_capture_round);
148 }
149 }
150
151 for (ScreenCapturer* capturer : capturers) {
152 if (capturer == *capturers.begin()) {
153 // TODO(zijiehe): ScreenCapturerX11 and ScreenCapturerWinGdi cannot
154 // capture a correct frame again if screen does not update.
155 continue;
156 }
157 std::unique_ptr<DesktopFrame> frame =
158 CaptureFrame(capturer, &callback_);
159 if (!frame) {
160 return;
161 }
162
163 ASSERT_TRUE(ArePixelsColoredBy(*frame, rect, color));
164 }
165 }
166 }
167 }
168
169 void TestCaptureUpdatedRegion() {
170 TestCaptureUpdatedRegion({capturer_.get()});
171 }
172
173 #if defined(WEBRTC_WIN)
174 bool SetDirectxCapturerMode() {
175 if (!ScreenCapturerWinDirectx::IsSupported()) {
176 LOG(LS_WARNING) << "Directx capturer is not supported";
177 return false;
178 }
179
180 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
181 options.set_allow_directx_capturer(true);
182 capturer_.reset(ScreenCapturer::Create(options));
183 return true;
184 }
185 #endif // defined(WEBRTC_WIN)
186
45 std::unique_ptr<ScreenCapturer> capturer_; 187 std::unique_ptr<ScreenCapturer> capturer_;
46 MockScreenCapturerCallback callback_; 188 MockScreenCapturerCallback callback_;
47 }; 189 };
48 190
49 class FakeSharedMemory : public SharedMemory { 191 class FakeSharedMemory : public SharedMemory {
50 public: 192 public:
51 FakeSharedMemory(char* buffer, size_t size) 193 FakeSharedMemory(char* buffer, size_t size)
52 : SharedMemory(buffer, size, 0, kTestSharedMemoryId), 194 : SharedMemory(buffer, size, 0, kTestSharedMemoryId),
53 buffer_(buffer) { 195 buffer_(buffer) {
54 } 196 }
(...skipping 12 matching lines...) Expand all
67 209
68 std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override { 210 std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
69 return std::unique_ptr<SharedMemory>( 211 return std::unique_ptr<SharedMemory>(
70 new FakeSharedMemory(new char[size], size)); 212 new FakeSharedMemory(new char[size], size));
71 } 213 }
72 214
73 private: 215 private:
74 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory); 216 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory);
75 }; 217 };
76 218
77 ACTION_P(SaveUniquePtrArg, dest) {
78 *dest = std::move(*arg1);
79 }
80
81 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) { 219 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
82 webrtc::ScreenCapturer::ScreenList screens; 220 webrtc::ScreenCapturer::ScreenList screens;
83 EXPECT_TRUE(capturer_->GetScreenList(&screens)); 221 EXPECT_TRUE(capturer_->GetScreenList(&screens));
84 for (webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin(); 222 for (webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin();
85 it != screens.end(); ++it) { 223 it != screens.end(); ++it) {
86 EXPECT_TRUE(capturer_->SelectScreen(it->id)); 224 EXPECT_TRUE(capturer_->SelectScreen(it->id));
87 } 225 }
88 } 226 }
89 227
90 TEST_F(ScreenCapturerTest, StartCapturer) { 228 TEST_F(ScreenCapturerTest, StartCapturer) {
(...skipping 19 matching lines...) Expand all
110 248
111 // Verify that the region contains whole screen. 249 // Verify that the region contains whole screen.
112 EXPECT_FALSE(frame->updated_region().is_empty()); 250 EXPECT_FALSE(frame->updated_region().is_empty());
113 DesktopRegion::Iterator it(frame->updated_region()); 251 DesktopRegion::Iterator it(frame->updated_region());
114 ASSERT_TRUE(!it.IsAtEnd()); 252 ASSERT_TRUE(!it.IsAtEnd());
115 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size()))); 253 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
116 it.Advance(); 254 it.Advance();
117 EXPECT_TRUE(it.IsAtEnd()); 255 EXPECT_TRUE(it.IsAtEnd());
118 } 256 }
119 257
258 TEST_F(ScreenCapturerTest, CaptureUpdatedRegion) {
259 TestCaptureUpdatedRegion();
260 }
261
120 #if defined(WEBRTC_WIN) 262 #if defined(WEBRTC_WIN)
121 263
122 TEST_F(ScreenCapturerTest, UseSharedBuffers) { 264 TEST_F(ScreenCapturerTest, UseSharedBuffers) {
123 std::unique_ptr<DesktopFrame> frame; 265 std::unique_ptr<DesktopFrame> frame;
124 EXPECT_CALL(callback_, 266 EXPECT_CALL(callback_,
125 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 267 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
126 .WillOnce(SaveUniquePtrArg(&frame)); 268 .WillOnce(SaveUniquePtrArg(&frame));
127 269
128 capturer_->Start(&callback_); 270 capturer_->Start(&callback_);
129 capturer_->SetSharedMemoryFactory( 271 capturer_->SetSharedMemoryFactory(
(...skipping 14 matching lines...) Expand all
144 EXPECT_CALL(callback_, 286 EXPECT_CALL(callback_,
145 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 287 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
146 .WillOnce(SaveUniquePtrArg(&frame)); 288 .WillOnce(SaveUniquePtrArg(&frame));
147 289
148 capturer_->Start(&callback_); 290 capturer_->Start(&callback_);
149 capturer_->Capture(DesktopRegion()); 291 capturer_->Capture(DesktopRegion());
150 ASSERT_TRUE(frame); 292 ASSERT_TRUE(frame);
151 } 293 }
152 294
153 TEST_F(ScreenCapturerTest, UseDirectxCapturer) { 295 TEST_F(ScreenCapturerTest, UseDirectxCapturer) {
154 if (!ScreenCapturerWinDirectx::IsSupported()) { 296 if (!SetDirectxCapturerMode()) {
155 LOG(LS_WARNING) << "Directx capturer is not supported";
156 return; 297 return;
157 } 298 }
158 299
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; 300 std::unique_ptr<DesktopFrame> frame;
164 EXPECT_CALL(callback_, 301 EXPECT_CALL(callback_,
165 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 302 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
166 .WillOnce(SaveUniquePtrArg(&frame)); 303 .WillOnce(SaveUniquePtrArg(&frame));
167 304
168 capturer_->Start(&callback_); 305 capturer_->Start(&callback_);
169 capturer_->Capture(DesktopRegion()); 306 capturer_->Capture(DesktopRegion());
170 ASSERT_TRUE(frame); 307 ASSERT_TRUE(frame);
171 } 308 }
172 309
173 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { 310 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) {
174 if (!ScreenCapturerWinDirectx::IsSupported()) { 311 if (!SetDirectxCapturerMode()) {
175 LOG(LS_WARNING) << "Directx capturer is not supported";
176 return; 312 return;
177 } 313 }
178 314
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; 315 std::unique_ptr<DesktopFrame> frame;
184 EXPECT_CALL(callback_, 316 EXPECT_CALL(callback_,
185 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 317 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
186 .WillOnce(SaveUniquePtrArg(&frame)); 318 .WillOnce(SaveUniquePtrArg(&frame));
187 319
188 capturer_->Start(&callback_); 320 capturer_->Start(&callback_);
189 capturer_->SetSharedMemoryFactory( 321 capturer_->SetSharedMemoryFactory(
190 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); 322 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
191 capturer_->Capture(DesktopRegion()); 323 capturer_->Capture(DesktopRegion());
192 ASSERT_TRUE(frame); 324 ASSERT_TRUE(frame);
193 ASSERT_TRUE(frame->shared_memory()); 325 ASSERT_TRUE(frame->shared_memory());
194 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); 326 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
195 } 327 }
196 328
329 TEST_F(ScreenCapturerTest, CaptureUpdatedRegionWithDirectxCapturer) {
330 if (!SetDirectxCapturerMode()) {
331 return;
332 }
333
334 TestCaptureUpdatedRegion();
335 }
336
337 TEST_F(ScreenCapturerTest, TwoDirectxCapturers) {
338 if (!SetDirectxCapturerMode()) {
339 return;
340 }
341
342 std::unique_ptr<ScreenCapturer> capturer2(capturer_.release());
343 RTC_CHECK(SetDirectxCapturerMode());
344 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()});
345 }
346
197 #endif // defined(WEBRTC_WIN) 347 #endif // defined(WEBRTC_WIN)
198 348
199 } // namespace webrtc 349 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/desktop_capture/rgba_color.cc ('k') | webrtc/modules/desktop_capture/screen_drawer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698