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

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: Resolve review comments 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>
11 #include <memory> 14 #include <memory>
12 #include <utility> 15 #include <utility>
16 #include <vector>
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"
18 #include "webrtc/base/constructormagic.h" 22 #include "webrtc/base/constructormagic.h"
19 #include "webrtc/base/logging.h" 23 #include "webrtc/base/logging.h"
24 #include "webrtc/modules/desktop_capture/color.h"
20 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" 25 #include "webrtc/modules/desktop_capture/desktop_capture_options.h"
21 #include "webrtc/modules/desktop_capture/desktop_frame.h" 26 #include "webrtc/modules/desktop_capture/desktop_frame.h"
22 #include "webrtc/modules/desktop_capture/desktop_region.h" 27 #include "webrtc/modules/desktop_capture/desktop_region.h"
23 #include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h" 28 #include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
29 #include "webrtc/modules/desktop_capture/screen_drawer.h"
30 #include "webrtc/system_wrappers/include/sleep.h"
24 31
25 #if defined(WEBRTC_WIN) 32 #if defined(WEBRTC_WIN)
26 #include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h" 33 #include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
27 #endif // defined(WEBRTC_WIN) 34 #endif // defined(WEBRTC_WIN)
28 35
29 using ::testing::_; 36 using ::testing::_;
30 using ::testing::AnyNumber; 37 using ::testing::AnyNumber;
31 using ::testing::Return; 38 using ::testing::Return;
32 39
33 const int kTestSharedMemoryId = 123; 40 const int kTestSharedMemoryId = 123;
34 41
35 namespace webrtc { 42 namespace webrtc {
36 43
44 namespace {
45
46 ACTION_P(SaveUniquePtrArg, dest) {
47 *dest = std::move(*arg1);
48 }
49
50 // Expects |capturer| to successfully capture a frame, and returns it.
51 std::unique_ptr<DesktopFrame> CaptureFrame(
52 ScreenCapturer* capturer,
53 MockScreenCapturerCallback* callback) {
54 std::unique_ptr<DesktopFrame> frame;
55 EXPECT_CALL(*callback,
56 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
57 .WillOnce(SaveUniquePtrArg(&frame));
58 capturer->Capture(DesktopRegion());
59 EXPECT_TRUE(frame);
60 return frame;
61 }
62
63 // Expects color in |rect| of |frame| is |color|.
64 void ExpectPixelsAreColoredBy(const DesktopFrame& frame,
65 DesktopRect rect,
66 Color color) {
67 // updated_region() should cover the painted area.
68 DesktopRegion updated_region(frame.updated_region());
69 updated_region.IntersectWith(rect);
70 ASSERT_TRUE(updated_region.Equals(DesktopRegion(rect)));
Jamie 2016/08/26 22:29:09 It looks like this test will pass if updated_regio
Hzj_jie 2016/08/29 21:57:28 Yes, currently it's expected. Before change 220244
Jamie 2016/08/31 17:39:39 So will you update this test to be more exact once
Hzj_jie 2016/08/31 21:22:39 Yes, all the area covered by ScreenDrawer::Drawabl
71
72 // Color in the |rect| should be |color|.
73 uint8_t* row = frame.GetFrameDataAtPos(rect.top_left());
74 for (int i = 0; i < rect.height(); i++) {
75 uint8_t* column = row;
76 for (int j = 0; j < rect.width(); j++) {
77 ASSERT_EQ(color, column);
78 column += DesktopFrame::kBytesPerPixel;
79 }
80 row += frame.stride();
81 }
82 }
83
84 } // namespace
85
37 class ScreenCapturerTest : public testing::Test { 86 class ScreenCapturerTest : public testing::Test {
38 public: 87 public:
39 void SetUp() override { 88 void SetUp() override {
40 capturer_.reset( 89 capturer_.reset(
41 ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault())); 90 ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault()));
42 } 91 }
43 92
44 protected: 93 protected:
94 void TestCaptureUpdatedRegion(
95 std::vector<ScreenCapturer*> capturers = std::vector<ScreenCapturer*>()) {
96 // Always test capturer_.
97 capturers.push_back(capturer_.get());
Jamie 2016/08/26 22:29:10 I think the code would be cleaner if you explicitl
Hzj_jie 2016/08/29 21:57:28 Done.
98 // A large enough area for the tests, which should be able to fulfill by
99 // most of systems.
100 const int kTestArea = 512;
101 const int kRectSize = 32;
102 std::unique_ptr<ScreenDrawer> drawer = ScreenDrawer::Create();
103 if (!drawer || drawer->DrawableRegion().is_empty()) {
104 LOG(LS_WARNING) << "No ScreenDrawer implementation for current platform.";
105 return;
106 }
107 if (drawer->DrawableRegion().width() < kTestArea ||
108 drawer->DrawableRegion().height() < kTestArea) {
109 LOG(LS_WARNING) << "ScreenDrawer::DrawableRegion() is too small for the "
110 "CaptureUpdatedRegion tests.";
111 return;
112 }
113 for (ScreenCapturer* capturer : capturers) {
114 capturer->Start(&callback_);
115 }
116 #if defined(WEBRTC_LINUX)
117 // TODO(zijiehe): ScreenCapturerX11 won't be able to capture correct images
118 // in the first several capture attempts.
119 for (int i = 0; i < 10; i++) {
120 for (ScreenCapturer* capturer : capturers) {
121 std::unique_ptr<DesktopFrame> frame =
122 CaptureFrame(capturer, &callback_);
123 if (!frame) {
124 return;
125 }
126 }
127 }
128 #endif
129
130 for (int c = 0; c < 3; c++) {
131 for (int i = 0; i < kTestArea - kRectSize; i += 16) {
132 DesktopRect rect = DesktopRect::MakeXYWH(i, i, kRectSize, kRectSize);
133 Color color = Color::FromBGR((c == 0 ? (i & 0xff) : 0x7f),
134 (c == 1 ? (i & 0xff) : 0x7f),
135 (c == 2 ? (i & 0xff) : 0x7f));
136 drawer->Clear();
137 drawer->DrawRectangle(rect, color);
138 drawer->WaitForPendingPaintings();
139 rect.Translate(drawer->DrawableRegion().top_left());
Jamie 2016/08/26 22:29:10 This line goes away if you use the same frame-of-r
Hzj_jie 2016/08/29 21:57:28 Done.
140
141 for (ScreenCapturer* capturer : capturers) {
142 std::unique_ptr<DesktopFrame> frame =
143 CaptureFrame(capturer, &callback_);
144 if (!frame) {
145 return;
Jamie 2016/08/26 22:29:10 Shouldn't this be a test failure?
Hzj_jie 2016/08/29 21:57:28 The assertion has been added in CaptureFrame alrea
146 }
147
148 ExpectPixelsAreColoredBy(*frame, rect, color);
149 }
150 }
151 }
152 }
153
154 #if defined(WEBRTC_WIN)
155 bool UseDirectxCapturer() {
Jamie 2016/08/26 22:29:10 Since this returns a bool, it's not clear that it'
Hzj_jie 2016/08/29 21:57:28 Done.
156 if (!ScreenCapturerWinDirectx::IsSupported()) {
157 LOG(LS_WARNING) << "Directx capturer is not supported";
158 return false;
159 }
160
161 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
162 options.set_allow_directx_capturer(true);
163 capturer_.reset(ScreenCapturer::Create(options));
164 return true;
165 }
166 #endif // defined(WEBRTC_WIN)
167
45 std::unique_ptr<ScreenCapturer> capturer_; 168 std::unique_ptr<ScreenCapturer> capturer_;
46 MockScreenCapturerCallback callback_; 169 MockScreenCapturerCallback callback_;
47 }; 170 };
48 171
49 class FakeSharedMemory : public SharedMemory { 172 class FakeSharedMemory : public SharedMemory {
50 public: 173 public:
51 FakeSharedMemory(char* buffer, size_t size) 174 FakeSharedMemory(char* buffer, size_t size)
52 : SharedMemory(buffer, size, 0, kTestSharedMemoryId), 175 : SharedMemory(buffer, size, 0, kTestSharedMemoryId),
53 buffer_(buffer) { 176 buffer_(buffer) {
54 } 177 }
(...skipping 12 matching lines...) Expand all
67 190
68 std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override { 191 std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
69 return std::unique_ptr<SharedMemory>( 192 return std::unique_ptr<SharedMemory>(
70 new FakeSharedMemory(new char[size], size)); 193 new FakeSharedMemory(new char[size], size));
71 } 194 }
72 195
73 private: 196 private:
74 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory); 197 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory);
75 }; 198 };
76 199
77 ACTION_P(SaveUniquePtrArg, dest) {
78 *dest = std::move(*arg1);
79 }
80
81 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) { 200 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
82 webrtc::ScreenCapturer::ScreenList screens; 201 webrtc::ScreenCapturer::ScreenList screens;
83 EXPECT_TRUE(capturer_->GetScreenList(&screens)); 202 EXPECT_TRUE(capturer_->GetScreenList(&screens));
84 for (webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin(); 203 for (webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin();
85 it != screens.end(); ++it) { 204 it != screens.end(); ++it) {
86 EXPECT_TRUE(capturer_->SelectScreen(it->id)); 205 EXPECT_TRUE(capturer_->SelectScreen(it->id));
87 } 206 }
88 } 207 }
89 208
90 TEST_F(ScreenCapturerTest, StartCapturer) { 209 TEST_F(ScreenCapturerTest, StartCapturer) {
(...skipping 19 matching lines...) Expand all
110 229
111 // Verify that the region contains whole screen. 230 // Verify that the region contains whole screen.
112 EXPECT_FALSE(frame->updated_region().is_empty()); 231 EXPECT_FALSE(frame->updated_region().is_empty());
113 DesktopRegion::Iterator it(frame->updated_region()); 232 DesktopRegion::Iterator it(frame->updated_region());
114 ASSERT_TRUE(!it.IsAtEnd()); 233 ASSERT_TRUE(!it.IsAtEnd());
115 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size()))); 234 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
116 it.Advance(); 235 it.Advance();
117 EXPECT_TRUE(it.IsAtEnd()); 236 EXPECT_TRUE(it.IsAtEnd());
118 } 237 }
119 238
239 TEST_F(ScreenCapturerTest, CaptureUpdatedRegion) {
240 TestCaptureUpdatedRegion();
241 }
242
120 #if defined(WEBRTC_WIN) 243 #if defined(WEBRTC_WIN)
121 244
122 TEST_F(ScreenCapturerTest, UseSharedBuffers) { 245 TEST_F(ScreenCapturerTest, UseSharedBuffers) {
123 std::unique_ptr<DesktopFrame> frame; 246 std::unique_ptr<DesktopFrame> frame;
124 EXPECT_CALL(callback_, 247 EXPECT_CALL(callback_,
125 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 248 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
126 .WillOnce(SaveUniquePtrArg(&frame)); 249 .WillOnce(SaveUniquePtrArg(&frame));
127 250
128 capturer_->Start(&callback_); 251 capturer_->Start(&callback_);
129 capturer_->SetSharedMemoryFactory( 252 capturer_->SetSharedMemoryFactory(
(...skipping 14 matching lines...) Expand all
144 EXPECT_CALL(callback_, 267 EXPECT_CALL(callback_,
145 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 268 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
146 .WillOnce(SaveUniquePtrArg(&frame)); 269 .WillOnce(SaveUniquePtrArg(&frame));
147 270
148 capturer_->Start(&callback_); 271 capturer_->Start(&callback_);
149 capturer_->Capture(DesktopRegion()); 272 capturer_->Capture(DesktopRegion());
150 ASSERT_TRUE(frame); 273 ASSERT_TRUE(frame);
151 } 274 }
152 275
153 TEST_F(ScreenCapturerTest, UseDirectxCapturer) { 276 TEST_F(ScreenCapturerTest, UseDirectxCapturer) {
154 if (!ScreenCapturerWinDirectx::IsSupported()) { 277 if (!UseDirectxCapturer()) {
155 LOG(LS_WARNING) << "Directx capturer is not supported";
156 return; 278 return;
157 } 279 }
158 280
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; 281 std::unique_ptr<DesktopFrame> frame;
164 EXPECT_CALL(callback_, 282 EXPECT_CALL(callback_,
165 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 283 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
166 .WillOnce(SaveUniquePtrArg(&frame)); 284 .WillOnce(SaveUniquePtrArg(&frame));
167 285
168 capturer_->Start(&callback_); 286 capturer_->Start(&callback_);
169 capturer_->Capture(DesktopRegion()); 287 capturer_->Capture(DesktopRegion());
170 ASSERT_TRUE(frame); 288 ASSERT_TRUE(frame);
171 } 289 }
172 290
173 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { 291 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) {
174 if (!ScreenCapturerWinDirectx::IsSupported()) { 292 if (!UseDirectxCapturer()) {
175 LOG(LS_WARNING) << "Directx capturer is not supported";
176 return; 293 return;
177 } 294 }
178 295
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; 296 std::unique_ptr<DesktopFrame> frame;
184 EXPECT_CALL(callback_, 297 EXPECT_CALL(callback_,
185 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 298 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
186 .WillOnce(SaveUniquePtrArg(&frame)); 299 .WillOnce(SaveUniquePtrArg(&frame));
187 300
188 capturer_->Start(&callback_); 301 capturer_->Start(&callback_);
189 capturer_->SetSharedMemoryFactory( 302 capturer_->SetSharedMemoryFactory(
190 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); 303 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
191 capturer_->Capture(DesktopRegion()); 304 capturer_->Capture(DesktopRegion());
192 ASSERT_TRUE(frame); 305 ASSERT_TRUE(frame);
193 ASSERT_TRUE(frame->shared_memory()); 306 ASSERT_TRUE(frame->shared_memory());
194 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); 307 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
195 } 308 }
196 309
310 TEST_F(ScreenCapturerTest, CaptureUpdatedRegionWithDirectxCapturer) {
311 if (!UseDirectxCapturer()) {
312 return;
313 }
314
315 TestCaptureUpdatedRegion();
316 }
317
318 TEST_F(ScreenCapturerTest, TwoDirectxCapturers) {
319 if (!UseDirectxCapturer()) {
320 return;
321 }
322
323 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
324 options.set_allow_directx_capturer(true);
325 std::unique_ptr<ScreenCapturer> capturer2(ScreenCapturer::Create(options));
Jamie 2016/08/26 22:29:10 You could instead take ownership of capturer_ and
Hzj_jie 2016/08/29 21:57:28 Done.
326
327 TestCaptureUpdatedRegion({capturer2.get()});
328 }
329
197 #endif // defined(WEBRTC_WIN) 330 #endif // defined(WEBRTC_WIN)
198 331
199 } // namespace webrtc 332 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698