Chromium Code Reviews| 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 |