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 600 times, |
| 156 // typically 30 seconds, until they succeeded captured a |color| rectangle at |
| 157 // |rect|. This function uses |drawer|->WaitForPendingDraws() between two |
| 158 // attempts to wait for the 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 = 600; |
| 165 for (int i = 0; i < wait_capture_round; i++) { |
| 166 drawer->WaitForPendingDraws(); |
| 167 for (size_t j = 0; j < capturers.size(); j++) { |
| 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++; |
| 184 } |
| 185 } |
| 186 |
| 187 if (succeeded_capturers == capturers.size()) { |
| 188 break; |
| 189 } |
| 190 } |
| 191 |
| 192 ASSERT_EQ(succeeded_capturers, capturers.size()); |
| 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 // TODO(zijiehe): Find out the reason of failure of this test on trybot. |
| 279 TEST_F(ScreenCapturerTest, DISABLED_TwoCapturers) { |
| 280 std::unique_ptr<ScreenCapturer> capturer2 = std::move(capturer_); |
| 281 SetUp(); |
| 282 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); |
| 283 } |
| 284 |
262 #if defined(WEBRTC_WIN) | 285 #if defined(WEBRTC_WIN) |
263 | 286 |
264 TEST_F(ScreenCapturerTest, UseSharedBuffers) { | 287 TEST_F(ScreenCapturerTest, UseSharedBuffers) { |
265 std::unique_ptr<DesktopFrame> frame; | 288 std::unique_ptr<DesktopFrame> frame; |
266 EXPECT_CALL(callback_, | 289 EXPECT_CALL(callback_, |
267 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) | 290 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) |
268 .WillOnce(SaveUniquePtrArg(&frame)); | 291 .WillOnce(SaveUniquePtrArg(&frame)); |
269 | 292 |
270 capturer_->Start(&callback_); | 293 capturer_->Start(&callback_); |
271 capturer_->SetSharedMemoryFactory( | 294 capturer_->SetSharedMemoryFactory( |
272 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); | 295 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); |
273 capturer_->Capture(DesktopRegion()); | 296 capturer_->Capture(DesktopRegion()); |
274 | 297 |
275 ASSERT_TRUE(frame); | 298 ASSERT_TRUE(frame); |
276 ASSERT_TRUE(frame->shared_memory()); | 299 ASSERT_TRUE(frame->shared_memory()); |
277 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); | 300 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); |
278 } | 301 } |
279 | 302 |
280 TEST_F(ScreenCapturerTest, UseMagnifier) { | 303 TEST_F(ScreenCapturerTest, UseMagnifier) { |
281 DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); | 304 CreateMagnifierCapturer(); |
282 options.set_allow_use_magnification_api(true); | |
283 capturer_.reset(ScreenCapturer::Create(options)); | |
284 | 305 |
285 std::unique_ptr<DesktopFrame> frame; | 306 std::unique_ptr<DesktopFrame> frame; |
286 EXPECT_CALL(callback_, | 307 EXPECT_CALL(callback_, |
287 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) | 308 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) |
288 .WillOnce(SaveUniquePtrArg(&frame)); | 309 .WillOnce(SaveUniquePtrArg(&frame)); |
289 | 310 |
290 capturer_->Start(&callback_); | 311 capturer_->Start(&callback_); |
291 capturer_->Capture(DesktopRegion()); | 312 capturer_->Capture(DesktopRegion()); |
292 ASSERT_TRUE(frame); | 313 ASSERT_TRUE(frame); |
293 } | 314 } |
294 | 315 |
295 TEST_F(ScreenCapturerTest, UseDirectxCapturer) { | 316 TEST_F(ScreenCapturerTest, UseDirectxCapturer) { |
296 if (!SetDirectxCapturerMode()) { | 317 if (!CreateDirectxCapturer()) { |
297 return; | 318 return; |
298 } | 319 } |
299 | 320 |
300 std::unique_ptr<DesktopFrame> frame; | 321 std::unique_ptr<DesktopFrame> frame; |
301 EXPECT_CALL(callback_, | 322 EXPECT_CALL(callback_, |
302 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) | 323 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) |
303 .WillOnce(SaveUniquePtrArg(&frame)); | 324 .WillOnce(SaveUniquePtrArg(&frame)); |
304 | 325 |
305 capturer_->Start(&callback_); | 326 capturer_->Start(&callback_); |
306 capturer_->Capture(DesktopRegion()); | 327 capturer_->Capture(DesktopRegion()); |
307 ASSERT_TRUE(frame); | 328 ASSERT_TRUE(frame); |
308 } | 329 } |
309 | 330 |
310 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { | 331 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { |
311 if (!SetDirectxCapturerMode()) { | 332 if (!CreateDirectxCapturer()) { |
312 return; | 333 return; |
313 } | 334 } |
314 | 335 |
315 std::unique_ptr<DesktopFrame> frame; | 336 std::unique_ptr<DesktopFrame> frame; |
316 EXPECT_CALL(callback_, | 337 EXPECT_CALL(callback_, |
317 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) | 338 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) |
318 .WillOnce(SaveUniquePtrArg(&frame)); | 339 .WillOnce(SaveUniquePtrArg(&frame)); |
319 | 340 |
320 capturer_->Start(&callback_); | 341 capturer_->Start(&callback_); |
321 capturer_->SetSharedMemoryFactory( | 342 capturer_->SetSharedMemoryFactory( |
322 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); | 343 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); |
323 capturer_->Capture(DesktopRegion()); | 344 capturer_->Capture(DesktopRegion()); |
324 ASSERT_TRUE(frame); | 345 ASSERT_TRUE(frame); |
325 ASSERT_TRUE(frame->shared_memory()); | 346 ASSERT_TRUE(frame->shared_memory()); |
326 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); | 347 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); |
327 } | 348 } |
328 | 349 |
329 TEST_F(ScreenCapturerTest, CaptureUpdatedRegionWithDirectxCapturer) { | 350 TEST_F(ScreenCapturerTest, CaptureUpdatedRegionWithDirectxCapturer) { |
330 if (!SetDirectxCapturerMode()) { | 351 if (!CreateDirectxCapturer()) { |
331 return; | 352 return; |
332 } | 353 } |
333 | 354 |
334 TestCaptureUpdatedRegion(); | 355 TestCaptureUpdatedRegion(); |
335 } | 356 } |
336 | 357 |
337 TEST_F(ScreenCapturerTest, TwoDirectxCapturers) { | 358 TEST_F(ScreenCapturerTest, TwoDirectxCapturers) { |
338 if (!SetDirectxCapturerMode()) { | 359 if (!CreateDirectxCapturer()) { |
339 return; | 360 return; |
340 } | 361 } |
341 | 362 |
342 std::unique_ptr<ScreenCapturer> capturer2(capturer_.release()); | 363 std::unique_ptr<ScreenCapturer> capturer2 = std::move(capturer_); |
343 RTC_CHECK(SetDirectxCapturerMode()); | 364 RTC_CHECK(CreateDirectxCapturer()); |
344 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); | 365 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); |
345 } | 366 } |
346 | 367 |
| 368 TEST_F(ScreenCapturerTest, TwoMagnifierCapturers) { |
| 369 CreateMagnifierCapturer(); |
| 370 std::unique_ptr<ScreenCapturer> capturer2 = std::move(capturer_); |
| 371 CreateMagnifierCapturer(); |
| 372 TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); |
| 373 } |
| 374 |
347 #endif // defined(WEBRTC_WIN) | 375 #endif // defined(WEBRTC_WIN) |
348 | 376 |
349 } // namespace webrtc | 377 } // namespace webrtc |
OLD | NEW |