OLD | NEW |
---|---|
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 |
(...skipping 30 matching lines...) Expand all Loading... | |
41 const int kTestSharedMemoryId = 123; | 41 const int kTestSharedMemoryId = 123; |
42 | 42 |
43 namespace webrtc { | 43 namespace webrtc { |
44 | 44 |
45 namespace { | 45 namespace { |
46 | 46 |
47 ACTION_P(SaveUniquePtrArg, dest) { | 47 ACTION_P(SaveUniquePtrArg, dest) { |
48 *dest = std::move(*arg1); | 48 *dest = std::move(*arg1); |
49 } | 49 } |
50 | 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|. | 51 // Returns true if color in |rect| of |frame| is |color|. |
65 bool ArePixelsColoredBy(const DesktopFrame& frame, | 52 bool ArePixelsColoredBy(const DesktopFrame& frame, |
66 DesktopRect rect, | 53 DesktopRect rect, |
67 RgbaColor color) { | 54 RgbaColor color) { |
68 // updated_region() should cover the painted area. | 55 // updated_region() should cover the painted area. |
69 DesktopRegion updated_region(frame.updated_region()); | 56 DesktopRegion updated_region(frame.updated_region()); |
70 updated_region.IntersectWith(rect); | 57 updated_region.IntersectWith(rect); |
71 if (!updated_region.Equals(DesktopRegion(rect))) { | 58 if (!updated_region.Equals(DesktopRegion(rect))) { |
72 return false; | 59 return false; |
73 } | 60 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 drawer->DrawableRegion().height() < kTestArea) { | 100 drawer->DrawableRegion().height() < kTestArea) { |
114 LOG(LS_WARNING) << "ScreenDrawer::DrawableRegion() is too small for the " | 101 LOG(LS_WARNING) << "ScreenDrawer::DrawableRegion() is too small for the " |
115 "CaptureUpdatedRegion tests."; | 102 "CaptureUpdatedRegion tests."; |
116 return; | 103 return; |
117 } | 104 } |
118 | 105 |
119 for (ScreenCapturer* capturer : capturers) { | 106 for (ScreenCapturer* capturer : capturers) { |
120 capturer->Start(&callback_); | 107 capturer->Start(&callback_); |
121 } | 108 } |
122 | 109 |
110 // Draw a set of |kRectSize| by |kRectSize| rectangles at (|i|, |i|). One of | |
111 // (controlled by |c|) its primary colors is |i|, and the other two are | |
112 // 0xff. So we won't draw a white rectangle. | |
123 for (int c = 0; c < 3; c++) { | 113 for (int c = 0; c < 3; c++) { |
124 for (int i = 0; i < kTestArea - kRectSize; i += 16) { | 114 for (int i = 0; i < kTestArea - kRectSize; i += 16) { |
125 DesktopRect rect = DesktopRect::MakeXYWH(i, i, kRectSize, kRectSize); | 115 DesktopRect rect = DesktopRect::MakeXYWH(i, i, kRectSize, kRectSize); |
126 rect.Translate(drawer->DrawableRegion().top_left()); | 116 rect.Translate(drawer->DrawableRegion().top_left()); |
127 RgbaColor color((c == 0 ? (i & 0xff) : 0x7f), | 117 RgbaColor color((c == 0 ? (i & 0xff) : 0x7f), |
128 (c == 1 ? (i & 0xff) : 0x7f), | 118 (c == 1 ? (i & 0xff) : 0x7f), |
129 (c == 2 ? (i & 0xff) : 0x7f)); | 119 (c == 2 ? (i & 0xff) : 0x7f)); |
130 drawer->Clear(); | 120 drawer->Clear(); |
131 drawer->DrawRectangle(rect, color); | 121 drawer->DrawRectangle(rect, color); |
132 | 122 TestCaptureOneFrame(capturers, drawer.get(), rect, color); |
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 } | 123 } |
166 } | 124 } |
167 } | 125 } |
168 | 126 |
169 void TestCaptureUpdatedRegion() { | 127 void TestCaptureUpdatedRegion() { |
170 TestCaptureUpdatedRegion({capturer_.get()}); | 128 TestCaptureUpdatedRegion({capturer_.get()}); |
171 } | 129 } |
172 | 130 |
173 #if defined(WEBRTC_WIN) | 131 #if defined(WEBRTC_WIN) |
174 bool SetDirectxCapturerMode() { | 132 bool CreateDirectxCapturer() { |
175 if (!ScreenCapturerWinDirectx::IsSupported()) { | 133 if (!ScreenCapturerWinDirectx::IsSupported()) { |
176 LOG(LS_WARNING) << "Directx capturer is not supported"; | 134 LOG(LS_WARNING) << "Directx capturer is not supported"; |
177 return false; | 135 return false; |
178 } | 136 } |
179 | 137 |
180 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); | 138 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); |
181 options.set_allow_directx_capturer(true); | 139 options.set_allow_directx_capturer(true); |
182 capturer_.reset(ScreenCapturer::Create(options)); | 140 capturer_.reset(ScreenCapturer::Create(options)); |
183 return true; | 141 return true; |
184 } | 142 } |
143 | |
144 void CreateMagnifierCapturer() { | |
145 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); | |
146 options.set_allow_use_magnification_api(true); | |
147 capturer_.reset(ScreenCapturer::Create(options)); | |
148 } | |
185 #endif // defined(WEBRTC_WIN) | 149 #endif // defined(WEBRTC_WIN) |
186 | 150 |
187 std::unique_ptr<ScreenCapturer> capturer_; | 151 std::unique_ptr<ScreenCapturer> capturer_; |
188 MockScreenCapturerCallback callback_; | 152 MockScreenCapturerCallback callback_; |
153 | |
154 private: | |
155 // Repeats capturing the frame by using |capturers| one-by-one for 20 times. | |
156 // Until they succeeded captured a |color| rectangle at |rect|. This function | |
157 // uses |drawer|->WaitForPendingDraws() between two attempts to wait for the | |
158 // screen to update. | |
159 void TestCaptureOneFrame(std::vector<ScreenCapturer*> capturers, | |
160 ScreenDrawer* drawer, | |
161 DesktopRect rect, | |
162 RgbaColor color) { | |
163 size_t succeeded_capturers = 0; | |
164 const int wait_capture_round = 20; | |
165 for (int i = 0; i < wait_capture_round; i++) { | |
166 drawer->WaitForPendingDraws(); | |
167 for (size_t j = 0; j < capturers.size(); j++) { | |
Sergey Ulanov
2016/09/14 00:08:44
You could use a range loop here.
for (auto& captu
Hzj_jie
2016/09/14 03:21:54
I need it to mark capturers[j] = nullptr or captur
| |
168 if (capturers[j] == nullptr) { | |
169 // ScreenCapturer should return an empty updated_region() if no | |
170 // update detected. So we won't test it again if it has captured | |
171 // the rectangle we drew. | |
172 continue; | |
173 } | |
174 std::unique_ptr<DesktopFrame> frame = CaptureFrame(capturers[j]); | |
175 if (!frame) { | |
176 // CaptureFrame() has triggered an assertion failure already, we | |
177 // only need to return here. | |
178 return; | |
179 } | |
180 | |
181 if (ArePixelsColoredBy(*frame, rect, color)) { | |
182 capturers[j] = nullptr; | |
183 succeeded_capturers++; | |
Sergey Ulanov
2016/09/14 00:08:44
Instead of setting capturers to nullptr and keepin
Hzj_jie
2016/09/14 03:21:54
It seems like this approach will make the logic mo
| |
184 } | |
185 } | |
186 | |
187 if (succeeded_capturers == capturers.size()) { | |
188 break; | |
189 } | |
190 | |
191 ASSERT_LT(i, wait_capture_round); | |
Sergey Ulanov
2016/09/14 00:08:44
Do you really need this assert? It just verifies t
Hzj_jie
2016/09/14 03:21:54
Sorry, this is not correct, I expect all capturers
| |
192 } | |
193 } | |
194 | |
195 // Expects |capturer| to successfully capture a frame, and returns it. | |
196 std::unique_ptr<DesktopFrame> CaptureFrame(ScreenCapturer* capturer) { | |
197 std::unique_ptr<DesktopFrame> frame; | |
198 EXPECT_CALL(callback_, | |
199 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) | |
200 .WillOnce(SaveUniquePtrArg(&frame)); | |
201 capturer->Capture(DesktopRegion()); | |
202 EXPECT_TRUE(frame); | |
203 return frame; | |
204 } | |
189 }; | 205 }; |
190 | 206 |
191 class FakeSharedMemory : public SharedMemory { | 207 class FakeSharedMemory : public SharedMemory { |
192 public: | 208 public: |
193 FakeSharedMemory(char* buffer, size_t size) | 209 FakeSharedMemory(char* buffer, size_t size) |
194 : SharedMemory(buffer, size, 0, kTestSharedMemoryId), | 210 : SharedMemory(buffer, size, 0, kTestSharedMemoryId), |
195 buffer_(buffer) { | 211 buffer_(buffer) { |
196 } | 212 } |
197 virtual ~FakeSharedMemory() { | 213 virtual ~FakeSharedMemory() { |
198 delete[] buffer_; | 214 delete[] buffer_; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
252 ASSERT_TRUE(!it.IsAtEnd()); | 268 ASSERT_TRUE(!it.IsAtEnd()); |
253 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size()))); | 269 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size()))); |
254 it.Advance(); | 270 it.Advance(); |
255 EXPECT_TRUE(it.IsAtEnd()); | 271 EXPECT_TRUE(it.IsAtEnd()); |
256 } | 272 } |
257 | 273 |
258 TEST_F(ScreenCapturerTest, CaptureUpdatedRegion) { | 274 TEST_F(ScreenCapturerTest, CaptureUpdatedRegion) { |
259 TestCaptureUpdatedRegion(); | 275 TestCaptureUpdatedRegion(); |
260 } | 276 } |
261 | 277 |
278 TEST_F(ScreenCapturerTest, TwoCapturers) { | |
279 std::unique_ptr<ScreenCapturer> capturer2 = std::move(capturer_); | |
280 SetUp(); | |
281 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); | |
282 } | |
283 | |
262 #if defined(WEBRTC_WIN) | 284 #if defined(WEBRTC_WIN) |
263 | 285 |
264 TEST_F(ScreenCapturerTest, UseSharedBuffers) { | 286 TEST_F(ScreenCapturerTest, UseSharedBuffers) { |
265 std::unique_ptr<DesktopFrame> frame; | 287 std::unique_ptr<DesktopFrame> frame; |
266 EXPECT_CALL(callback_, | 288 EXPECT_CALL(callback_, |
267 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) | 289 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) |
268 .WillOnce(SaveUniquePtrArg(&frame)); | 290 .WillOnce(SaveUniquePtrArg(&frame)); |
269 | 291 |
270 capturer_->Start(&callback_); | 292 capturer_->Start(&callback_); |
271 capturer_->SetSharedMemoryFactory( | 293 capturer_->SetSharedMemoryFactory( |
272 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); | 294 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); |
273 capturer_->Capture(DesktopRegion()); | 295 capturer_->Capture(DesktopRegion()); |
274 | 296 |
275 ASSERT_TRUE(frame); | 297 ASSERT_TRUE(frame); |
276 ASSERT_TRUE(frame->shared_memory()); | 298 ASSERT_TRUE(frame->shared_memory()); |
277 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); | 299 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); |
278 } | 300 } |
279 | 301 |
280 TEST_F(ScreenCapturerTest, UseMagnifier) { | 302 TEST_F(ScreenCapturerTest, UseMagnifier) { |
281 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); | 303 CreateMagnifierCapturer(); |
282 options.set_allow_use_magnification_api(true); | |
283 capturer_.reset(ScreenCapturer::Create(options)); | |
284 | 304 |
285 std::unique_ptr<DesktopFrame> frame; | 305 std::unique_ptr<DesktopFrame> frame; |
286 EXPECT_CALL(callback_, | 306 EXPECT_CALL(callback_, |
287 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) | 307 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) |
288 .WillOnce(SaveUniquePtrArg(&frame)); | 308 .WillOnce(SaveUniquePtrArg(&frame)); |
289 | 309 |
290 capturer_->Start(&callback_); | 310 capturer_->Start(&callback_); |
291 capturer_->Capture(DesktopRegion()); | 311 capturer_->Capture(DesktopRegion()); |
292 ASSERT_TRUE(frame); | 312 ASSERT_TRUE(frame); |
293 } | 313 } |
294 | 314 |
295 TEST_F(ScreenCapturerTest, UseDirectxCapturer) { | 315 TEST_F(ScreenCapturerTest, UseDirectxCapturer) { |
296 if (!SetDirectxCapturerMode()) { | 316 if (!CreateDirectxCapturer()) { |
297 return; | 317 return; |
298 } | 318 } |
299 | 319 |
300 std::unique_ptr<DesktopFrame> frame; | 320 std::unique_ptr<DesktopFrame> frame; |
301 EXPECT_CALL(callback_, | 321 EXPECT_CALL(callback_, |
302 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) | 322 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) |
303 .WillOnce(SaveUniquePtrArg(&frame)); | 323 .WillOnce(SaveUniquePtrArg(&frame)); |
304 | 324 |
305 capturer_->Start(&callback_); | 325 capturer_->Start(&callback_); |
306 capturer_->Capture(DesktopRegion()); | 326 capturer_->Capture(DesktopRegion()); |
307 ASSERT_TRUE(frame); | 327 ASSERT_TRUE(frame); |
308 } | 328 } |
309 | 329 |
310 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { | 330 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { |
311 if (!SetDirectxCapturerMode()) { | 331 if (!CreateDirectxCapturer()) { |
312 return; | 332 return; |
313 } | 333 } |
314 | 334 |
315 std::unique_ptr<DesktopFrame> frame; | 335 std::unique_ptr<DesktopFrame> frame; |
316 EXPECT_CALL(callback_, | 336 EXPECT_CALL(callback_, |
317 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) | 337 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) |
318 .WillOnce(SaveUniquePtrArg(&frame)); | 338 .WillOnce(SaveUniquePtrArg(&frame)); |
319 | 339 |
320 capturer_->Start(&callback_); | 340 capturer_->Start(&callback_); |
321 capturer_->SetSharedMemoryFactory( | 341 capturer_->SetSharedMemoryFactory( |
322 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); | 342 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); |
323 capturer_->Capture(DesktopRegion()); | 343 capturer_->Capture(DesktopRegion()); |
324 ASSERT_TRUE(frame); | 344 ASSERT_TRUE(frame); |
325 ASSERT_TRUE(frame->shared_memory()); | 345 ASSERT_TRUE(frame->shared_memory()); |
326 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); | 346 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); |
327 } | 347 } |
328 | 348 |
329 TEST_F(ScreenCapturerTest, CaptureUpdatedRegionWithDirectxCapturer) { | 349 TEST_F(ScreenCapturerTest, CaptureUpdatedRegionWithDirectxCapturer) { |
330 if (!SetDirectxCapturerMode()) { | 350 if (!CreateDirectxCapturer()) { |
331 return; | 351 return; |
332 } | 352 } |
333 | 353 |
334 TestCaptureUpdatedRegion(); | 354 TestCaptureUpdatedRegion(); |
335 } | 355 } |
336 | 356 |
337 TEST_F(ScreenCapturerTest, TwoDirectxCapturers) { | 357 TEST_F(ScreenCapturerTest, TwoDirectxCapturers) { |
338 if (!SetDirectxCapturerMode()) { | 358 if (!CreateDirectxCapturer()) { |
339 return; | 359 return; |
340 } | 360 } |
341 | 361 |
342 std::unique_ptr<ScreenCapturer> capturer2(capturer_.release()); | 362 std::unique_ptr<ScreenCapturer> capturer2 = std::move(capturer_); |
343 RTC_CHECK(SetDirectxCapturerMode()); | 363 RTC_CHECK(CreateDirectxCapturer()); |
344 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); | 364 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); |
345 } | 365 } |
346 | 366 |
367 TEST_F(ScreenCapturerTest, TwoMagnifierCapturers) { | |
368 CreateMagnifierCapturer(); | |
369 std::unique_ptr<ScreenCapturer> capturer2 = std::move(capturer_); | |
370 CreateMagnifierCapturer(); | |
371 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); | |
372 } | |
373 | |
347 #endif // defined(WEBRTC_WIN) | 374 #endif // defined(WEBRTC_WIN) |
348 | 375 |
349 } // namespace webrtc | 376 } // namespace webrtc |
OLD | NEW |