| 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 #ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_ | 5 #ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_ |
| 6 #define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_ | 6 #define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_ |
| 7 | 7 |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 bool is_universal_; | 136 bool is_universal_; |
| 137 std::vector<T> elements_; | 137 std::vector<T> elements_; |
| 138 }; | 138 }; |
| 139 | 139 |
| 140 // This class represents a set of (height, width) screen resolution candidates | 140 // This class represents a set of (height, width) screen resolution candidates |
| 141 // determined by width, height and aspect-ratio constraints. | 141 // determined by width, height and aspect-ratio constraints. |
| 142 // This class supports widths and heights from 0 to kMaxDimension, both | 142 // This class supports widths and heights from 0 to kMaxDimension, both |
| 143 // inclusive and aspect ratios from 0.0 to positive infinity, both inclusive. | 143 // inclusive and aspect ratios from 0.0 to positive infinity, both inclusive. |
| 144 class CONTENT_EXPORT ResolutionSet { | 144 class CONTENT_EXPORT ResolutionSet { |
| 145 public: | 145 public: |
| 146 static constexpr int kMaxDimension = std::numeric_limits<int>::max(); | 146 static const int kMaxDimension = std::numeric_limits<int>::max(); |
| 147 | 147 |
| 148 // Helper class that represents (height, width) points on a plane. | 148 // Helper class that represents (height, width) points on a plane. |
| 149 // TODO(guidou): Use a generic point/vector class that uses double once it | 149 // TODO(guidou): Use a generic point/vector class that uses double once it |
| 150 // becomes available (e.g., a gfx::Vector2dD). | 150 // becomes available (e.g., a gfx::Vector2dD). |
| 151 class CONTENT_EXPORT Point { | 151 class CONTENT_EXPORT Point { |
| 152 public: | 152 public: |
| 153 // Creates a (|height|, |width|) point. |height| and |width| must be finite. | 153 // Creates a (|height|, |width|) point. |height| and |width| must be finite. |
| 154 Point(double height, double width); | 154 Point(double height, double width); |
| 155 Point(const Point& other); | 155 Point(const Point& other); |
| 156 Point& operator=(const Point& other); | 156 Point& operator=(const Point& other); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 // * If two ideal values are given, they are used to determine a single ideal | 239 // * If two ideal values are given, they are used to determine a single ideal |
| 240 // point, which can be one of: | 240 // point, which can be one of: |
| 241 // - (|ideal_height|, |ideal_width|), | 241 // - (|ideal_height|, |ideal_width|), |
| 242 // - (|ideal_height|, |ideal_height|*|ideal_aspect_ratio|), or | 242 // - (|ideal_height|, |ideal_height|*|ideal_aspect_ratio|), or |
| 243 // - (|ideal_width| / |ideal_aspect_ratio|, |ideal_width|). | 243 // - (|ideal_width| / |ideal_aspect_ratio|, |ideal_width|). |
| 244 // The point in the set closest to the ideal point is returned. | 244 // The point in the set closest to the ideal point is returned. |
| 245 // * If a single ideal value is given, a point in the set closest to the line | 245 // * If a single ideal value is given, a point in the set closest to the line |
| 246 // defined by the ideal value is returned. If there is more than one point | 246 // defined by the ideal value is returned. If there is more than one point |
| 247 // closest to the ideal line, the following tie-breaker rules are used: | 247 // closest to the ideal line, the following tie-breaker rules are used: |
| 248 // - If |ideal_height| is provided, the point closest to | 248 // - If |ideal_height| is provided, the point closest to |
| 249 // (|ideal_height|, |ideal_height| * kDefaultAspectRatio). | 249 // (|ideal_height|, |ideal_height| * default_aspect_ratio), where |
| 250 // default_aspect_ratio is the result of the floating-point division |
| 251 // |default_width|/|default_height|. |
| 250 // - If |ideal_width| is provided, the point closest to | 252 // - If |ideal_width| is provided, the point closest to |
| 251 // (|ideal_width| / kDefaultAspectRatio, |ideal_width|). | 253 // (|ideal_width| / default_aspect_ratio, |ideal_width|). |
| 252 // - If |ideal_aspect_ratio| is provided, the point with largest area among | 254 // - If |ideal_aspect_ratio| is provided, the point with largest area among |
| 253 // the points closest to | 255 // the points closest to |
| 254 // (kDefaultHeight, kDefaultHeight * aspect_ratio) and | 256 // (|default_height|, |default_height| * aspect_ratio) and |
| 255 // (kDefaultWidth / aspect_ratio, kDefaultWidth), | 257 // (|default_width| / aspect_ratio, |default_width|), |
| 256 // where aspect_ratio is |ideal_aspect_ratio| if the ideal line intersects | 258 // where aspect_ratio is |ideal_aspect_ratio| if the ideal line intersects |
| 257 // the set, and the closest aspect ratio to |ideal_aspect_ratio| among the | 259 // the set, and the closest aspect ratio to |ideal_aspect_ratio| among the |
| 258 // points in the set if no point in the set has an aspect ratio equal to | 260 // points in the set if no point in the set has an aspect ratio equal to |
| 259 // |ideal_aspect_ratio|. | 261 // |ideal_aspect_ratio|. |
| 260 // * If no ideal value is given, proceed as if only |ideal_aspect_ratio| was | 262 // * If no ideal value is given, proceed as if only |ideal_aspect_ratio| was |
| 261 // provided with a value of kDefaultAspectRatio. | 263 // provided with a value of default_aspect_ratio. |
| 262 // | 264 // |
| 263 // This is intended to support the implementation of the spec algorithm for | 265 // This is intended to support the implementation of the spec algorithm for |
| 264 // selection of track settings, as defined in | 266 // selection of track settings, as defined in |
| 265 // https://w3c.github.io/mediacapture-main/#dfn-selectsettings. | 267 // https://w3c.github.io/mediacapture-main/#dfn-selectsettings. |
| 266 // | 268 // |
| 267 // The main difference between this algorithm and the spec is that when ideal | 269 // The main difference between this algorithm and the spec is that when ideal |
| 268 // values are provided, the spec mandates finding a point that minimizes the | 270 // values are provided, the spec mandates finding a point that minimizes the |
| 269 // sum of custom relative distances for each provided ideal value, while this | 271 // sum of custom relative distances for each provided ideal value, while this |
| 270 // algorithm minimizes either the Euclidean distance (sum of square distances) | 272 // algorithm minimizes either the Euclidean distance (sum of square distances) |
| 271 // on a height-width plane for the cases where two or three ideal values are | 273 // on a height-width plane for the cases where two or three ideal values are |
| 272 // provided, or the absolute distance for the case with one ideal value. | 274 // provided, or the absolute distance for the case with one ideal value. |
| 273 // Also, in the case with three ideal values, this algorithm ignores the | 275 // Also, in the case with three ideal values, this algorithm ignores the |
| 274 // distance to the ideal aspect ratio. | 276 // distance to the ideal aspect ratio. |
| 275 // In most cases the difference in the final result should be negligible. | 277 // In most cases the difference in the final result should be negligible. |
| 276 // The reason to follow this approach is that optimization in the worst case | 278 // The reason to follow this approach is that optimization in the worst case |
| 277 // is reduced to projection of a point on line segment, which is a simple | 279 // is reduced to projection of a point on line segment, which is a simple |
| 278 // operation that provides exact results. Using the distance function of the | 280 // operation that provides exact results. Using the distance function of the |
| 279 // spec, which is not continuous, would require complex optimization methods | 281 // spec, which is not continuous, would require complex optimization methods |
| 280 // that do not necessarily guarantee finding the real optimal value. | 282 // that do not necessarily guarantee finding the real optimal value. |
| 281 // | 283 // |
| 282 // This function has undefined behavior if this set is empty. | 284 // This function has undefined behavior if this set is empty. |
| 283 Point SelectClosestPointToIdeal( | 285 Point SelectClosestPointToIdeal( |
| 284 const blink::WebMediaTrackConstraintSet& constraint_set) const; | 286 const blink::WebMediaTrackConstraintSet& constraint_set, |
| 287 int default_height, |
| 288 int default_width) const; |
| 285 | 289 |
| 286 // Utilities that return ResolutionSets constrained on a specific variable. | 290 // Utilities that return ResolutionSets constrained on a specific variable. |
| 287 static ResolutionSet FromHeight(int min, int max); | 291 static ResolutionSet FromHeight(int min, int max); |
| 288 static ResolutionSet FromExactHeight(int value); | 292 static ResolutionSet FromExactHeight(int value); |
| 289 static ResolutionSet FromWidth(int min, int max); | 293 static ResolutionSet FromWidth(int min, int max); |
| 290 static ResolutionSet FromExactWidth(int value); | 294 static ResolutionSet FromExactWidth(int value); |
| 291 static ResolutionSet FromAspectRatio(double min, double max); | 295 static ResolutionSet FromAspectRatio(double min, double max); |
| 292 static ResolutionSet FromExactAspectRatio(double value); | 296 static ResolutionSet FromExactAspectRatio(double value); |
| 293 | 297 |
| 294 // Returns a ResolutionCandidateSet initialized with |constraint_set|'s | 298 // Returns a ResolutionCandidateSet initialized with |constraint_set|'s |
| 295 // width, height and aspectRatio constraints. | 299 // width, height and aspectRatio constraints. |
| 296 static ResolutionSet FromConstraintSet( | 300 static ResolutionSet FromConstraintSet( |
| 297 const blink::WebMediaTrackConstraintSet& constraint_set); | 301 const blink::WebMediaTrackConstraintSet& constraint_set); |
| 298 | 302 |
| 299 private: | 303 private: |
| 300 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, | 304 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, |
| 301 ResolutionVertices); | 305 ResolutionVertices); |
| 302 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, | 306 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, |
| 303 ResolutionPointSetClosestPoint); | 307 ResolutionPointSetClosestPoint); |
| 304 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, | 308 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, |
| 305 ResolutionLineSetClosestPoint); | 309 ResolutionLineSetClosestPoint); |
| 306 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, | 310 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, |
| 307 ResolutionGeneralSetClosestPoint); | 311 ResolutionGeneralSetClosestPoint); |
| 308 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, | 312 FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest, |
| 309 ResolutionIdealOutsideSinglePoint); | 313 ResolutionIdealOutsideSinglePoint); |
| 310 | 314 |
| 311 // Implements SelectClosestPointToIdeal() for the case when only the ideal | 315 // Implements SelectClosestPointToIdeal() for the case when only the ideal |
| 312 // aspect ratio is provided. | 316 // aspect ratio is provided. |
| 313 Point SelectClosestPointToIdealAspectRatio(double ideal_aspect_ratio) const; | 317 Point SelectClosestPointToIdealAspectRatio(double ideal_aspect_ratio, |
| 318 int default_height, |
| 319 int default_width) const; |
| 314 | 320 |
| 315 // Returns the closest point in this set to |point|. If |point| is included in | 321 // Returns the closest point in this set to |point|. If |point| is included in |
| 316 // this set, Point is returned. If this set is empty, behavior is undefined. | 322 // this set, Point is returned. If this set is empty, behavior is undefined. |
| 317 Point ClosestPointTo(const Point& point) const; | 323 Point ClosestPointTo(const Point& point) const; |
| 318 | 324 |
| 319 // Returns the vertices of the set that have the property accessed | 325 // Returns the vertices of the set that have the property accessed |
| 320 // by |accessor| closest to |value|. The returned vector always has one or two | 326 // by |accessor| closest to |value|. The returned vector always has one or two |
| 321 // elements. Behavior is undefined if the set is empty. | 327 // elements. Behavior is undefined if the set is empty. |
| 322 std::vector<Point> GetClosestVertices(double (Point::*accessor)() const, | 328 std::vector<Point> GetClosestVertices(double (Point::*accessor)() const, |
| 323 double value) const; | 329 double value) const; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 347 double max_aspect_ratio_; | 353 double max_aspect_ratio_; |
| 348 }; | 354 }; |
| 349 | 355 |
| 350 // Scalar multiplication for Points. | 356 // Scalar multiplication for Points. |
| 351 ResolutionSet::Point CONTENT_EXPORT operator*(double d, | 357 ResolutionSet::Point CONTENT_EXPORT operator*(double d, |
| 352 const ResolutionSet::Point& p); | 358 const ResolutionSet::Point& p); |
| 353 | 359 |
| 354 } // namespace content | 360 } // namespace content |
| 355 | 361 |
| 356 #endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_ | 362 #endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_ |
| OLD | NEW |