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