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

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: Created 4 years, 4 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"
20 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" 24 #include "webrtc/modules/desktop_capture/desktop_capture_options.h"
21 #include "webrtc/modules/desktop_capture/desktop_frame.h" 25 #include "webrtc/modules/desktop_capture/desktop_frame.h"
22 #include "webrtc/modules/desktop_capture/desktop_region.h" 26 #include "webrtc/modules/desktop_capture/desktop_region.h"
23 #include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h" 27 #include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
28 #include "webrtc/modules/desktop_capture/screen_painter.h"
29 #include "webrtc/system_wrappers/include/sleep.h"
24 30
25 #if defined(WEBRTC_WIN) 31 #if defined(WEBRTC_WIN)
26 #include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h" 32 #include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
27 #endif // defined(WEBRTC_WIN) 33 #endif // defined(WEBRTC_WIN)
28 34
29 using ::testing::_; 35 using ::testing::_;
30 using ::testing::AnyNumber; 36 using ::testing::AnyNumber;
31 using ::testing::Return; 37 using ::testing::Return;
32 38
33 const int kTestSharedMemoryId = 123; 39 const int kTestSharedMemoryId = 123;
34 40
35 namespace webrtc { 41 namespace webrtc {
36 42
43 namespace {
44
45 ACTION_P(SaveUniquePtrArg, dest) {
46 *dest = std::move(*arg1);
47 }
48
49 // Expects |capturer| to successfully capture a frame, and returns it.
50 std::unique_ptr<DesktopFrame> CaptureFrame(
51 ScreenCapturer* capturer,
52 MockScreenCapturerCallback* callback) {
53 std::unique_ptr<DesktopFrame> frame;
54 EXPECT_CALL(*callback,
55 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
56 .WillOnce(SaveUniquePtrArg(&frame));
57 capturer->Capture(DesktopRegion());
58 EXPECT_TRUE(frame);
59 return frame;
60 }
61
62 // Expects color in |rect| of |frame| is |color|.
63 void ExpectPixelsAreColoredBy(const DesktopFrame& frame,
64 DesktopRect rect,
65 ScreenPainter::Color color) {
66 uint8_t* row = frame.GetFrameDataAtPos(rect.top_left());
67 for (int i = 0; i < rect.height(); i++) {
68 uint8_t* column = row;
69 for (int j = 0; j < rect.width(); j++) {
70 ASSERT_EQ(color, column);
71 column += DesktopFrame::kBytesPerPixel;
72 }
73 row += frame.stride();
74 }
75 }
76
77 // Finds the visible region and offset of ScreenDrawer drawable region in
78 // ScreenCapturer reachable area. The top left of the DesktopRect returned is
79 // the offset of ScreenDrawer drawable region, which maps to (0, 0) of
80 // ScreenDrawer::DrawableRegion(). The size of the DesktopRect indicates the
81 // size of visible region. So to ensure rendering a shape in the visible area of
82 // ScreenCapturer, you can randomize points within the DesktopRect::size() and
83 // use DesktopRect::Translate(-top_left().left(), -top_left().top()) or
84 // DesktopVector::subtract(top_left()) to translate into the coordinate of
85 // ScreenDrawer. This function returns an empty DesktopRect if calibration
86 // failed.
87 DesktopRect CalibrateScreenDrawerPosition(
88 ScreenPainter* painter,
89 ScreenCapturer* capturer,
90 MockScreenCapturerCallback* callback) {
91 const int kAnchorSize = 20;
92 if (painter->DrawableRegion().width() < kAnchorSize ||
93 painter->DrawableRegion().height() < 1) {
94 LOG(LS_WARNING) << "DrawableRegion is too small for calibration.";
95 return DesktopRect();
96 }
97 std::vector<ScreenPainter::Color> anchor_colors;
98 painter->Clear();
99 painter->DrawColorfulHorizontalLine(DesktopVector(), kAnchorSize,
100 &anchor_colors);
101 // We do not need a very accurate positiin, so reduce the sample rate by
102 // 1/256. This usually does not make too much difference.
103 for (int i = std::max(painter->DrawableRegion().width(),
104 painter->DrawableRegion().height()) -
105 1;
106 i > 0; i -= 16) {
107 for (int j = i; j < std::max(painter->DrawableRegion().width(),
108 painter->DrawableRegion().height()) -
109 1;
110 j += anchor_colors.size() * 16) {
111 painter->DrawColorfulHorizontalLine(DesktopVector(j, i), anchor_colors);
112 }
113 }
114 painter->WaitForPendingPaintings();
115
116 std::unique_ptr<DesktopFrame> frame = CaptureFrame(capturer, callback);
117 painter->Clear();
118 if (!frame) {
119 return DesktopRect();
120 }
121
122 const uint8_t* const end =
123 frame->data() + frame->stride() * frame->size().height() -
124 anchor_colors.size() * sizeof(ScreenPainter::Color);
125 DesktopVector top_left(-1, -1);
126 DesktopVector right_bottom;
127 for (const uint8_t* i = frame->data(); i < end;
128 i += DesktopFrame::kBytesPerPixel) {
129 if (ScreenPainter::Color::PixelsMatch(anchor_colors, i)) {
130 right_bottom = frame->GetPosAtFrameData(i);
131 if (top_left.x() < 0 && top_left.y() < 0) {
132 top_left = right_bottom;
133 }
134 }
135 }
136
137 if (top_left.x() >= 0 && top_left.y() >= 0) {
138 return DesktopRect::MakeLTRB(top_left, right_bottom);
139 }
140
141 return DesktopRect();
142 }
143
144 } // namespace
145
37 class ScreenCapturerTest : public testing::Test { 146 class ScreenCapturerTest : public testing::Test {
38 public: 147 public:
39 void SetUp() override { 148 void SetUp() override {
40 capturer_.reset( 149 capturer_.reset(
41 ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault())); 150 ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault()));
42 } 151 }
43 152
44 protected: 153 protected:
45 std::unique_ptr<ScreenCapturer> capturer_; 154 std::unique_ptr<ScreenCapturer> capturer_;
46 MockScreenCapturerCallback callback_; 155 MockScreenCapturerCallback callback_;
(...skipping 20 matching lines...) Expand all
67 176
68 std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override { 177 std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
69 return std::unique_ptr<SharedMemory>( 178 return std::unique_ptr<SharedMemory>(
70 new FakeSharedMemory(new char[size], size)); 179 new FakeSharedMemory(new char[size], size));
71 } 180 }
72 181
73 private: 182 private:
74 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory); 183 RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory);
75 }; 184 };
76 185
77 ACTION_P(SaveUniquePtrArg, dest) {
78 *dest = std::move(*arg1);
79 }
80
81 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) { 186 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
82 webrtc::ScreenCapturer::ScreenList screens; 187 webrtc::ScreenCapturer::ScreenList screens;
83 EXPECT_TRUE(capturer_->GetScreenList(&screens)); 188 EXPECT_TRUE(capturer_->GetScreenList(&screens));
84 for (webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin(); 189 for (webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin();
85 it != screens.end(); ++it) { 190 it != screens.end(); ++it) {
86 EXPECT_TRUE(capturer_->SelectScreen(it->id)); 191 EXPECT_TRUE(capturer_->SelectScreen(it->id));
87 } 192 }
88 } 193 }
89 194
90 TEST_F(ScreenCapturerTest, StartCapturer) { 195 TEST_F(ScreenCapturerTest, StartCapturer) {
(...skipping 19 matching lines...) Expand all
110 215
111 // Verify that the region contains whole screen. 216 // Verify that the region contains whole screen.
112 EXPECT_FALSE(frame->updated_region().is_empty()); 217 EXPECT_FALSE(frame->updated_region().is_empty());
113 DesktopRegion::Iterator it(frame->updated_region()); 218 DesktopRegion::Iterator it(frame->updated_region());
114 ASSERT_TRUE(!it.IsAtEnd()); 219 ASSERT_TRUE(!it.IsAtEnd());
115 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size()))); 220 EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
116 it.Advance(); 221 it.Advance();
117 EXPECT_TRUE(it.IsAtEnd()); 222 EXPECT_TRUE(it.IsAtEnd());
118 } 223 }
119 224
225 TEST_F(ScreenCapturerTest, CaptureUpdatedRegion) {
226 std::unique_ptr<ScreenPainter> painter = ScreenPainter::Create();
227 if (!painter || painter->DrawableRegion().is_empty()) {
228 LOG(LS_WARNING) << "No ScreenPainter implementation for current platform.";
229 return;
230 }
231 capturer_->Start(&callback_);
232
233 const DesktopRect anchor =
234 CalibrateScreenDrawerPosition(painter.get(), capturer_.get(), &callback_);
235 if (anchor.is_empty()) {
236 LOG(LS_WARNING) << "Failed to calibrate ScreenDrawer, it usually means "
237 "ScreenDrawer cannot draw in ScreenCapturer reachable "
238 "area.";
239 return;
240 }
241
242 painter->Clear();
243 ScreenPainter::Color color;
244 DesktopRect rect;
245 painter->DrawRandomColorRectangleIn(anchor.size(), &color, &rect);
246 rect.Translate(anchor.top_left());
247 painter->WaitForPendingPaintings();
248 std::unique_ptr<DesktopFrame> frame =
249 CaptureFrame(capturer_.get(), &callback_);
250 if (!frame) {
251 return;
252 }
253
254 // updated_region() should cover the painted area.
255 DesktopRegion updated_region(frame->updated_region());
256 updated_region.IntersectWith(rect);
257 ASSERT_TRUE(updated_region.Equals(DesktopRegion(rect)));
258
259 // Color in the |rect| should be |color|.
260 ExpectPixelsAreColoredBy(*frame, rect, color);
261 }
262
120 #if defined(WEBRTC_WIN) 263 #if defined(WEBRTC_WIN)
121 264
122 TEST_F(ScreenCapturerTest, UseSharedBuffers) { 265 TEST_F(ScreenCapturerTest, UseSharedBuffers) {
123 std::unique_ptr<DesktopFrame> frame; 266 std::unique_ptr<DesktopFrame> frame;
124 EXPECT_CALL(callback_, 267 EXPECT_CALL(callback_,
125 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) 268 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
126 .WillOnce(SaveUniquePtrArg(&frame)); 269 .WillOnce(SaveUniquePtrArg(&frame));
127 270
128 capturer_->Start(&callback_); 271 capturer_->Start(&callback_);
129 capturer_->SetSharedMemoryFactory( 272 capturer_->SetSharedMemoryFactory(
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory())); 333 std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
191 capturer_->Capture(DesktopRegion()); 334 capturer_->Capture(DesktopRegion());
192 ASSERT_TRUE(frame); 335 ASSERT_TRUE(frame);
193 ASSERT_TRUE(frame->shared_memory()); 336 ASSERT_TRUE(frame->shared_memory());
194 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); 337 EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
195 } 338 }
196 339
197 #endif // defined(WEBRTC_WIN) 340 #endif // defined(WEBRTC_WIN)
198 341
199 } // namespace webrtc 342 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698