| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "media/capture/content/capture_resolution_chooser.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include "base/location.h" | |
| 10 #include "base/macros.h" | |
| 11 #include "testing/gtest/include/gtest/gtest.h" | |
| 12 | |
| 13 using tracked_objects::Location; | |
| 14 | |
| 15 namespace media { | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 // 16:9 maximum and minimum frame sizes. | |
| 20 const int kMaxFrameWidth = 3840; | |
| 21 const int kMaxFrameHeight = 2160; | |
| 22 const int kMinFrameWidth = 320; | |
| 23 const int kMinFrameHeight = 180; | |
| 24 | |
| 25 // Checks whether |size| is strictly between (inclusive) |min_size| and | |
| 26 // |max_size| and has the same aspect ratio as |max_size|. | |
| 27 void ExpectIsWithinBoundsAndSameAspectRatio(const Location& location, | |
| 28 const gfx::Size& min_size, | |
| 29 const gfx::Size& max_size, | |
| 30 const gfx::Size& size) { | |
| 31 SCOPED_TRACE(::testing::Message() << "From here: " << location.ToString()); | |
| 32 EXPECT_LE(min_size.width(), size.width()); | |
| 33 EXPECT_LE(min_size.height(), size.height()); | |
| 34 EXPECT_GE(max_size.width(), size.width()); | |
| 35 EXPECT_GE(max_size.height(), size.height()); | |
| 36 EXPECT_NEAR(static_cast<double>(max_size.width()) / max_size.height(), | |
| 37 static_cast<double>(size.width()) / size.height(), 0.01); | |
| 38 } | |
| 39 | |
| 40 // Test that the correct snapped frame sizes are computed for a |chooser| | |
| 41 // configured with either of the variable-resolution change policies, and are | |
| 42 // correctly found when searched. | |
| 43 void TestSnappedFrameSizes(CaptureResolutionChooser* chooser, | |
| 44 const gfx::Size& smallest_size) { | |
| 45 const int kSizes[17][2] = { | |
| 46 {kMaxFrameWidth, kMaxFrameHeight}, | |
| 47 {3520, 1980}, | |
| 48 {3200, 1800}, | |
| 49 {2880, 1620}, | |
| 50 {2560, 1440}, | |
| 51 {2240, 1260}, | |
| 52 {1920, 1080}, | |
| 53 {1760, 990}, | |
| 54 {1600, 900}, | |
| 55 {1440, 810}, | |
| 56 {1280, 720}, | |
| 57 {1120, 630}, | |
| 58 {960, 540}, | |
| 59 {800, 450}, | |
| 60 {640, 360}, | |
| 61 {480, 270}, | |
| 62 {320, 180}, | |
| 63 }; | |
| 64 | |
| 65 const gfx::Size largest_size(kMaxFrameWidth, kMaxFrameHeight); | |
| 66 chooser->SetSourceSize(largest_size); | |
| 67 | |
| 68 // There should be no size larger than the largest size. | |
| 69 for (int i = 1; i < 4; ++i) { | |
| 70 EXPECT_EQ(largest_size, | |
| 71 chooser->FindLargerFrameSize(largest_size.GetArea(), i)); | |
| 72 EXPECT_EQ(largest_size, | |
| 73 chooser->FindLargerFrameSize(largest_size.GetArea() * 2, +i)); | |
| 74 } | |
| 75 | |
| 76 // There should be no size smaller than the smallest size. | |
| 77 for (int i = 1; i < 4; ++i) { | |
| 78 EXPECT_EQ(smallest_size, | |
| 79 chooser->FindSmallerFrameSize(smallest_size.GetArea(), i)); | |
| 80 EXPECT_EQ(smallest_size, | |
| 81 chooser->FindSmallerFrameSize(smallest_size.GetArea() / 2, i)); | |
| 82 } | |
| 83 | |
| 84 // Test the "find Nth lower size" logic. | |
| 85 for (size_t skips = 1; skips < 4; ++skips) { | |
| 86 for (size_t i = skips; i < arraysize(kSizes); ++i) { | |
| 87 EXPECT_EQ( | |
| 88 gfx::Size(kSizes[i][0], kSizes[i][1]), | |
| 89 chooser->FindSmallerFrameSize( | |
| 90 gfx::Size(kSizes[i - skips][0], kSizes[i - skips][1]).GetArea(), | |
| 91 skips)); | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 // Test the "find Nth higher size" logic. | |
| 96 for (size_t skips = 1; skips < 4; ++skips) { | |
| 97 for (size_t i = skips; i < arraysize(kSizes); ++i) { | |
| 98 EXPECT_EQ(gfx::Size(kSizes[i - skips][0], kSizes[i - skips][1]), | |
| 99 chooser->FindLargerFrameSize( | |
| 100 gfx::Size(kSizes[i][0], kSizes[i][1]).GetArea(), skips)); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 // Test the "find nearest size" logic. | |
| 105 for (size_t i = 1; i < arraysize(kSizes) - 1; ++i) { | |
| 106 const gfx::Size size(kSizes[i][0], kSizes[i][1]); | |
| 107 const int a_somewhat_smaller_area = | |
| 108 gfx::Size((kSizes[i - 1][0] + 3 * kSizes[i][0]) / 4, | |
| 109 (kSizes[i - 1][1] + 3 * kSizes[i][1]) / 4).GetArea(); | |
| 110 EXPECT_EQ(size, chooser->FindNearestFrameSize(a_somewhat_smaller_area)); | |
| 111 | |
| 112 const int a_smidge_smaller_area = size.GetArea() - 1; | |
| 113 EXPECT_EQ(size, chooser->FindNearestFrameSize(a_smidge_smaller_area)); | |
| 114 | |
| 115 const int a_smidge_larger_area = size.GetArea() + 1; | |
| 116 EXPECT_EQ(size, chooser->FindNearestFrameSize(a_smidge_larger_area)); | |
| 117 | |
| 118 const int a_somewhat_larger_area = | |
| 119 gfx::Size((kSizes[i + 1][0] + 3 * kSizes[i][0]) / 4, | |
| 120 (kSizes[i + 1][1] + 3 * kSizes[i][1]) / 4).GetArea(); | |
| 121 EXPECT_EQ(size, chooser->FindNearestFrameSize(a_somewhat_larger_area)); | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 // Test that setting the target frame area results in the correct capture sizes | |
| 126 // being computed for a |chooser| configured with either of the | |
| 127 // variable-resolution change policies. | |
| 128 void TestTargetedFrameAreas(CaptureResolutionChooser* chooser, | |
| 129 const gfx::Size& smallest_size) { | |
| 130 chooser->SetSourceSize(gfx::Size(1280, 720)); | |
| 131 | |
| 132 // The computed capture size cannot be larger than the source size, even | |
| 133 // though the |chooser| is configured with a larger max frame size. | |
| 134 chooser->SetTargetFrameArea(kMaxFrameWidth * kMaxFrameHeight); | |
| 135 EXPECT_EQ(gfx::Size(1280, 720), chooser->capture_size()); | |
| 136 | |
| 137 chooser->SetTargetFrameArea(1280 * 720 + 1); | |
| 138 EXPECT_EQ(gfx::Size(1280, 720), chooser->capture_size()); | |
| 139 chooser->SetTargetFrameArea(1280 * 720 - 1); | |
| 140 EXPECT_EQ(gfx::Size(1280, 720), chooser->capture_size()); | |
| 141 | |
| 142 chooser->SetTargetFrameArea(1120 * 630 + 1); | |
| 143 EXPECT_EQ(gfx::Size(1120, 630), chooser->capture_size()); | |
| 144 chooser->SetTargetFrameArea(1120 * 630 - 1); | |
| 145 EXPECT_EQ(gfx::Size(1120, 630), chooser->capture_size()); | |
| 146 | |
| 147 chooser->SetTargetFrameArea(800 * 450 + 1); | |
| 148 EXPECT_EQ(gfx::Size(800, 450), chooser->capture_size()); | |
| 149 chooser->SetTargetFrameArea(800 * 450 - 1); | |
| 150 EXPECT_EQ(gfx::Size(800, 450), chooser->capture_size()); | |
| 151 | |
| 152 chooser->SetTargetFrameArea(640 * 360 + 1); | |
| 153 EXPECT_EQ(gfx::Size(640, 360), chooser->capture_size()); | |
| 154 chooser->SetTargetFrameArea(640 * 360 - 1); | |
| 155 EXPECT_EQ(gfx::Size(640, 360), chooser->capture_size()); | |
| 156 | |
| 157 chooser->SetTargetFrameArea(smallest_size.GetArea() + 1); | |
| 158 EXPECT_EQ(smallest_size, chooser->capture_size()); | |
| 159 chooser->SetTargetFrameArea(smallest_size.GetArea() - 1); | |
| 160 EXPECT_EQ(smallest_size, chooser->capture_size()); | |
| 161 | |
| 162 chooser->SetTargetFrameArea(smallest_size.GetArea() / 2); | |
| 163 EXPECT_EQ(smallest_size, chooser->capture_size()); | |
| 164 | |
| 165 chooser->SetTargetFrameArea(0); | |
| 166 EXPECT_EQ(smallest_size, chooser->capture_size()); | |
| 167 | |
| 168 // If the source size has increased, the |chooser| is now permitted to compute | |
| 169 // higher capture sizes. | |
| 170 chooser->SetSourceSize(gfx::Size(kMaxFrameWidth, kMaxFrameHeight)); | |
| 171 chooser->SetTargetFrameArea(kMaxFrameWidth * kMaxFrameHeight); | |
| 172 EXPECT_EQ(gfx::Size(kMaxFrameWidth, kMaxFrameHeight), | |
| 173 chooser->capture_size()); | |
| 174 | |
| 175 chooser->SetTargetFrameArea(3200 * 1800 + 1); | |
| 176 EXPECT_EQ(gfx::Size(3200, 1800), chooser->capture_size()); | |
| 177 chooser->SetTargetFrameArea(3200 * 1800 - 1); | |
| 178 EXPECT_EQ(gfx::Size(3200, 1800), chooser->capture_size()); | |
| 179 | |
| 180 chooser->SetTargetFrameArea(640 * 360 + 1); | |
| 181 EXPECT_EQ(gfx::Size(640, 360), chooser->capture_size()); | |
| 182 chooser->SetTargetFrameArea(640 * 360 - 1); | |
| 183 EXPECT_EQ(gfx::Size(640, 360), chooser->capture_size()); | |
| 184 | |
| 185 chooser->SetTargetFrameArea(0); | |
| 186 EXPECT_EQ(smallest_size, chooser->capture_size()); | |
| 187 } | |
| 188 | |
| 189 } // namespace | |
| 190 | |
| 191 TEST(CaptureResolutionChooserTest, | |
| 192 FixedResolutionPolicy_CaptureSizeAlwaysFixed) { | |
| 193 const gfx::Size the_one_frame_size(kMaxFrameWidth, kMaxFrameHeight); | |
| 194 CaptureResolutionChooser chooser(the_one_frame_size, | |
| 195 RESOLUTION_POLICY_FIXED_RESOLUTION); | |
| 196 EXPECT_EQ(the_one_frame_size, chooser.capture_size()); | |
| 197 | |
| 198 chooser.SetSourceSize(the_one_frame_size); | |
| 199 EXPECT_EQ(the_one_frame_size, chooser.capture_size()); | |
| 200 | |
| 201 chooser.SetSourceSize(gfx::Size(kMaxFrameWidth + 424, kMaxFrameHeight - 101)); | |
| 202 EXPECT_EQ(the_one_frame_size, chooser.capture_size()); | |
| 203 | |
| 204 chooser.SetSourceSize(gfx::Size(kMaxFrameWidth - 202, kMaxFrameHeight + 56)); | |
| 205 EXPECT_EQ(the_one_frame_size, chooser.capture_size()); | |
| 206 | |
| 207 chooser.SetSourceSize(gfx::Size(kMinFrameWidth, kMinFrameHeight)); | |
| 208 EXPECT_EQ(the_one_frame_size, chooser.capture_size()); | |
| 209 | |
| 210 // Ensure that there is only one snapped frame size. | |
| 211 chooser.SetSourceSize(the_one_frame_size); | |
| 212 for (int i = 1; i < 4; ++i) { | |
| 213 EXPECT_EQ(the_one_frame_size, | |
| 214 chooser.FindNearestFrameSize(the_one_frame_size.GetArea() * i)); | |
| 215 EXPECT_EQ(the_one_frame_size, | |
| 216 chooser.FindSmallerFrameSize(the_one_frame_size.GetArea(), i)); | |
| 217 EXPECT_EQ(the_one_frame_size, | |
| 218 chooser.FindLargerFrameSize(the_one_frame_size.GetArea(), i)); | |
| 219 } | |
| 220 | |
| 221 // Ensure that changing the target frame area does not change the computed | |
| 222 // frame size. | |
| 223 chooser.SetTargetFrameArea(0); | |
| 224 EXPECT_EQ(the_one_frame_size, chooser.capture_size()); | |
| 225 chooser.SetTargetFrameArea(the_one_frame_size.GetArea() / 2); | |
| 226 EXPECT_EQ(the_one_frame_size, chooser.capture_size()); | |
| 227 } | |
| 228 | |
| 229 TEST(CaptureResolutionChooserTest, | |
| 230 FixedAspectRatioPolicy_CaptureSizeHasSameAspectRatio) { | |
| 231 CaptureResolutionChooser chooser(gfx::Size(kMaxFrameWidth, kMaxFrameHeight), | |
| 232 RESOLUTION_POLICY_FIXED_ASPECT_RATIO); | |
| 233 | |
| 234 // Starting condition. | |
| 235 const gfx::Size min_size(kMinFrameWidth, kMinFrameHeight); | |
| 236 const gfx::Size max_size(kMaxFrameWidth, kMaxFrameHeight); | |
| 237 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 238 chooser.capture_size()); | |
| 239 | |
| 240 // Max size in --> max size out. | |
| 241 chooser.SetSourceSize(gfx::Size(kMaxFrameWidth, kMaxFrameHeight)); | |
| 242 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 243 chooser.capture_size()); | |
| 244 | |
| 245 // Various source sizes within bounds. | |
| 246 chooser.SetSourceSize(gfx::Size(640, 480)); | |
| 247 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 248 chooser.capture_size()); | |
| 249 | |
| 250 chooser.SetSourceSize(gfx::Size(480, 640)); | |
| 251 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 252 chooser.capture_size()); | |
| 253 | |
| 254 chooser.SetSourceSize(gfx::Size(640, 640)); | |
| 255 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 256 chooser.capture_size()); | |
| 257 | |
| 258 // Bad source size results in no update. | |
| 259 const gfx::Size unchanged_size = chooser.capture_size(); | |
| 260 chooser.SetSourceSize(gfx::Size(0, 0)); | |
| 261 EXPECT_EQ(unchanged_size, chooser.capture_size()); | |
| 262 | |
| 263 // Downscaling size (preserving aspect ratio) when source size exceeds the | |
| 264 // upper bounds. | |
| 265 chooser.SetSourceSize(gfx::Size(kMaxFrameWidth * 2, kMaxFrameHeight * 2)); | |
| 266 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 267 chooser.capture_size()); | |
| 268 | |
| 269 chooser.SetSourceSize(gfx::Size(kMaxFrameWidth * 2, kMaxFrameHeight)); | |
| 270 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 271 chooser.capture_size()); | |
| 272 | |
| 273 chooser.SetSourceSize(gfx::Size(kMaxFrameWidth, kMaxFrameHeight * 2)); | |
| 274 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 275 chooser.capture_size()); | |
| 276 | |
| 277 // Upscaling size (preserving aspect ratio) when source size is under the | |
| 278 // lower bounds. | |
| 279 chooser.SetSourceSize(gfx::Size(kMinFrameWidth / 2, kMinFrameHeight / 2)); | |
| 280 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 281 chooser.capture_size()); | |
| 282 | |
| 283 chooser.SetSourceSize(gfx::Size(kMinFrameWidth / 2, kMaxFrameHeight)); | |
| 284 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 285 chooser.capture_size()); | |
| 286 | |
| 287 chooser.SetSourceSize(gfx::Size(kMinFrameWidth, kMinFrameHeight / 2)); | |
| 288 ExpectIsWithinBoundsAndSameAspectRatio(FROM_HERE, min_size, max_size, | |
| 289 chooser.capture_size()); | |
| 290 | |
| 291 // For a chooser configured with the "fixed aspect ratio" policy, the smallest | |
| 292 // possible computed size is the one with 180 lines of resolution and the same | |
| 293 // aspect ratio. | |
| 294 const gfx::Size smallest_size(180 * kMaxFrameWidth / kMaxFrameHeight, 180); | |
| 295 | |
| 296 TestSnappedFrameSizes(&chooser, smallest_size); | |
| 297 TestTargetedFrameAreas(&chooser, smallest_size); | |
| 298 } | |
| 299 | |
| 300 TEST(CaptureResolutionChooserTest, | |
| 301 AnyWithinLimitPolicy_CaptureSizeIsAnythingWithinLimits) { | |
| 302 const gfx::Size max_size(kMaxFrameWidth, kMaxFrameHeight); | |
| 303 CaptureResolutionChooser chooser(max_size, | |
| 304 RESOLUTION_POLICY_ANY_WITHIN_LIMIT); | |
| 305 | |
| 306 // Starting condition. | |
| 307 EXPECT_EQ(max_size, chooser.capture_size()); | |
| 308 | |
| 309 // Max size in --> max size out. | |
| 310 chooser.SetSourceSize(max_size); | |
| 311 EXPECT_EQ(max_size, chooser.capture_size()); | |
| 312 | |
| 313 // Various source sizes within bounds. | |
| 314 chooser.SetSourceSize(gfx::Size(640, 480)); | |
| 315 EXPECT_EQ(gfx::Size(640, 480), chooser.capture_size()); | |
| 316 | |
| 317 chooser.SetSourceSize(gfx::Size(480, 640)); | |
| 318 EXPECT_EQ(gfx::Size(480, 640), chooser.capture_size()); | |
| 319 | |
| 320 chooser.SetSourceSize(gfx::Size(640, 640)); | |
| 321 EXPECT_EQ(gfx::Size(640, 640), chooser.capture_size()); | |
| 322 | |
| 323 chooser.SetSourceSize(gfx::Size(2, 2)); | |
| 324 EXPECT_EQ(gfx::Size(2, 2), chooser.capture_size()); | |
| 325 | |
| 326 // Bad source size results in no update. | |
| 327 const gfx::Size unchanged_size = chooser.capture_size(); | |
| 328 chooser.SetSourceSize(gfx::Size(0, 0)); | |
| 329 EXPECT_EQ(unchanged_size, chooser.capture_size()); | |
| 330 | |
| 331 // Downscaling size (preserving aspect ratio) when source size exceeds the | |
| 332 // upper bounds. | |
| 333 chooser.SetSourceSize(gfx::Size(kMaxFrameWidth * 2, kMaxFrameHeight * 2)); | |
| 334 EXPECT_EQ(max_size, chooser.capture_size()); | |
| 335 | |
| 336 chooser.SetSourceSize(gfx::Size(kMaxFrameWidth * 2, kMaxFrameHeight)); | |
| 337 EXPECT_EQ(gfx::Size(kMaxFrameWidth, kMaxFrameHeight / 2), | |
| 338 chooser.capture_size()); | |
| 339 | |
| 340 chooser.SetSourceSize(gfx::Size(kMaxFrameWidth, kMaxFrameHeight * 2)); | |
| 341 EXPECT_EQ(gfx::Size(kMaxFrameWidth / 2, kMaxFrameHeight), | |
| 342 chooser.capture_size()); | |
| 343 | |
| 344 // For a chooser configured with the "any within limit" policy, the smallest | |
| 345 // possible computed size is smallest non-empty snapped size (which is 90 | |
| 346 // lines of resolution) with the same aspect ratio as the maximum size. | |
| 347 const gfx::Size smallest_size(90 * kMaxFrameWidth / kMaxFrameHeight, 90); | |
| 348 | |
| 349 TestSnappedFrameSizes(&chooser, smallest_size); | |
| 350 TestTargetedFrameAreas(&chooser, smallest_size); | |
| 351 } | |
| 352 | |
| 353 } // namespace media | |
| OLD | NEW |