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/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(),
38 // Test that the correct snapped frame sizes are computed for a |chooser|
39 // configured with either of the variable-resolution change policies, and are
40 // correctly found when searched.
41 void TestSnappedFrameSizes(CaptureResolutionChooser
* chooser
,
42 const gfx::Size
& smallest_size
) {
43 const int kSizes
[17][2] = {
44 { kMaxFrameWidth
, kMaxFrameHeight
},
45 { 3520, 1980 }, { 3200, 1800 }, { 2880, 1620}, { 2560, 1440 },
46 { 2240, 1260 }, { 1920, 1080 }, { 1760, 990 }, { 1600, 900 },
47 { 1440, 810 }, { 1280, 720 }, { 1120, 630 }, { 960, 540 },
48 { 800, 450 }, { 640, 360 }, { 480, 270 }, { 320, 180 },
51 const gfx::Size
largest_size(kMaxFrameWidth
, kMaxFrameHeight
);
52 chooser
->SetSourceSize(largest_size
);
54 // There should be no size larger than the largest size.
55 for (int i
= 1; i
< 4; ++i
) {
56 EXPECT_EQ(largest_size
,
57 chooser
->FindLargerFrameSize(largest_size
.GetArea(), i
));
58 EXPECT_EQ(largest_size
,
59 chooser
->FindLargerFrameSize(largest_size
.GetArea() * 2, +i
));
62 // There should be no size smaller than the smallest size.
63 for (int i
= 1; i
< 4; ++i
) {
64 EXPECT_EQ(smallest_size
,
65 chooser
->FindSmallerFrameSize(smallest_size
.GetArea(), i
));
66 EXPECT_EQ(smallest_size
,
67 chooser
->FindSmallerFrameSize(smallest_size
.GetArea() / 2, i
));
70 // Test the "find Nth lower size" logic.
71 for (size_t skips
= 1; skips
< 4; ++skips
) {
72 for (size_t i
= skips
; i
< arraysize(kSizes
); ++i
) {
73 EXPECT_EQ(gfx::Size(kSizes
[i
][0], kSizes
[i
][1]),
74 chooser
->FindSmallerFrameSize(
75 gfx::Size(kSizes
[i
- skips
][0],
76 kSizes
[i
- skips
][1]).GetArea(),
81 // Test the "find Nth higher size" logic.
82 for (size_t skips
= 1; skips
< 4; ++skips
) {
83 for (size_t i
= skips
; i
< arraysize(kSizes
); ++i
) {
84 EXPECT_EQ(gfx::Size(kSizes
[i
- skips
][0], kSizes
[i
- skips
][1]),
85 chooser
->FindLargerFrameSize(
86 gfx::Size(kSizes
[i
][0], kSizes
[i
][1]).GetArea(),
91 // Test the "find nearest size" logic.
92 for (size_t i
= 1; i
< arraysize(kSizes
) - 1; ++i
) {
93 const gfx::Size
size(kSizes
[i
][0], kSizes
[i
][1]);
94 const int a_somewhat_smaller_area
=
95 gfx::Size((kSizes
[i
- 1][0] + 3 * kSizes
[i
][0]) / 4,
96 (kSizes
[i
- 1][1] + 3 * kSizes
[i
][1]) / 4).GetArea();
97 EXPECT_EQ(size
, chooser
->FindNearestFrameSize(a_somewhat_smaller_area
));
99 const int a_smidge_smaller_area
= size
.GetArea() - 1;
100 EXPECT_EQ(size
, chooser
->FindNearestFrameSize(a_smidge_smaller_area
));
102 const int a_smidge_larger_area
= size
.GetArea() + 1;
103 EXPECT_EQ(size
, chooser
->FindNearestFrameSize(a_smidge_larger_area
));
105 const int a_somewhat_larger_area
=
106 gfx::Size((kSizes
[i
+ 1][0] + 3 * kSizes
[i
][0]) / 4,
107 (kSizes
[i
+ 1][1] + 3 * kSizes
[i
][1]) / 4).GetArea();
108 EXPECT_EQ(size
, chooser
->FindNearestFrameSize(a_somewhat_larger_area
));
112 // Test that setting the target frame area results in the correct capture sizes
113 // being computed for a |chooser| configured with either of the
114 // variable-resolution change policies.
115 void TestTargetedFrameAreas(CaptureResolutionChooser
* chooser
,
116 const gfx::Size
& smallest_size
) {
117 chooser
->SetSourceSize(gfx::Size(1280, 720));
119 // The computed capture size cannot be larger than the source size, even
120 // though the |chooser| is configured with a larger max frame size.
121 chooser
->SetTargetFrameArea(kMaxFrameWidth
* kMaxFrameHeight
);
122 EXPECT_EQ(gfx::Size(1280, 720), chooser
->capture_size());
124 chooser
->SetTargetFrameArea(1280 * 720 + 1);
125 EXPECT_EQ(gfx::Size(1280, 720), chooser
->capture_size());
126 chooser
->SetTargetFrameArea(1280 * 720 - 1);
127 EXPECT_EQ(gfx::Size(1280, 720), chooser
->capture_size());
129 chooser
->SetTargetFrameArea(1120 * 630 + 1);
130 EXPECT_EQ(gfx::Size(1120, 630), chooser
->capture_size());
131 chooser
->SetTargetFrameArea(1120 * 630 - 1);
132 EXPECT_EQ(gfx::Size(1120, 630), chooser
->capture_size());
134 chooser
->SetTargetFrameArea(800 * 450 + 1);
135 EXPECT_EQ(gfx::Size(800, 450), chooser
->capture_size());
136 chooser
->SetTargetFrameArea(800 * 450 - 1);
137 EXPECT_EQ(gfx::Size(800, 450), chooser
->capture_size());
139 chooser
->SetTargetFrameArea(640 * 360 + 1);
140 EXPECT_EQ(gfx::Size(640, 360), chooser
->capture_size());
141 chooser
->SetTargetFrameArea(640 * 360 - 1);
142 EXPECT_EQ(gfx::Size(640, 360), chooser
->capture_size());
144 chooser
->SetTargetFrameArea(smallest_size
.GetArea() + 1);
145 EXPECT_EQ(smallest_size
, chooser
->capture_size());
146 chooser
->SetTargetFrameArea(smallest_size
.GetArea() - 1);
147 EXPECT_EQ(smallest_size
, chooser
->capture_size());
149 chooser
->SetTargetFrameArea(smallest_size
.GetArea() / 2);
150 EXPECT_EQ(smallest_size
, chooser
->capture_size());
152 chooser
->SetTargetFrameArea(0);
153 EXPECT_EQ(smallest_size
, chooser
->capture_size());
155 // If the source size has increased, the |chooser| is now permitted to compute
156 // higher capture sizes.
157 chooser
->SetSourceSize(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
));
158 chooser
->SetTargetFrameArea(kMaxFrameWidth
* kMaxFrameHeight
);
159 EXPECT_EQ(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
),
160 chooser
->capture_size());
162 chooser
->SetTargetFrameArea(3200 * 1800 + 1);
163 EXPECT_EQ(gfx::Size(3200, 1800), chooser
->capture_size());
164 chooser
->SetTargetFrameArea(3200 * 1800 - 1);
165 EXPECT_EQ(gfx::Size(3200, 1800), chooser
->capture_size());
167 chooser
->SetTargetFrameArea(640 * 360 + 1);
168 EXPECT_EQ(gfx::Size(640, 360), chooser
->capture_size());
169 chooser
->SetTargetFrameArea(640 * 360 - 1);
170 EXPECT_EQ(gfx::Size(640, 360), chooser
->capture_size());
172 chooser
->SetTargetFrameArea(0);
173 EXPECT_EQ(smallest_size
, chooser
->capture_size());
178 TEST(CaptureResolutionChooserTest
,
179 FixedResolutionPolicy_CaptureSizeAlwaysFixed
) {
180 const gfx::Size
the_one_frame_size(kMaxFrameWidth
, kMaxFrameHeight
);
181 CaptureResolutionChooser
chooser(the_one_frame_size
,
182 RESOLUTION_POLICY_FIXED_RESOLUTION
);
183 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
185 chooser
.SetSourceSize(the_one_frame_size
);
186 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
188 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
+ 424, kMaxFrameHeight
- 101));
189 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
191 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
- 202, kMaxFrameHeight
+ 56));
192 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
194 chooser
.SetSourceSize(gfx::Size(kMinFrameWidth
, kMinFrameHeight
));
195 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
197 // Ensure that there is only one snapped frame size.
198 chooser
.SetSourceSize(the_one_frame_size
);
199 for (int i
= 1; i
< 4; ++i
) {
200 EXPECT_EQ(the_one_frame_size
,
201 chooser
.FindNearestFrameSize(the_one_frame_size
.GetArea() * i
));
202 EXPECT_EQ(the_one_frame_size
,
203 chooser
.FindSmallerFrameSize(the_one_frame_size
.GetArea(), i
));
204 EXPECT_EQ(the_one_frame_size
,
205 chooser
.FindLargerFrameSize(the_one_frame_size
.GetArea(), i
));
208 // Ensure that changing the target frame area does not change the computed
210 chooser
.SetTargetFrameArea(0);
211 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
212 chooser
.SetTargetFrameArea(the_one_frame_size
.GetArea() / 2);
213 EXPECT_EQ(the_one_frame_size
, chooser
.capture_size());
216 TEST(CaptureResolutionChooserTest
,
217 FixedAspectRatioPolicy_CaptureSizeHasSameAspectRatio
) {
218 CaptureResolutionChooser
chooser(
219 gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
),
220 RESOLUTION_POLICY_FIXED_ASPECT_RATIO
);
222 // Starting condition.
223 const gfx::Size
min_size(kMinFrameWidth
, kMinFrameHeight
);
224 const gfx::Size
max_size(kMaxFrameWidth
, kMaxFrameHeight
);
225 ExpectIsWithinBoundsAndSameAspectRatio(
226 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
228 // Max size in --> max size out.
229 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
));
230 ExpectIsWithinBoundsAndSameAspectRatio(
231 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
233 // Various source sizes within bounds.
234 chooser
.SetSourceSize(gfx::Size(640, 480));
235 ExpectIsWithinBoundsAndSameAspectRatio(
236 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
238 chooser
.SetSourceSize(gfx::Size(480, 640));
239 ExpectIsWithinBoundsAndSameAspectRatio(
240 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
242 chooser
.SetSourceSize(gfx::Size(640, 640));
243 ExpectIsWithinBoundsAndSameAspectRatio(
244 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
246 // Bad source size results in no update.
247 const gfx::Size unchanged_size
= chooser
.capture_size();
248 chooser
.SetSourceSize(gfx::Size(0, 0));
249 EXPECT_EQ(unchanged_size
, chooser
.capture_size());
251 // Downscaling size (preserving aspect ratio) when source size exceeds the
253 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
* 2, kMaxFrameHeight
* 2));
254 ExpectIsWithinBoundsAndSameAspectRatio(
255 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
257 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
* 2, kMaxFrameHeight
));
258 ExpectIsWithinBoundsAndSameAspectRatio(
259 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
261 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
* 2));
262 ExpectIsWithinBoundsAndSameAspectRatio(
263 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
265 // Upscaling size (preserving aspect ratio) when source size is under the
267 chooser
.SetSourceSize(gfx::Size(kMinFrameWidth
/ 2, kMinFrameHeight
/ 2));
268 ExpectIsWithinBoundsAndSameAspectRatio(
269 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
271 chooser
.SetSourceSize(gfx::Size(kMinFrameWidth
/ 2, kMaxFrameHeight
));
272 ExpectIsWithinBoundsAndSameAspectRatio(
273 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
275 chooser
.SetSourceSize(gfx::Size(kMinFrameWidth
, kMinFrameHeight
/ 2));
276 ExpectIsWithinBoundsAndSameAspectRatio(
277 FROM_HERE
, min_size
, max_size
, chooser
.capture_size());
279 // For a chooser configured with the "fixed aspect ratio" policy, the smallest
280 // possible computed size is the one with 180 lines of resolution and the same
282 const gfx::Size
smallest_size(180 * kMaxFrameWidth
/ kMaxFrameHeight
, 180);
284 TestSnappedFrameSizes(&chooser
, smallest_size
);
285 TestTargetedFrameAreas(&chooser
, smallest_size
);
288 TEST(CaptureResolutionChooserTest
,
289 AnyWithinLimitPolicy_CaptureSizeIsAnythingWithinLimits
) {
290 const gfx::Size
max_size(kMaxFrameWidth
, kMaxFrameHeight
);
291 CaptureResolutionChooser
chooser(
292 max_size
, RESOLUTION_POLICY_ANY_WITHIN_LIMIT
);
294 // Starting condition.
295 EXPECT_EQ(max_size
, chooser
.capture_size());
297 // Max size in --> max size out.
298 chooser
.SetSourceSize(max_size
);
299 EXPECT_EQ(max_size
, chooser
.capture_size());
301 // Various source sizes within bounds.
302 chooser
.SetSourceSize(gfx::Size(640, 480));
303 EXPECT_EQ(gfx::Size(640, 480), chooser
.capture_size());
305 chooser
.SetSourceSize(gfx::Size(480, 640));
306 EXPECT_EQ(gfx::Size(480, 640), chooser
.capture_size());
308 chooser
.SetSourceSize(gfx::Size(640, 640));
309 EXPECT_EQ(gfx::Size(640, 640), chooser
.capture_size());
311 chooser
.SetSourceSize(gfx::Size(2, 2));
312 EXPECT_EQ(gfx::Size(2, 2), chooser
.capture_size());
314 // Bad source size results in no update.
315 const gfx::Size unchanged_size
= chooser
.capture_size();
316 chooser
.SetSourceSize(gfx::Size(0, 0));
317 EXPECT_EQ(unchanged_size
, chooser
.capture_size());
319 // Downscaling size (preserving aspect ratio) when source size exceeds the
321 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
* 2, kMaxFrameHeight
* 2));
322 EXPECT_EQ(max_size
, chooser
.capture_size());
324 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
* 2, kMaxFrameHeight
));
325 EXPECT_EQ(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
/ 2),
326 chooser
.capture_size());
328 chooser
.SetSourceSize(gfx::Size(kMaxFrameWidth
, kMaxFrameHeight
* 2));
329 EXPECT_EQ(gfx::Size(kMaxFrameWidth
/ 2, kMaxFrameHeight
),
330 chooser
.capture_size());
332 // For a chooser configured with the "any within limit" policy, the smallest
333 // possible computed size is smallest non-empty snapped size (which is 90
334 // lines of resolution) with the same aspect ratio as the maximum size.
335 const gfx::Size
smallest_size(90 * kMaxFrameWidth
/ kMaxFrameHeight
, 90);
337 TestSnappedFrameSizes(&chooser
, smallest_size
);
338 TestTargetedFrameAreas(&chooser
, smallest_size
);