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 |