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

Side by Side Diff: content/renderer/media/media_stream_constraints_util_video_source_unittest.cc

Issue 2668023002: Spec-compatible algorithm for selecting video source and settings. (Closed)
Patch Set: remove public kDefaultFailedConstraintName. Use empty string instead. Created 3 years, 10 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 // Copyright 2017 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 "content/renderer/media/media_stream_constraints_util_video_source.h"
6
7 #include <algorithm>
8 #include <utility>
9
10 #include "base/optional.h"
11 #include "content/renderer/media/media_stream_video_source.h"
12 #include "content/renderer/media/mock_constraint_factory.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
15
16 namespace content {
17
18 namespace {
19
20 const char kDeviceID1[] = "fake_device_1";
21 const char kDeviceID2[] = "fake_device_2";
22 const char kDeviceID3[] = "fake_device_3";
23 }
24
25 class MediaStreamConstraintsUtilVideoSourceTest : public testing::Test {
26 public:
27 void SetUp() override {
28 ::mojom::VideoInputDeviceCapabilitiesPtr device =
29 ::mojom::VideoInputDeviceCapabilities::New();
30 device->device_id = kDeviceID1;
31 device->facing_mode = ::mojom::FacingMode::NONE;
32 device->formats = {
33 media::VideoCaptureFormat(gfx::Size(200, 200), 40.0f,
34 media::PIXEL_FORMAT_I420),
35 // This entry is is the closest to defaults.
36 media::VideoCaptureFormat(gfx::Size(500, 500), 40.0f,
37 media::PIXEL_FORMAT_I420),
38 media::VideoCaptureFormat(gfx::Size(1000, 1000), 20.0f,
39 media::PIXEL_FORMAT_I420),
40 };
41 capabilities_.device_capabilities.push_back(std::move(device));
42
43 device = ::mojom::VideoInputDeviceCapabilities::New();
44 device->device_id = kDeviceID2;
45 device->facing_mode = ::mojom::FacingMode::ENVIRONMENT;
46 device->formats = {
47 media::VideoCaptureFormat(gfx::Size(40, 30), 20.0f,
48 media::PIXEL_FORMAT_I420),
49 media::VideoCaptureFormat(gfx::Size(320, 240), 30.0f,
50 media::PIXEL_FORMAT_I420),
51 // This format has defaults for all settings
52 media::VideoCaptureFormat(
53 gfx::Size(MediaStreamVideoSource::kDefaultWidth,
54 MediaStreamVideoSource::kDefaultHeight),
55 MediaStreamVideoSource::kDefaultFrameRate,
56 media::PIXEL_FORMAT_I420),
57 media::VideoCaptureFormat(gfx::Size(800, 600), 20.0f,
58 media::PIXEL_FORMAT_I420),
59 };
60 capabilities_.device_capabilities.push_back(std::move(device));
61
62 device = ::mojom::VideoInputDeviceCapabilities::New();
63 device->device_id = kDeviceID3;
64 device->facing_mode = ::mojom::FacingMode::USER;
65 device->formats = {
66 media::VideoCaptureFormat(gfx::Size(320, 240), 10.0f,
67 media::PIXEL_FORMAT_I420),
68 media::VideoCaptureFormat(gfx::Size(640, 480), 10.0f,
69 media::PIXEL_FORMAT_I420),
70 // This format has defaults for all settings
71 media::VideoCaptureFormat(
72 gfx::Size(MediaStreamVideoSource::kDefaultWidth,
73 MediaStreamVideoSource::kDefaultHeight),
74 MediaStreamVideoSource::kDefaultFrameRate,
75 media::PIXEL_FORMAT_I420),
76 media::VideoCaptureFormat(gfx::Size(1280, 720), 60.0f,
77 media::PIXEL_FORMAT_I420),
78 media::VideoCaptureFormat(gfx::Size(1920, 1080), 60.0f,
79 media::PIXEL_FORMAT_I420),
80 media::VideoCaptureFormat(gfx::Size(2304, 1536), 10.0f,
81 media::PIXEL_FORMAT_I420),
82 };
83 capabilities_.device_capabilities.push_back(std::move(device));
84
85 capabilities_.power_line_capabilities = {
86 media::PowerLineFrequency::FREQUENCY_DEFAULT,
87 media::PowerLineFrequency::FREQUENCY_50HZ,
88 media::PowerLineFrequency::FREQUENCY_60HZ,
89 };
90
91 default_device_ = capabilities_.device_capabilities[0].get();
92 low_res_device_ = capabilities_.device_capabilities[1].get();
93 high_res_device_ = capabilities_.device_capabilities[2].get();
94 default_closest_format_ = &default_device_->formats[1];
95 low_res_closest_format_ = &low_res_device_->formats[2];
96 high_res_closest_format_ = &high_res_device_->formats[2];
97 high_res_highest_format_ = &high_res_device_->formats[5];
98 }
99
100 protected:
101 void SelectSettings() {
hta - Chromium 2017/02/02 00:32:39 As a matter of style, wouldn't it be prettier if S
Guido Urdaneta 2017/02/02 11:35:39 Done.
102 blink::WebMediaConstraints constraints =
103 constraint_factory_.CreateWebMediaConstraints();
104 result_ = SelectVideoCaptureSourceSettings(capabilities_, constraints);
105 }
106
107 VideoCaptureCapabilities capabilities_;
108 const mojom::VideoInputDeviceCapabilities* default_device_;
109 const mojom::VideoInputDeviceCapabilities* low_res_device_;
110 const mojom::VideoInputDeviceCapabilities* high_res_device_;
111 // Closest formats to the default settings.
112 const media::VideoCaptureFormat* default_closest_format_;
113 const media::VideoCaptureFormat* low_res_closest_format_;
114 const media::VideoCaptureFormat* high_res_closest_format_;
115 const media::VideoCaptureFormat* high_res_highest_format_;
116
117 MockConstraintFactory constraint_factory_;
118 VideoCaptureSourceSelectionResult result_;
119 };
120
121 // The overconstrained tests verify that failure of any single required
122 // constraint results in failure to select a candidate.
123 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, OverconstrainedOnDeviceID) {
124 constraint_factory_.Reset();
125 constraint_factory_.basic().deviceId.setExact(
126 blink::WebString::fromASCII("NONEXSISTING"));
127 SelectSettings();
128 EXPECT_FALSE(result_.has_value());
129 EXPECT_EQ(constraint_factory_.basic().deviceId.name(),
130 result_.failed_constraint_name);
131 }
132
133 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, OverconstrainedOnFacingMode) {
134 constraint_factory_.Reset();
135 // No device in |capabilities_| has facing mode equal to LEFT.
136 constraint_factory_.basic().facingMode.setExact(
137 blink::WebString::fromASCII("left"));
138 SelectSettings();
139 EXPECT_FALSE(result_.has_value());
140 EXPECT_EQ(constraint_factory_.basic().facingMode.name(),
141 result_.failed_constraint_name);
142 }
143
144 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, OverconstrainedOnHeight) {
145 constraint_factory_.Reset();
146 constraint_factory_.basic().height.setExact(123467890);
147 SelectSettings();
148 EXPECT_FALSE(result_.has_value());
149 EXPECT_EQ(constraint_factory_.basic().height.name(),
150 result_.failed_constraint_name);
151
152 constraint_factory_.Reset();
153 constraint_factory_.basic().height.setMin(123467890);
154 SelectSettings();
155 EXPECT_FALSE(result_.has_value());
156 EXPECT_EQ(constraint_factory_.basic().height.name(),
157 result_.failed_constraint_name);
158
159 constraint_factory_.Reset();
160 constraint_factory_.basic().height.setMax(0);
161 SelectSettings();
162 EXPECT_FALSE(result_.has_value());
163 EXPECT_EQ(constraint_factory_.basic().height.name(),
164 result_.failed_constraint_name);
165 }
166
167 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, OverconstrainedOnWidth) {
168 constraint_factory_.Reset();
169 constraint_factory_.basic().width.setExact(123467890);
170 SelectSettings();
171 EXPECT_FALSE(result_.has_value());
172 EXPECT_EQ(constraint_factory_.basic().width.name(),
173 result_.failed_constraint_name);
174
175 constraint_factory_.Reset();
176 constraint_factory_.basic().width.setMin(123467890);
177 SelectSettings();
178 EXPECT_FALSE(result_.has_value());
179 EXPECT_EQ(constraint_factory_.basic().width.name(),
180 result_.failed_constraint_name);
181
182 constraint_factory_.Reset();
183 constraint_factory_.basic().width.setMax(0);
184 SelectSettings();
185 EXPECT_FALSE(result_.has_value());
186 EXPECT_EQ(constraint_factory_.basic().width.name(),
187 result_.failed_constraint_name);
188 }
189
190 TEST_F(MediaStreamConstraintsUtilVideoSourceTest,
191 OverconstrainedOnAspectRatio) {
192 constraint_factory_.Reset();
193 constraint_factory_.basic().aspectRatio.setExact(123467890.0);
194 SelectSettings();
195 EXPECT_FALSE(result_.has_value());
196 EXPECT_EQ(constraint_factory_.basic().aspectRatio.name(),
197 result_.failed_constraint_name);
198
199 constraint_factory_.Reset();
200 constraint_factory_.basic().aspectRatio.setMin(123467890.0);
201 SelectSettings();
202 EXPECT_FALSE(result_.has_value());
203 EXPECT_EQ(constraint_factory_.basic().aspectRatio.name(),
204 result_.failed_constraint_name);
205
206 constraint_factory_.Reset();
207 constraint_factory_.basic().aspectRatio.setMax(0.0);
hta - Chromium 2017/02/02 00:32:39 This might cause an "illegal parameter" some day.
Guido Urdaneta 2017/02/02 11:35:39 Done. 0.01 works (minimum supported is 0.05).
208 SelectSettings();
209 EXPECT_FALSE(result_.has_value());
210 EXPECT_EQ(constraint_factory_.basic().aspectRatio.name(),
211 result_.failed_constraint_name);
212 }
213
214 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, OverconstrainedOnFrameRate) {
215 constraint_factory_.Reset();
216 constraint_factory_.basic().frameRate.setExact(123467890.0);
217 SelectSettings();
218 EXPECT_FALSE(result_.has_value());
219 EXPECT_EQ(constraint_factory_.basic().frameRate.name(),
220 result_.failed_constraint_name);
221
222 constraint_factory_.Reset();
223 constraint_factory_.basic().frameRate.setMin(123467890.0);
224 SelectSettings();
225 EXPECT_FALSE(result_.has_value());
226 EXPECT_EQ(constraint_factory_.basic().frameRate.name(),
227 result_.failed_constraint_name);
228
229 constraint_factory_.Reset();
230 constraint_factory_.basic().frameRate.setMax(0.0);
231 SelectSettings();
232 EXPECT_FALSE(result_.has_value());
233 EXPECT_EQ(constraint_factory_.basic().frameRate.name(),
234 result_.failed_constraint_name);
235 }
236
237 TEST_F(MediaStreamConstraintsUtilVideoSourceTest,
238 OverconstrainedOnPowerLineFrequency) {
239 constraint_factory_.Reset();
240 constraint_factory_.basic().googPowerLineFrequency.setExact(123467890);
241 SelectSettings();
242 EXPECT_FALSE(result_.has_value());
243 EXPECT_EQ(constraint_factory_.basic().googPowerLineFrequency.name(),
244 result_.failed_constraint_name);
245
246 constraint_factory_.Reset();
247 constraint_factory_.basic().googPowerLineFrequency.setMin(123467890);
248 SelectSettings();
249 EXPECT_FALSE(result_.has_value());
250 EXPECT_EQ(constraint_factory_.basic().googPowerLineFrequency.name(),
251 result_.failed_constraint_name);
252
253 constraint_factory_.Reset();
254 constraint_factory_.basic().googPowerLineFrequency.setMax(-1);
255 SelectSettings();
256 EXPECT_FALSE(result_.has_value());
257 EXPECT_EQ(constraint_factory_.basic().googPowerLineFrequency.name(),
258 result_.failed_constraint_name);
259 }
260
261 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, Unconstrained) {
hta - Chromium 2017/02/02 00:32:39 As a matter of style, I'd put the successful test
Guido Urdaneta 2017/02/02 11:35:39 Done. Changed the order to: 1. Unconstrained 2. Ov
262 constraint_factory_.Reset();
263 SelectSettings();
264 EXPECT_TRUE(result_.has_value());
265 // Should select the default device with closest-to-default settings.
266 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
267 EXPECT_EQ(default_device_->facing_mode, result_.settings.facing_mode());
268 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
269 media::VideoCaptureFormat::ToString(result_.settings.format()));
270 }
271
272 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryDeviceID) {
273 constraint_factory_.Reset();
274 constraint_factory_.basic().deviceId.setExact(
275 blink::WebString::fromASCII(default_device_->device_id));
276 SelectSettings();
277 EXPECT_TRUE(result_.has_value());
278 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
279 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
280 media::VideoCaptureFormat::ToString(result_.settings.format()));
281 EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
282 result_.settings.power_line_frequency());
283
284 constraint_factory_.basic().deviceId.setExact(
285 blink::WebString::fromASCII(low_res_device_->device_id));
286 SelectSettings();
287 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
288 EXPECT_EQ(media::VideoCaptureFormat::ToString(*low_res_closest_format_),
289 media::VideoCaptureFormat::ToString(result_.settings.format()));
290 EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
291 result_.settings.power_line_frequency());
292
293 constraint_factory_.basic().deviceId.setExact(
294 blink::WebString::fromASCII(high_res_device_->device_id));
295 SelectSettings();
296 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
297 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_closest_format_),
298 media::VideoCaptureFormat::ToString(result_.settings.format()));
299 EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
300 result_.settings.power_line_frequency());
301 }
302
303 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryFacingMode) {
304 constraint_factory_.Reset();
305 constraint_factory_.basic().facingMode.setExact(
306 blink::WebString::fromASCII("environment"));
307 SelectSettings();
308 EXPECT_TRUE(result_.has_value());
309 EXPECT_EQ(::mojom::FacingMode::ENVIRONMENT, result_.settings.facing_mode());
310 // Only the low-res device supports environment facing mode. Should select
311 // default settings for everything else.
312 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
313 EXPECT_EQ(media::VideoCaptureFormat::ToString(*low_res_closest_format_),
314 media::VideoCaptureFormat::ToString(result_.settings.format()));
315 EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
316 result_.settings.power_line_frequency());
317
318 constraint_factory_.basic().facingMode.setExact(
319 blink::WebString::fromASCII("user"));
320 SelectSettings();
321 EXPECT_TRUE(result_.has_value());
322 EXPECT_EQ(::mojom::FacingMode::USER, result_.settings.facing_mode());
323 // Only the high-res device supports user facing mode. Should select default
324 // settings for everything else.
325 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
326 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_closest_format_),
327 media::VideoCaptureFormat::ToString(result_.settings.format()));
328 EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
329 result_.settings.power_line_frequency());
330 }
331
332 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryPowerLineFrequency) {
333 constraint_factory_.Reset();
334 const media::PowerLineFrequency kPowerLineFrequencies[] = {
335 media::PowerLineFrequency::FREQUENCY_50HZ,
336 media::PowerLineFrequency::FREQUENCY_60HZ};
337 for (auto power_line_frequency : kPowerLineFrequencies) {
338 constraint_factory_.basic().googPowerLineFrequency.setExact(
339 static_cast<long>(power_line_frequency));
340 SelectSettings();
341 EXPECT_TRUE(result_.has_value());
342 EXPECT_EQ(power_line_frequency, result_.settings.power_line_frequency());
343 // The default device and settings closest to the default should be
344 // selected.
345 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
346 EXPECT_EQ(default_device_->facing_mode, result_.settings.facing_mode());
347 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
348 media::VideoCaptureFormat::ToString(result_.settings.format()));
349 }
350 }
351
352 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryExactHeight) {
353 constraint_factory_.Reset();
354 const int kHeight = MediaStreamVideoSource::kDefaultHeight;
355 constraint_factory_.basic().height.setExact(kHeight);
356 SelectSettings();
357 EXPECT_TRUE(result_.has_value());
358 // All devices in |capabilities_| support the requested height. The algorithm
359 // should prefer the first device that supports the requested height natively,
360 // which is the low-res device.
361 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
362 EXPECT_EQ(kHeight, result_.settings.GetHeight());
363
364 const int kLargeHeight = 1500;
365 constraint_factory_.basic().height.setExact(kLargeHeight);
366 SelectSettings();
367 EXPECT_TRUE(result_.has_value());
368 // Only the high-res device at the highest resolution supports the requested
369 // height, even if not natively.
370 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
371 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
372 media::VideoCaptureFormat::ToString(result_.settings.format()));
373 }
374
375 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryMinHeight) {
376 constraint_factory_.Reset();
377 const int kHeight = MediaStreamVideoSource::kDefaultHeight;
378 constraint_factory_.basic().height.setMin(kHeight);
379 SelectSettings();
380 EXPECT_TRUE(result_.has_value());
381 // All devices in |capabilities_| support the requested height range. The
382 // algorithm should prefer the default device.
383 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
384 EXPECT_LE(kHeight, result_.settings.GetHeight());
385
386 const int kLargeHeight = 1500;
387 constraint_factory_.basic().height.setMin(kLargeHeight);
388 SelectSettings();
389 EXPECT_TRUE(result_.has_value());
390 // Only the high-res device at the highest resolution supports the requested
391 // height range.
392 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
393 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
394 media::VideoCaptureFormat::ToString(result_.settings.format()));
395 }
396
397 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryMaxHeight) {
398 constraint_factory_.Reset();
399 const int kLowHeight = 20;
400 constraint_factory_.basic().height.setMax(kLowHeight);
401 SelectSettings();
402 EXPECT_TRUE(result_.has_value());
403 // All devices in |capabilities_| support the requested height range. The
404 // algorithm should prefer the settings that natively exceed the requested
405 // maximum by the lowest amount. In this case it is the low-res device.
406 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
407 EXPECT_EQ(media::VideoCaptureFormat::ToString(low_res_device_->formats[0]),
408 media::VideoCaptureFormat::ToString(result_.settings.format()));
409 }
410
411 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryHeightRange) {
412 constraint_factory_.Reset();
413 {
414 const int kMinHeight = 480;
415 const int kMaxHeight = 720;
416 constraint_factory_.basic().height.setMin(kMinHeight);
417 constraint_factory_.basic().height.setMax(kMaxHeight);
418 SelectSettings();
419 EXPECT_TRUE(result_.has_value());
420 EXPECT_GE(result_.settings.GetHeight(), kMinHeight);
421 EXPECT_LE(result_.settings.GetHeight(), kMaxHeight);
422 // All devices in |capabilities_| support the constraint range. The
423 // algorithm should prefer the default device since it has at least one
424 // native format (the closest-to-default format) included in the requested
425 // range.
426 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
427 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
428 media::VideoCaptureFormat::ToString(result_.settings.format()));
429 }
430
431 {
432 const int kMinHeight = 550;
433 const int kMaxHeight = 650;
434 constraint_factory_.basic().height.setMin(kMinHeight);
435 constraint_factory_.basic().height.setMax(kMaxHeight);
436 SelectSettings();
437 EXPECT_TRUE(result_.has_value());
438 EXPECT_GE(result_.settings.GetHeight(), kMinHeight);
439 EXPECT_LE(result_.settings.GetHeight(), kMaxHeight);
440 // In this case, the algorithm should prefer the low-res device since it is
441 // the first device with a native format (800x600) included in the requested
442 // range.
443 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
444 EXPECT_EQ(800, result_.settings.GetWidth());
445 EXPECT_EQ(600, result_.settings.GetHeight());
446 }
447
448 {
449 const int kMinHeight = 700;
450 const int kMaxHeight = 800;
451 constraint_factory_.basic().height.setMin(kMinHeight);
452 constraint_factory_.basic().height.setMax(kMaxHeight);
453 SelectSettings();
454 EXPECT_TRUE(result_.has_value());
455 EXPECT_GE(result_.settings.GetHeight(), kMinHeight);
456 EXPECT_LE(result_.settings.GetHeight(), kMaxHeight);
457 // In this case, the algorithm should prefer the high-res device since it is
458 // the only device with a native format (1280x720) included in the requested
459 // range.
460 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
461 EXPECT_EQ(1280, result_.settings.GetWidth());
462 EXPECT_EQ(720, result_.settings.GetHeight());
463 }
464 }
465
466 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, IdealHeight) {
467 constraint_factory_.Reset();
468 {
469 const int kIdealHeight = 480;
470 constraint_factory_.basic().height.setIdeal(kIdealHeight);
471 SelectSettings();
472 EXPECT_TRUE(result_.has_value());
473 // The algorithm should select the first device that supports the ideal
474 // height natively.
475 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
476 EXPECT_EQ(kIdealHeight, result_.settings.GetHeight());
477 }
478
479 {
480 const int kIdealHeight = 481;
481 constraint_factory_.basic().height.setIdeal(kIdealHeight);
482 SelectSettings();
483 EXPECT_TRUE(result_.has_value());
484 // In this case, the default device is selected because it can satisfy the
485 // ideal at a lower cost than the other devices (500 vs 600 or 720).
486 // Note that a native resolution of 480 is further from the ideal than
487 // 500 cropped to 480.
488 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
489 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
490 media::VideoCaptureFormat::ToString(result_.settings.format()));
491 }
492
493 {
494 const int kIdealHeight = 1079;
495 constraint_factory_.basic().height.setIdeal(kIdealHeight);
496 SelectSettings();
497 EXPECT_TRUE(result_.has_value());
498 // In this case, the high-res device has two configurations that satisfy
499 // the ideal value (1920x1080 and 2304x1536). Select the one with shortest
500 // native distance to the ideal value (1920x1080).
501 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
502 EXPECT_EQ(1920, result_.settings.GetWidth());
503 EXPECT_EQ(1080, result_.settings.GetHeight());
504 }
505
506 {
507 const int kIdealHeight = 1200;
508 constraint_factory_.basic().height.setIdeal(kIdealHeight);
509 SelectSettings();
510 EXPECT_TRUE(result_.has_value());
511 // The algorithm must the select the only device that can satisfy the ideal,
512 // which is the high-res device at the highest resolution.
513 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
514 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
515 media::VideoCaptureFormat::ToString(result_.settings.format()));
516 }
517 }
518
519 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryExactWidth) {
520 constraint_factory_.Reset();
521 const int kWidth = 640;
522 constraint_factory_.basic().width.setExact(kWidth);
523 SelectSettings();
524 EXPECT_TRUE(result_.has_value());
525 // All devices in |capabilities_| support the requested width. The algorithm
526 // should prefer the first device that supports the requested width natively,
527 // which is the low-res device.
528 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
529 EXPECT_EQ(kWidth, result_.settings.GetWidth());
530
531 const int kLargeWidth = 2000;
532 constraint_factory_.basic().width.setExact(kLargeWidth);
533 SelectSettings();
534 EXPECT_TRUE(result_.has_value());
535 EXPECT_LE(kLargeWidth, result_.settings.GetWidth());
536 // Only the high-res device at the highest resolution supports the requested
537 // width, even if not natively.
538 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
539 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
540 media::VideoCaptureFormat::ToString(result_.settings.format()));
541 }
542
543 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryMinWidth) {
544 constraint_factory_.Reset();
545 const int kWidth = 640;
546 constraint_factory_.basic().width.setMin(kWidth);
547 SelectSettings();
548 EXPECT_TRUE(result_.has_value());
549 // All devices in |capabilities_| support the requested width range. The
550 // algorithm should prefer the default device at 1000x1000, which is the
551 // first configuration that satisfies the minimum width.
552 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
553 EXPECT_LE(kWidth, result_.settings.GetWidth());
554 EXPECT_EQ(1000, result_.settings.GetWidth());
555 EXPECT_EQ(1000, result_.settings.GetHeight());
556
557 const int kLargeWidth = 2000;
558 constraint_factory_.basic().width.setMin(kLargeWidth);
559 SelectSettings();
560 EXPECT_TRUE(result_.has_value());
561 // Only the high-res device at the highest resolution supports the requested
562 // minimum width.
563 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
564 EXPECT_LE(kLargeWidth, result_.settings.GetWidth());
565 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
566 media::VideoCaptureFormat::ToString(result_.settings.format()));
567 }
568
569 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryMaxWidth) {
570 constraint_factory_.Reset();
571 const int kLowWidth = 30;
572 constraint_factory_.basic().width.setMax(kLowWidth);
573 SelectSettings();
574 EXPECT_TRUE(result_.has_value());
575 // All devices in |capabilities_| support the requested width range. The
576 // algorithm should prefer the settings that natively exceed the requested
577 // maximum by the lowest amount. In this case it is the low-res device at its
578 // lowest resolution.
579 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
580 EXPECT_EQ(media::VideoCaptureFormat::ToString(low_res_device_->formats[0]),
581 media::VideoCaptureFormat::ToString(result_.settings.format()));
582 }
583
584 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryWidthRange) {
585 constraint_factory_.Reset();
586 {
587 const int kMinWidth = 640;
588 const int kMaxWidth = 1280;
589 constraint_factory_.basic().width.setMin(kMinWidth);
590 constraint_factory_.basic().width.setMax(kMaxWidth);
591 SelectSettings();
592 EXPECT_TRUE(result_.has_value());
593 EXPECT_GE(result_.settings.GetWidth(), kMinWidth);
594 EXPECT_LE(result_.settings.GetWidth(), kMaxWidth);
595 // All devices in |capabilities_| support the constraint range. The
596 // algorithm should prefer the default device since it has at least one
597 // native format (1000x1000) included in the requested range.
598 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
599 EXPECT_EQ(1000, result_.settings.GetWidth());
600 EXPECT_EQ(1000, result_.settings.GetHeight());
601 }
602
603 {
604 const int kMinWidth = 750;
605 const int kMaxWidth = 850;
606 constraint_factory_.basic().width.setMin(kMinWidth);
607 constraint_factory_.basic().width.setMax(kMaxWidth);
608 SelectSettings();
609 EXPECT_TRUE(result_.has_value());
610 EXPECT_GE(result_.settings.GetWidth(), kMinWidth);
611 EXPECT_LE(result_.settings.GetWidth(), kMaxWidth);
612 // In this case, the algorithm should prefer the low-res device since it is
613 // the first device with a native format (800x600) included in the requested
614 // range.
615 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
616 EXPECT_EQ(800, result_.settings.GetWidth());
617 EXPECT_EQ(600, result_.settings.GetHeight());
618 }
619
620 {
621 const int kMinWidth = 1900;
622 const int kMaxWidth = 2000;
623 constraint_factory_.basic().width.setMin(kMinWidth);
624 constraint_factory_.basic().width.setMax(kMaxWidth);
625 SelectSettings();
626 EXPECT_TRUE(result_.has_value());
627 EXPECT_GE(result_.settings.GetWidth(), kMinWidth);
628 EXPECT_LE(result_.settings.GetWidth(), kMaxWidth);
629 // In this case, the algorithm should prefer the high-res device since it is
630 // the only device with a native format (1920x1080) included in the
631 // requested range.
632 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
633 EXPECT_EQ(1920, result_.settings.GetWidth());
634 EXPECT_EQ(1080, result_.settings.GetHeight());
635 }
636 }
637
638 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, IdealWidth) {
639 constraint_factory_.Reset();
640 {
641 const int kIdealWidth = 320;
642 constraint_factory_.basic().width.setIdeal(kIdealWidth);
643 SelectSettings();
644 EXPECT_TRUE(result_.has_value());
645 // The algorithm should select the first device that supports the ideal
646 // width natively, which is the low-res device at 320x240.
647 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
648 EXPECT_EQ(kIdealWidth, result_.settings.GetWidth());
649 }
650
651 {
652 const int kIdealWidth = 321;
653 constraint_factory_.basic().width.setIdeal(kIdealWidth);
654 SelectSettings();
655 EXPECT_TRUE(result_.has_value());
656 // In this case, the default device is selected because it can satisfy the
657 // ideal at a lower cost than the other devices (500 vs 640).
658 // Note that a native resolution of 320 is further from the ideal value of
659 // 321 than 500 cropped to 321.
660 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
661 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
662 media::VideoCaptureFormat::ToString(result_.settings.format()));
663 }
664
665 {
666 const int kIdealWidth = 2000;
667 constraint_factory_.basic().width.setIdeal(kIdealWidth);
668 SelectSettings();
669 EXPECT_TRUE(result_.has_value());
670 // The algorithm must the select the only device that can satisfy the ideal.
671 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
672 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
673 media::VideoCaptureFormat::ToString(result_.settings.format()));
674 }
675
676 {
677 const int kIdealWidth = 3000;
678 constraint_factory_.basic().width.setIdeal(kIdealWidth);
679 SelectSettings();
680 EXPECT_TRUE(result_.has_value());
681 // The algorithm must the select the device and setting with less distance
682 // to the ideal.
683 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
684 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
685 media::VideoCaptureFormat::ToString(result_.settings.format()));
686 }
687 }
688
689 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryExactFrameRate) {
690 constraint_factory_.Reset();
691 const double kFrameRate = MediaStreamVideoSource::kDefaultFrameRate;
692 constraint_factory_.basic().frameRate.setExact(kFrameRate);
693 SelectSettings();
694 EXPECT_TRUE(result_.has_value());
695 // All devices in |capabilities_| support the requested frame rate. The
696 // algorithm should prefer the first device that supports the requested frame
697 // rate natively, which is the low-res device at 640x480x30Hz.
698 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
699 EXPECT_EQ(kFrameRate, result_.settings.GetFrameRate());
700 EXPECT_EQ(640, result_.settings.GetWidth());
701 EXPECT_EQ(480, result_.settings.GetHeight());
702
703 const double kLargeFrameRate = 50;
704 constraint_factory_.basic().frameRate.setExact(kLargeFrameRate);
705 SelectSettings();
706 EXPECT_TRUE(result_.has_value());
707 // Only the high-res device supports the requested frame rate, even if not
708 // natively. The least expensive configuration that supports the requested
709 // frame rate is 1280x720x60Hz.
710 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
711 EXPECT_EQ(60.0, result_.settings.GetFrameRate());
712 EXPECT_EQ(1280, result_.settings.GetWidth());
713 EXPECT_EQ(720, result_.settings.GetHeight());
714 }
715
716 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryMinFrameRate) {
717 constraint_factory_.Reset();
718 const double kFrameRate = MediaStreamVideoSource::kDefaultFrameRate;
719 constraint_factory_.basic().frameRate.setMin(kFrameRate);
720 SelectSettings();
721 EXPECT_TRUE(result_.has_value());
722 // All devices in |capabilities_| support the requested frame-rate range. The
723 // algorithm should prefer the default device.
724 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
725 // The format closest to the default satisfies the constraint.
726 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
727 media::VideoCaptureFormat::ToString(result_.settings.format()));
728
729 const double kLargeFrameRate = 50;
730 constraint_factory_.basic().frameRate.setMin(kLargeFrameRate);
731 SelectSettings();
732 EXPECT_TRUE(result_.has_value());
733 // Only the high-res device supports the requested frame-rate range.
734 // The least expensive configuration is 1280x720x60Hz.
735 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
736 EXPECT_LE(kLargeFrameRate, result_.settings.GetFrameRate());
737 EXPECT_EQ(1280, result_.settings.GetWidth());
738 EXPECT_EQ(720, result_.settings.GetHeight());
739 }
740
741 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryMaxFrameRate) {
742 constraint_factory_.Reset();
743 const double kLowFrameRate = 10;
744 constraint_factory_.basic().frameRate.setMax(kLowFrameRate);
745 SelectSettings();
746 EXPECT_TRUE(result_.has_value());
747 // All devices in |capabilities_| support the requested frame-rate range. The
748 // algorithm should prefer the settings that natively exceed the requested
749 // maximum by the lowest amount. In this case it is the high-res device with
750 // default resolution .
751 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
752 EXPECT_EQ(kLowFrameRate, result_.settings.GetFrameRate());
753 EXPECT_EQ(MediaStreamVideoSource::kDefaultHeight,
754 result_.settings.GetHeight());
755 EXPECT_EQ(MediaStreamVideoSource::kDefaultWidth, result_.settings.GetWidth());
756 }
757
758 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryFrameRateRange) {
759 constraint_factory_.Reset();
760 {
761 const double kMinFrameRate = 10;
762 const double kMaxFrameRate = 40;
763 constraint_factory_.basic().frameRate.setMin(kMinFrameRate);
764 constraint_factory_.basic().frameRate.setMax(kMaxFrameRate);
765 SelectSettings();
766 EXPECT_TRUE(result_.has_value());
767 EXPECT_LE(kMinFrameRate, result_.settings.GetFrameRate());
768 EXPECT_GE(kMaxFrameRate, result_.settings.GetFrameRate());
769 // All devices in |capabilities_| support the constraint range. The
770 // algorithm should prefer the default device since its closest-to-default
771 // format has a frame rate included in the requested range.
772 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
773 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
774 media::VideoCaptureFormat::ToString(result_.settings.format()));
775 }
776
777 {
778 const double kMinFrameRate = 25;
779 const double kMaxFrameRate = 35;
780 constraint_factory_.basic().frameRate.setMin(kMinFrameRate);
781 constraint_factory_.basic().frameRate.setMax(kMaxFrameRate);
782 SelectSettings();
783 EXPECT_TRUE(result_.has_value());
784 EXPECT_GE(result_.settings.GetFrameRate(), kMinFrameRate);
785 EXPECT_LE(result_.settings.GetFrameRate(), kMaxFrameRate);
786 // In this case, the algorithm should prefer the low-res device since it is
787 // the first device with a native frame rate included in the requested
788 // range. The default resolution should be preferred as secondary criterion.
789 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
790 EXPECT_EQ(media::VideoCaptureFormat::ToString(*low_res_closest_format_),
791 media::VideoCaptureFormat::ToString(result_.settings.format()));
792 }
793
794 {
795 const double kMinFrameRate = 50;
796 const double kMaxFrameRate = 70;
797 constraint_factory_.basic().frameRate.setMin(kMinFrameRate);
798 constraint_factory_.basic().frameRate.setMax(kMaxFrameRate);
799 SelectSettings();
800 EXPECT_TRUE(result_.has_value());
801 EXPECT_GE(result_.settings.GetFrameRate(), kMinFrameRate);
802 EXPECT_LE(result_.settings.GetFrameRate(), kMaxFrameRate);
803 // In this case, the algorithm should prefer the high-res device since it is
804 // the only device with a native format included in the requested range.
805 // The 1280x720 resolution should be selected due to closeness to default
806 // settings, which is the second tie-breaker criterion that applies.
807 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
808 EXPECT_EQ(1280, result_.settings.GetWidth());
809 EXPECT_EQ(720, result_.settings.GetHeight());
810 }
811 }
812
813 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, IdealFrameRate) {
814 constraint_factory_.Reset();
815 {
816 const double kIdealFrameRate = MediaStreamVideoSource::kDefaultFrameRate;
817 constraint_factory_.basic().frameRate.setIdeal(kIdealFrameRate);
818 SelectSettings();
819 EXPECT_TRUE(result_.has_value());
820 // The algorithm should select the first configuration that supports the
821 // ideal frame rate natively, which is the low-res device. Default
822 // resolution should be selected as secondary criterion.
823 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
824 EXPECT_EQ(media::VideoCaptureFormat::ToString(*low_res_closest_format_),
825 media::VideoCaptureFormat::ToString(result_.settings.format()));
826 }
827
828 {
829 const double kIdealFrameRate = 31;
830 constraint_factory_.basic().frameRate.setIdeal(kIdealFrameRate);
831 SelectSettings();
832 EXPECT_TRUE(result_.has_value());
833 // In this case, the default device is selected because it can satisfy the
834 // ideal at a lower cost than the other devices (40 vs 60).
835 // Note that a native frame rate of 30 is further from the ideal than
836 // 31 adjusted to 30.
837 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
838 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
839 media::VideoCaptureFormat::ToString(result_.settings.format()));
840 }
841
842 {
843 const double kIdealFrameRate = 55;
844 constraint_factory_.basic().frameRate.setIdeal(kIdealFrameRate);
845 SelectSettings();
846 EXPECT_TRUE(result_.has_value());
847 // The high-res device format 1280x720x60.0 must be selected because its
848 // frame rate can satisfy the ideal frame rate and has resolution closest
849 // to the default.
850 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
851 EXPECT_EQ(1280, result_.settings.GetWidth());
852 EXPECT_EQ(720, result_.settings.GetHeight());
853 EXPECT_EQ(60, result_.settings.GetFrameRate());
854 }
855
856 {
857 const double kIdealFrameRate = 100;
858 constraint_factory_.basic().frameRate.setIdeal(kIdealFrameRate);
859 SelectSettings();
860 EXPECT_TRUE(result_.has_value());
861 // The algorithm must select settings with frame rate closest to the ideal.
862 // The high-res device format 1280x720x60.0 must be selected because its
863 // frame rate it closest to the ideal value and it has resolution closest to
864 // the default.
865 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
866 EXPECT_EQ(1280, result_.settings.GetWidth());
867 EXPECT_EQ(720, result_.settings.GetHeight());
868 EXPECT_EQ(60, result_.settings.GetFrameRate());
869 }
870 }
871
872 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryExactAspectRatio) {
873 constraint_factory_.Reset();
874 const double kAspectRatio = 4.0 / 3.0;
875 constraint_factory_.basic().aspectRatio.setExact(kAspectRatio);
876 SelectSettings();
877 EXPECT_TRUE(result_.has_value());
878 double min_width = 1.0;
879 double max_width = result_.settings.GetWidth();
880 double min_height = 1.0;
881 double max_height = result_.settings.GetHeight();
882 double min_aspect_ratio = min_width / max_height;
883 double max_aspect_ratio = max_width / min_height;
884 // The requested aspect ratio must be within the supported range.
885 EXPECT_GE(kAspectRatio, min_aspect_ratio);
886 EXPECT_LE(kAspectRatio, max_aspect_ratio);
887 // All devices in |capabilities_| support the requested aspect ratio.
888 // The algorithm should prefer the first device that supports the requested
889 // aspect ratio.
890 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
891 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
892 media::VideoCaptureFormat::ToString(result_.settings.format()));
893
894 const long kMinWidth = 500;
895 const long kMaxWidth = 1000;
896 const long kMaxHeight = 500;
897 constraint_factory_.basic().height.setMax(kMaxHeight);
898 constraint_factory_.basic().width.setMin(kMinWidth);
899 constraint_factory_.basic().width.setMax(kMaxWidth);
900 constraint_factory_.basic().aspectRatio.setExact(kAspectRatio);
901 SelectSettings();
902 EXPECT_TRUE(result_.has_value());
903 min_width = std::max(1L, kMinWidth);
904 max_width = std::min(result_.settings.GetWidth(), kMaxWidth);
905 min_height = 1.0;
906 max_height = std::min(result_.settings.GetHeight(), kMaxHeight);
907 min_aspect_ratio = min_width / max_height;
908 max_aspect_ratio = max_width / min_height;
909 // The requested aspect ratio must be within the supported range.
910 EXPECT_GE(kAspectRatio, min_aspect_ratio);
911 EXPECT_LE(kAspectRatio, max_aspect_ratio);
912 // The default device can support the requested aspect ratio with the default
913 // settings (500x500) using cropping.
914 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
915 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
916 media::VideoCaptureFormat::ToString(result_.settings.format()));
917
918 const long kMinHeight = 480;
919 constraint_factory_.basic().height.setMin(kMinHeight);
920 constraint_factory_.basic().height.setMax(kMaxHeight);
921 constraint_factory_.basic().width.setMin(kMinWidth);
922 constraint_factory_.basic().width.setMax(kMaxWidth);
923 constraint_factory_.basic().aspectRatio.setExact(kAspectRatio);
924 SelectSettings();
925 EXPECT_TRUE(result_.has_value());
926 min_width = std::max(1L, kMinWidth);
927 max_width = std::min(result_.settings.GetWidth(), kMaxWidth);
928 min_height = std::max(1L, kMinHeight);
929 max_height = std::min(result_.settings.GetHeight(), kMaxHeight);
930 min_aspect_ratio = min_width / max_height;
931 max_aspect_ratio = max_width / min_height;
932 // The requested aspect ratio must be within the supported range.
933 EXPECT_GE(kAspectRatio, min_aspect_ratio);
934 EXPECT_LE(kAspectRatio, max_aspect_ratio);
935 // Given resolution constraints, the default device with closest-to-default
936 // settings cannot satisfy the required aspect ratio.
937 // The first device that can do it is the low-res device with a native
938 // resolution of 640x480. Higher resolutions for the default device are more
939 // penalized by the constraints than the default native resolution of the
940 // low-res device.
941 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
942 EXPECT_EQ(media::VideoCaptureFormat::ToString(*low_res_closest_format_),
943 media::VideoCaptureFormat::ToString(result_.settings.format()));
944 }
945
946 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryMinAspectRatio) {
947 constraint_factory_.Reset();
948 const double kAspectRatio = 4.0 / 3.0;
949 constraint_factory_.basic().aspectRatio.setMin(kAspectRatio);
950 SelectSettings();
951 EXPECT_TRUE(result_.has_value());
952 double max_width = result_.settings.GetWidth();
953 double min_height = 1.0;
954 double max_aspect_ratio = max_width / min_height;
955 // Minimum constraint aspect ratio must be less than or equal to the maximum
956 // supported by the source.
957 EXPECT_LE(kAspectRatio, max_aspect_ratio);
958 // All devices in |capabilities_| support the requested aspect-ratio range.
959 // The algorithm should prefer the first device that supports the requested
960 // aspect-ratio range, which in this case is the default device.
961 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
962 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
963 media::VideoCaptureFormat::ToString(result_.settings.format()));
964
965 const long kMinWidth = 500;
966 const long kMaxWidth = 1000;
967 const long kMinHeight = 480;
968 const long kMaxHeight = 500;
969 constraint_factory_.basic().width.setMin(kMinWidth);
970 constraint_factory_.basic().width.setMax(kMaxWidth);
971 constraint_factory_.basic().height.setMin(kMinHeight);
972 constraint_factory_.basic().height.setMax(kMaxHeight);
973 constraint_factory_.basic().aspectRatio.setMin(kAspectRatio);
974 SelectSettings();
975 EXPECT_TRUE(result_.has_value());
976 max_width = std::min(result_.settings.GetWidth(), kMaxWidth);
977 min_height = std::max(1L, kMinHeight);
978 max_aspect_ratio = max_width / min_height;
979 // Minimum constraint aspect ratio must be less than or equal to the minimum
980 // supported by the source.
981 EXPECT_LE(kAspectRatio, max_aspect_ratio);
982 // Given resolution constraints, the default device with closest-to-default
983 // settings cannot satisfy the required minimum aspect ratio (maximum would
984 // be 500/480). The first device that can is the low-res device with a native
985 // resolution of 640x480.
986 // Higher resolutions for the default device are more penalized by the
987 // constraints than the default native resolution of the low-res device.
988 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
989 EXPECT_EQ(media::VideoCaptureFormat::ToString(*low_res_closest_format_),
990 media::VideoCaptureFormat::ToString(result_.settings.format()));
991 }
992
993 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryMaxAspectRatio) {
994 constraint_factory_.Reset();
995 const double kAspectRatio = 0.5;
996 constraint_factory_.basic().aspectRatio.setMax(kAspectRatio);
997 SelectSettings();
998 EXPECT_TRUE(result_.has_value());
999 double min_width = 1.0;
1000 double max_height = result_.settings.GetHeight();
1001 double min_aspect_ratio = min_width / max_height;
1002 // Minimum constraint aspect ratio must be less than or equal to the maximum
1003 // supported by the source.
1004 EXPECT_GE(kAspectRatio, min_aspect_ratio);
1005 // All devices in |capabilities_| support the requested aspect-ratio range.
1006 // The algorithm should prefer the first device that supports the requested
1007 // aspect-ratio range, which in this case is the default device.
1008 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
1009 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
1010 media::VideoCaptureFormat::ToString(result_.settings.format()));
1011
1012 const long kExactWidth = 360;
1013 const long kMinHeight = 360;
1014 const long kMaxHeight = 720;
1015 constraint_factory_.basic().width.setExact(kExactWidth);
1016 constraint_factory_.basic().height.setMin(kMinHeight);
1017 constraint_factory_.basic().height.setMax(kMaxHeight);
1018 constraint_factory_.basic().aspectRatio.setMax(kAspectRatio);
1019 SelectSettings();
1020 EXPECT_TRUE(result_.has_value());
1021 min_width = std::max(1L, kExactWidth);
1022 max_height = std::min(result_.settings.GetHeight(), kMaxHeight);
1023 min_aspect_ratio = min_width / max_height;
1024 // Minimum constraint aspect ratio must be less than or equal to the minimum
1025 // supported by the source.
1026 EXPECT_GE(kAspectRatio, min_aspect_ratio);
1027 // Given resolution constraints, the default device with closest-to-default
1028 // settings cannot satisfy the required maximum aspect ratio (maximum would
1029 // be 360/500).
1030 // The high-res device with a native resolution of 1280x720 can support
1031 // 360x720 with cropping with less penalty than the default device at
1032 // 1000x1000.
1033 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1034 EXPECT_EQ(1280, result_.settings.GetWidth());
1035 EXPECT_EQ(720, result_.settings.GetHeight());
1036 }
1037
1038 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, MandatoryAspectRatioRange) {
1039 constraint_factory_.Reset();
1040 {
1041 const double kMinAspectRatio = 0.5;
1042 const double kMaxAspectRatio = 1.0;
1043
1044 constraint_factory_.basic().aspectRatio.setMin(kMinAspectRatio);
1045 constraint_factory_.basic().aspectRatio.setMax(kMaxAspectRatio);
1046 SelectSettings();
1047 EXPECT_TRUE(result_.has_value());
1048 double min_width = 1.0;
1049 double max_width = result_.settings.GetWidth();
1050 double min_height = 1.0;
1051 double max_height = result_.settings.GetHeight();
1052 double min_aspect_ratio = min_width / max_height;
1053 double max_aspect_ratio = max_width / min_height;
1054 // Constraint aspect-ratio range must have nonempty intersection with
1055 // supported range.
1056 EXPECT_LE(kMinAspectRatio, max_aspect_ratio);
1057 EXPECT_GE(kMaxAspectRatio, min_aspect_ratio);
1058 // All devices in |capabilities_| support the requested aspect-ratio range.
1059 // The algorithm should prefer the first device that supports the requested
1060 // aspect-ratio range, which in this case is the default device.
1061 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
1062 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
1063 media::VideoCaptureFormat::ToString(result_.settings.format()));
1064 }
1065
1066 {
1067 const double kMinAspectRatio = 3.0;
1068 const double kMaxAspectRatio = 4.0;
1069
1070 const long kExactHeight = 600;
1071 constraint_factory_.Reset();
1072 constraint_factory_.basic().height.setMin(kExactHeight);
1073 constraint_factory_.basic().aspectRatio.setMin(kMinAspectRatio);
1074 constraint_factory_.basic().aspectRatio.setMax(kMaxAspectRatio);
1075 SelectSettings();
1076 EXPECT_TRUE(result_.has_value());
1077 double min_width = 1.0;
1078 double max_width = result_.settings.GetWidth();
1079 double min_height = 1.0;
1080 double max_height = result_.settings.GetHeight();
1081 double min_aspect_ratio = min_width / max_height;
1082 double max_aspect_ratio = max_width / min_height;
1083 // Constraint aspect-ratio range must have nonempty intersection with
1084 // supported range.
1085 EXPECT_LE(kMinAspectRatio, max_aspect_ratio);
1086 EXPECT_GE(kMaxAspectRatio, min_aspect_ratio);
1087 // The only device that supports the resolution and aspect ratio constraint
1088 // is the high-res device. The 1920x1080 is the least expensive format.
1089 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1090 EXPECT_EQ(1920, result_.settings.GetWidth());
1091 EXPECT_EQ(1080, result_.settings.GetHeight());
1092 }
1093 }
1094
1095 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, IdealAspectRatio) {
1096 constraint_factory_.Reset();
1097 {
1098 const double kIdealAspectRatio = 0.5;
1099 constraint_factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
1100 SelectSettings();
1101 EXPECT_TRUE(result_.has_value());
1102 double min_width = 1.0;
1103 double max_width = result_.settings.GetWidth();
1104 double min_height = 1.0;
1105 double max_height = result_.settings.GetHeight();
1106 double min_aspect_ratio = min_width / max_height;
1107 double max_aspect_ratio = max_width / min_height;
1108 // All devices in |capabilities_| support the ideal aspect-ratio.
1109 // The algorithm should prefer the default device with closest-to-default
1110 // settings.
1111 EXPECT_LE(kIdealAspectRatio, max_aspect_ratio);
1112 EXPECT_GE(kIdealAspectRatio, min_aspect_ratio);
1113 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
1114 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
1115 media::VideoCaptureFormat::ToString(result_.settings.format()));
1116 }
1117
1118 {
1119 const double kIdealAspectRatio = 1500.0;
1120 constraint_factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
1121 SelectSettings();
1122 EXPECT_TRUE(result_.has_value());
1123 // The only device that supports the ideal aspect ratio is the high-res
1124 // device. The least expensive way to support it with the 1920x1080 format
1125 // cropped to 1500x1.
1126 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1127 EXPECT_EQ(1920, result_.settings.GetWidth());
1128 EXPECT_EQ(1080, result_.settings.GetHeight());
1129 }
1130
1131 {
1132 const double kIdealAspectRatio = 2000.0;
1133 constraint_factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
1134 SelectSettings();
1135 EXPECT_TRUE(result_.has_value());
1136 // The only device that supports the ideal aspect ratio is the high-res
1137 // device with its highest resolution, cropped to 2000x1.
1138 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1139 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
1140 media::VideoCaptureFormat::ToString(result_.settings.format()));
1141 }
1142
1143 {
1144 const double kIdealAspectRatio = 4000.0;
1145 constraint_factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
1146 SelectSettings();
1147 EXPECT_TRUE(result_.has_value());
1148 // The configuration closest to the ideal aspect ratio is is the high-res
1149 // device with its highest resolution, cropped to 2304x1.
1150 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1151 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
1152 media::VideoCaptureFormat::ToString(result_.settings.format()));
1153 }
1154
1155 {
1156 const double kIdealAspectRatio = 2.0;
1157 constraint_factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
1158 constraint_factory_.basic().height.setExact(400);
1159 SelectSettings();
1160 EXPECT_TRUE(result_.has_value());
1161 // The first device to support the ideal aspect ratio and the resolution
1162 // constraint is the low-res device. The 800x600 format cropped to 800x400
1163 // is the lest expensive way to achieve it.
1164 EXPECT_EQ(low_res_device_->device_id, result_.settings.device_id());
1165 EXPECT_EQ(800, result_.settings.GetWidth());
1166 EXPECT_EQ(600, result_.settings.GetHeight());
1167 }
1168
1169 {
1170 const double kIdealAspectRatio = 3.0;
1171 constraint_factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
1172 constraint_factory_.basic().height.setExact(400);
1173 SelectSettings();
1174 EXPECT_TRUE(result_.has_value());
1175 // The only device that supports the ideal aspect ratio and the resolution
1176 // constraint is the high-res device. The 1280x720 cropped to 1200x400 is
1177 // the lest expensive way to achieve it.
1178 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1179 EXPECT_EQ(1280, result_.settings.GetWidth());
1180 EXPECT_EQ(720, result_.settings.GetHeight());
1181 }
1182 }
1183
1184 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, AdvancedExactResolution) {
1185 {
1186 constraint_factory_.Reset();
1187 blink::WebMediaTrackConstraintSet& advanced1 =
1188 constraint_factory_.AddAdvanced();
1189 advanced1.width.setExact(4000);
1190 advanced1.height.setExact(4000);
1191 blink::WebMediaTrackConstraintSet& advanced2 =
1192 constraint_factory_.AddAdvanced();
1193 advanced2.width.setExact(3000);
1194 advanced2.height.setExact(3000);
1195 SelectSettings();
1196 // No device supports the advanced constraint sets.
1197 // Tie-breaker rule that applies is closeness to default settings.
1198 EXPECT_EQ(default_device_->device_id, result_.settings.device_id());
1199 EXPECT_EQ(media::VideoCaptureFormat::ToString(*default_closest_format_),
1200 media::VideoCaptureFormat::ToString(result_.settings.format()));
1201
1202 blink::WebMediaTrackConstraintSet& advanced3 =
1203 constraint_factory_.AddAdvanced();
1204 advanced3.width.setExact(1920);
1205 advanced3.height.setExact(1080);
1206 SelectSettings();
1207 EXPECT_TRUE(result_.has_value());
1208 // The high-res device natively supports the third advanced constraint set
1209 // and should be selected.
1210 // First tie-breaker rule that applies is support for advanced constraints
1211 // that appear first. Second tie-breaker rule is custom distance to advanced
1212 // constraint sets that appear first.
1213 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1214 EXPECT_EQ(1920, result_.settings.GetWidth());
1215 EXPECT_EQ(1080, result_.settings.GetHeight());
1216
1217 blink::WebMediaTrackConstraintSet& advanced4 =
1218 constraint_factory_.AddAdvanced();
1219 advanced4.width.setExact(640);
1220 advanced4.height.setExact(480);
1221 SelectSettings();
1222 EXPECT_TRUE(result_.has_value());
1223 // First tie-breaker rule that applies is support for advanced constraints
1224 // that appear first, which leaves out configurations that only support the
1225 // fourth advanced constraint set in favor of configurations that support
1226 // the third set.
1227 // Second tie-breaker rule is custom distance to advanced constraint sets
1228 // that appear first.
1229 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1230 EXPECT_EQ(1920, result_.settings.GetWidth());
1231 EXPECT_EQ(1080, result_.settings.GetHeight());
1232
1233 constraint_factory_.basic().width.setIdeal(800);
1234 constraint_factory_.basic().height.setIdeal(600);
1235 SelectSettings();
1236 EXPECT_TRUE(result_.has_value());
1237 // The ideal value is supported by the same configuration, so nothing
1238 // changes.
1239 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1240 EXPECT_EQ(1920, result_.settings.GetWidth());
1241 EXPECT_EQ(1080, result_.settings.GetHeight());
1242
1243 constraint_factory_.basic().width.setIdeal(2000);
1244 constraint_factory_.basic().height.setIdeal(1500);
1245 SelectSettings();
1246 EXPECT_TRUE(result_.has_value());
1247 // The closest configuration to the ideal resolution is the high-res device
1248 // at the highest resolution.
1249 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1250 EXPECT_EQ(media::VideoCaptureFormat::ToString(*high_res_highest_format_),
1251 media::VideoCaptureFormat::ToString(result_.settings.format()));
1252 }
1253 }
1254
1255 TEST_F(MediaStreamConstraintsUtilVideoSourceTest,
1256 AdvancedResolutionAndFrameRate) {
1257 {
1258 constraint_factory_.Reset();
1259 blink::WebMediaTrackConstraintSet& advanced1 =
1260 constraint_factory_.AddAdvanced();
1261 advanced1.width.setExact(1920);
1262 advanced1.height.setExact(1080);
1263 blink::WebMediaTrackConstraintSet& advanced2 =
1264 constraint_factory_.AddAdvanced();
1265 advanced2.frameRate.setExact(60.0);
1266 blink::WebMediaTrackConstraintSet& advanced3 =
1267 constraint_factory_.AddAdvanced();
1268 advanced3.width.setExact(2304);
1269 advanced3.height.setExact(1536);
1270 SelectSettings();
1271 EXPECT_TRUE(result_.has_value());
1272 // The high-res device is the only one that satisfies the first advanced
1273 // set. 2304x1536x10.0 satisfies sets 1 and 3, while 1920x1080x60.0
1274 // satisfies sets 1, and 2. The latter must be selected, regardless of
1275 // any other criteria.
1276 EXPECT_EQ(high_res_device_->device_id, result_.settings.device_id());
1277 EXPECT_EQ(1920, result_.settings.GetWidth());
1278 EXPECT_EQ(1080, result_.settings.GetHeight());
1279 EXPECT_EQ(60.0, result_.settings.GetFrameRate());
1280 }
1281 }
1282
1283 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, NoDevicesNoConstraints) {
1284 VideoCaptureCapabilities capabilities;
1285 constraint_factory_.Reset();
1286 auto result = SelectVideoCaptureSourceSettings(
1287 capabilities, constraint_factory_.CreateWebMediaConstraints());
1288 EXPECT_FALSE(result.has_value());
1289 EXPECT_TRUE(std::string(result.failed_constraint_name).empty());
1290 }
1291
1292 TEST_F(MediaStreamConstraintsUtilVideoSourceTest, NoDevicesWithConstraints) {
1293 VideoCaptureCapabilities capabilities;
1294 constraint_factory_.Reset();
1295 constraint_factory_.basic().height.setExact(100);
1296 auto result = SelectVideoCaptureSourceSettings(
1297 capabilities, constraint_factory_.CreateWebMediaConstraints());
1298 EXPECT_FALSE(result.has_value());
1299 EXPECT_TRUE(std::string(result.failed_constraint_name).empty());
1300 }
1301
1302 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698