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

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

Issue 2728633002: Add utility set classes to support getUserMedia constraint proccessing. (Closed)
Patch Set: Created 3 years, 9 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_sets.h"
6
7 #include <cmath>
8
9 #include "content/renderer/media/media_stream_constraints_util.h"
10 #include "content/renderer/media/media_stream_video_source.h"
11 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
12
13 namespace content {
14
15 using Point = ResolutionSet::Point;
16
17 namespace {
18
19 constexpr double kTolerance = 1e-5;
20
21 constexpr int kDefaultHeight = MediaStreamVideoSource::kDefaultHeight;
22 constexpr int kDefaultWidth = MediaStreamVideoSource::kDefaultWidth;
23 constexpr double kDefaultAspectRatio =
24 MediaStreamVideoSource::kDefaultAspectRatio;
25
26 // Not perfect, but good enough for this application.
27 bool AreApproximatelyEqual(double d1, double d2) {
28 if (std::fabs((d1 - d2)) <= kTolerance)
29 return true;
30
31 return d1 == d2 ||
hbos_chromium 2017/03/03 16:01:42 Isn't any value minus itself 0.0 even with finite
Guido Urdaneta 2017/03/06 11:08:22 No, it isn't in floating point. Inf-Inf is NaN. An
hbos_chromium 2017/03/08 21:03:00 Acknowledged.
32 (std::fabs((d1 - d2) / d1) <= kTolerance &&
33 std::fabs((d1 - d2) / d2) <= kTolerance);
hta - Chromium 2017/03/03 11:02:36 I'm trying to imagine a realistic case where you w
Guido Urdaneta 2017/03/06 11:08:22 d1=Inf, d2=Inf.
Guido Urdaneta 2017/03/06 15:08:21 The relative comparisons are for large values.
34 }
35
36 bool IsLess(double d1, double d2) {
37 return d1 < d2 && !AreApproximatelyEqual(d1, d2);
38 }
39
40 bool IsLessOrEqual(double d1, double d2) {
41 return d1 < d2 || AreApproximatelyEqual(d1, d2);
42 }
43
44 bool IsGreater(double d1, double d2) {
45 return d1 > d2 && !AreApproximatelyEqual(d1, d2);
46 }
47
48 bool IsGreaterOrEqual(double d1, double d2) {
49 return d1 > d2 || AreApproximatelyEqual(d1, d2);
50 }
51
52 int DimensionFromConstraintValue(long dimension) {
hta - Chromium 2017/03/03 11:02:36 Why return value int when argument is long? Consis
Guido Urdaneta 2017/03/06 11:08:22 This is intended to transform values coming from b
53 if (dimension > ResolutionSet::kMaxConstrainedDimension) {
54 return ResolutionSet::kMaxConstrainedDimension + 1;
55 } else if (dimension < ResolutionSet::kMinConstrainedDimension) {
56 return 0;
57 }
58
59 return static_cast<int>(dimension);
60 }
61
62 int MinDimensionFromConstraint(const blink::LongConstraint& constraint) {
63 if (!ConstraintHasMin(constraint))
64 return 0;
65
66 return DimensionFromConstraintValue(ConstraintMin(constraint));
67 }
68
69 int MaxDimensionFromConstraint(const blink::LongConstraint& constraint) {
70 if (!ConstraintHasMax(constraint))
71 return ResolutionSet::kMaxConstrainedDimension + 1;
72
73 return DimensionFromConstraintValue(ConstraintMax(constraint));
74 }
75
76 double AspectRatioFromConstraintValue(double aspect_ratio) {
77 return aspect_ratio < ResolutionSet::kMinConstrainedAspectRatio
78 ? 0.0
hta - Chromium 2017/03/03 11:02:36 Why 0.0 and not ResolutionSet::kMinConstrainedAspe
Guido Urdaneta 2017/03/06 11:08:22 The question became obsolete now that the concept
79 : aspect_ratio;
80 }
81
82 double MinAspectRatioFromConstraint(const blink::DoubleConstraint& constraint) {
83 if (!ConstraintHasMin(constraint))
84 return 0.0;
85
86 return AspectRatioFromConstraintValue(ConstraintMin(constraint));
87 }
88
89 double MaxAspectRatioFromConstraint(const blink::DoubleConstraint& constraint) {
90 if (!ConstraintHasMax(constraint))
91 return HUGE_VAL;
92
93 return AspectRatioFromConstraintValue(ConstraintMax(constraint));
94 }
95
96 // Utility to transform |dimension| to a value in the supported range.
97 // Useful for ideal values.
98 int ToValidConstrainedDimension(long dimension) {
hta - Chromium 2017/03/03 11:02:35 When you have these functions that change the valu
Guido Urdaneta 2017/03/06 11:08:22 Acknowledged. I removed the would-be Clamp functio
99 if (dimension > ResolutionSet::kMaxConstrainedDimension)
100 return ResolutionSet::kMaxConstrainedDimension;
101 else if (dimension < ResolutionSet::kMinConstrainedDimension)
102 return ResolutionSet::kMinConstrainedDimension;
103
104 return dimension;
105 }
106
107 // Utility to transform |aspect_ratio| to a value in the supported range.
108 // Useful for ideal values.
109 double ToValidConstrainedAspectRatio(double aspect_ratio) {
110 if (aspect_ratio > ResolutionSet::kMaxConstrainedAspectRatio)
111 return ResolutionSet::kMaxConstrainedAspectRatio;
112 else if (aspect_ratio < ResolutionSet::kMinConstrainedAspectRatio)
113 return ResolutionSet::kMinConstrainedAspectRatio;
114
115 return aspect_ratio;
116 }
117
118 // Returns the point in the segment determined by |vertices| closest to
119 // |point|.
120 // |vertices| must have 1 or 2 elements. Otherwise, behavior is undefined.
121 Point GetClosestPoint(const std::vector<Point> vertices, const Point& point) {
hbos_chromium 2017/03/03 16:01:41 1-2 vertices: is this to avoid having to check if
Guido Urdaneta 2017/03/06 11:08:22 Done. Also expanded the documentation a bit.
122 DCHECK(!vertices.empty());
123 // If only a single vertex closest to |point|, return that vertex.
124 if (vertices.size() == 1U)
125 return vertices[0];
126
127 DCHECK_EQ(vertices.size(), 2U);
128 // If a polygon side is closest to the ideal height, return the
129 // point with aspect ratio closest to the default.
130 return Point::ClosestPointInSegment(point, vertices[0], vertices[1]);
131 }
132
133 Point SelectPointWithLargestArea(const Point& p1, const Point& p2) {
134 return p1.width() * p1.height() > p2.width() * p2.height() ? p1 : p2;
135 }
136
137 } // namespace
138
139 Point::Point(double height, double width) : height_(height), width_(width) {}
140 Point::Point(const Point& other) = default;
141 Point& Point::operator=(const Point& other) = default;
142 Point::~Point() = default;
143
144 bool Point::operator==(const Point& other) const {
145 return height_ == other.height_ && width_ == other.width_;
146 }
147
148 bool Point::operator!=(const Point& other) const {
149 return !(*this == other);
150 }
151
152 bool Point::IsApproximatelyEqualTo(const Point& other) const {
153 return AreApproximatelyEqual(height_, other.height_) &&
154 AreApproximatelyEqual(width_, other.width_);
155 }
156
157 Point Point::operator+(const Point& other) const {
158 return Point(height_ + other.height_, width_ + other.width_);
159 }
160
161 Point Point::operator-(const Point& other) const {
162 return Point(height_ - other.height_, width_ - other.width_);
163 }
164
165 Point operator*(double d, const Point& p) {
166 return Point(d * p.height(), d * p.width());
167 }
168
169 // Returns the dot product between |p1| and |p2|.
170 // static
171 double Point::Dot(const Point& p1, const Point& p2) {
172 return p1.height_ * p2.height_ + p1.width_ * p2.width_;
173 }
174
175 // static
176 double Point::DistanceToPoint(const Point& p1, const Point& p2) {
177 Point diff = p1 - p2;
178 return Dot(diff, diff);
179 }
180
181 // static
182 Point Point::ClosestPointInSegment(const Point& p,
183 const Point& s1,
184 const Point& s2) {
185 // If |s1| and |s2| are the same, it is not really a segment. The closest
186 // point to |p| is |s1|=|s2|.
187 if (s1 == s2)
188 return s1;
189
190 // Translate coordinates to a system where the origin is |s1|.
191 Point p_trans = p - s1;
192 Point s2_trans = s2 - s1;
193
194 // On this system, we are interested in the projection of |p_trans| on
195 // |s2_trans|. The projection is m * |s2_trans|, where
196 // m = Dot(|s2_trans|, |p_trans|) / Dot(|s2_trans|, |s2_trans|).
197 // If 0 <= m <= 1, the projection falls within the segment, and the closest
198 // point is the projection itself.
199 // If m < 0, the closest point is S1.
200 // If m > 1, the closest point is S2.
201 double m = Dot(s2_trans, p_trans) / Dot(s2_trans, s2_trans);
202 if (m < 0)
203 return s1;
204 else if (m > 1)
205 return s2;
206
207 // Return the projection in the original coordinate system.
208 return s1 + m * s2_trans;
209 }
210
211 ResolutionSet::ResolutionSet(int min_height,
212 int max_height,
213 int min_width,
214 int max_width,
215 double min_aspect_ratio,
216 double max_aspect_ratio)
217 : min_height_(min_height),
218 max_height_(max_height),
219 min_width_(min_width),
220 max_width_(max_width),
221 min_aspect_ratio_(min_aspect_ratio),
222 max_aspect_ratio_(max_aspect_ratio) {
223 DCHECK_GE(min_height_, 0);
224 DCHECK_GE(max_height_, 0);
225 DCHECK_LE(max_height_, kMaxConstrainedDimension + 1);
226 DCHECK_GE(min_width_, 0);
227 DCHECK_GE(max_width_, 0);
228 DCHECK_LE(max_width_, kMaxConstrainedDimension + 1);
hbos_chromium 2017/03/03 16:01:42 Here and elsewhere I would prefer kMaxDimension.
Guido Urdaneta 2017/03/06 11:08:22 Done. Question: Do you refer to a kMaxDimension in
hbos_chromium 2017/03/08 21:03:00 This is good.
229 DCHECK_GE(min_aspect_ratio_, 0.0);
230 DCHECK_GE(max_aspect_ratio_, 0.0);
231 }
232
233 ResolutionSet::ResolutionSet()
234 : ResolutionSet(0,
235 kMaxConstrainedDimension + 1,
236 0,
237 kMaxConstrainedDimension + 1,
238 0.0,
239 HUGE_VAL) {}
240
241 ResolutionSet::ResolutionSet(const ResolutionSet& other) = default;
242 ResolutionSet::~ResolutionSet() = default;
243 ResolutionSet& ResolutionSet::operator=(const ResolutionSet& other) = default;
244
245 bool ResolutionSet::IsHeightEmpty() const {
246 return min_height_ > max_height_ || min_height_ > kMaxConstrainedDimension ||
247 max_height_ <= 0;
248 }
249
250 bool ResolutionSet::IsWidthEmpty() const {
251 return min_width_ > max_width_ || min_width_ > kMaxConstrainedDimension ||
252 max_width_ <= 0;
253 }
254
255 bool ResolutionSet::IsAspectRatioEmpty() const {
256 double max_resolution_aspect_ratio =
257 static_cast<double>(max_width_) / static_cast<double>(min_height_);
258 double min_resolution_aspect_ratio =
259 static_cast<double>(min_width_) / static_cast<double>(max_height_);
260
261 return IsGreater(min_aspect_ratio_, max_aspect_ratio_) ||
262 IsLess(max_resolution_aspect_ratio, min_aspect_ratio_) ||
263 IsGreater(min_resolution_aspect_ratio, max_aspect_ratio_) ||
264 !std::isfinite(min_aspect_ratio_) || max_aspect_ratio_ <= 0.0;
265 }
266
267 bool ResolutionSet::IsEmpty() const {
268 return IsHeightEmpty() || IsWidthEmpty() || IsAspectRatioEmpty();
269 }
270
271 // These functions return true if a particular variable is constrained.
272 bool ResolutionSet::HasMinHeight() const {
273 return min_height_ >= kMinConstrainedDimension;
274 }
275
276 bool ResolutionSet::HasMaxHeight() const {
277 return max_height_ <= kMaxConstrainedDimension;
278 }
279
280 bool ResolutionSet::HasMinWidth() const {
281 return min_width_ >= kMinConstrainedDimension;
282 }
283
284 bool ResolutionSet::HasMaxWidth() const {
285 return max_width_ <= kMaxConstrainedDimension;
286 }
287
288 bool ResolutionSet::HasMinAspectRatio() const {
289 return min_aspect_ratio_ > 0.0;
290 }
291
292 bool ResolutionSet::HasMaxAspectRatio() const {
293 return std::isfinite(max_aspect_ratio_);
294 }
295
296 bool ResolutionSet::IsHeightUnconstrained() const {
297 return !HasMinHeight() && !HasMaxHeight();
298 }
299
300 bool ResolutionSet::IsWidthUnconstrained() const {
301 return !HasMinWidth() && !HasMaxWidth();
302 }
303
304 bool ResolutionSet::IsAspectRatioUnconstrained() const {
305 return !HasMinAspectRatio() && !HasMaxAspectRatio();
306 }
307
308 bool ResolutionSet::ContainsPoint(int height, int width) const {
309 return ContainsPoint(Point(height, width));
310 }
311
312 bool ResolutionSet::ContainsPoint(const Point& point) const {
313 double ratio = point.width() / point.height();
hbos_chromium 2017/03/03 16:01:42 Watch out for divide by zero!
Guido Urdaneta 2017/03/06 11:08:22 Inf aspect ratio is fine. NaN (0/0) or (Inf/Inf) i
hbos_chromium 2017/03/08 21:03:00 Acknowledged.
314 // (0.0, 0.0) is always included in the aspect-ratio range.
hbos_chromium 2017/03/03 16:01:42 Why? If min resolution is > (0,0) then it isn't co
Guido Urdaneta 2017/03/06 11:08:22 In that case (0,0) would be part of the set of poi
hbos_chromium 2017/03/08 21:03:00 Acknowledged.
315 return point.height() >= min_height_ && point.height() <= max_height_ &&
316 point.width() >= min_width_ && point.width() <= max_width_ &&
317 ((IsGreaterOrEqual(ratio, min_aspect_ratio_) &&
318 IsLessOrEqual(ratio, max_aspect_ratio_)) ||
319 (point.width() == 0.0 && point.height() == 0.0));
hbos_chromium 2017/03/03 16:01:42 (Good that the comparators take precision errors i
Guido Urdaneta 2017/03/06 11:08:22 Acknowledged.
320 }
321
322 ResolutionSet ResolutionSet::Intersection(const ResolutionSet& other) const {
323 return ResolutionSet(std::max(min_height_, other.min_height_),
324 std::min(max_height_, other.max_height_),
325 std::max(min_width_, other.min_width_),
326 std::min(max_width_, other.max_width_),
327 std::max(min_aspect_ratio_, other.min_aspect_ratio_),
328 std::min(max_aspect_ratio_, other.max_aspect_ratio_));
hbos_chromium 2017/03/03 16:01:41 I think this is incorrect if there is an offset be
Guido Urdaneta 2017/03/06 11:08:22 The case you are showing is impossible here. All a
hbos_chromium 2017/03/08 21:03:00 Acknowledged.
329 }
330
331 Point ResolutionSet::ClosestPointTo(const Point& point) const {
332 DCHECK(std::numeric_limits<double>::has_infinity);
333
334 if (ContainsPoint(point))
335 return point;
336
337 auto vertices = ComputeVertices();
338 DCHECK_GE(vertices.size(), 1U);
339 Point best_candidate(0, 0);
340 double best_distance = HUGE_VAL;
341 for (size_t i = 0; i < vertices.size(); ++i) {
342 Point candidate = Point::ClosestPointInSegment(
343 point, vertices[i], vertices[(i + 1) % vertices.size()]);
344 double distance = Point::DistanceToPoint(point, candidate);
345 if (distance < best_distance) {
346 best_candidate = candidate;
347 best_distance = distance;
348 }
349 }
350
351 DCHECK(std::isfinite(best_distance));
352 return best_candidate;
353 }
354
355 std::vector<Point> ResolutionSet::GetClosestVertices(double (Point::*accessor)()
356 const,
357 double value) const {
358 DCHECK(!IsEmpty());
359 std::vector<Point> vertices = ComputeVertices();
360 std::vector<Point> closest_vertices;
361 double best_diff = HUGE_VAL;
362 for (const auto& vertex : vertices) {
363 double diff = std::fabs((vertex.*accessor)() - value);
364 if (diff <= best_diff) {
365 if (diff < best_diff) {
366 best_diff = diff;
367 closest_vertices.clear();
368 }
369 closest_vertices.push_back(vertex);
370 }
371 }
372 DCHECK(!closest_vertices.empty());
373 DCHECK_LE(closest_vertices.size(), 2U);
374 return closest_vertices;
375 }
376
377 Point ResolutionSet::SelectClosestPointToIdealAspectRatio(
378 double ideal_aspect_ratio) const {
379 ResolutionSet intersection =
380 Intersection(ResolutionSet::FromExactAspectRatio(ideal_aspect_ratio));
381 if (!intersection.IsEmpty()) {
382 Point default_height_point(kDefaultHeight,
383 kDefaultHeight * ideal_aspect_ratio);
384 Point default_width_point(kDefaultWidth / ideal_aspect_ratio,
385 kDefaultWidth);
386 return SelectPointWithLargestArea(
387 intersection.ClosestPointTo(default_height_point),
388 intersection.ClosestPointTo(default_width_point));
389 }
390 std::vector<Point> closest_vertices =
391 GetClosestVertices(&Point::AspectRatio, ideal_aspect_ratio);
392 double actual_aspect_ratio = closest_vertices[0].AspectRatio();
393 Point default_height_point(kDefaultHeight,
394 kDefaultHeight * actual_aspect_ratio);
395 Point default_width_point(kDefaultWidth / actual_aspect_ratio, kDefaultWidth);
396 return SelectPointWithLargestArea(
397 GetClosestPoint(closest_vertices, default_height_point),
398 GetClosestPoint(closest_vertices, default_width_point));
399 }
400
401 Point ResolutionSet::SelectClosestPointToIdeal(
402 const blink::WebMediaTrackConstraintSet& constraint_set) const {
403 DCHECK(!IsEmpty());
404 int num_ideals = 0;
405 if (constraint_set.height.hasIdeal())
406 ++num_ideals;
407 if (constraint_set.width.hasIdeal())
408 ++num_ideals;
409 if (constraint_set.aspectRatio.hasIdeal())
410 ++num_ideals;
411
412 switch (num_ideals) {
413 case 0:
414 return SelectClosestPointToIdealAspectRatio(kDefaultAspectRatio);
415
416 case 1:
417 // This case requires a point closest to a line.
418 // In all variants, if the ideal line intersects the polygon, select the
419 // point in the intersection that is closest to preserving the default
420 // aspect ratio or a default dimension.
421 // If the ideal line is outside the polygon, there is either a single
422 // vertex or a polygon side closest to the ideal line. If a single vertex,
423 // select that vertex. If a polygon side, select the point on that side
424 // that is closest to preserving the default aspect ratio or a default
425 // dimension.
426 if (constraint_set.height.hasIdeal()) {
427 int ideal_height =
428 ToValidConstrainedDimension(constraint_set.height.ideal());
429 ResolutionSet ideal_line = ResolutionSet::FromExactHeight(ideal_height);
430 ResolutionSet intersection = Intersection(ideal_line);
431 if (!intersection.IsEmpty()) {
432 return intersection.ClosestPointTo(
433 Point(ideal_height, ideal_height * kDefaultAspectRatio));
434 }
435 std::vector<Point> closest_vertices =
436 GetClosestVertices(&Point::height, ideal_height);
437 Point ideal_point(closest_vertices[0].height(),
438 closest_vertices[0].height() * kDefaultAspectRatio);
439 return GetClosestPoint(closest_vertices, ideal_point);
440 } else if (constraint_set.width.hasIdeal()) {
441 int ideal_width =
442 ToValidConstrainedDimension(constraint_set.width.ideal());
443 ResolutionSet ideal_line = ResolutionSet::FromExactWidth(ideal_width);
444 ResolutionSet intersection = Intersection(ideal_line);
445 if (!intersection.IsEmpty()) {
446 return intersection.ClosestPointTo(
447 Point(ideal_width / kDefaultAspectRatio, ideal_width));
448 }
449 std::vector<Point> closest_vertices =
450 GetClosestVertices(&Point::width, ideal_width);
451 Point ideal_point(closest_vertices[0].width() / kDefaultAspectRatio,
452 closest_vertices[0].width());
453 return GetClosestPoint(closest_vertices, ideal_point);
454 } else {
455 DCHECK(constraint_set.aspectRatio.hasIdeal());
456 double ideal_aspect_ratio =
457 ToValidConstrainedAspectRatio(constraint_set.aspectRatio.ideal());
458 return SelectClosestPointToIdealAspectRatio(ideal_aspect_ratio);
459 }
460 NOTREACHED();
461
462 default:
hta - Chromium 2017/03/03 11:02:36 This is the case that will handle 2 and 3 ideal va
Guido Urdaneta 2017/03/06 11:08:22 Done.
463 double ideal_height;
464 double ideal_width;
465 if (constraint_set.height.hasIdeal()) {
466 ideal_height =
467 ToValidConstrainedDimension(constraint_set.height.ideal());
468 ideal_width =
469 constraint_set.width.hasIdeal()
470 ? ToValidConstrainedDimension(constraint_set.width.ideal())
471 : ideal_height *
472 ToValidConstrainedAspectRatio(
473 constraint_set.aspectRatio.ideal());
474 } else {
475 DCHECK(constraint_set.width.hasIdeal());
476 DCHECK(constraint_set.aspectRatio.hasIdeal());
477 ideal_width = ToValidConstrainedDimension(constraint_set.width.ideal());
478 ideal_height =
479 ideal_width /
480 ToValidConstrainedAspectRatio(constraint_set.aspectRatio.ideal());
481 }
482 return ClosestPointTo(Point(ideal_height, ideal_width));
483 }
484 NOTREACHED();
485 }
486
487 // static
488 ResolutionSet ResolutionSet::FromHeight(int min, int max) {
489 return ResolutionSet(min, max, 0, kMaxConstrainedDimension + 1, 0.0,
490 HUGE_VAL);
491 }
492
493 // static
494 ResolutionSet ResolutionSet::FromExactHeight(int value) {
495 return ResolutionSet(value, value, 0, kMaxConstrainedDimension + 1, 0.0,
496 HUGE_VAL);
497 }
498
499 // static
500 ResolutionSet ResolutionSet::FromWidth(int min, int max) {
501 return ResolutionSet(0, kMaxConstrainedDimension + 1, min, max, 0.0,
502 HUGE_VAL);
503 }
504
505 // static
506 ResolutionSet ResolutionSet::FromExactWidth(int value) {
507 return ResolutionSet(0, kMaxConstrainedDimension + 1, value, value, 0.0,
508 HUGE_VAL);
509 }
510
511 // static
512 ResolutionSet ResolutionSet::FromAspectRatio(double min, double max) {
513 return ResolutionSet(0, kMaxConstrainedDimension + 1, 0,
514 kMaxConstrainedDimension + 1, min, max);
515 }
516
517 // static
518 ResolutionSet ResolutionSet::FromExactAspectRatio(double value) {
519 return ResolutionSet(0, kMaxConstrainedDimension + 1, 0,
520 kMaxConstrainedDimension + 1, value, value);
521 }
522
523 std::vector<Point> ResolutionSet::ComputeVertices() const {
524 std::vector<Point> vertices;
525 // Add vertices in counterclockwise order
526 // Start with min_height, min_width and continue along min_width.
527 TryAddVertex(&vertices, Point(min_height_, min_width_));
528 TryAddVertex(&vertices, Point(min_width_ / max_aspect_ratio_, min_width_));
529 TryAddVertex(&vertices, Point(min_width_ / min_aspect_ratio_, min_width_));
530 TryAddVertex(&vertices, Point(max_height_, min_width_));
531 // Continue along max_height.
532 TryAddVertex(&vertices, Point(max_height_, max_height_ * min_aspect_ratio_));
533 TryAddVertex(&vertices, Point(max_height_, max_height_ * max_aspect_ratio_));
534 TryAddVertex(&vertices, Point(max_height_, max_width_));
535 // Continue along max_width.
536 TryAddVertex(&vertices, Point(max_width_ / min_aspect_ratio_, max_width_));
537 TryAddVertex(&vertices, Point(max_width_ / max_aspect_ratio_, max_width_));
538 TryAddVertex(&vertices, Point(min_height_, max_width_));
539 // Finish along min_height.
540 TryAddVertex(&vertices, Point(min_height_, min_height_ * max_aspect_ratio_));
541 TryAddVertex(&vertices, Point(min_height_, min_height_ * min_aspect_ratio_));
542
543 DCHECK_LE(vertices.size(), 6U);
544 return vertices;
545 }
546
547 void ResolutionSet::TryAddVertex(std::vector<Point>* vertices,
548 const Point& point) const {
549 if (!ContainsPoint(point))
550 return;
551
552 // Add the point to the |vertices| if not already added.
553 // This is to prevent duplicates in case an aspect ratio intersects a width
554 // or height right on a vertex.
555 if (vertices->empty() ||
556 (*(vertices->end() - 1) != point && *vertices->begin() != point)) {
557 vertices->push_back(point);
558 }
559 }
560
561 ResolutionSet ResolutionSet::FromConstraintSet(
562 const blink::WebMediaTrackConstraintSet& constraint_set) {
563 return ResolutionSet(
564 MinDimensionFromConstraint(constraint_set.height),
565 MaxDimensionFromConstraint(constraint_set.height),
566 MinDimensionFromConstraint(constraint_set.width),
567 MaxDimensionFromConstraint(constraint_set.width),
568 MinAspectRatioFromConstraint(constraint_set.aspectRatio),
569 MaxAspectRatioFromConstraint(constraint_set.aspectRatio));
570 }
571
572 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698