| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |