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

Side by Side Diff: webrtc/modules/desktop_capture/screen_capturer_differ_wrapper_unittest.cc

Issue 2202443002: [WebRTC] Add ScreenCapturerDifferWrapper to share Differ across ScreenCapturers (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Resolve review comments 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
(Empty)
1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h"
12
13 #include <initializer_list>
14 #include <memory>
15 #include <utility>
16 #include <vector>
17
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webrtc/base/random.h"
20 #include "webrtc/base/timeutils.h"
21 #include "webrtc/modules/desktop_capture/desktop_geometry.h"
22 #include "webrtc/modules/desktop_capture/desktop_region.h"
23 #include "webrtc/modules/desktop_capture/differ_block.h"
24 #include "webrtc/modules/desktop_capture/fake_screen_capturer.h"
25 #include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
26 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
27 #include "webrtc/typedefs.h"
28
29 namespace webrtc {
30
31 namespace {
32
33 // ScreenCapturerDifferWrapper always use a 32 x 32 pixel block. So we normalize
34 // the |rects|.
35 DesktopRect NormalizeDesktopRect(DesktopRect rect, DesktopSize size) {
36 DesktopRect block_size_rect = DesktopRect::MakeLTRB(
37 rect.left() / kBlockSize * kBlockSize,
38 rect.top() / kBlockSize * kBlockSize,
39 (rect.right() + kBlockSize - 1) / kBlockSize * kBlockSize,
40 (rect.bottom() + kBlockSize - 1) / kBlockSize * kBlockSize);
41 block_size_rect.IntersectWith(DesktopRect::MakeSize(size));
42 return block_size_rect;
43 }
44
45 // Compares and asserts |frame|.updated_region() equals to |rects|. This
46 // function does not care about the order of the |rects|.
47 template <template <typename, typename...> class T = std::initializer_list,
48 typename... Rect>
49 void AssertUpdatedRegionIs(const DesktopFrame& frame,
50 const T<DesktopRect, Rect...>& rects) {
51 for (const DesktopRect& rect : rects) {
52 DesktopRect block_size_rect = NormalizeDesktopRect(rect, frame.size());
53 bool found = false;
54 for (DesktopRegion::Iterator it(frame.updated_region()); !it.IsAtEnd();
55 it.Advance()) {
56 if (it.rect().equals(block_size_rect)) {
57 found = true;
58 break;
59 }
60 }
61
62 ASSERT_TRUE(found);
63 }
64 }
65
66 // Compares and asserts |frame|.updated_region() covers all rectangles in
67 // |rects|, but does not cover areas other than a kBlockSize expansion. This
68 // function does not care about the order of the |rects|, and it does not expect
69 // DesktopRegion to return an exact area of each rectangle in |rects|.
70 template <template <typename, typename...> class T = std::initializer_list,
71 typename... Rect>
72 void AssertUpdatedRegionCovers(const DesktopFrame& frame,
73 const T<DesktopRect, Rect...>& rects) {
74 DesktopRegion region;
75 for (const auto& rect : rects) {
76 region.AddRect(NormalizeDesktopRect(rect, frame.size()));
77 }
78 ASSERT_TRUE(frame.updated_region().Equals(region));
79 }
80
81 // Executes a ScreenCapturerDifferWrapper::Capture() and compares its output
82 // DesktopFrame::updated_region() with |updated_region| if |check_result| is
83 // true. If |exactly_match| is true, AssertUpdatedRegionIs() will be used,
84 // otherwise AssertUpdatedRegionCovers() will be used.
85 template <template <typename, typename...> class T = std::initializer_list,
86 typename... Rect>
87 void ExecuteDifferWrapperCase(BlackWhiteDesktopFrameGenerator* frame_generator,
88 ScreenCapturerDifferWrapper* capturer,
89 MockScreenCapturerCallback* callback,
90 const T<DesktopRect, Rect...>& updated_region,
91 bool check_result,
92 bool exactly_match) {
93 EXPECT_CALL(*callback,
94 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, testing::_))
95 .Times(1)
96 .WillOnce(testing::Invoke([&updated_region, check_result, exactly_match](
97 DesktopCapturer::Result result,
98 std::unique_ptr<DesktopFrame>* frame) {
99 ASSERT_EQ(result, DesktopCapturer::Result::SUCCESS);
100 if (check_result) {
101 if (exactly_match) {
102 AssertUpdatedRegionIs(**frame, updated_region);
103 } else {
104 AssertUpdatedRegionCovers(**frame, updated_region);
105 }
106 }
107 }));
108 for (const auto& rect : updated_region) {
109 frame_generator->updated_region()->AddRect(rect);
110 }
111 capturer->Capture(DesktopRegion());
112 }
113
114 // Executes a ScreenCapturerDifferWrapper::Capture(), if updated_region() is not
115 // set, this function will reset ScreenCapturerDifferWrapper internal
116 // DesktopFrame into white.
117 void ExecuteCapturer(ScreenCapturerDifferWrapper* capturer,
118 MockScreenCapturerCallback* callback) {
119 EXPECT_CALL(*callback,
120 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, testing::_))
121 .Times(1);
122 capturer->Capture(DesktopRegion());
123 }
124
125 void ExecuteDifferWrapperTest(bool with_hints,
126 bool enlarge_updated_region,
127 bool random_updated_region,
128 bool check_result) {
129 BlackWhiteDesktopFrameGenerator frame_generator;
130 std::unique_ptr<FakeScreenCapturer> fake(new FakeScreenCapturer());
131 fake->set_frame_generator(&frame_generator);
132 ScreenCapturerDifferWrapper capturer(std::move(fake), !with_hints);
133 MockScreenCapturerCallback callback;
134 frame_generator.set_provide_updated_region_hints(with_hints);
135 frame_generator.set_enlarge_updated_region(enlarge_updated_region);
136 frame_generator.set_add_random_updated_region(random_updated_region);
137
138 capturer.Start(&callback);
139
140 EXPECT_CALL(callback,
141 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, testing::_))
142 .Times(1)
143 .WillOnce(testing::Invoke([](DesktopCapturer::Result result,
144 std::unique_ptr<DesktopFrame>* frame) {
145 ASSERT_EQ(result, DesktopCapturer::Result::SUCCESS);
146 AssertUpdatedRegionIs(**frame,
147 {DesktopRect::MakeSize((*frame)->size())});
148 }));
149 capturer.Capture(DesktopRegion());
150
151 ExecuteDifferWrapperCase(&frame_generator, &capturer, &callback,
152 {DesktopRect::MakeLTRB(100, 100, 200, 200),
153 DesktopRect::MakeLTRB(300, 300, 400, 400)},
154 check_result, true);
155 ExecuteCapturer(&capturer, &callback);
156
157 ExecuteDifferWrapperCase(
158 &frame_generator, &capturer, &callback,
159 {DesktopRect::MakeLTRB(0, 0, 40, 40),
160 DesktopRect::MakeLTRB(0, frame_generator.size()->height() - 40, 40,
161 frame_generator.size()->height()),
162 DesktopRect::MakeLTRB(frame_generator.size()->width() - 40, 0,
163 frame_generator.size()->width(), 40),
164 DesktopRect::MakeLTRB(frame_generator.size()->width() - 40,
165 frame_generator.size()->height() - 40,
166 frame_generator.size()->width(),
167 frame_generator.size()->height())},
168 check_result, true);
169
170 Random random(rtc::TimeMillis());
171 // Fuzzing tests.
172 for (int i = 0; i < 1000; i++) {
173 if (enlarge_updated_region) {
174 frame_generator.set_enlarge_range(random.Rand(1, 50));
175 }
176 frame_generator.size()->set(random.Rand(500, 2000), random.Rand(500, 2000));
177 ExecuteCapturer(&capturer, &callback);
178 std::vector<DesktopRect> updated_region;
179 for (int j = random.Rand(50); j >= 0; j--) {
180 // At least a 1 x 1 updated region.
181 const int left = random.Rand(0, frame_generator.size()->width() - 2);
182 const int top = random.Rand(0, frame_generator.size()->height() - 2);
183 const int right = random.Rand(left + 1, frame_generator.size()->width());
184 const int bottom = random.Rand(top + 1, frame_generator.size()->height());
185 updated_region.push_back(DesktopRect::MakeLTRB(left, top, right, bottom));
186 }
187 ExecuteDifferWrapperCase(&frame_generator, &capturer, &callback,
188 updated_region, check_result, false);
189 }
190 }
191
192 } // namespace
193
194 TEST(ScreenCapturerDifferWrapperTest, CaptureWithoutHints) {
195 ExecuteDifferWrapperTest(false, false, false, true);
196 }
197
198 TEST(ScreenCapturerDifferWrapperTest, CaptureWithHints) {
199 ExecuteDifferWrapperTest(true, false, false, true);
200 }
201
202 TEST(ScreenCapturerDifferWrapperTest, CaptureWithEnlargedHints) {
203 ExecuteDifferWrapperTest(true, true, false, true);
204 }
205
206 TEST(ScreenCapturerDifferWrapperTest, CaptureWithRandomHints) {
207 ExecuteDifferWrapperTest(true, false, true, true);
208 }
209
210 TEST(ScreenCapturerDifferWrapperTest, CaptureWithEnlargedAndRandomHints) {
211 ExecuteDifferWrapperTest(true, true, true, true);
212 }
213
214 // SSE2 is not available on ARM / MIPS, so the performance should be extremely
215 // lower.
216 #if defined(WEBRTC_ARCH_X86_FAMILY)
217 // When hints are enabled, ScreenCapturerDifferWrapper has a slightly better
218 // performance in current configuration, but not so significant. Following is
219 // one run result.
220 // [ RUN ] DISABLED_CaptureWithoutHintsPerf
221 // [ OK ] DISABLED_CaptureWithoutHintsPerf (8889 ms)
222 // [ RUN ] DISABLED_CaptureWithHintsPerf
223 // [ OK ] DISABLED_CaptureWithHintsPerf (7814 ms)
224 // [ RUN ] DISABLED_CaptureWithEnlargedHintsPerf
225 // [ OK ] DISABLED_CaptureWithEnlargedHintsPerf (7999 ms)
226 // [ RUN ] DISABLED_CaptureWithRandomHintsPerf
227 // [ OK ] DISABLED_CaptureWithRandomHintsPerf (8429 ms)
228 // [ RUN ] DISABLED_CaptureWithEnlargedAndRandomHintsPerf
229 // [ OK ] DISABLED_CaptureWithEnlargedAndRandomHintsPerf (8552 ms)
230 TEST(ScreenCapturerDifferWrapperTest, DISABLED_CaptureWithoutHintsPerf) {
231 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
232 return;
233 }
234
235 int64_t started = rtc::TimeMillis();
236 ExecuteDifferWrapperTest(false, false, false, false);
237 ASSERT_LE(rtc::TimeMillis() - started, 15000);
238 }
239
240 TEST(ScreenCapturerDifferWrapperTest, DISABLED_CaptureWithHintsPerf) {
241 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
242 return;
243 }
244
245 int64_t started = rtc::TimeMillis();
246 ExecuteDifferWrapperTest(true, false, false, false);
247 ASSERT_LE(rtc::TimeMillis() - started, 15000);
248 }
249
250 TEST(ScreenCapturerDifferWrapperTest, DISABLED_CaptureWithEnlargedHintsPerf) {
251 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
252 return;
253 }
254
255 int64_t started = rtc::TimeMillis();
256 ExecuteDifferWrapperTest(true, true, false, false);
257 ASSERT_LE(rtc::TimeMillis() - started, 15000);
258 }
259
260 TEST(ScreenCapturerDifferWrapperTest, DISABLED_CaptureWithRandomHintsPerf) {
261 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
262 return;
263 }
264
265 int64_t started = rtc::TimeMillis();
266 ExecuteDifferWrapperTest(true, false, true, false);
267 ASSERT_LE(rtc::TimeMillis() - started, 15000);
268 }
269
270 TEST(ScreenCapturerDifferWrapperTest,
271 DISABLED_CaptureWithEnlargedAndRandomHintsPerf) {
272 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
273 return;
274 }
275
276 int64_t started = rtc::TimeMillis();
277 ExecuteDifferWrapperTest(true, true, true, false);
278 ASSERT_LE(rtc::TimeMillis() - started, 15000);
279 }
280 #endif
281
282 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698