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

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

Issue 2777703002: Introduce SelectSettings algorithm for MediaStream video tracks. (Closed)
Patch Set: static asserts Created 3 years, 8 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
1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/media_stream_constraints_util_sets.h" 5 #include "content/renderer/media/media_stream_constraints_util_sets.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "content/renderer/media/media_stream_constraints_util.h" 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" 10 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
12 11
13 namespace content { 12 namespace content {
14 13
15 using Point = ResolutionSet::Point; 14 using Point = ResolutionSet::Point;
16 15
17 namespace { 16 namespace {
18 17
19 constexpr double kTolerance = 1e-5; 18 constexpr double kTolerance = 1e-5;
20 19
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. 20 // Not perfect, but good enough for this application.
27 bool AreApproximatelyEqual(double d1, double d2) { 21 bool AreApproximatelyEqual(double d1, double d2) {
28 if (std::fabs((d1 - d2)) <= kTolerance) 22 if (std::fabs((d1 - d2)) <= kTolerance)
29 return true; 23 return true;
30 24
31 return d1 == d2 || (std::fabs((d1 - d2) / d1) <= kTolerance && 25 return d1 == d2 || (std::fabs((d1 - d2) / d1) <= kTolerance &&
32 std::fabs((d1 - d2) / d2) <= kTolerance); 26 std::fabs((d1 - d2) / d2) <= kTolerance);
33 } 27 }
34 28
35 bool IsLess(double d1, double d2) { 29 bool IsLess(double d1, double d2) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 ResolutionSet ResolutionSet::Intersection(const ResolutionSet& other) const { 261 ResolutionSet ResolutionSet::Intersection(const ResolutionSet& other) const {
268 return ResolutionSet(std::max(min_height_, other.min_height_), 262 return ResolutionSet(std::max(min_height_, other.min_height_),
269 std::min(max_height_, other.max_height_), 263 std::min(max_height_, other.max_height_),
270 std::max(min_width_, other.min_width_), 264 std::max(min_width_, other.min_width_),
271 std::min(max_width_, other.max_width_), 265 std::min(max_width_, other.max_width_),
272 std::max(min_aspect_ratio_, other.min_aspect_ratio_), 266 std::max(min_aspect_ratio_, other.min_aspect_ratio_),
273 std::min(max_aspect_ratio_, other.max_aspect_ratio_)); 267 std::min(max_aspect_ratio_, other.max_aspect_ratio_));
274 } 268 }
275 269
276 Point ResolutionSet::SelectClosestPointToIdeal( 270 Point ResolutionSet::SelectClosestPointToIdeal(
277 const blink::WebMediaTrackConstraintSet& constraint_set) const { 271 const blink::WebMediaTrackConstraintSet& constraint_set,
272 int default_height,
273 int default_width) const {
274 DCHECK_GE(default_height, 1);
275 DCHECK_GE(default_width, 1);
276 double default_aspect_ratio =
277 static_cast<double>(default_width) / static_cast<double>(default_height);
278
278 DCHECK(!IsEmpty()); 279 DCHECK(!IsEmpty());
279 int num_ideals = 0; 280 int num_ideals = 0;
280 if (constraint_set.height.hasIdeal()) 281 if (constraint_set.height.hasIdeal())
281 ++num_ideals; 282 ++num_ideals;
282 if (constraint_set.width.hasIdeal()) 283 if (constraint_set.width.hasIdeal())
283 ++num_ideals; 284 ++num_ideals;
284 if (constraint_set.aspectRatio.hasIdeal()) 285 if (constraint_set.aspectRatio.hasIdeal())
285 ++num_ideals; 286 ++num_ideals;
286 287
287 switch (num_ideals) { 288 switch (num_ideals) {
288 case 0: 289 case 0:
289 return SelectClosestPointToIdealAspectRatio(kDefaultAspectRatio); 290 return SelectClosestPointToIdealAspectRatio(
291 default_aspect_ratio, default_height, default_width);
290 292
291 case 1: 293 case 1:
292 // This case requires a point closest to a line. 294 // This case requires a point closest to a line.
293 // In all variants, if the ideal line intersects the polygon, select the 295 // In all variants, if the ideal line intersects the polygon, select the
294 // point in the intersection that is closest to preserving the default 296 // point in the intersection that is closest to preserving the default
295 // aspect ratio or a default dimension. 297 // aspect ratio or a default dimension.
296 // If the ideal line is outside the polygon, there is either a single 298 // If the ideal line is outside the polygon, there is either a single
297 // vertex or a polygon side closest to the ideal line. If a single vertex, 299 // vertex or a polygon side closest to the ideal line. If a single vertex,
298 // select that vertex. If a polygon side, select the point on that side 300 // select that vertex. If a polygon side, select the point on that side
299 // that is closest to preserving the default aspect ratio or a default 301 // that is closest to preserving the default aspect ratio or a default
300 // dimension. 302 // dimension.
301 if (constraint_set.height.hasIdeal()) { 303 if (constraint_set.height.hasIdeal()) {
302 int ideal_height = ToValidDimension(constraint_set.height.ideal()); 304 int ideal_height = ToValidDimension(constraint_set.height.ideal());
303 ResolutionSet ideal_line = ResolutionSet::FromExactHeight(ideal_height); 305 ResolutionSet ideal_line = ResolutionSet::FromExactHeight(ideal_height);
304 ResolutionSet intersection = Intersection(ideal_line); 306 ResolutionSet intersection = Intersection(ideal_line);
305 if (!intersection.IsEmpty()) { 307 if (!intersection.IsEmpty()) {
306 return intersection.ClosestPointTo( 308 return intersection.ClosestPointTo(
307 Point(ideal_height, ideal_height * kDefaultAspectRatio)); 309 Point(ideal_height, ideal_height * default_aspect_ratio));
308 } 310 }
309 std::vector<Point> closest_vertices = 311 std::vector<Point> closest_vertices =
310 GetClosestVertices(&Point::height, ideal_height); 312 GetClosestVertices(&Point::height, ideal_height);
311 Point ideal_point(closest_vertices[0].height(), 313 Point ideal_point(closest_vertices[0].height(),
312 closest_vertices[0].height() * kDefaultAspectRatio); 314 closest_vertices[0].height() * default_aspect_ratio);
313 return GetClosestPointToVertexOrSide(closest_vertices, ideal_point); 315 return GetClosestPointToVertexOrSide(closest_vertices, ideal_point);
314 } else if (constraint_set.width.hasIdeal()) { 316 } else if (constraint_set.width.hasIdeal()) {
315 int ideal_width = ToValidDimension(constraint_set.width.ideal()); 317 int ideal_width = ToValidDimension(constraint_set.width.ideal());
316 ResolutionSet ideal_line = ResolutionSet::FromExactWidth(ideal_width); 318 ResolutionSet ideal_line = ResolutionSet::FromExactWidth(ideal_width);
317 ResolutionSet intersection = Intersection(ideal_line); 319 ResolutionSet intersection = Intersection(ideal_line);
318 if (!intersection.IsEmpty()) { 320 if (!intersection.IsEmpty()) {
319 return intersection.ClosestPointTo( 321 return intersection.ClosestPointTo(
320 Point(ideal_width / kDefaultAspectRatio, ideal_width)); 322 Point(ideal_width / default_aspect_ratio, ideal_width));
321 } 323 }
322 std::vector<Point> closest_vertices = 324 std::vector<Point> closest_vertices =
323 GetClosestVertices(&Point::width, ideal_width); 325 GetClosestVertices(&Point::width, ideal_width);
324 Point ideal_point(closest_vertices[0].width() / kDefaultAspectRatio, 326 Point ideal_point(closest_vertices[0].width() / default_aspect_ratio,
325 closest_vertices[0].width()); 327 closest_vertices[0].width());
326 return GetClosestPointToVertexOrSide(closest_vertices, ideal_point); 328 return GetClosestPointToVertexOrSide(closest_vertices, ideal_point);
327 } else { 329 } else {
328 DCHECK(constraint_set.aspectRatio.hasIdeal()); 330 DCHECK(constraint_set.aspectRatio.hasIdeal());
329 double ideal_aspect_ratio = 331 double ideal_aspect_ratio =
330 ToValidAspectRatio(constraint_set.aspectRatio.ideal()); 332 ToValidAspectRatio(constraint_set.aspectRatio.ideal());
331 return SelectClosestPointToIdealAspectRatio(ideal_aspect_ratio); 333 return SelectClosestPointToIdealAspectRatio(
334 ideal_aspect_ratio, default_height, default_width);
332 } 335 }
333 336
334 case 2: 337 case 2:
335 case 3: 338 case 3:
336 double ideal_height; 339 double ideal_height;
337 double ideal_width; 340 double ideal_width;
338 if (constraint_set.height.hasIdeal()) { 341 if (constraint_set.height.hasIdeal()) {
339 ideal_height = ToValidDimension(constraint_set.height.ideal()); 342 ideal_height = ToValidDimension(constraint_set.height.ideal());
340 ideal_width = 343 ideal_width =
341 constraint_set.width.hasIdeal() 344 constraint_set.width.hasIdeal()
(...skipping 10 matching lines...) Expand all
352 return ClosestPointTo(Point(ideal_height, ideal_width)); 355 return ClosestPointTo(Point(ideal_height, ideal_width));
353 356
354 default: 357 default:
355 NOTREACHED(); 358 NOTREACHED();
356 } 359 }
357 NOTREACHED(); 360 NOTREACHED();
358 return Point(-1, -1); 361 return Point(-1, -1);
359 } 362 }
360 363
361 Point ResolutionSet::SelectClosestPointToIdealAspectRatio( 364 Point ResolutionSet::SelectClosestPointToIdealAspectRatio(
362 double ideal_aspect_ratio) const { 365 double ideal_aspect_ratio,
366 int default_height,
367 int default_width) const {
363 ResolutionSet intersection = 368 ResolutionSet intersection =
364 Intersection(ResolutionSet::FromExactAspectRatio(ideal_aspect_ratio)); 369 Intersection(ResolutionSet::FromExactAspectRatio(ideal_aspect_ratio));
365 if (!intersection.IsEmpty()) { 370 if (!intersection.IsEmpty()) {
366 Point default_height_point(kDefaultHeight, 371 Point default_height_point(default_height,
367 kDefaultHeight * ideal_aspect_ratio); 372 default_height * ideal_aspect_ratio);
368 Point default_width_point(kDefaultWidth / ideal_aspect_ratio, 373 Point default_width_point(default_width / ideal_aspect_ratio,
369 kDefaultWidth); 374 default_width);
370 return SelectPointWithLargestArea( 375 return SelectPointWithLargestArea(
371 intersection.ClosestPointTo(default_height_point), 376 intersection.ClosestPointTo(default_height_point),
372 intersection.ClosestPointTo(default_width_point)); 377 intersection.ClosestPointTo(default_width_point));
373 } 378 }
374 std::vector<Point> closest_vertices = 379 std::vector<Point> closest_vertices =
375 GetClosestVertices(&Point::AspectRatio, ideal_aspect_ratio); 380 GetClosestVertices(&Point::AspectRatio, ideal_aspect_ratio);
376 double actual_aspect_ratio = closest_vertices[0].AspectRatio(); 381 double actual_aspect_ratio = closest_vertices[0].AspectRatio();
377 Point default_height_point(kDefaultHeight, 382 Point default_height_point(default_height,
378 kDefaultHeight * actual_aspect_ratio); 383 default_height * actual_aspect_ratio);
379 Point default_width_point(kDefaultWidth / actual_aspect_ratio, kDefaultWidth); 384 Point default_width_point(default_width / actual_aspect_ratio, default_width);
380 return SelectPointWithLargestArea( 385 return SelectPointWithLargestArea(
381 GetClosestPointToVertexOrSide(closest_vertices, default_height_point), 386 GetClosestPointToVertexOrSide(closest_vertices, default_height_point),
382 GetClosestPointToVertexOrSide(closest_vertices, default_width_point)); 387 GetClosestPointToVertexOrSide(closest_vertices, default_width_point));
383 } 388 }
384 389
385 Point ResolutionSet::ClosestPointTo(const Point& point) const { 390 Point ResolutionSet::ClosestPointTo(const Point& point) const {
386 DCHECK(std::numeric_limits<double>::has_infinity); 391 DCHECK(std::numeric_limits<double>::has_infinity);
392 DCHECK(std::isfinite(point.height()));
393 DCHECK(std::isfinite(point.width()));
387 394
388 if (ContainsPoint(point)) 395 if (ContainsPoint(point))
389 return point; 396 return point;
390 397
391 auto vertices = ComputeVertices(); 398 auto vertices = ComputeVertices();
392 DCHECK_GE(vertices.size(), 1U); 399 DCHECK_GE(vertices.size(), 1U);
393 Point best_candidate(0, 0); 400 Point best_candidate(0, 0);
394 double best_distance = HUGE_VAL; 401 double best_distance = HUGE_VAL;
395 for (size_t i = 0; i < vertices.size(); ++i) { 402 for (size_t i = 0; i < vertices.size(); ++i) {
396 Point candidate = Point::ClosestPointInSegment( 403 Point candidate = Point::ClosestPointInSegment(
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 return ResolutionSet( 527 return ResolutionSet(
521 MinDimensionFromConstraint(constraint_set.height), 528 MinDimensionFromConstraint(constraint_set.height),
522 MaxDimensionFromConstraint(constraint_set.height), 529 MaxDimensionFromConstraint(constraint_set.height),
523 MinDimensionFromConstraint(constraint_set.width), 530 MinDimensionFromConstraint(constraint_set.width),
524 MaxDimensionFromConstraint(constraint_set.width), 531 MaxDimensionFromConstraint(constraint_set.width),
525 MinAspectRatioFromConstraint(constraint_set.aspectRatio), 532 MinAspectRatioFromConstraint(constraint_set.aspectRatio),
526 MaxAspectRatioFromConstraint(constraint_set.aspectRatio)); 533 MaxAspectRatioFromConstraint(constraint_set.aspectRatio));
527 } 534 }
528 535
529 } // namespace content 536 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698