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

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

Issue 2728633002: Add utility set classes to support getUserMedia constraint proccessing. (Closed)
Patch Set: fix Windows compile issues + comments/formatting 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 #include <string>
9 #include <vector>
10
11 #include "content/renderer/media/media_stream_video_source.h"
12 #include "content/renderer/media/mock_constraint_factory.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace content {
16
17 using Point = ResolutionSet::Point;
18
19 namespace {
20
21 // Defined as macro in order to get more informative line-number information
22 // when a test fails.
23 #define EXPECT_POINT_EQ(p1, p2) \
24 do { \
25 EXPECT_DOUBLE_EQ((p1).height(), (p2).height()); \
26 EXPECT_DOUBLE_EQ((p1).width(), (p2).width()); \
27 } while (0)
28
29 // Checks if |point| is an element of |vertices| using
30 // Point::IsApproximatelyEqualTo() to test for equality.
31 void VerticesContain(const std::vector<Point>& vertices, const Point& point) {
32 bool result = false;
33 for (const auto& vertex : vertices) {
34 if (point.IsApproximatelyEqualTo(vertex)) {
35 result = true;
36 break;
37 }
38 }
39 EXPECT_TRUE(result);
40 }
41
42 bool AreCounterclockwise(const std::vector<Point>& vertices) {
43 // Single point or segment are trivial cases.
44 if (vertices.size() <= 2)
45 return true;
46 else if (vertices.size() > 6) // Polygons of more than 6 sides are not valid.
47 return false;
48
49 // The polygon defined by a resolution set is always convex and has at most 6
50 // sides. When producing a list of the vertices for such a polygon, it is
51 // important that they are returned in counterclockwise (or clockwise) order,
52 // to make sure that any consecutive pair of vertices (modulo the number of
53 // vertices) corresponds to a polygon side. Our implementation uses
54 // counterclockwise order.
55 // Compute orientation using the determinant of each diagonal in the
56 // polygon, using the first vertex as reference.
57 Point prev_diagonal = vertices[1] - vertices[0];
58 for (auto vertex = vertices.begin() + 2; vertex != vertices.end(); ++vertex) {
59 Point current_diagonal = *vertex - vertices[0];
60 // The determinant of the two diagonals returns the signed area of the
61 // parallelogram they generate. The area is positive if the diagonals are in
62 // counterclockwise order, zero if the diagonals have the same direction and
63 // negative if the diagonals are in clockwise order.
64 // See https://en.wikipedia.org/wiki/Determinant#2_.C3.97_2_matrices.
65 double det = prev_diagonal.height() * current_diagonal.width() -
66 current_diagonal.height() * prev_diagonal.width();
67 if (det <= 0)
68 return false;
69 prev_diagonal = current_diagonal;
70 }
71 return true;
72 }
73
74 // Determines if |vertices| is valid according to the contract for
75 // ResolutionCandidateSet::ComputeVertices().
76 bool AreValidVertices(const ResolutionSet& set,
77 const std::vector<Point>& vertices) {
78 // Verify that every vertex is included in |set|.
79 for (const auto& vertex : vertices) {
80 if (!set.ContainsPoint(vertex))
81 return false;
82 }
83
84 return AreCounterclockwise(vertices);
85 }
86
87 // This function provides an alternative method for computing the projection
88 // of |point| on the line of segment |s1||s2| to be used to compare the results
89 // provided by Point::ClosestPointInSegment(). Since it relies on library
90 // functions, it has larger error in practice than
91 // Point::ClosestPointInSegment(), so results must be compared with
92 // Point::IsApproximatelyEqualTo().
93 // This function only computes projections. The result may be outside the
94 // segment |s1||s2|.
95 Point ProjectionOnSegmentLine(const Point& point,
96 const Point& s1,
97 const Point& s2) {
98 double segment_slope =
99 (s2.width() - s1.width()) / (s2.height() - s1.height());
100 double segment_angle = std::atan(segment_slope);
101 double norm = std::sqrt(Point::Dot(point, point));
102 double angle =
103 (point.height() == 0 && point.width() == 0)
104 ? 0.0
105 : std::atan(point.width() / point.height()) - segment_angle;
106 double projection_length = norm * std::cos(angle);
107 double projection_height = projection_length * std::cos(segment_angle);
108 double projection_width = projection_length * std::sin(segment_angle);
109 return Point(projection_height, projection_width);
110 }
111
112 } // namespace
113
114 class MediaStreamConstraintsUtilSetsTest : public testing::Test {
115 protected:
116 using P = Point;
117 MockConstraintFactory factory_;
118 };
119
120 // This test tests the test-harness function AreValidVertices.
121 TEST_F(MediaStreamConstraintsUtilSetsTest, VertexListValidity) {
122 EXPECT_TRUE(AreCounterclockwise({P(1, 1)}));
123 EXPECT_TRUE(AreCounterclockwise({P(1, 1)}));
124 EXPECT_TRUE(AreCounterclockwise({P(1, 0), P(0, 1)}));
125 EXPECT_TRUE(AreCounterclockwise({P(1, 1), P(0, 0), P(1, 0)}));
126
127 // Not in counterclockwise order.
128 EXPECT_FALSE(AreCounterclockwise({P(1, 0), P(0, 0), P(1, 1)}));
129
130 // Final vertex aligned with the previous two vertices.
131 EXPECT_FALSE(AreCounterclockwise({P(1, 0), P(1, 1), P(1, 1.5), P(1, 0.1)}));
132
133 // Not in counterclockwise order.
134 EXPECT_FALSE(
135 AreCounterclockwise({P(1, 0), P(3, 0), P(2, 2), P(3.1, 1), P(0, 1)}));
136
137 EXPECT_TRUE(AreCounterclockwise(
138 {P(1, 0), P(3, 0), P(3.1, 1), P(3, 2), P(1, 2), P(0.9, 1)}));
139
140 // Not in counterclockwise order.
141 EXPECT_FALSE(AreCounterclockwise(
142 {P(1, 0), P(3, 0), P(3.1, 1), P(1, 2), P(3, 2), P(0.9, 1)}));
143
144 // Counterclockwise, but more than 6 vertices.
145 EXPECT_FALSE(AreCounterclockwise(
146 {P(1, 0), P(3, 0), P(3.1, 1), P(3, 2), P(2, 2.1), P(1, 2), P(0.9, 1)}));
147 }
148
149 TEST_F(MediaStreamConstraintsUtilSetsTest, PointOperations) {
150 const Point kZero(0, 0);
151
152 // Basic equality and inequality
153 EXPECT_EQ(P(0, 0), kZero);
154 EXPECT_EQ(P(50, 50), P(50, 50));
155 EXPECT_NE(kZero, P(50, 50));
156 EXPECT_NE(P(50, 50), P(100, 100));
157 EXPECT_NE(P(50, 50), P(100, 50));
158
159 // Operations with zero.
160 EXPECT_EQ(kZero, kZero + kZero);
161 EXPECT_EQ(kZero, kZero - kZero);
162 EXPECT_EQ(kZero, 0.0 * kZero);
163 EXPECT_EQ(0.0, P::Dot(kZero, kZero));
164 EXPECT_EQ(0.0, P::SquareEuclideanDistance(kZero, kZero));
165 EXPECT_EQ(kZero, P::ClosestPointInSegment(kZero, kZero, kZero));
166
167 // Operations with zero and nonzero values.
168 EXPECT_EQ(P(50, 50), kZero + P(50, 50));
169 EXPECT_EQ(P(50, 50) + kZero, kZero + P(50, 50));
170 EXPECT_EQ(P(50, 50), P(50, 50) - kZero);
171 EXPECT_EQ(kZero, P(50, 50) - P(50, 50));
172 EXPECT_EQ(kZero, 0.0 * P(50, 50));
173 EXPECT_EQ(0.0, P::Dot(kZero, P(50, 50)));
174 EXPECT_EQ(0.0, P::Dot(P(50, 50), kZero));
175 EXPECT_EQ(5000, P::SquareEuclideanDistance(kZero, P(50, 50)));
176 EXPECT_EQ(P::SquareEuclideanDistance(P(50, 50), kZero),
177 P::SquareEuclideanDistance(kZero, P(50, 50)));
178 EXPECT_EQ(kZero, P::ClosestPointInSegment(kZero, kZero, P(50, 50)));
179 EXPECT_EQ(kZero, P::ClosestPointInSegment(kZero, P(50, 50), kZero));
180 EXPECT_EQ(P(50, 50),
181 P::ClosestPointInSegment(P(50, 50), P(50, 50), P(50, 50)));
182
183 // Operations with nonzero values.
184 // Additions.
185 EXPECT_EQ(P(100, 50), P(50, 50) + P(50, 0));
186 EXPECT_EQ(P(100, 50), P(50, 0) + P(50, 50));
187
188 // Substractions.
189 EXPECT_EQ(P(50, 50), P(100, 100) - P(50, 50));
190 EXPECT_EQ(P(50, 50), P(100, 50) - P(50, 0));
191 EXPECT_EQ(P(50, 0), P(100, 50) - P(50, 50));
192
193 // Scalar-vector products.
194 EXPECT_EQ(P(50, 50), 1.0 * P(50, 50));
195 EXPECT_EQ(P(75, 75), 1.5 * P(50, 50));
196 EXPECT_EQ(P(200, 100), 2.0 * P(100, 50));
197 EXPECT_EQ(2.0 * (P(100, 100) + P(100, 50)),
198 2.0 * P(100, 100) + 2.0 * P(100, 50));
199
200 // Dot products.
201 EXPECT_EQ(2 * 50 * 100, P::Dot(P(50, 50), P(100, 100)));
202 EXPECT_EQ(P::Dot(P(100, 100), P(50, 50)), P::Dot(P(50, 50), P(100, 100)));
203 EXPECT_EQ(0, P::Dot(P(100, 0), P(0, 100)));
204
205 // Distances.
206 EXPECT_EQ(25, P::SquareEuclideanDistance(P(4, 0), P(0, 3)));
207 EXPECT_EQ(75 * 75, P::SquareEuclideanDistance(P(100, 0), P(25, 0)));
208 EXPECT_EQ(75 * 75, P::SquareEuclideanDistance(P(0, 100), P(0, 25)));
209 EXPECT_EQ(5 * 5 + 9 * 9, P::SquareEuclideanDistance(P(5, 1), P(10, 10)));
210
211 // Closest point to segment from (10,0) to (50,0).
212 EXPECT_EQ(P(25, 0), P::ClosestPointInSegment(P(25, 25), P(10, 0), P(50, 0)));
213 EXPECT_EQ(P(50, 0),
214 P::ClosestPointInSegment(P(100, 100), P(10, 0), P(50, 0)));
215 EXPECT_EQ(P(10, 0), P::ClosestPointInSegment(P(0, 100), P(10, 0), P(50, 0)));
216
217 // Closest point to segment from (0,10) to (0,50).
218 EXPECT_EQ(P(0, 25), P::ClosestPointInSegment(P(25, 25), P(0, 10), P(0, 50)));
219 EXPECT_EQ(P(0, 50),
220 P::ClosestPointInSegment(P(100, 100), P(0, 10), P(0, 50)));
221 EXPECT_EQ(P(0, 10), P::ClosestPointInSegment(P(100, 0), P(0, 10), P(0, 50)));
222
223 // Closest point to segment from (0,10) to (10,0).
224 EXPECT_EQ(P(5, 5), P::ClosestPointInSegment(P(25, 25), P(0, 10), P(10, 0)));
225 EXPECT_EQ(P(5, 5), P::ClosestPointInSegment(P(100, 100), P(0, 10), P(10, 0)));
226 EXPECT_EQ(P(10, 0), P::ClosestPointInSegment(P(100, 0), P(0, 10), P(10, 0)));
227 EXPECT_EQ(P(0, 10), P::ClosestPointInSegment(P(0, 100), P(0, 10), P(10, 0)));
228 }
229
230 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionUnconstrained) {
231 ResolutionSet set;
232 EXPECT_TRUE(set.ContainsPoint(0, 0));
233 EXPECT_TRUE(set.ContainsPoint(1, 1));
234 EXPECT_TRUE(set.ContainsPoint(2000, 2000));
235 EXPECT_FALSE(set.IsHeightEmpty());
236 EXPECT_FALSE(set.IsWidthEmpty());
237 EXPECT_FALSE(set.IsAspectRatioEmpty());
238 }
239
240 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionConstrained) {
241 ResolutionSet set = ResolutionSet::FromHeight(10, 100);
242 EXPECT_FALSE(set.ContainsPoint(0, 0));
243 EXPECT_TRUE(set.ContainsPoint(10, 10));
244 EXPECT_TRUE(set.ContainsPoint(50, 50));
245 EXPECT_TRUE(set.ContainsPoint(100, 100));
246 EXPECT_FALSE(set.ContainsPoint(500, 500));
247 EXPECT_FALSE(set.IsHeightEmpty());
248 EXPECT_FALSE(set.IsWidthEmpty());
249 EXPECT_FALSE(set.IsAspectRatioEmpty());
250
251 set = ResolutionSet::FromHeight(0, 100);
252 EXPECT_TRUE(set.ContainsPoint(0, 0));
253 EXPECT_TRUE(set.ContainsPoint(10, 10));
254 EXPECT_TRUE(set.ContainsPoint(50, 50));
255 EXPECT_TRUE(set.ContainsPoint(100, 100));
256 EXPECT_FALSE(set.ContainsPoint(500, 500));
257 EXPECT_FALSE(set.IsHeightEmpty());
258 EXPECT_FALSE(set.IsWidthEmpty());
259 EXPECT_FALSE(set.IsAspectRatioEmpty());
260
261 set = ResolutionSet::FromHeight(100, ResolutionSet::kMaxDimension);
262 EXPECT_FALSE(set.ContainsPoint(0, 0));
263 EXPECT_FALSE(set.ContainsPoint(10, 10));
264 EXPECT_FALSE(set.ContainsPoint(50, 50));
265 EXPECT_TRUE(set.ContainsPoint(100, 100));
266 EXPECT_TRUE(set.ContainsPoint(500, 500));
267 EXPECT_FALSE(set.IsHeightEmpty());
268 EXPECT_FALSE(set.IsWidthEmpty());
269 EXPECT_FALSE(set.IsAspectRatioEmpty());
270
271 set = ResolutionSet::FromWidth(10, 100);
272 EXPECT_FALSE(set.ContainsPoint(0, 0));
273 EXPECT_TRUE(set.ContainsPoint(10, 10));
274 EXPECT_TRUE(set.ContainsPoint(50, 50));
275 EXPECT_TRUE(set.ContainsPoint(100, 100));
276 EXPECT_FALSE(set.ContainsPoint(500, 500));
277 EXPECT_FALSE(set.IsHeightEmpty());
278 EXPECT_FALSE(set.IsWidthEmpty());
279 EXPECT_FALSE(set.IsAspectRatioEmpty());
280
281 set = ResolutionSet::FromWidth(0, 100);
282 EXPECT_TRUE(set.ContainsPoint(0, 0));
283 EXPECT_TRUE(set.ContainsPoint(10, 10));
284 EXPECT_TRUE(set.ContainsPoint(50, 50));
285 EXPECT_TRUE(set.ContainsPoint(100, 100));
286 EXPECT_FALSE(set.ContainsPoint(500, 500));
287 EXPECT_FALSE(set.IsHeightEmpty());
288 EXPECT_FALSE(set.IsWidthEmpty());
289 EXPECT_FALSE(set.IsAspectRatioEmpty());
290
291 set = ResolutionSet::FromWidth(100, ResolutionSet::kMaxDimension);
292 EXPECT_FALSE(set.ContainsPoint(0, 0));
293 EXPECT_FALSE(set.ContainsPoint(10, 10));
294 EXPECT_FALSE(set.ContainsPoint(50, 50));
295 EXPECT_TRUE(set.ContainsPoint(100, 100));
296 EXPECT_TRUE(set.ContainsPoint(500, 500));
297 EXPECT_FALSE(set.IsHeightEmpty());
298 EXPECT_FALSE(set.IsWidthEmpty());
299 EXPECT_FALSE(set.IsAspectRatioEmpty());
300
301 set = ResolutionSet::FromAspectRatio(1.0, 2.0);
302 EXPECT_TRUE(set.ContainsPoint(0, 0));
303 EXPECT_TRUE(set.ContainsPoint(10, 10));
304 EXPECT_TRUE(set.ContainsPoint(10, 20));
305 EXPECT_TRUE(set.ContainsPoint(100, 100));
306 EXPECT_TRUE(set.ContainsPoint(2000, 4000));
307 EXPECT_FALSE(set.ContainsPoint(1, 50));
308 EXPECT_FALSE(set.ContainsPoint(50, 1));
309 EXPECT_FALSE(set.IsHeightEmpty());
310 EXPECT_FALSE(set.IsWidthEmpty());
311 EXPECT_FALSE(set.IsAspectRatioEmpty());
312
313 set = ResolutionSet::FromAspectRatio(0.0, 2.0);
314 EXPECT_TRUE(set.ContainsPoint(0, 0));
315 EXPECT_TRUE(set.ContainsPoint(10, 10));
316 EXPECT_TRUE(set.ContainsPoint(10, 20));
317 EXPECT_TRUE(set.ContainsPoint(100, 100));
318 EXPECT_TRUE(set.ContainsPoint(2000, 4000));
319 EXPECT_FALSE(set.ContainsPoint(1, 50));
320 EXPECT_TRUE(set.ContainsPoint(50, 1));
321 EXPECT_FALSE(set.IsHeightEmpty());
322 EXPECT_FALSE(set.IsWidthEmpty());
323 EXPECT_FALSE(set.IsAspectRatioEmpty());
324
325 set = ResolutionSet::FromAspectRatio(1.0, HUGE_VAL);
326 EXPECT_TRUE(set.ContainsPoint(0, 0));
327 EXPECT_TRUE(set.ContainsPoint(10, 10));
328 EXPECT_TRUE(set.ContainsPoint(10, 20));
329 EXPECT_TRUE(set.ContainsPoint(100, 100));
330 EXPECT_TRUE(set.ContainsPoint(2000, 4000));
331 EXPECT_TRUE(set.ContainsPoint(1, 50));
332 EXPECT_FALSE(set.ContainsPoint(50, 1));
333 EXPECT_FALSE(set.IsHeightEmpty());
334 EXPECT_FALSE(set.IsWidthEmpty());
335 EXPECT_FALSE(set.IsAspectRatioEmpty());
336 }
337
338 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionTrivialEmptiness) {
339 ResolutionSet set = ResolutionSet::FromHeight(100, 10);
340 EXPECT_TRUE(set.IsEmpty());
341 EXPECT_TRUE(set.IsHeightEmpty());
342 EXPECT_FALSE(set.IsWidthEmpty());
343 EXPECT_FALSE(set.IsAspectRatioEmpty());
344
345 set = ResolutionSet::FromWidth(100, 10);
346 EXPECT_TRUE(set.IsEmpty());
347 EXPECT_FALSE(set.IsHeightEmpty());
348 EXPECT_TRUE(set.IsWidthEmpty());
349 EXPECT_FALSE(set.IsAspectRatioEmpty());
350
351 set = ResolutionSet::FromAspectRatio(100.0, 10.0);
352 EXPECT_TRUE(set.IsEmpty());
353 EXPECT_FALSE(set.IsHeightEmpty());
354 EXPECT_FALSE(set.IsWidthEmpty());
355 EXPECT_TRUE(set.IsAspectRatioEmpty());
356 }
357
358 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionLineConstraintsEmptiness) {
359 ResolutionSet set(1, 1, 1, 1, 1, 1);
360 EXPECT_FALSE(set.IsEmpty());
361 EXPECT_FALSE(set.ContainsPoint(0, 0));
362 EXPECT_TRUE(set.ContainsPoint(1, 1));
363 EXPECT_FALSE(set.ContainsPoint(1, 0));
364 EXPECT_FALSE(set.ContainsPoint(0, 1));
365
366 // Three lines that do not intersect in the same point is empty.
367 set = ResolutionSet(1, 1, 1, 1, 0.5, 0.5);
368 EXPECT_TRUE(set.IsEmpty());
369 EXPECT_TRUE(set.IsAspectRatioEmpty());
370 EXPECT_FALSE(set.ContainsPoint(0, 0));
371 EXPECT_FALSE(set.ContainsPoint(1, 1));
372 EXPECT_FALSE(set.ContainsPoint(1, 0));
373 EXPECT_FALSE(set.ContainsPoint(0, 1));
374 }
375
376 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionBoxEmptiness) {
377 int kMin = 100;
378 int kMax = 200;
379 // Max aspect ratio below box.
380 ResolutionSet set(kMin, kMax, kMin, kMax, 0.4, 0.4);
381 EXPECT_TRUE(set.IsEmpty());
382 EXPECT_TRUE(set.IsAspectRatioEmpty());
383
384 // Min aspect ratio above box.
385 set = ResolutionSet(kMin, kMax, kMin, kMax, 3.0, HUGE_VAL);
386 EXPECT_TRUE(set.IsEmpty());
387 EXPECT_TRUE(set.IsAspectRatioEmpty());
388
389 // Min aspect ratio crosses box.
390 set = ResolutionSet(kMin, kMax, kMin, kMax, 1.0, HUGE_VAL);
391 EXPECT_FALSE(set.IsEmpty());
392
393 // Max aspect ratio crosses box.
394 set = ResolutionSet(kMin, kMax, kMin, kMax, 0.0, 1.0);
395 EXPECT_FALSE(set.IsEmpty());
396
397 // Min and max aspect ratios cross box.
398 set = ResolutionSet(kMin, kMax, kMin, kMax, 0.9, 1.1);
399 EXPECT_FALSE(set.IsEmpty());
400
401 // Min and max aspect ratios cover box.
402 set = ResolutionSet(kMin, kMax, kMin, kMax, 0.2, 100);
403 EXPECT_FALSE(set.IsEmpty());
404 }
405
406 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionPointIntersection) {
407 ResolutionSet set1(1, 2, 1, 2, 0.0, HUGE_VAL);
408 ResolutionSet set2 = ResolutionSet::FromExactAspectRatio(0.5);
409 auto intersection = set1.Intersection(set2);
410
411 // The intersection should contain only the point (h=2, w=1)
412 EXPECT_TRUE(intersection.ContainsPoint(2, 1));
413
414 // It should not contain any point in the vicinity of the included point
415 // (integer version).
416 EXPECT_FALSE(intersection.ContainsPoint(1, 0));
417 EXPECT_FALSE(intersection.ContainsPoint(2, 0));
418 EXPECT_FALSE(intersection.ContainsPoint(3, 0));
419 EXPECT_FALSE(intersection.ContainsPoint(1, 1));
420 EXPECT_FALSE(intersection.ContainsPoint(3, 1));
421 EXPECT_FALSE(intersection.ContainsPoint(1, 2));
422 EXPECT_FALSE(intersection.ContainsPoint(2, 2));
423 EXPECT_FALSE(intersection.ContainsPoint(3, 2));
424
425 // It should not contain any point in the vicinity of the included point
426 // (floating-point version).
427 EXPECT_FALSE(intersection.ContainsPoint(P(2.0001, 1.0001)));
428 EXPECT_FALSE(intersection.ContainsPoint(P(2.0001, 1.0)));
429 EXPECT_FALSE(intersection.ContainsPoint(P(2.0001, 0.9999)));
430 EXPECT_FALSE(intersection.ContainsPoint(P(2.0, 1.0001)));
431 EXPECT_FALSE(intersection.ContainsPoint(P(2.0, 0.9999)));
432 EXPECT_FALSE(intersection.ContainsPoint(P(1.9999, 1.0001)));
433 EXPECT_FALSE(intersection.ContainsPoint(P(1.9999, 1.0)));
434 EXPECT_FALSE(intersection.ContainsPoint(P(1.9999, 0.9999)));
435 }
436
437 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionLineIntersection) {
438 ResolutionSet set1(1, 2, 1, 2, 0.0, HUGE_VAL);
439 ResolutionSet set2 = ResolutionSet::FromExactAspectRatio(1.0);
440
441 // The intersection should contain (1,1) and (2,2)
442 auto intersection = set1.Intersection(set2);
443 EXPECT_TRUE(intersection.ContainsPoint(1, 1));
444 EXPECT_TRUE(intersection.ContainsPoint(2, 2));
445
446 // It should not contain the other points in the bounding box.
447 EXPECT_FALSE(intersection.ContainsPoint(1, 2));
448 EXPECT_FALSE(intersection.ContainsPoint(2, 1));
449 }
450
451 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionBoxIntersection) {
452 const int kMin1 = 0;
453 const int kMax1 = 2;
454 ResolutionSet set1(kMin1, kMax1, kMin1, kMax1, 0.0, HUGE_VAL);
455
456 const int kMin2 = 1;
457 const int kMax2 = 3;
458 ResolutionSet set2(kMin2, kMax2, kMin2, kMax2, 0.0, HUGE_VAL);
459
460 auto intersection = set1.Intersection(set2);
461 for (int i = kMin1; i <= kMax2; ++i) {
462 for (int j = kMin1; j <= kMax2; ++j) {
463 if (i >= kMin2 && j >= kMin2 && i <= kMax1 && j <= kMax1)
464 EXPECT_TRUE(intersection.ContainsPoint(i, j));
465 else
466 EXPECT_FALSE(intersection.ContainsPoint(i, j));
467 }
468 }
469 }
470
471 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionPointSetClosestPoint) {
472 const int kHeight = 10;
473 const int kWidth = 10;
474 const double kAspectRatio = 1.0;
475 ResolutionSet set(kHeight, kHeight, kWidth, kWidth, kAspectRatio,
476 kAspectRatio);
477
478 for (int height = 0; height < 100; height += 10) {
479 for (int width = 0; width < 100; width += 10) {
480 EXPECT_EQ(P(kHeight, kWidth), set.ClosestPointTo(P(height, width)));
481 }
482 }
483 }
484
485 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionLineSetClosestPoint) {
486 {
487 const int kHeight = 10;
488 auto set = ResolutionSet::FromExactHeight(kHeight);
489 for (int height = 0; height < 100; height += 10) {
490 for (int width = 0; width < 100; width += 10) {
491 EXPECT_EQ(P(kHeight, width), set.ClosestPointTo(P(height, width)));
492 }
493 }
494 const int kWidth = 10;
495 set = ResolutionSet::FromExactWidth(kWidth);
496 for (int height = 0; height < 100; height += 10) {
497 for (int width = 0; width < 100; width += 10) {
498 EXPECT_EQ(P(height, kWidth), set.ClosestPointTo(P(height, width)));
499 }
500 }
501 }
502
503 {
504 const double kAspectRatios[] = {0.0, 0.1, 0.2, 0.5,
505 1.0, 2.0, 5.0, HUGE_VAL};
506 for (double aspect_ratio : kAspectRatios) {
507 auto set = ResolutionSet::FromExactAspectRatio(aspect_ratio);
508 for (int height = 0; height < 100; height += 10) {
509 for (int width = 0; width < 100; width += 10) {
510 Point point(height, width);
511 Point expected =
512 ProjectionOnSegmentLine(point, P(0, 0), P(1, aspect_ratio));
513 Point actual = set.ClosestPointTo(point);
514 // This requires higher tolerance than ExpectPointEx due to the larger
515 // error of the alternative projection method.
516 EXPECT_TRUE(expected.IsApproximatelyEqualTo(actual));
517 }
518 }
519 }
520 }
521 }
522
523 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionGeneralSetClosestPoint) {
524 // This set contains the following vertices:
525 // (10, 10), (20, 10), (100, 50), (100, 100), (100/1.5, 100), (10, 15)
526 ResolutionSet set(10, 100, 10, 100, 0.5, 1.5);
527
528 // Check that vertices are the closest points to themselves.
529 auto vertices = set.ComputeVertices();
530 for (auto& vertex : vertices)
531 EXPECT_EQ(vertex, set.ClosestPointTo(vertex));
532
533 // Point inside the set.
534 EXPECT_EQ(P(11, 11), set.ClosestPointTo(P(11, 11)));
535
536 // Close to horizontal segment (10, 10) (20, 10).
537 EXPECT_EQ(P(15, 10), set.ClosestPointTo(P(15, 9)));
538
539 // Close to horizontal segment (100, 100) (100/1.5, 100).
540 EXPECT_EQ(P(99, 100), set.ClosestPointTo(P(99, 200)));
541
542 // Close to vertical segment (10, 15) (10, 10).
543 EXPECT_EQ(P(10, 12.5), set.ClosestPointTo(P(2, 12.5)));
544
545 // Close to vertical segment (100, 50) (100, 100).
546 EXPECT_EQ(P(100, 75), set.ClosestPointTo(P(120, 75)));
547
548 // Close to oblique segment (20, 10) (100, 50)
549 {
550 Point point(70, 15);
551 Point expected = ProjectionOnSegmentLine(point, P(20, 10), P(100, 50));
552 Point actual = set.ClosestPointTo(point);
553 EXPECT_POINT_EQ(expected, actual);
554 }
555
556 // Close to oblique segment (100/1.5, 100) (10, 15)
557 {
558 Point point(12, 70);
559 Point expected =
560 ProjectionOnSegmentLine(point, P(100 / 1.5, 100), P(10, 15));
561 Point actual = set.ClosestPointTo(point);
562 EXPECT_POINT_EQ(expected, actual);
563 }
564
565 // Points close to vertices.
566 EXPECT_EQ(P(10, 10), set.ClosestPointTo(P(9, 9)));
567 EXPECT_EQ(P(20, 10), set.ClosestPointTo(P(20, 9)));
568 EXPECT_EQ(P(100, 50), set.ClosestPointTo(P(101, 50)));
569 EXPECT_EQ(P(100, 100), set.ClosestPointTo(P(101, 101)));
570 EXPECT_EQ(P(100 / 1.5, 100), set.ClosestPointTo(P(100 / 1.5, 101)));
571 EXPECT_EQ(P(10, 15), set.ClosestPointTo(P(9, 15)));
572 }
573
574 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionIdealIntersects) {
575 ResolutionSet set(100, 1000, 100, 1000, 0.5, 2.0);
576
577 int kIdealHeight = 500;
578 int kIdealWidth = 1000;
579 double kIdealAspectRatio = 1.5;
580
581 // Ideal height.
582 {
583 factory_.Reset();
584 factory_.basic().height.setIdeal(kIdealHeight);
585 Point point = set.SelectClosestPointToIdeal(
586 factory_.CreateWebMediaConstraints().basic());
587 EXPECT_POINT_EQ(
588 Point(kIdealHeight,
589 kIdealHeight * MediaStreamVideoSource::kDefaultAspectRatio),
590 point);
591 }
592
593 // Ideal width.
594 {
595 factory_.Reset();
596 factory_.basic().width.setIdeal(kIdealWidth);
597 Point point = set.SelectClosestPointToIdeal(
598 factory_.CreateWebMediaConstraints().basic());
599 EXPECT_POINT_EQ(
600 Point(kIdealWidth / MediaStreamVideoSource::kDefaultAspectRatio,
601 kIdealWidth),
602 point);
603 }
604
605 // Ideal aspect ratio.
606 {
607 factory_.Reset();
608 factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
609 Point point = set.SelectClosestPointToIdeal(
610 factory_.CreateWebMediaConstraints().basic());
611 EXPECT_DOUBLE_EQ(MediaStreamVideoSource::kDefaultHeight, point.height());
612 EXPECT_DOUBLE_EQ(MediaStreamVideoSource::kDefaultHeight * kIdealAspectRatio,
613 point.width());
614 }
615
616 // Ideal height and width.
617 {
618 factory_.Reset();
619 factory_.basic().height.setIdeal(kIdealHeight);
620 factory_.basic().width.setIdeal(kIdealWidth);
621 Point point = set.SelectClosestPointToIdeal(
622 factory_.CreateWebMediaConstraints().basic());
623 EXPECT_POINT_EQ(Point(kIdealHeight, kIdealWidth), point);
624 }
625
626 // Ideal height and aspect-ratio.
627 {
628 factory_.Reset();
629 factory_.basic().height.setIdeal(kIdealHeight);
630 factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
631 Point point = set.SelectClosestPointToIdeal(
632 factory_.CreateWebMediaConstraints().basic());
633 EXPECT_POINT_EQ(Point(kIdealHeight, kIdealHeight * kIdealAspectRatio),
634 point);
635 }
636
637 // Ideal width and aspect-ratio.
638 {
639 factory_.Reset();
640 factory_.basic().width.setIdeal(kIdealWidth);
641 factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
642 Point point = set.SelectClosestPointToIdeal(
643 factory_.CreateWebMediaConstraints().basic());
644 EXPECT_POINT_EQ(Point(kIdealWidth / kIdealAspectRatio, kIdealWidth), point);
645 }
646
647 // Ideal height, width and aspect-ratio.
648 {
649 factory_.Reset();
650 factory_.basic().height.setIdeal(kIdealHeight);
651 factory_.basic().width.setIdeal(kIdealWidth);
652 factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
653 Point point = set.SelectClosestPointToIdeal(
654 factory_.CreateWebMediaConstraints().basic());
655 // Ideal aspect ratio should be ignored.
656 EXPECT_POINT_EQ(Point(kIdealHeight, kIdealWidth), point);
657 }
658 }
659
660 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionIdealOutsideSinglePoint) {
661 // This set is a triangle with vertices (100,100), (1000,100) and (1000,1000).
662 ResolutionSet set(100, 1000, 100, 1000, 0.0, 1.0);
663
664 int kIdealHeight = 50;
665 int kIdealWidth = 1100;
666 double kIdealAspectRatio = 0.09;
667 Point kVertex1(100, 100);
668 Point kVertex2(1000, 100);
669 Point kVertex3(1000, 1000);
670
671 // Ideal height.
672 {
673 factory_.Reset();
674 factory_.basic().height.setIdeal(kIdealHeight);
675 Point point = set.SelectClosestPointToIdeal(
676 factory_.CreateWebMediaConstraints().basic());
677 EXPECT_POINT_EQ(kVertex1, point);
678 }
679
680 // Ideal width.
681 {
682 factory_.Reset();
683 factory_.basic().width.setIdeal(kIdealWidth);
684 Point point = set.SelectClosestPointToIdeal(
685 factory_.CreateWebMediaConstraints().basic());
686 EXPECT_POINT_EQ(kVertex3, point);
687 }
688
689 // Ideal aspect ratio.
690 {
691 factory_.Reset();
692 factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
693 Point point = set.SelectClosestPointToIdeal(
694 factory_.CreateWebMediaConstraints().basic());
695 EXPECT_POINT_EQ(kVertex2, point);
696 }
697
698 // Ideal height and width.
699 {
700 factory_.Reset();
701 factory_.basic().height.setIdeal(kIdealHeight);
702 factory_.basic().width.setIdeal(kIdealWidth);
703 Point point = set.SelectClosestPointToIdeal(
704 factory_.CreateWebMediaConstraints().basic());
705 Point expected = set.ClosestPointTo(Point(kIdealHeight, kIdealWidth));
706 EXPECT_POINT_EQ(expected, point);
707 }
708
709 // Ideal height and aspect-ratio.
710 {
711 factory_.Reset();
712 factory_.basic().height.setIdeal(kIdealHeight);
713 factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
714 Point point = set.SelectClosestPointToIdeal(
715 factory_.CreateWebMediaConstraints().basic());
716 Point expected = set.ClosestPointTo(
717 Point(kIdealHeight, kIdealHeight * kIdealAspectRatio));
718 EXPECT_POINT_EQ(expected, point);
719 }
720
721 // Ideal width and aspect-ratio.
722 {
723 factory_.Reset();
724 factory_.basic().width.setIdeal(kIdealWidth);
725 factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
726 Point point = set.SelectClosestPointToIdeal(
727 factory_.CreateWebMediaConstraints().basic());
728 Point expected =
729 set.ClosestPointTo(Point(kIdealWidth / kIdealAspectRatio, kIdealWidth));
730 EXPECT_POINT_EQ(expected, point);
731 }
732
733 // Ideal height, width and aspect-ratio.
734 {
735 factory_.Reset();
736 factory_.basic().height.setIdeal(kIdealHeight);
737 factory_.basic().width.setIdeal(kIdealWidth);
738 factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
739 Point point = set.SelectClosestPointToIdeal(
740 factory_.CreateWebMediaConstraints().basic());
741 // kIdealAspectRatio is ignored if all three ideals are given.
742 Point expected = set.ClosestPointTo(Point(kIdealHeight, kIdealWidth));
743 EXPECT_POINT_EQ(expected, point);
744 }
745 }
746
747 TEST_F(MediaStreamConstraintsUtilSetsTest,
748 ResolutionIdealOutsideMultiplePoints) {
749 // This set is a triangle with vertices (100,100), (1000,100) and (1000,1000).
750 ResolutionSet set(100, 1000, 100, 1000, 0.0, 1.0);
751
752 int kIdealHeight = 1100;
753 int kIdealWidth = 50;
754 double kIdealAspectRatio = 11.0;
755 Point kVertex1(100, 100);
756 Point kVertex2(1000, 100);
757 Point kVertex3(1000, 1000);
758
759 // Ideal height.
760 {
761 factory_.Reset();
762 factory_.basic().height.setIdeal(kIdealHeight);
763 Point point = set.SelectClosestPointToIdeal(
764 factory_.CreateWebMediaConstraints().basic());
765 // Parallel to the side between kVertex2 and kVertex3. Point closest to
766 // default aspect ratio is kVertex3.
767 EXPECT_POINT_EQ(kVertex3, point);
768 }
769
770 // Ideal width.
771 {
772 factory_.Reset();
773 factory_.basic().width.setIdeal(kIdealWidth);
774 Point point = set.SelectClosestPointToIdeal(
775 factory_.CreateWebMediaConstraints().basic());
776 // Parallel to the side between kVertex1 and kVertex2. Point closest to
777 // default aspect ratio is kVertex1.
778 EXPECT_POINT_EQ(kVertex1, point);
779 }
780
781 // Ideal aspect ratio.
782 {
783 factory_.Reset();
784 factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
785 Point point = set.SelectClosestPointToIdeal(
786 factory_.CreateWebMediaConstraints().basic());
787 // The side between kVertex1 and kVertex3 is closest. The points closest to
788 // default dimensions are (kDefaultHeight, kDefaultHeight * AR)
789 // and (kDefaultWidth / AR, kDefaultWidth). Since the aspect ratio of the
790 // polygon side is less than the default, the algorithm preserves the
791 // default width.
792 Point expected(
793 MediaStreamVideoSource::kDefaultWidth / kVertex1.AspectRatio(),
794 MediaStreamVideoSource::kDefaultWidth);
795 EXPECT_POINT_EQ(expected, point);
796 EXPECT_TRUE(set.ContainsPoint(expected));
797 }
798 }
799
800 TEST_F(MediaStreamConstraintsUtilSetsTest,
801 ResolutionUnconstrainedExtremeIdeal) {
802 ResolutionSet set;
803
804 // Ideal height.
805 {
806 factory_.Reset();
807 factory_.basic().height.setIdeal(std::numeric_limits<long>::max());
808 Point point = set.SelectClosestPointToIdeal(
809 factory_.CreateWebMediaConstraints().basic());
810 EXPECT_POINT_EQ(
811 Point(ResolutionSet::kMaxDimension, ResolutionSet::kMaxDimension),
812 point);
813 factory_.basic().height.setIdeal(0);
814 point = set.SelectClosestPointToIdeal(
815 factory_.CreateWebMediaConstraints().basic());
816 EXPECT_POINT_EQ(Point(0, 0), point);
817 }
818
819 // Ideal width.
820 {
821 factory_.Reset();
822 factory_.basic().width.setIdeal(std::numeric_limits<long>::max());
823 Point point = set.SelectClosestPointToIdeal(
824 factory_.CreateWebMediaConstraints().basic());
825 EXPECT_POINT_EQ(Point(ResolutionSet::kMaxDimension /
826 MediaStreamVideoSource::kDefaultAspectRatio,
827 ResolutionSet::kMaxDimension),
828 point);
829 factory_.basic().width.setIdeal(0);
830 point = set.SelectClosestPointToIdeal(
831 factory_.CreateWebMediaConstraints().basic());
832 EXPECT_POINT_EQ(Point(0, 0), point);
833 }
834
835 // Ideal Aspect Ratio.
836 {
837 factory_.Reset();
838 factory_.basic().aspectRatio.setIdeal(HUGE_VAL);
839 Point point = set.SelectClosestPointToIdeal(
840 factory_.CreateWebMediaConstraints().basic());
841 EXPECT_POINT_EQ(Point(0, ResolutionSet::kMaxDimension), point);
842 factory_.basic().aspectRatio.setIdeal(0.0);
843 point = set.SelectClosestPointToIdeal(
844 factory_.CreateWebMediaConstraints().basic());
845 EXPECT_POINT_EQ(Point(ResolutionSet::kMaxDimension, 0), point);
846 }
847 }
848
849 TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionVertices) {
850 // Empty set.
851 {
852 ResolutionSet set(1000, 100, 1000, 100, 0.5, 1.5);
853 ASSERT_TRUE(set.IsEmpty());
854 auto vertices = set.ComputeVertices();
855 EXPECT_EQ(0U, vertices.size());
856 EXPECT_TRUE(AreValidVertices(set, vertices));
857 }
858
859 // Three lines that intersect at the same point.
860 {
861 ResolutionSet set(1, 1, 1, 1, 1, 1);
862 EXPECT_FALSE(set.IsEmpty());
863 auto vertices = set.ComputeVertices();
864 EXPECT_EQ(1U, vertices.size());
865 VerticesContain(vertices, Point(1, 1));
866 EXPECT_TRUE(AreValidVertices(set, vertices));
867 }
868
869 // A line segment with the lower-left and upper-right corner of the box.
870 {
871 ResolutionSet set(0, 100, 0, 100, 1.0, 1.0);
872 EXPECT_FALSE(set.IsEmpty());
873 auto vertices = set.ComputeVertices();
874 EXPECT_EQ(2U, vertices.size());
875 VerticesContain(vertices, Point(0, 0));
876 VerticesContain(vertices, Point(100, 100));
877 EXPECT_TRUE(AreValidVertices(set, vertices));
878
879 set = ResolutionSet(0, 100, 0, 100, 1.0, HUGE_VAL);
880 EXPECT_FALSE(set.IsEmpty());
881 vertices = set.ComputeVertices();
882 EXPECT_EQ(3U, vertices.size());
883 VerticesContain(vertices, Point(0, 0));
884 VerticesContain(vertices, Point(100, 100));
885 VerticesContain(vertices, Point(0, 100));
886 EXPECT_TRUE(AreValidVertices(set, vertices));
887
888 set = ResolutionSet(0, 100, 0, 100, 0, 1.0);
889 EXPECT_FALSE(set.IsEmpty());
890 vertices = set.ComputeVertices();
891 EXPECT_EQ(3U, vertices.size());
892 VerticesContain(vertices, Point(0, 0));
893 VerticesContain(vertices, Point(100, 100));
894 VerticesContain(vertices, Point(100, 0));
895 EXPECT_TRUE(AreValidVertices(set, vertices));
896 }
897
898 // A line segment that crosses the bottom and right sides of the box.
899 {
900 const double kAspectRatio = 50.0 / 75.0;
901 ResolutionSet set(50, 100, 50, 100, kAspectRatio, kAspectRatio);
902 auto vertices = set.ComputeVertices();
903 EXPECT_EQ(2U, vertices.size());
904 VerticesContain(vertices, Point(50 / kAspectRatio, 50));
905 VerticesContain(vertices, Point(100, 100.0 * kAspectRatio));
906 EXPECT_TRUE(AreValidVertices(set, vertices));
907
908 set = ResolutionSet(50, 100, 50, 100, kAspectRatio, HUGE_VAL);
909 vertices = set.ComputeVertices();
910 EXPECT_EQ(5U, vertices.size());
911 VerticesContain(vertices, Point(50 / kAspectRatio, 50));
912 VerticesContain(vertices, Point(100, 100.0 * kAspectRatio));
913 VerticesContain(vertices, Point(50, 50));
914 VerticesContain(vertices, Point(50, 100));
915 VerticesContain(vertices, Point(100, 100));
916 EXPECT_TRUE(AreValidVertices(set, vertices));
917
918 set = ResolutionSet(50, 100, 50, 100, 0.0, kAspectRatio);
919 vertices = set.ComputeVertices();
920 EXPECT_EQ(3U, vertices.size());
921 VerticesContain(vertices, Point(50 / kAspectRatio, 50));
922 VerticesContain(vertices, Point(100, 100.0 * kAspectRatio));
923 VerticesContain(vertices, Point(100, 50));
924 EXPECT_TRUE(AreValidVertices(set, vertices));
925 }
926
927 // A line segment that crosses the left and top sides of the box.
928 {
929 const double kAspectRatio = 75.0 / 50.0;
930 ResolutionSet set(50, 100, 50, 100, kAspectRatio, kAspectRatio);
931 auto vertices = set.ComputeVertices();
932 EXPECT_EQ(2U, vertices.size());
933 VerticesContain(vertices, Point(50, 50 * kAspectRatio));
934 VerticesContain(vertices, Point(100 / kAspectRatio, 100));
935 EXPECT_TRUE(AreValidVertices(set, vertices));
936
937 set = ResolutionSet(50, 100, 50, 100, kAspectRatio, HUGE_VAL);
938 vertices = set.ComputeVertices();
939 EXPECT_EQ(3U, vertices.size());
940 VerticesContain(vertices, Point(50, 50 * kAspectRatio));
941 VerticesContain(vertices, Point(100 / kAspectRatio, 100));
942 VerticesContain(vertices, Point(50, 100));
943 EXPECT_TRUE(AreValidVertices(set, vertices));
944
945 set = ResolutionSet(50, 100, 50, 100, 0.0, kAspectRatio);
946 vertices = set.ComputeVertices();
947 EXPECT_EQ(5U, vertices.size());
948 VerticesContain(vertices, Point(50, 50 * kAspectRatio));
949 VerticesContain(vertices, Point(100 / kAspectRatio, 100));
950 VerticesContain(vertices, Point(50, 50));
951 VerticesContain(vertices, Point(100, 100));
952 VerticesContain(vertices, Point(100, 50));
953 EXPECT_TRUE(AreValidVertices(set, vertices));
954 }
955
956 // An aspect ratio constraint crosses the bottom and top sides of the box.
957 {
958 const double kAspectRatio = 75.0 / 50.0;
959 ResolutionSet set(0, 100, 50, 100, kAspectRatio, kAspectRatio);
960 auto vertices = set.ComputeVertices();
961 EXPECT_EQ(2U, vertices.size());
962 VerticesContain(vertices, Point(50 / kAspectRatio, 50));
963 VerticesContain(vertices, Point(100 / kAspectRatio, 100));
964 EXPECT_TRUE(AreValidVertices(set, vertices));
965
966 set = ResolutionSet(0, 100, 50, 100, kAspectRatio, HUGE_VAL);
967 vertices = set.ComputeVertices();
968 EXPECT_EQ(4U, vertices.size());
969 VerticesContain(vertices, Point(50 / kAspectRatio, 50));
970 VerticesContain(vertices, Point(100 / kAspectRatio, 100));
971 VerticesContain(vertices, Point(0, 50));
972 VerticesContain(vertices, Point(0, 100));
973 EXPECT_TRUE(AreValidVertices(set, vertices));
974
975 set = ResolutionSet(0, 100, 50, 100, 0.0, kAspectRatio);
976 vertices = set.ComputeVertices();
977 EXPECT_EQ(4U, vertices.size());
978 VerticesContain(vertices, Point(50 / kAspectRatio, 50));
979 VerticesContain(vertices, Point(100 / kAspectRatio, 100));
980 VerticesContain(vertices, Point(100, 50));
981 VerticesContain(vertices, Point(100, 100));
982 EXPECT_TRUE(AreValidVertices(set, vertices));
983 }
984
985 // An aspect-ratio constraint crosses the left and right sides of the box.
986 {
987 const double kAspectRatio = 75.0 / 50.0;
988 ResolutionSet set(50, 100, 0, 200, kAspectRatio, kAspectRatio);
989 auto vertices = set.ComputeVertices();
990 // This one fails if floating-point precision is too high.
991 EXPECT_EQ(2U, vertices.size());
992 VerticesContain(vertices, Point(50, 50 * kAspectRatio));
993 VerticesContain(vertices, Point(100, 100 * kAspectRatio));
994 EXPECT_TRUE(AreValidVertices(set, vertices));
995
996 set = ResolutionSet(50, 100, 0, 200, kAspectRatio, HUGE_VAL);
997 vertices = set.ComputeVertices();
998 // This one fails if floating-point precision is too high.
999 EXPECT_EQ(4U, vertices.size());
1000 VerticesContain(vertices, Point(50, 50 * kAspectRatio));
1001 VerticesContain(vertices, Point(100, 100 * kAspectRatio));
1002 VerticesContain(vertices, Point(50, 200));
1003 VerticesContain(vertices, Point(100, 200));
1004 EXPECT_TRUE(AreValidVertices(set, vertices));
1005
1006 set = ResolutionSet(50, 100, 0, 200, 0.0, kAspectRatio);
1007 vertices = set.ComputeVertices();
1008 EXPECT_EQ(4U, vertices.size());
1009 VerticesContain(vertices, Point(50, 50 * kAspectRatio));
1010 VerticesContain(vertices, Point(100, 100 * kAspectRatio));
1011 VerticesContain(vertices, Point(50, 0));
1012 VerticesContain(vertices, Point(100, 0));
1013 EXPECT_TRUE(AreValidVertices(set, vertices));
1014 }
1015
1016 // Aspect-ratio lines touch the corners of the box.
1017 {
1018 ResolutionSet set(50, 100, 50, 100, 0.5, 2.0);
1019 auto vertices = set.ComputeVertices();
1020 EXPECT_EQ(4U, vertices.size());
1021 VerticesContain(vertices, Point(50, 50));
1022 VerticesContain(vertices, Point(100, 50));
1023 VerticesContain(vertices, Point(50, 100));
1024 VerticesContain(vertices, Point(100, 100));
1025 EXPECT_TRUE(AreValidVertices(set, vertices));
1026 }
1027
1028 // Hexagons.
1029 {
1030 ResolutionSet set(10, 100, 10, 100, 0.5, 1.5);
1031 auto vertices = set.ComputeVertices();
1032 EXPECT_EQ(6U, vertices.size());
1033 VerticesContain(vertices, Point(10, 10));
1034 VerticesContain(vertices, Point(100, 100));
1035 VerticesContain(vertices, Point(10, 10 * 1.5));
1036 VerticesContain(vertices, Point(100 / 1.5, 100));
1037 VerticesContain(vertices, Point(10 / 0.5, 10));
1038 VerticesContain(vertices, Point(100, 100 * 0.5));
1039 EXPECT_TRUE(AreValidVertices(set, vertices));
1040
1041 set = ResolutionSet(50, 100, 50, 100, 50.0 / 75.0, 75.0 / 50.0);
1042 vertices = set.ComputeVertices();
1043 EXPECT_EQ(6U, vertices.size());
1044 VerticesContain(vertices, Point(50, 50));
1045 VerticesContain(vertices, Point(100, 100));
1046 VerticesContain(vertices, Point(75, 50));
1047 VerticesContain(vertices, Point(50, 75));
1048 VerticesContain(vertices, Point(100, 100.0 * 50.0 / 75.0));
1049 VerticesContain(vertices, Point(100 * 50.0 / 75.0, 100.0));
1050 EXPECT_TRUE(AreValidVertices(set, vertices));
1051 }
1052
1053 // Both aspect-ratio constraints cross the left and top sides of the box.
1054 {
1055 ResolutionSet set(10, 100, 10, 100, 1.5, 1.7);
1056 auto vertices = set.ComputeVertices();
1057 EXPECT_EQ(4U, vertices.size());
1058 VerticesContain(vertices, Point(10, 10 * 1.5));
1059 VerticesContain(vertices, Point(10, 10 * 1.7));
1060 VerticesContain(vertices, Point(100 / 1.5, 100));
1061 VerticesContain(vertices, Point(100 / 1.7, 100));
1062 EXPECT_TRUE(AreValidVertices(set, vertices));
1063 }
1064
1065 // Both aspect-ratio constraints cross the left and right sides of the box.
1066 {
1067 ResolutionSet set(10, 100, 10, ResolutionSet::kMaxDimension, 1.5, 1.7);
1068 auto vertices = set.ComputeVertices();
1069 EXPECT_EQ(4U, vertices.size());
1070 VerticesContain(vertices, Point(10, 10 * 1.5));
1071 VerticesContain(vertices, Point(10, 10 * 1.7));
1072 VerticesContain(vertices, Point(100, 100 * 1.5));
1073 VerticesContain(vertices, Point(100, 100 * 1.7));
1074 EXPECT_TRUE(AreValidVertices(set, vertices));
1075 }
1076
1077 // Both aspect-ratio constraints cross the bottom and top sides of the box.
1078 {
1079 ResolutionSet set(10, 100, 50, 100, 2.0, 4.0);
1080 auto vertices = set.ComputeVertices();
1081 EXPECT_EQ(4U, vertices.size());
1082 VerticesContain(vertices, Point(50 / 2.0, 50));
1083 VerticesContain(vertices, Point(100 / 2.0, 100));
1084 VerticesContain(vertices, Point(50 / 4.0, 50));
1085 VerticesContain(vertices, Point(100 / 4.0, 100));
1086 EXPECT_TRUE(AreValidVertices(set, vertices));
1087 }
1088
1089 // Both aspect-ratio constraints cross the bottom and right sides of the box.
1090 {
1091 ResolutionSet set(10, 100, 50, 100, 0.7, 0.9);
1092 auto vertices = set.ComputeVertices();
1093 EXPECT_EQ(4U, vertices.size());
1094 VerticesContain(vertices, Point(50 / 0.7, 50));
1095 VerticesContain(vertices, Point(50 / 0.9, 50));
1096 VerticesContain(vertices, Point(100, 100 * 0.7));
1097 VerticesContain(vertices, Point(100, 100 * 0.9));
1098 EXPECT_TRUE(AreValidVertices(set, vertices));
1099 }
1100
1101 // Pentagons.
1102 {
1103 ResolutionSet set(10, 100, 50, 100, 0.7, 4.0);
1104 auto vertices = set.ComputeVertices();
1105 EXPECT_EQ(5U, vertices.size());
1106 VerticesContain(vertices, Point(50 / 0.7, 50));
1107 VerticesContain(vertices, Point(100, 100 * 0.7));
1108 VerticesContain(vertices, Point(50 / 4.0, 50));
1109 VerticesContain(vertices, Point(100 / 4.0, 100));
1110 VerticesContain(vertices, Point(100, 100));
1111 EXPECT_TRUE(AreValidVertices(set, vertices));
1112
1113 set = ResolutionSet(50, 100, 10, 100, 0.7, 1.5);
1114 vertices = set.ComputeVertices();
1115 EXPECT_EQ(5U, vertices.size());
1116 VerticesContain(vertices, Point(50, 50 * 0.7));
1117 VerticesContain(vertices, Point(100, 100 * 0.7));
1118 VerticesContain(vertices, Point(50, 50 * 1.5));
1119 VerticesContain(vertices, Point(100 / 1.5, 100));
1120 VerticesContain(vertices, Point(100, 100));
1121 EXPECT_TRUE(AreValidVertices(set, vertices));
1122 }
1123
1124 // Extreme aspect ratios, for completeness.
1125 {
1126 ResolutionSet set(0, 100, 0, ResolutionSet::kMaxDimension, 0.0, 0.0);
1127 auto vertices = set.ComputeVertices();
1128 EXPECT_EQ(2U, vertices.size());
1129 VerticesContain(vertices, Point(0, 0));
1130 VerticesContain(vertices, Point(100, 0));
1131 EXPECT_TRUE(AreValidVertices(set, vertices));
1132
1133 set = ResolutionSet(0, ResolutionSet::kMaxDimension, 0, 100, HUGE_VAL,
1134 HUGE_VAL);
1135 vertices = set.ComputeVertices();
1136 EXPECT_EQ(2U, vertices.size());
1137 VerticesContain(vertices, Point(0, 0));
1138 VerticesContain(vertices, Point(0, 100));
1139 EXPECT_TRUE(AreValidVertices(set, vertices));
1140 }
1141 }
1142
1143 TEST_F(MediaStreamConstraintsUtilSetsTest, NumericRangeSetDouble) {
1144 using DoubleRangeSet = NumericRangeSet<double>;
1145 // Set with maximum supported range.
1146 DoubleRangeSet set;
1147 EXPECT_EQ(0.0, set.Min());
1148 EXPECT_EQ(HUGE_VAL, set.Max());
1149 EXPECT_FALSE(set.IsEmpty());
1150
1151 // Constrained set.
1152 const double kMin = 1.0;
1153 const double kMax = 10.0;
1154 set = DoubleRangeSet(kMin, kMax);
1155 EXPECT_EQ(kMin, set.Min());
1156 EXPECT_EQ(kMax, set.Max());
1157 EXPECT_FALSE(set.IsEmpty());
1158
1159 // Empty set.
1160 set = DoubleRangeSet(kMax, kMin);
1161 EXPECT_TRUE(set.IsEmpty());
1162
1163 // Intersection.
1164 set = DoubleRangeSet(kMin, kMax);
1165 const double kMin2 = 5.0;
1166 const double kMax2 = 20.0;
1167 auto intersection = set.Intersection(DoubleRangeSet(kMin2, kMax2));
1168 EXPECT_EQ(kMin2, intersection.Min());
1169 EXPECT_EQ(kMax, intersection.Max());
1170 EXPECT_FALSE(intersection.IsEmpty());
1171
1172 // Empty intersection.
1173 intersection = set.Intersection(DoubleRangeSet(kMax + 1, HUGE_VAL));
1174 EXPECT_TRUE(intersection.IsEmpty());
1175 }
1176
1177 TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetString) {
1178 // Universal set.
1179 using StringSet = DiscreteSet<std::string>;
1180 StringSet set = StringSet::UniversalSet();
1181 EXPECT_TRUE(set.Contains("arbitrary"));
1182 EXPECT_TRUE(set.Contains("strings"));
1183 EXPECT_FALSE(set.IsEmpty());
1184 EXPECT_TRUE(set.is_universal());
1185 EXPECT_FALSE(set.HasExplicitElements());
1186
1187 // Constrained set.
1188 set = StringSet(std::vector<std::string>({"a", "b", "c"}));
1189 EXPECT_TRUE(set.Contains("a"));
1190 EXPECT_TRUE(set.Contains("b"));
1191 EXPECT_TRUE(set.Contains("c"));
1192 EXPECT_FALSE(set.Contains("d"));
1193 EXPECT_FALSE(set.IsEmpty());
1194 EXPECT_FALSE(set.is_universal());
1195 EXPECT_TRUE(set.HasExplicitElements());
1196 EXPECT_EQ(std::string("a"), set.FirstElement());
1197
1198 // Empty set.
1199 set = StringSet::EmptySet();
1200 EXPECT_FALSE(set.Contains("a"));
1201 EXPECT_FALSE(set.Contains("b"));
1202 EXPECT_TRUE(set.IsEmpty());
1203 EXPECT_FALSE(set.is_universal());
1204 EXPECT_FALSE(set.HasExplicitElements());
1205
1206 // Intersection.
1207 set = StringSet(std::vector<std::string>({"a", "b", "c"}));
1208 StringSet set2 = StringSet(std::vector<std::string>({"b", "c", "d"}));
1209 auto intersection = set.Intersection(set2);
1210 EXPECT_FALSE(intersection.Contains("a"));
1211 EXPECT_TRUE(intersection.Contains("b"));
1212 EXPECT_TRUE(intersection.Contains("c"));
1213 EXPECT_FALSE(intersection.Contains("d"));
1214 EXPECT_FALSE(intersection.IsEmpty());
1215 EXPECT_FALSE(intersection.is_universal());
1216 EXPECT_TRUE(intersection.HasExplicitElements());
1217 EXPECT_EQ(std::string("b"), intersection.FirstElement());
1218
1219 // Empty intersection.
1220 set2 = StringSet(std::vector<std::string>({"d", "e", "f"}));
1221 intersection = set.Intersection(set2);
1222 EXPECT_FALSE(intersection.Contains("a"));
1223 EXPECT_FALSE(intersection.Contains("b"));
1224 EXPECT_FALSE(intersection.Contains("c"));
1225 EXPECT_FALSE(intersection.Contains("d"));
1226 EXPECT_TRUE(intersection.IsEmpty());
1227 EXPECT_FALSE(intersection.is_universal());
1228 EXPECT_FALSE(intersection.HasExplicitElements());
1229 }
1230
1231 TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetBool) {
1232 using BoolSet = DiscreteSet<bool>;
1233 // Universal set.
1234 BoolSet set = BoolSet::UniversalSet();
1235 EXPECT_TRUE(set.Contains(true));
1236 EXPECT_TRUE(set.Contains(false));
1237 EXPECT_FALSE(set.IsEmpty());
1238 EXPECT_TRUE(set.is_universal());
1239 EXPECT_FALSE(set.HasExplicitElements());
1240
1241 // Constrained set.
1242 set = BoolSet({true});
1243 EXPECT_TRUE(set.Contains(true));
1244 EXPECT_FALSE(set.Contains(false));
1245 EXPECT_FALSE(set.IsEmpty());
1246 EXPECT_FALSE(set.is_universal());
1247 EXPECT_TRUE(set.HasExplicitElements());
1248 EXPECT_TRUE(set.FirstElement());
1249
1250 set = BoolSet({false});
1251 EXPECT_FALSE(set.Contains(true));
1252 EXPECT_TRUE(set.Contains(false));
1253 EXPECT_FALSE(set.IsEmpty());
1254 EXPECT_FALSE(set.is_universal());
1255 EXPECT_TRUE(set.HasExplicitElements());
1256 EXPECT_FALSE(set.FirstElement());
1257
1258 // Empty set.
1259 set = BoolSet::EmptySet();
1260 EXPECT_FALSE(set.Contains(true));
1261 EXPECT_FALSE(set.Contains(false));
1262 EXPECT_TRUE(set.IsEmpty());
1263 EXPECT_FALSE(set.is_universal());
1264 EXPECT_FALSE(set.HasExplicitElements());
1265
1266 // Intersection.
1267 set = BoolSet::UniversalSet();
1268 auto intersection = set.Intersection(BoolSet({true}));
1269 EXPECT_TRUE(intersection.Contains(true));
1270 EXPECT_FALSE(intersection.Contains(false));
1271 intersection = set.Intersection(set);
1272 EXPECT_TRUE(intersection.Contains(true));
1273 EXPECT_TRUE(intersection.Contains(true));
1274
1275 // Empty intersection.
1276 set = BoolSet({true});
1277 intersection = set.Intersection(BoolSet({false}));
1278 EXPECT_TRUE(intersection.IsEmpty());
1279 }
1280
1281 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/media_stream_constraints_util_sets.cc ('k') | content/renderer/media/media_stream_video_source.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698