1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/capture/content/capture_resolution_chooser.h"
7 #include "base/location.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 using tracked_objects::Location
;
16 // 16:9 maximum and minimum frame sizes.
17 const int kMaxFrameWidth
= 3840;
18 const int kMaxFrameHeight
= 2160;
19 const int kMinFrameWidth
= 320;
20 const int kMinFrameHeight
= 180;
22 // Checks whether |size| is strictly between (inclusive) |min_size| and
23 // |max_size| and has the same aspect ratio as |max_size|.
24 void ExpectIsWithinBoundsAndSameAspectRatio(const Location
& location
,
25 const gfx::Size
& min_size
,
26 const gfx::Size
& max_size
,
27 const gfx::Size
& size
) {
28 SCOPED_TRACE(::testing::Message() << "From here: " << location
.ToString());
29 EXPECT_LE(min_size
.width(), size
.width());
30 EXPECT_LE(min_size
.height(), size
.height());
31 EXPECT_GE(max_size
.width(), size
.width());
32 EXPECT_GE(max_size
.height(), size
.height());
33 EXPECT_NEAR(static_cast<double>(max_size
.width()) / max_size
.height(),
34 static_cast<double>(size
.width()) / size
.height(), 0.01);
37 // Test that the correct snapped frame sizes are computed for a |chooser|
38 // configured with either of the variable-resolution change policies, and are
39 // correctly found when searched.
40 void TestSnappedFrameSizes(CaptureResolutionChooser
* chooser
,
41 const gfx::Size
& smallest_size
) {
42 const int kSizes
[17][2] = {
43 {kMaxFrameWidth
, kMaxFrameHeight
},
62 const gfx::Size
largest_size(kMaxFrameWidth
, kMaxFrameHeight
);
63 chooser
->SetSourceSize(largest_size
);
65 // There should be no size larger than the largest size.
66 for (int i
= 1; i
< 4; ++i
) {
67 EXPECT_EQ(largest_size
,
68 chooser
->FindLargerFrameSize(largest_size
.GetArea(), i
));
69 EXPECT_EQ(largest_size
,
70 chooser
->FindLargerFrameSize(largest_size
.GetArea() * 2, +i
));
73 // There should be no size smaller than the smallest size.
74 for (int i
= 1; i
< 4; ++i
) {
75 EXPECT_EQ(smallest_size
,
76 chooser
->FindSmallerFrameSize(smallest_size
.GetArea(), i
));
77 EXPECT_EQ(smallest_size
,
78 chooser
->FindSmallerFrameSize(smallest_size
.GetArea() / 2, i
));
81 // Test the "find Nth lower size" logic.
82 for (size_t skips
= 1; skips
< 4; ++skips
) {
83 for (size_t i
= skips
; i
< arraysize(kSizes
); ++i
) {
85 gfx::Size(kSizes
[i
][0], kSizes
[i
][1]),
86 chooser
->FindSmallerFrameSize(
87 gfx::Size(kSizes
[i
- skips
][0], kSizes
[i
- skips
][1]).GetArea(),
92 // Test the "find Nth higher size" logic.
93 for (size_t skips
= 1; skips
< 4; ++skips
) {
94 for (size_t i
= skips
; i
< arraysize(kSizes
); ++i
) {
95 EXPECT_EQ(gfx::Size(kSizes
[i
- skips
][0], kSizes
[i
- skips
][1]),
96 chooser
->FindLargerFrameSize(
97 gfx::Size(kSizes
[i
][0], kSizes
[i
][1]).GetArea(), skips
));
101 // Test the "find nearest size" logic.
102 for (size_t i
= 1; i
< arraysize(kSizes
) - 1; ++i
) {
103 const gfx::Size
size(kSizes
[i
][0], kSizes
[i
][1]);
104 const int a_somewhat_smaller_area
=
105 gfx::Size((kSizes
[i
- 1][0] + 3 * kSizes
[i
][0]) / 4,
106 (kSizes
[i
- 1][1] + 3 * kSizes
[i
][1]) / 4).GetArea();
107 EXPECT_EQ(size
, chooser
->FindNearestFrameSize(a_somewhat_smaller_area
));
109 const int a_smidge_smaller_area
= size
.GetArea() - 1;
110 EXPECT_EQ(size
, chooser
->FindNearestFrameSize(a_smidge_smaller_area
));
112 const int a_smidge_larger_area
= size
.GetArea() + 1;
113 EXPECT_EQ(size
, chooser
->FindNearestFrameSize(a_smidge_larger_area
));
115 const int a_somewhat_larger_area
=
116 gfx::Size((kSizes
[i
+ 1][0] + 3 * kSizes
[i
][0]) / 4,
117 (kSizes
[i
+ 1][1] + 3 * kSizes
[i
][1]) / 4).GetArea();
118 EXPECT_EQ(size
, chooser
->FindNearestFrameSize(a_somewhat_larger_area
));
122 // Test that setting the target frame area results in the correct capture sizes
123 // being computed for a |chooser| configured with either of the
124 // variable-resolution change policies.
125 void TestTargetedFrameAreas(CaptureResolutionChooser
* chooser
,
126 const gfx::Size
& smallest_size
) {
127 chooser
->SetSourceSize(gfx::Size(1280, 720));
129 // The computed capture size cannot be larger than the source size, even
130 // though the |chooser| is configured with a larger max frame size.
131 chooser
->SetTargetFrameArea(kMaxFrameWidth
* kMaxFrameHeight
);
132 EXPECT_EQ(gfx::Size(1280, 720), chooser
->capture_size());
134 chooser
->SetTargetFrameArea(1280 * 720 + 1);
135 EXPECT_EQ(gfx::Size(1280, 720), chooser
->capture_size());
136 chooser
->SetTargetFrameArea(1280 * 720 - 1);
137 EXPECT_EQ(gfx::Size(1280, 720), chooser
->capture_size());
139 chooser
->SetTargetFrameArea(1120 * 630 + 1);
140 EXPECT_EQ(gfx::Size(1120, 630), chooser
->capture_size());
141 chooser
->SetTargetFrameArea(1120 * 630 - 1);
142 EXPECT_EQ(gfx::Size(1120, 630), chooser
->capture_size());
144 chooser
->SetTargetFrameArea(800 * 450 + 1);
145 EXPECT_EQ(gfx::Size(800, 450), chooser
->capture_size());
146 chooser
->SetTargetFrameArea(800 * 450 - 1);
147 EXPECT_EQ(gfx::Size(800, 450), chooser
->capture_size());
149 chooser
->SetTargetFrameArea(640 * 360 + 1);
150 EXPECT_EQ(gfx::Size(640, 360), chooser
->capture_size());
151 chooser
->SetTargetFrameArea(640 * 360 - 1);
152 EXPECT_EQ(gfx::Size(640, 360), chooser
->capture_size());
154 chooser
->SetTargetFrameArea(smallest_size
.GetArea() + 1);
155 EXPECT_EQ(smallest_size
, chooser
->capture_size());
156 chooser
->SetTargetFrameArea(smallest_size
.GetArea() - 1);
157 EXPECT_EQ(smallest_size
, chooser
->capture_size());
159 chooser
->SetTargetFrameArea(smallest_size
.GetArea() / 2);
160 EXPECT_EQ(smallest_size
, chooser
->capture_size());
162 chooser
->SetTargetFrameArea(0);
163 EXPECT_EQ(smallest_size
, chooser
->capture_size());
165 // If the source size has increased, the |chooser| is now permitted to compute
166 // higher capture sizes.
167 chooser
->SetSourceSize(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
));
168 chooser
->SetTargetFrameArea(kMaxFrameWidth
* kMaxFrameHeight
);
169 EXPECT_EQ(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
),
170 chooser
->capture_size());
172 chooser
->SetTargetFrameArea(3200 * 1800 + 1);
173 EXPECT_EQ(gfx::Size(3200, 1800), chooser
->capture_size());
174 chooser
->SetTargetFrameArea(3200 * 1800 - 1);
175 EXPECT_EQ(gfx::Size(3200, 1800), chooser
->capture_size());
177 chooser
->SetTargetFrameArea(640 * 360 + 1);
178 EXPECT_EQ(gfx::Size(640, 360), chooser
->capture_size());
179 chooser
->SetTargetFrameArea(640 * 360 - 1);
180 EXPECT_EQ(gfx::Size(640, 360), chooser
->capture_size());
182 chooser
->SetTargetFrameArea(0);
183 EXPECT_EQ(smallest_size
, chooser
->capture_size());
188 TEST(CaptureResolutionChooserTest
,
189 FixedResolutionPolicy_CaptureSizeAlwaysFixed
) {
190 const gfx::Size
the_one_frame_size(kMaxFrameWidth
, kMaxFrameHeight
);
191 CaptureResolutionChooser
chooser(the_one_frame_size
,
192 RESOLUTION_POLICY_FIXED_RESOLUTION
);
193 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
195 chooser
.SetSourceSize(the_one_frame_size
);
196 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
198 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
+ 424, kMaxFrameHeight
- 101));
199 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
201 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
- 202, kMaxFrameHeight
+ 56));
202 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
204 chooser
.SetSourceSize(gfx::Size(kMinFrameWidth
, kMinFrameHeight
));
205 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
207 // Ensure that there is only one snapped frame size.
208 chooser
.SetSourceSize(the_one_frame_size
);
209 for (int i
= 1; i
< 4; ++i
) {
210 EXPECT_EQ(the_one_frame_size
,
211 chooser
.FindNearestFrameSize(the_one_frame_size
.GetArea() * i
));
212 EXPECT_EQ(the_one_frame_size
,
213 chooser
.FindSmallerFrameSize(the_one_frame_size
.GetArea(), i
));
214 EXPECT_EQ(the_one_frame_size
,
215 chooser
.FindLargerFrameSize(the_one_frame_size
.GetArea(), i
));
218 // Ensure that changing the target frame area does not change the computed
220 chooser
.SetTargetFrameArea(0);
221 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
222 chooser
.SetTargetFrameArea(the_one_frame_size
.GetArea() / 2);
223 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
226 TEST(CaptureResolutionChooserTest
,
227 FixedAspectRatioPolicy_CaptureSizeHasSameAspectRatio
) {
228 CaptureResolutionChooser
chooser(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
),
229 RESOLUTION_POLICY_FIXED_ASPECT_RATIO
);
231 // Starting condition.
232 const gfx::Size
min_size(kMinFrameWidth
, kMinFrameHeight
);
233 const gfx::Size
max_size(kMaxFrameWidth
, kMaxFrameHeight
);
234 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
235 chooser
.capture_size());
237 // Max size in --> max size out.
238 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
));
239 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
240 chooser
.capture_size());
242 // Various source sizes within bounds.
243 chooser
.SetSourceSize(gfx::Size(640, 480));
244 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
245 chooser
.capture_size());
247 chooser
.SetSourceSize(gfx::Size(480, 640));
248 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
249 chooser
.capture_size());
251 chooser
.SetSourceSize(gfx::Size(640, 640));
252 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
253 chooser
.capture_size());
255 // Bad source size results in no update.
256 const gfx::Size unchanged_size
= chooser
.capture_size();
257 chooser
.SetSourceSize(gfx::Size(0, 0));
258 EXPECT_EQ(unchanged_size
, chooser
.capture_size());
260 // Downscaling size (preserving aspect ratio) when source size exceeds the
262 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
* 2, kMaxFrameHeight
* 2));
263 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
264 chooser
.capture_size());
266 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
* 2, kMaxFrameHeight
));
267 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
268 chooser
.capture_size());
270 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
* 2));
271 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
272 chooser
.capture_size());
274 // Upscaling size (preserving aspect ratio) when source size is under the
276 chooser
.SetSourceSize(gfx::Size(kMinFrameWidth
/ 2, kMinFrameHeight
/ 2));
277 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
278 chooser
.capture_size());
280 chooser
.SetSourceSize(gfx::Size(kMinFrameWidth
/ 2, kMaxFrameHeight
));
281 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
282 chooser
.capture_size());
284 chooser
.SetSourceSize(gfx::Size(kMinFrameWidth
, kMinFrameHeight
/ 2));
285 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE
, min_size
, max_size
,
286 chooser
.capture_size());
288 // For a chooser configured with the "fixed aspect ratio" policy, the smallest
289 // possible computed size is the one with 180 lines of resolution and the same
291 const gfx::Size
smallest_size(180 * kMaxFrameWidth
/ kMaxFrameHeight
, 180);
293 TestSnappedFrameSizes(&chooser
, smallest_size
);
294 TestTargetedFrameAreas(&chooser
, smallest_size
);
297 TEST(CaptureResolutionChooserTest
,
298 AnyWithinLimitPolicy_CaptureSizeIsAnythingWithinLimits
) {
299 const gfx::Size
max_size(kMaxFrameWidth
, kMaxFrameHeight
);
300 CaptureResolutionChooser
chooser(max_size
,
301 RESOLUTION_POLICY_ANY_WITHIN_LIMIT
);
303 // Starting condition.
304 EXPECT_EQ(max_size
, chooser
.capture_size());
306 // Max size in --> max size out.
307 chooser
.SetSourceSize(max_size
);
308 EXPECT_EQ(max_size
, chooser
.capture_size());
310 // Various source sizes within bounds.
311 chooser
.SetSourceSize(gfx::Size(640, 480));
312 EXPECT_EQ(gfx::Size(640, 480), chooser
.capture_size());
314 chooser
.SetSourceSize(gfx::Size(480, 640));
315 EXPECT_EQ(gfx::Size(480, 640), chooser
.capture_size());
317 chooser
.SetSourceSize(gfx::Size(640, 640));
318 EXPECT_EQ(gfx::Size(640, 640), chooser
.capture_size());
320 chooser
.SetSourceSize(gfx::Size(2, 2));
321 EXPECT_EQ(gfx::Size(2, 2), chooser
.capture_size());
323 // Bad source size results in no update.
324 const gfx::Size unchanged_size
= chooser
.capture_size();
325 chooser
.SetSourceSize(gfx::Size(0, 0));
326 EXPECT_EQ(unchanged_size
, chooser
.capture_size());
328 // Downscaling size (preserving aspect ratio) when source size exceeds the
330 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
* 2, kMaxFrameHeight
* 2));
331 EXPECT_EQ(max_size
, chooser
.capture_size());
333 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
* 2, kMaxFrameHeight
));
334 EXPECT_EQ(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
/ 2),
335 chooser
.capture_size());
337 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
* 2));
338 EXPECT_EQ(gfx::Size(kMaxFrameWidth
/ 2, kMaxFrameHeight
),
339 chooser
.capture_size());
341 // For a chooser configured with the "any within limit" policy, the smallest
342 // possible computed size is smallest non-empty snapped size (which is 90
343 // lines of resolution) with the same aspect ratio as the maximum size.
344 const gfx::Size
smallest_size(90 * kMaxFrameWidth
/ kMaxFrameHeight
, 90);
346 TestSnappedFrameSizes(&chooser
, smallest_size
);
347 TestTargetedFrameAreas(&chooser
, smallest_size
);