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

Unified 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: Add missing#include and make ResolutionSet::ClosestPointTo private 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/media_stream_constraints_util_sets_unittest.cc
diff --git a/content/renderer/media/media_stream_constraints_util_sets_unittest.cc b/content/renderer/media/media_stream_constraints_util_sets_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..10ffd4abedc0f52224ffe3f4f0ca9857c958598f
--- /dev/null
+++ b/content/renderer/media/media_stream_constraints_util_sets_unittest.cc
@@ -0,0 +1,1252 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/media_stream_constraints_util_sets.h"
+
+#include <cmath>
+#include <string>
+#include <vector>
+
+#include "content/renderer/media/media_stream_video_source.h"
+#include "content/renderer/media/mock_constraint_factory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+using Point = ResolutionSet::Point;
+
+namespace {
+
+// Defined as macro in order to get more informative line-number information
+// when a test fails.
+#define EXPECT_POINT_EQ(p1, p2) \
+ do { \
+ EXPECT_DOUBLE_EQ((p1).height(), (p2).height()); \
+ EXPECT_DOUBLE_EQ((p1).width(), (p2).width()); \
+ } while (0)
+
+// Checks if |point| is an element of |vertices| using
+// Point::IsApproximatelyEqualTo() to test for equality.
+void VerticesContain(const std::vector<Point>& vertices, const Point& point) {
+ bool result = false;
+ for (const auto& vertex : vertices) {
+ if (point.IsApproximatelyEqualTo(vertex)) {
+ result = true;
+ break;
+ }
+ }
+ EXPECT_TRUE(result);
+}
+
+// Determines if |vertices| is valid according to the contract for
+// ResolutionCandidateSet::ComputeVertices().
+bool AreValidVertices(const std::vector<Point>& vertices) {
+ // Single-segment, single point or single segment are trivial cases.
hta - Chromium 2017/03/08 12:42:51 Nit: remove repeated "single-segment"
Guido Urdaneta 2017/03/09 17:55:43 Done.
+ if (vertices.size() <= 2)
+ return true;
+ else if (vertices.size() > 6) // Polygons of more than 6 sides are not valid.
+ return false;
+
+ // For the case of 3 to 6 vertices, the vertices must be in counterclockwise
+ // order. Compute orientation using the determinant of each diagonal in the
+ // polygon, using the first vertex as reference.
hbos_chromium 2017/03/09 11:34:22 Because this test uses the first vertex as the ref
Guido Urdaneta 2017/03/09 17:55:43 Your solution to 1 is in principle correct (check
hbos_chromium 2017/03/10 09:17:26 I think the only case 1) doesn't guard against is
+ Point prev_diagonal = vertices[1] - vertices[0];
+ for (auto vertex = vertices.begin() + 2; vertex != vertices.end(); ++vertex) {
+ Point current_diagonal = *vertex - vertices[0];
+ // The determinant of the two diagonals returns the signed area of the
+ // parallelogram they generate. The area is positive if the diagonals are in
+ // counterclockwise order, zero if the diagonals have the same direction and
+ // negative if the diagonals are in clockwise order.
+ // See https://en.wikipedia.org/wiki/Determinant#2_.C3.97_2_matrices.
+ double det = prev_diagonal.height() * current_diagonal.width() -
+ current_diagonal.height() * prev_diagonal.width();
+ if (det <= 0)
+ return false;
hbos_chromium 2017/03/09 11:34:22 I think this is prone to rounding errors. Parallel
Guido Urdaneta 2017/03/09 17:55:43 Acknowledged.
hbos_chromium 2017/03/10 09:17:26 How about <= kTolerance? In case of future tests f
+ prev_diagonal = current_diagonal;
+ }
+ return true;
+}
+
+// This function provides an alternative method for computing the projection
+// of |point| on the line of segment |s1||s2| to be used to compare the results
+// provided by Point::ClosestPointInSegment(). Since it relies on library
+// functions, it has larger error in practice than
+// Point::ClosestPointInSegment(), so results must be compared with
+// Point::IsApproximatelyEqualTo().
+// This function only computes projections. The result may be outside the
+// segment |s1||s2|.
+Point ProjectionOnSegmentLine(const Point& point,
+ const Point& s1,
+ const Point& s2) {
+ double segment_slope =
+ (s2.width() - s1.width()) / (s2.height() - s1.height());
+ double segment_angle = std::atan(segment_slope);
+ double norm = std::sqrt(Point::Dot(point, point));
+ double angle =
+ (point.height() == 0 && point.width() == 0)
+ ? 0.0
+ : std::atan(point.width() / point.height()) - segment_angle;
+ double projection_length = norm * std::cos(angle);
+ double projection_height = projection_length * std::cos(segment_angle);
+ double projection_width = projection_length * std::sin(segment_angle);
+ return Point(projection_height, projection_width);
+}
+
+} // namespace
+
+class MediaStreamConstraintsUtilSetsTest : public testing::Test {
+ protected:
+ using P = Point;
+ MockConstraintFactory factory_;
+};
+
+// This test tests the test-harness function AreValidVertices.
+TEST_F(MediaStreamConstraintsUtilSetsTest, VertexListValidity) {
+ EXPECT_TRUE(AreValidVertices({P(1, 1)}));
+ EXPECT_TRUE(AreValidVertices({P(1, 1)}));
+ EXPECT_TRUE(AreValidVertices({P(1, 0), P(0, 1)}));
+ EXPECT_TRUE(AreValidVertices({P(1, 1), P(0, 0), P(1, 0)}));
+
+ // Not in counterclockwise order.
+ EXPECT_FALSE(AreValidVertices({P(1, 0), P(0, 0), P(1, 1)}));
+
+ // Final vertex aligned with the previous two vertices.
+ EXPECT_FALSE(AreValidVertices({P(1, 0), P(1, 1), P(1, 1.5), P(1, 0.1)}));
+
+ // Not in counterclockwise order.
+ EXPECT_FALSE(
+ AreValidVertices({P(1, 0), P(3, 0), P(2, 2), P(3.1, 1), P(0, 1)}));
+
+ EXPECT_TRUE(AreValidVertices(
+ {P(1, 0), P(3, 0), P(3.1, 1), P(3, 2), P(1, 2), P(0.9, 1)}));
+
+ // Not in counterclockwise order.
+ EXPECT_FALSE(AreValidVertices(
+ {P(1, 0), P(3, 0), P(3.1, 1), P(1, 2), P(3, 2), P(0.9, 1)}));
+
+ // Counterclockwise, but more than 6 vertices.
+ EXPECT_FALSE(AreValidVertices(
+ {P(1, 0), P(3, 0), P(3.1, 1), P(3, 2), P(2, 2.1), P(1, 2), P(0.9, 1)}));
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, PointOperations) {
+ const Point kZero(0, 0);
+
+ // Basic equality and inequality
+ EXPECT_EQ(P(0, 0), kZero);
+ EXPECT_EQ(P(50, 50), P(50, 50));
+ EXPECT_NE(kZero, P(50, 50));
+ EXPECT_NE(P(50, 50), P(100, 100));
+ EXPECT_NE(P(50, 50), P(100, 50));
+
+ // Operations with zero.
+ EXPECT_EQ(kZero, kZero + kZero);
+ EXPECT_EQ(kZero, kZero - kZero);
+ EXPECT_EQ(kZero, 0.0 * kZero);
+ EXPECT_EQ(0.0, P::Dot(kZero, kZero));
+ EXPECT_EQ(0.0, P::SquareEuclideanDistance(kZero, kZero));
+ EXPECT_EQ(kZero, P::ClosestPointInSegment(kZero, kZero, kZero));
+
+ // Operations with zero and nonzero values.
+ EXPECT_EQ(P(50, 50), kZero + P(50, 50));
+ EXPECT_EQ(P(50, 50) + kZero, kZero + P(50, 50));
+ EXPECT_EQ(P(50, 50), P(50, 50) - kZero);
+ EXPECT_EQ(kZero, P(50, 50) - P(50, 50));
+ EXPECT_EQ(kZero, 0.0 * P(50, 50));
+ EXPECT_EQ(0.0, P::Dot(kZero, P(50, 50)));
+ EXPECT_EQ(0.0, P::Dot(P(50, 50), kZero));
+ EXPECT_EQ(5000, P::SquareEuclideanDistance(kZero, P(50, 50)));
+ EXPECT_EQ(P::SquareEuclideanDistance(P(50, 50), kZero),
+ P::SquareEuclideanDistance(kZero, P(50, 50)));
+ EXPECT_EQ(kZero, P::ClosestPointInSegment(kZero, kZero, P(50, 50)));
+ EXPECT_EQ(kZero, P::ClosestPointInSegment(kZero, P(50, 50), kZero));
+ EXPECT_EQ(P(50, 50),
+ P::ClosestPointInSegment(P(50, 50), P(50, 50), P(50, 50)));
+
+ // Operations with nonzero values.
+ // Additions.
+ EXPECT_EQ(P(100, 50), P(50, 50) + P(50, 0));
+ EXPECT_EQ(P(100, 50), P(50, 0) + P(50, 50));
+
+ // Substractions.
+ EXPECT_EQ(P(50, 50), P(100, 100) - P(50, 50));
+ EXPECT_EQ(P(50, 50), P(100, 50) - P(50, 0));
+ EXPECT_EQ(P(50, 0), P(100, 50) - P(50, 50));
+
+ // Scalar-vector products.
+ EXPECT_EQ(P(50, 50), 1.0 * P(50, 50));
+ EXPECT_EQ(P(75, 75), 1.5 * P(50, 50));
+ EXPECT_EQ(P(200, 100), 2.0 * P(100, 50));
+ EXPECT_EQ(2.0 * (P(100, 100) + P(100, 50)),
+ 2.0 * P(100, 100) + 2.0 * P(100, 50));
+
+ // Dot products.
+ EXPECT_EQ(2 * 50 * 100, P::Dot(P(50, 50), P(100, 100)));
+ EXPECT_EQ(P::Dot(P(100, 100), P(50, 50)), P::Dot(P(50, 50), P(100, 100)));
+ EXPECT_EQ(0, P::Dot(P(100, 0), P(0, 100)));
+
+ // Distances.
+ EXPECT_EQ(25, P::SquareEuclideanDistance(P(4, 0), P(0, 3)));
+ EXPECT_EQ(75 * 75, P::SquareEuclideanDistance(P(100, 0), P(25, 0)));
+ EXPECT_EQ(75 * 75, P::SquareEuclideanDistance(P(0, 100), P(0, 25)));
+ EXPECT_EQ(5 * 5 + 9 * 9, P::SquareEuclideanDistance(P(5, 1), P(10, 10)));
+
+ // Closest point to segment from (10,0) to (50,0).
+ EXPECT_EQ(P(25, 0), P::ClosestPointInSegment(P(25, 25), P(10, 0), P(50, 0)));
+ EXPECT_EQ(P(50, 0),
+ P::ClosestPointInSegment(P(100, 100), P(10, 0), P(50, 0)));
+ EXPECT_EQ(P(10, 0), P::ClosestPointInSegment(P(0, 100), P(10, 0), P(50, 0)));
+
+ // Closest point to segment from (0,10) to (0,50).
+ EXPECT_EQ(P(0, 25), P::ClosestPointInSegment(P(25, 25), P(0, 10), P(0, 50)));
+ EXPECT_EQ(P(0, 50),
+ P::ClosestPointInSegment(P(100, 100), P(0, 10), P(0, 50)));
+ EXPECT_EQ(P(0, 10), P::ClosestPointInSegment(P(100, 0), P(0, 10), P(0, 50)));
+
+ // Closest point to segment from (0,10) to (10,0).
+ EXPECT_EQ(P(5, 5), P::ClosestPointInSegment(P(25, 25), P(0, 10), P(10, 0)));
+ EXPECT_EQ(P(5, 5), P::ClosestPointInSegment(P(100, 100), P(0, 10), P(10, 0)));
+ EXPECT_EQ(P(10, 0), P::ClosestPointInSegment(P(100, 0), P(0, 10), P(10, 0)));
+ EXPECT_EQ(P(0, 10), P::ClosestPointInSegment(P(0, 100), P(0, 10), P(10, 0)));
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionUnconstrained) {
+ ResolutionSet set;
+ EXPECT_TRUE(set.ContainsPoint(0, 0));
+ EXPECT_TRUE(set.ContainsPoint(1, 1));
+ EXPECT_TRUE(set.ContainsPoint(2000, 2000));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionConstrained) {
+ ResolutionSet set = ResolutionSet::FromHeight(10, 100);
+ EXPECT_FALSE(set.ContainsPoint(0, 0));
+ EXPECT_TRUE(set.ContainsPoint(10, 10));
+ EXPECT_TRUE(set.ContainsPoint(50, 50));
+ EXPECT_TRUE(set.ContainsPoint(100, 100));
+ EXPECT_FALSE(set.ContainsPoint(500, 500));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromHeight(0, 100);
+ EXPECT_TRUE(set.ContainsPoint(0, 0));
+ EXPECT_TRUE(set.ContainsPoint(10, 10));
+ EXPECT_TRUE(set.ContainsPoint(50, 50));
+ EXPECT_TRUE(set.ContainsPoint(100, 100));
+ EXPECT_FALSE(set.ContainsPoint(500, 500));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromHeight(100, ResolutionSet::kMaxDimension);
+ EXPECT_FALSE(set.ContainsPoint(0, 0));
+ EXPECT_FALSE(set.ContainsPoint(10, 10));
+ EXPECT_FALSE(set.ContainsPoint(50, 50));
+ EXPECT_TRUE(set.ContainsPoint(100, 100));
+ EXPECT_TRUE(set.ContainsPoint(500, 500));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromWidth(10, 100);
+ EXPECT_FALSE(set.ContainsPoint(0, 0));
+ EXPECT_TRUE(set.ContainsPoint(10, 10));
+ EXPECT_TRUE(set.ContainsPoint(50, 50));
+ EXPECT_TRUE(set.ContainsPoint(100, 100));
+ EXPECT_FALSE(set.ContainsPoint(500, 500));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromWidth(0, 100);
+ EXPECT_TRUE(set.ContainsPoint(0, 0));
+ EXPECT_TRUE(set.ContainsPoint(10, 10));
+ EXPECT_TRUE(set.ContainsPoint(50, 50));
+ EXPECT_TRUE(set.ContainsPoint(100, 100));
+ EXPECT_FALSE(set.ContainsPoint(500, 500));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromWidth(100, ResolutionSet::kMaxDimension);
+ EXPECT_FALSE(set.ContainsPoint(0, 0));
+ EXPECT_FALSE(set.ContainsPoint(10, 10));
+ EXPECT_FALSE(set.ContainsPoint(50, 50));
+ EXPECT_TRUE(set.ContainsPoint(100, 100));
+ EXPECT_TRUE(set.ContainsPoint(500, 500));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromAspectRatio(1.0, 2.0);
+ EXPECT_TRUE(set.ContainsPoint(0, 0));
+ EXPECT_TRUE(set.ContainsPoint(10, 10));
+ EXPECT_TRUE(set.ContainsPoint(10, 20));
+ EXPECT_TRUE(set.ContainsPoint(100, 100));
+ EXPECT_TRUE(set.ContainsPoint(2000, 4000));
+ EXPECT_FALSE(set.ContainsPoint(1, 50));
+ EXPECT_FALSE(set.ContainsPoint(50, 1));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromAspectRatio(0.0, 2.0);
+ EXPECT_TRUE(set.ContainsPoint(0, 0));
+ EXPECT_TRUE(set.ContainsPoint(10, 10));
+ EXPECT_TRUE(set.ContainsPoint(10, 20));
+ EXPECT_TRUE(set.ContainsPoint(100, 100));
+ EXPECT_TRUE(set.ContainsPoint(2000, 4000));
+ EXPECT_FALSE(set.ContainsPoint(1, 50));
+ EXPECT_TRUE(set.ContainsPoint(50, 1));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromAspectRatio(1.0, HUGE_VAL);
+ EXPECT_TRUE(set.ContainsPoint(0, 0));
+ EXPECT_TRUE(set.ContainsPoint(10, 10));
+ EXPECT_TRUE(set.ContainsPoint(10, 20));
+ EXPECT_TRUE(set.ContainsPoint(100, 100));
+ EXPECT_TRUE(set.ContainsPoint(2000, 4000));
+ EXPECT_TRUE(set.ContainsPoint(1, 50));
+ EXPECT_FALSE(set.ContainsPoint(50, 1));
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionTrivialEmptiness) {
+ ResolutionSet set = ResolutionSet::FromHeight(100, 10);
+ EXPECT_TRUE(set.IsEmpty());
+ EXPECT_TRUE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromWidth(100, 10);
+ EXPECT_TRUE(set.IsEmpty());
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_TRUE(set.IsWidthEmpty());
+ EXPECT_FALSE(set.IsAspectRatioEmpty());
+
+ set = ResolutionSet::FromAspectRatio(100.0, 10.0);
+ EXPECT_TRUE(set.IsEmpty());
+ EXPECT_FALSE(set.IsHeightEmpty());
+ EXPECT_FALSE(set.IsWidthEmpty());
+ EXPECT_TRUE(set.IsAspectRatioEmpty());
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionLineConstraintsEmptiness) {
+ ResolutionSet set(1, 1, 1, 1, 1, 1);
+ EXPECT_FALSE(set.IsEmpty());
+ EXPECT_FALSE(set.ContainsPoint(0, 0));
+ EXPECT_TRUE(set.ContainsPoint(1, 1));
+ EXPECT_FALSE(set.ContainsPoint(1, 0));
+ EXPECT_FALSE(set.ContainsPoint(0, 1));
+
+ // Three lines that do not intersect in the same point is empty.
+ set = ResolutionSet(1, 1, 1, 1, 0.5, 0.5);
+ EXPECT_TRUE(set.IsEmpty());
+ EXPECT_TRUE(set.IsAspectRatioEmpty());
+ EXPECT_FALSE(set.ContainsPoint(0, 0));
+ EXPECT_FALSE(set.ContainsPoint(1, 1));
+ EXPECT_FALSE(set.ContainsPoint(1, 0));
+ EXPECT_FALSE(set.ContainsPoint(0, 1));
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionBoxEmptiness) {
+ int kMin = 100;
+ int kMax = 200;
+ // Max aspect ratio below box.
+ ResolutionSet set(kMin, kMax, kMin, kMax, 0.4, 0.4);
+ EXPECT_TRUE(set.IsEmpty());
+ EXPECT_TRUE(set.IsAspectRatioEmpty());
+
+ // Min aspect ratio above box.
+ set = ResolutionSet(kMin, kMax, kMin, kMax, 3.0, HUGE_VAL);
+ EXPECT_TRUE(set.IsEmpty());
+ EXPECT_TRUE(set.IsAspectRatioEmpty());
+
+ // Min aspect ratio crosses box.
+ set = ResolutionSet(kMin, kMax, kMin, kMax, 1.0, HUGE_VAL);
+ EXPECT_FALSE(set.IsEmpty());
+
+ // Max aspect ratio crosses box.
+ set = ResolutionSet(kMin, kMax, kMin, kMax, 0.0, 1.0);
+ EXPECT_FALSE(set.IsEmpty());
+
+ // Min and max aspect ratios cross box.
+ set = ResolutionSet(kMin, kMax, kMin, kMax, 0.9, 1.1);
+ EXPECT_FALSE(set.IsEmpty());
+
+ // Min and max aspect ratios cover box.
+ set = ResolutionSet(kMin, kMax, kMin, kMax, 0.2, 100);
+ EXPECT_FALSE(set.IsEmpty());
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionPointIntersection) {
+ ResolutionSet set1(1, 2, 1, 2, 0.0, HUGE_VAL);
+ ResolutionSet set2 = ResolutionSet::FromExactAspectRatio(0.5);
+
+ // The intersection should contain only the point (h=2, w=1)
+ auto intersection = set1.Intersection(set2);
+ EXPECT_TRUE(intersection.ContainsPoint(2, 1));
hbos_chromium 2017/03/09 11:34:21 How about EXPECT-ing the ResolutionSet to be appro
Guido Urdaneta 2017/03/09 17:55:43 Checking set equality is tricky, because the corre
+
+ // It should not contain any point in the vicinity of the included point.
hbos_chromium 2017/03/09 11:34:22 nit: It's good if the vicinity is super close and
Guido Urdaneta 2017/03/09 17:55:43 Done.
+ EXPECT_FALSE(intersection.ContainsPoint(1, 0));
+ EXPECT_FALSE(intersection.ContainsPoint(2, 0));
+ EXPECT_FALSE(intersection.ContainsPoint(3, 0));
+ EXPECT_FALSE(intersection.ContainsPoint(1, 1));
+ EXPECT_FALSE(intersection.ContainsPoint(3, 1));
+ EXPECT_FALSE(intersection.ContainsPoint(1, 2));
+ EXPECT_FALSE(intersection.ContainsPoint(2, 2));
+ EXPECT_FALSE(intersection.ContainsPoint(3, 2));
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionLineIntersection) {
+ ResolutionSet set1(1, 2, 1, 2, 0.0, HUGE_VAL);
+ ResolutionSet set2 = ResolutionSet::FromExactAspectRatio(1.0);
+
+ // The intersection should contain (1,1) and (2,2)
+ auto intersection = set1.Intersection(set2);
+ EXPECT_TRUE(intersection.ContainsPoint(1, 1));
+ EXPECT_TRUE(intersection.ContainsPoint(2, 2));
+
+ // It should not contain the other points in the bounding box.
+ EXPECT_FALSE(intersection.ContainsPoint(1, 2));
+ EXPECT_FALSE(intersection.ContainsPoint(2, 1));
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionBoxIntersection) {
+ const int kMin1 = 0;
+ const int kMax1 = 2;
+ ResolutionSet set1(kMin1, kMax1, kMin1, kMax1, 0.0, HUGE_VAL);
+
+ const int kMin2 = 1;
+ const int kMax2 = 3;
+ ResolutionSet set2(kMin2, kMax2, kMin2, kMax2, 0.0, HUGE_VAL);
+
+ auto intersection = set1.Intersection(set2);
+ for (int i = kMin1; i <= kMax2; ++i) {
+ for (int j = kMin1; j <= kMax2; ++j) {
+ if (i >= kMin2 && j >= kMin2 && i <= kMax1 && j <= kMax1)
+ EXPECT_TRUE(intersection.ContainsPoint(i, j));
+ else
+ EXPECT_FALSE(intersection.ContainsPoint(i, j));
+ }
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionPointSetClosestPoint) {
+ const int kHeight = 10;
+ const int kWidth = 10;
+ const double kAspectRatio = 1.0;
+ ResolutionSet set(kHeight, kHeight, kWidth, kWidth, kAspectRatio,
+ kAspectRatio);
+
+ for (int height = 0; height < 100; height += 10) {
+ for (int width = 0; width < 100; width += 10) {
+ EXPECT_EQ(P(kHeight, kWidth), set.ClosestPointTo(P(height, width)));
+ }
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionLineSetClosestPoint) {
+ {
+ const int kHeight = 10;
+ auto set = ResolutionSet::FromExactHeight(kHeight);
+ for (int height = 0; height < 100; height += 10) {
+ for (int width = 0; width < 100; width += 10) {
+ EXPECT_EQ(P(kHeight, width), set.ClosestPointTo(P(height, width)));
+ }
+ }
+ const int kWidth = 10;
+ set = ResolutionSet::FromExactWidth(kWidth);
+ for (int height = 0; height < 100; height += 10) {
+ for (int width = 0; width < 100; width += 10) {
+ EXPECT_EQ(P(height, kWidth), set.ClosestPointTo(P(height, width)));
+ }
+ }
+ }
+
+ {
+ const double kAspectRatios[] = {0.0, 0.1, 0.2, 0.5,
+ 1.0, 2.0, 5.0, HUGE_VAL};
+ for (double aspect_ratio : kAspectRatios) {
+ auto set = ResolutionSet::FromExactAspectRatio(aspect_ratio);
+ for (int height = 0; height < 100; height += 10) {
+ for (int width = 0; width < 100; width += 10) {
+ Point point(height, width);
+ Point expected =
+ ProjectionOnSegmentLine(point, P(0, 0), P(1, aspect_ratio));
+ Point actual = set.ClosestPointTo(point);
+ // This requires higher tolerance than ExpectPointEx due to the larger
+ // error of the alternative projection method.
+ EXPECT_TRUE(expected.IsApproximatelyEqualTo(actual));
+ }
+ }
+ }
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionGeneralSetClosestPoint) {
+ // This set contains the following vertices:
+ // (10, 10), (20, 10), (100, 50), (100, 100), (100/1.5, 100), (10, 15)
+ ResolutionSet set(10, 100, 10, 100, 0.5, 1.5);
+
+ // Check that vertices are the closest points to themselves.
+ std::vector<Point> vertices = {P(10, 10), P(20, 10), P(100, 50),
+ P(100, 100), P(100 / 1.5, 100), P(10, 15)};
hbos_chromium 2017/03/09 11:34:21 EXPECT_EQ(vertices, set.ComputeVertices())
Guido Urdaneta 2017/03/09 17:55:43 I prefer to test that ComputeVertices works in Res
hbos_chromium 2017/03/10 09:17:26 Acknowledged.
+ for (auto& vertex : vertices)
+ EXPECT_EQ(vertex, set.ClosestPointTo(vertex));
+
+ // Point inside the set.
+ EXPECT_EQ(P(11, 11), set.ClosestPointTo(P(11, 11)));
+
+ // Close to horizontal segment (10, 10) (20, 10).
+ EXPECT_EQ(P(15, 10), set.ClosestPointTo(P(15, 9)));
+
+ // Close to horizontal segment (100, 100) (100/1.5, 100).
+ EXPECT_EQ(P(99, 100), set.ClosestPointTo(P(99, 200)));
+
+ // Close to vertical segment (10, 15) (10, 10).
+ EXPECT_EQ(P(10, 12.5), set.ClosestPointTo(P(2, 12.5)));
+
+ // Close to vertical segment (100, 50) (100, 100).
+ EXPECT_EQ(P(100, 75), set.ClosestPointTo(P(120, 75)));
+
+ // Close to oblique segment (20, 10) (100, 50)
+ {
+ Point point(70, 15);
+ Point expected = ProjectionOnSegmentLine(point, P(20, 10), P(100, 50));
+ Point actual = set.ClosestPointTo(point);
+ EXPECT_POINT_EQ(expected, actual);
+ }
+
+ // Close to oblique segment (100/1.5, 100) (10, 15)
+ {
+ Point point(12, 70);
+ Point expected =
+ ProjectionOnSegmentLine(point, P(100 / 1.5, 100), P(10, 15));
+ Point actual = set.ClosestPointTo(point);
+ EXPECT_POINT_EQ(expected, actual);
+ }
+
+ // Points close to vertices.
+ EXPECT_EQ(P(10, 10), set.ClosestPointTo(P(9, 9)));
+ EXPECT_EQ(P(20, 10), set.ClosestPointTo(P(20, 9)));
+ EXPECT_EQ(P(100, 50), set.ClosestPointTo(P(101, 50)));
+ EXPECT_EQ(P(100, 100), set.ClosestPointTo(P(101, 101)));
+ EXPECT_EQ(P(100 / 1.5, 100), set.ClosestPointTo(P(100 / 1.5, 101)));
+ EXPECT_EQ(P(10, 15), set.ClosestPointTo(P(9, 15)));
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionIdealIntersects) {
+ ResolutionSet set(100, 1000, 100, 1000, 0.5, 2.0);
hbos_chromium 2017/03/09 11:34:21 EXPECT_EQ the vertices returned by ComputeVertices
Guido Urdaneta 2017/03/09 17:55:43 I prefer to test that in ResolutionVertices. If yo
hbos_chromium 2017/03/10 09:17:26 Acknowledged.
+
+ int kIdealHeight = 500;
+ int kIdealWidth = 1000;
+ double kIdealAspectRatio = 1.5;
+
+ // Ideal height.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(kIdealHeight);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(
+ Point(kIdealHeight,
+ kIdealHeight * MediaStreamVideoSource::kDefaultAspectRatio),
+ point);
+ }
+
+ // Ideal width.
+ {
+ factory_.Reset();
+ factory_.basic().width.setIdeal(kIdealWidth);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(
+ Point(kIdealWidth / MediaStreamVideoSource::kDefaultAspectRatio,
+ kIdealWidth),
+ point);
+ }
+
+ // Ideal aspect ratio.
+ {
+ factory_.Reset();
+ factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_DOUBLE_EQ(MediaStreamVideoSource::kDefaultHeight, point.height());
+ EXPECT_DOUBLE_EQ(MediaStreamVideoSource::kDefaultHeight * kIdealAspectRatio,
+ point.width());
+ }
+
+ // Ideal height and width.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(kIdealHeight);
+ factory_.basic().width.setIdeal(kIdealWidth);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(Point(kIdealHeight, kIdealWidth), point);
+ }
+
+ // Ideal height and aspect-ratio.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(kIdealHeight);
+ factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(Point(kIdealHeight, kIdealHeight * kIdealAspectRatio),
+ point);
+ }
+
+ // Ideal width and aspect-ratio.
+ {
+ factory_.Reset();
+ factory_.basic().width.setIdeal(kIdealWidth);
+ factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(Point(kIdealWidth / kIdealAspectRatio, kIdealWidth), point);
+ }
+
+ // Ideal height, width and aspect-ratio.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(kIdealHeight);
+ factory_.basic().width.setIdeal(kIdealWidth);
+ factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ // Ideal aspect ratio should be ignored.
+ EXPECT_POINT_EQ(Point(kIdealHeight, kIdealWidth), point);
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionIdealOutsideSinglePoint) {
+ // This set is a triangle with vertices (100,100), (1000,100) and (1000,1000).
+ ResolutionSet set(100, 1000, 100, 1000, 0.0, 1.0);
hbos_chromium 2017/03/09 11:34:21 EXPECT_EQ the vertices returned by ComputeVertices
Guido Urdaneta 2017/03/09 17:55:43 Ditto.
+
+ int kIdealHeight = 50;
+ int kIdealWidth = 1100;
+ double kIdealAspectRatio = 0.09;
+ Point kVertex1(100, 100);
+ Point kVertex2(1000, 100);
+ Point kVertex3(1000, 1000);
+
+ // Ideal height.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(kIdealHeight);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(kVertex1, point);
+ }
+
+ // Ideal width.
+ {
+ factory_.Reset();
+ factory_.basic().width.setIdeal(kIdealWidth);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(kVertex3, point);
+ }
+
+ // Ideal aspect ratio.
+ {
+ factory_.Reset();
+ factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(kVertex2, point);
+ }
+
+ // Ideal height and width.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(kIdealHeight);
+ factory_.basic().width.setIdeal(kIdealWidth);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ Point expected = set.ClosestPointTo(Point(kIdealHeight, kIdealWidth));
+ EXPECT_POINT_EQ(expected, point);
+ }
+
+ // Ideal height and aspect-ratio.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(kIdealHeight);
+ factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ Point expected = set.ClosestPointTo(
+ Point(kIdealHeight, kIdealHeight * kIdealAspectRatio));
+ EXPECT_POINT_EQ(expected, point);
+ }
+
+ // Ideal width and aspect-ratio.
+ {
+ factory_.Reset();
+ factory_.basic().width.setIdeal(kIdealWidth);
+ factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ Point expected =
+ set.ClosestPointTo(Point(kIdealWidth / kIdealAspectRatio, kIdealWidth));
+ EXPECT_POINT_EQ(expected, point);
+ }
+
+ // Ideal height, width and aspect-ratio.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(kIdealHeight);
+ factory_.basic().width.setIdeal(kIdealWidth);
+ factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
hbos_chromium 2017/03/09 11:34:21 Comment saying the ideal aspect ratio doesn't matt
Guido Urdaneta 2017/03/09 17:55:43 Done.
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ Point expected = set.ClosestPointTo(Point(kIdealHeight, kIdealWidth));
+ EXPECT_POINT_EQ(expected, point);
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest,
+ ResolutionIdealOutsideMultiplePoints) {
+ // This set is a triangle with vertices (100,100), (1000,100) and (1000,1000).
+ ResolutionSet set(100, 1000, 100, 1000, 0.0, 1.0);
hbos_chromium 2017/03/09 11:34:21 EXPECT_EQ the vertices returned by ComputeVertices
Guido Urdaneta 2017/03/09 17:55:43 Ditto.
+
+ int kIdealHeight = 1100;
+ int kIdealWidth = 50;
+ double kIdealAspectRatio = 11.0;
+ Point kVertex1(100, 100);
+ Point kVertex2(1000, 100);
+ Point kVertex3(1000, 1000);
+
+ // Ideal height.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(kIdealHeight);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ // Parallel to the side between kVertex2 and kVertex3. Point closest to
+ // default aspect ratio is kVertex3.
+ EXPECT_POINT_EQ(kVertex3, point);
+ }
+
+ // Ideal width.
+ {
+ factory_.Reset();
+ factory_.basic().width.setIdeal(kIdealWidth);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ // Parallel to the side between kVertex1 and kVertex2. Point closest to
+ // default aspect ratio is kVertex1.
+ EXPECT_POINT_EQ(kVertex1, point);
+ }
+
+ // Ideal aspect ratio.
+ {
+ factory_.Reset();
+ factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ // The side between kVertex1 and kVertex3 is closest. The points closest to
+ // default dimensions are (kDefaultHeight, kDefaultHeight * AR)
+ // and (kDefaultWidth / AR, kDefaultWidth). Since the aspect ratio of the
+ // polygon side is less than the default, the algorithm preserves the
+ // default width.
+ EXPECT_POINT_EQ(
+ Point(MediaStreamVideoSource::kDefaultWidth / kVertex1.AspectRatio(),
+ MediaStreamVideoSource::kDefaultWidth),
hbos_chromium 2017/03/09 11:34:21 EXPECT_EQ that this point is inside the set.
Guido Urdaneta 2017/03/09 17:55:43 Done.
+ point);
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest,
+ ResolutionUnconstrainedExtremeIdeal) {
+ ResolutionSet set;
+
+ // Ideal height.
+ {
+ factory_.Reset();
+ factory_.basic().height.setIdeal(std::numeric_limits<long>::max());
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(
+ Point(ResolutionSet::kMaxDimension, ResolutionSet::kMaxDimension),
+ point);
+ factory_.basic().height.setIdeal(0);
+ point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(Point(0, 0), point);
+ }
+
+ // Ideal width.
+ {
+ factory_.Reset();
+ factory_.basic().width.setIdeal(std::numeric_limits<long>::max());
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(Point(ResolutionSet::kMaxDimension /
+ MediaStreamVideoSource::kDefaultAspectRatio,
+ ResolutionSet::kMaxDimension),
+ point);
+ factory_.basic().width.setIdeal(0);
+ point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(Point(0, 0), point);
+ }
+
+ // Ideal Aspect Ratio.
+ {
+ factory_.Reset();
+ factory_.basic().aspectRatio.setIdeal(HUGE_VAL);
+ Point point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(Point(0, ResolutionSet::kMaxDimension), point);
+ factory_.basic().aspectRatio.setIdeal(0.0);
+ point = set.SelectClosestPointToIdeal(
+ factory_.CreateWebMediaConstraints().basic());
+ EXPECT_POINT_EQ(Point(ResolutionSet::kMaxDimension, 0), point);
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionVertices) {
hbos_chromium 2017/03/09 11:34:21 Should VerticesContains be replaced by vertices wh
Guido Urdaneta 2017/03/09 17:55:43 Changed AreValidVertices to check that the vertice
+ // Empty set.
+ {
+ ResolutionSet set(1000, 100, 1000, 100, 0.5, 1.5);
+ ASSERT_TRUE(set.IsEmpty());
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(0U, vertices.size());
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // Three lines that intersect at the same point.
+ {
+ ResolutionSet set(1, 1, 1, 1, 1, 1);
+ EXPECT_FALSE(set.IsEmpty());
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(1U, vertices.size());
+ VerticesContain(vertices, Point(1, 1));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // A line segment with the lower-left and upper-right corner of the box.
+ {
+ ResolutionSet set(0, 100, 0, 100, 1.0, 1.0);
+ EXPECT_FALSE(set.IsEmpty());
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(2U, vertices.size());
+ VerticesContain(vertices, Point(0, 0));
+ VerticesContain(vertices, Point(100, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(0, 100, 0, 100, 1.0, HUGE_VAL);
+ EXPECT_FALSE(set.IsEmpty());
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(3U, vertices.size());
+ VerticesContain(vertices, Point(0, 0));
+ VerticesContain(vertices, Point(100, 100));
+ VerticesContain(vertices, Point(0, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(0, 100, 0, 100, 0, 1.0);
+ EXPECT_FALSE(set.IsEmpty());
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(3U, vertices.size());
+ VerticesContain(vertices, Point(0, 0));
+ VerticesContain(vertices, Point(100, 100));
+ VerticesContain(vertices, Point(100, 0));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // A line segment that crosses the bottom and right sides of the box.
+ {
+ const double kAspectRatio = 50.0 / 75.0;
+ ResolutionSet set(50, 100, 50, 100, kAspectRatio, kAspectRatio);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(2U, vertices.size());
+ VerticesContain(vertices, Point(50 / kAspectRatio, 50));
+ VerticesContain(vertices, Point(100, 100.0 * kAspectRatio));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(50, 100, 50, 100, kAspectRatio, HUGE_VAL);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(5U, vertices.size());
+ VerticesContain(vertices, Point(50 / kAspectRatio, 50));
+ VerticesContain(vertices, Point(100, 100.0 * kAspectRatio));
+ VerticesContain(vertices, Point(50, 50));
+ VerticesContain(vertices, Point(50, 100));
+ VerticesContain(vertices, Point(100, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(50, 100, 50, 100, 0.0, kAspectRatio);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(3U, vertices.size());
+ VerticesContain(vertices, Point(50 / kAspectRatio, 50));
+ VerticesContain(vertices, Point(100, 100.0 * kAspectRatio));
+ VerticesContain(vertices, Point(100, 50));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // A line segment that crosses the left and top sides of the box.
+ {
+ const double kAspectRatio = 75.0 / 50.0;
+ ResolutionSet set(50, 100, 50, 100, kAspectRatio, kAspectRatio);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(2U, vertices.size());
+ VerticesContain(vertices, Point(50, 50 * kAspectRatio));
+ VerticesContain(vertices, Point(100 / kAspectRatio, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(50, 100, 50, 100, kAspectRatio, HUGE_VAL);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(3U, vertices.size());
+ VerticesContain(vertices, Point(50, 50 * kAspectRatio));
+ VerticesContain(vertices, Point(100 / kAspectRatio, 100));
+ VerticesContain(vertices, Point(50, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(50, 100, 50, 100, 0.0, kAspectRatio);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(5U, vertices.size());
+ VerticesContain(vertices, Point(50, 50 * kAspectRatio));
+ VerticesContain(vertices, Point(100 / kAspectRatio, 100));
+ VerticesContain(vertices, Point(50, 50));
+ VerticesContain(vertices, Point(100, 100));
+ VerticesContain(vertices, Point(100, 50));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // An aspect ratio constraint crosses the bottom and top sides of the box.
+ {
+ const double kAspectRatio = 75.0 / 50.0;
+ ResolutionSet set(0, 100, 50, 100, kAspectRatio, kAspectRatio);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(2U, vertices.size());
+ VerticesContain(vertices, Point(50 / kAspectRatio, 50));
+ VerticesContain(vertices, Point(100 / kAspectRatio, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(0, 100, 50, 100, kAspectRatio, HUGE_VAL);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(4U, vertices.size());
+ VerticesContain(vertices, Point(50 / kAspectRatio, 50));
+ VerticesContain(vertices, Point(100 / kAspectRatio, 100));
+ VerticesContain(vertices, Point(0, 50));
+ VerticesContain(vertices, Point(0, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(0, 100, 50, 100, 0.0, kAspectRatio);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(4U, vertices.size());
+ VerticesContain(vertices, Point(50 / kAspectRatio, 50));
+ VerticesContain(vertices, Point(100 / kAspectRatio, 100));
+ VerticesContain(vertices, Point(100, 50));
+ VerticesContain(vertices, Point(100, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // An aspect-ratio constraint crosses the left and right sides of the box.
+ {
+ const double kAspectRatio = 75.0 / 50.0;
+ ResolutionSet set(50, 100, 0, 200, kAspectRatio, kAspectRatio);
+ auto vertices = set.ComputeVertices();
+ // This one fails if floating-point precision is too high.
+ EXPECT_EQ(2U, vertices.size());
+ VerticesContain(vertices, Point(50, 50 * kAspectRatio));
+ VerticesContain(vertices, Point(100, 100 * kAspectRatio));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(50, 100, 0, 200, kAspectRatio, HUGE_VAL);
+ vertices = set.ComputeVertices();
+ // This one fails if floating-point precision is too high.
+ EXPECT_EQ(4U, vertices.size());
+ VerticesContain(vertices, Point(50, 50 * kAspectRatio));
+ VerticesContain(vertices, Point(100, 100 * kAspectRatio));
+ VerticesContain(vertices, Point(50, 200));
+ VerticesContain(vertices, Point(100, 200));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(50, 100, 0, 200, 0.0, kAspectRatio);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(4U, vertices.size());
+ VerticesContain(vertices, Point(50, 50 * kAspectRatio));
+ VerticesContain(vertices, Point(100, 100 * kAspectRatio));
+ VerticesContain(vertices, Point(50, 0));
+ VerticesContain(vertices, Point(100, 0));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // Aspect-ratio lines touch the corners of the box.
+ {
+ ResolutionSet set(50, 100, 50, 100, 0.5, 2.0);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(4U, vertices.size());
+ VerticesContain(vertices, Point(50, 50));
+ VerticesContain(vertices, Point(100, 50));
+ VerticesContain(vertices, Point(50, 100));
+ VerticesContain(vertices, Point(100, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // Hexagons.
+ {
+ ResolutionSet set(10, 100, 10, 100, 0.5, 1.5);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(6U, vertices.size());
+ VerticesContain(vertices, Point(10, 10));
+ VerticesContain(vertices, Point(100, 100));
+ VerticesContain(vertices, Point(10, 10 * 1.5));
+ VerticesContain(vertices, Point(100 / 1.5, 100));
+ VerticesContain(vertices, Point(10 / 0.5, 10));
+ VerticesContain(vertices, Point(100, 100 * 0.5));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(50, 100, 50, 100, 50.0 / 75.0, 75.0 / 50.0);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(6U, vertices.size());
+ VerticesContain(vertices, Point(50, 50));
+ VerticesContain(vertices, Point(100, 100));
+ VerticesContain(vertices, Point(75, 50));
+ VerticesContain(vertices, Point(50, 75));
+ VerticesContain(vertices, Point(100, 100.0 * 50.0 / 75.0));
+ VerticesContain(vertices, Point(100 * 50.0 / 75.0, 100.0));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // Both aspect-ratio constraints cross the left and top sides of the box.
+ {
+ ResolutionSet set(10, 100, 10, 100, 1.5, 1.7);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(4U, vertices.size());
+ VerticesContain(vertices, Point(10, 10 * 1.5));
+ VerticesContain(vertices, Point(10, 10 * 1.7));
+ VerticesContain(vertices, Point(100 / 1.5, 100));
+ VerticesContain(vertices, Point(100 / 1.7, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // Both aspect-ratio constraints cross the left and right sides of the box.
+ {
+ ResolutionSet set(10, 100, 10, ResolutionSet::kMaxDimension, 1.5, 1.7);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(4U, vertices.size());
+ VerticesContain(vertices, Point(10, 10 * 1.5));
+ VerticesContain(vertices, Point(10, 10 * 1.7));
+ VerticesContain(vertices, Point(100, 100 * 1.5));
+ VerticesContain(vertices, Point(100, 100 * 1.7));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // Both aspect-ratio constraints cross the bottom and top sides of the box.
+ {
+ ResolutionSet set(10, 100, 50, 100, 2.0, 4.0);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(4U, vertices.size());
+ VerticesContain(vertices, Point(50 / 2.0, 50));
+ VerticesContain(vertices, Point(100 / 2.0, 100));
+ VerticesContain(vertices, Point(50 / 4.0, 50));
+ VerticesContain(vertices, Point(100 / 4.0, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // Both aspect-ratio constraints cross the bottom and right sides of the box.
+ {
+ ResolutionSet set(10, 100, 50, 100, 0.7, 0.9);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(4U, vertices.size());
+ VerticesContain(vertices, Point(50 / 0.7, 50));
+ VerticesContain(vertices, Point(50 / 0.9, 50));
+ VerticesContain(vertices, Point(100, 100 * 0.7));
+ VerticesContain(vertices, Point(100, 100 * 0.9));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // Pentagons.
+ {
+ ResolutionSet set(10, 100, 50, 100, 0.7, 4.0);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(5U, vertices.size());
+ VerticesContain(vertices, Point(50 / 0.7, 50));
+ VerticesContain(vertices, Point(100, 100 * 0.7));
+ VerticesContain(vertices, Point(50 / 4.0, 50));
+ VerticesContain(vertices, Point(100 / 4.0, 100));
+ VerticesContain(vertices, Point(100, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(50, 100, 10, 100, 0.7, 1.5);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(5U, vertices.size());
+ VerticesContain(vertices, Point(50, 50 * 0.7));
+ VerticesContain(vertices, Point(100, 100 * 0.7));
+ VerticesContain(vertices, Point(50, 50 * 1.5));
+ VerticesContain(vertices, Point(100 / 1.5, 100));
+ VerticesContain(vertices, Point(100, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+
+ // Extreme aspect ratios, for completeness.
+ {
+ ResolutionSet set(0, 100, 0, ResolutionSet::kMaxDimension, 0.0, 0.0);
+ auto vertices = set.ComputeVertices();
+ EXPECT_EQ(2U, vertices.size());
+ VerticesContain(vertices, Point(0, 0));
+ VerticesContain(vertices, Point(100, 0));
+ EXPECT_TRUE(AreValidVertices(vertices));
+
+ set = ResolutionSet(0, ResolutionSet::kMaxDimension, 0, 100, HUGE_VAL,
+ HUGE_VAL);
+ vertices = set.ComputeVertices();
+ EXPECT_EQ(2U, vertices.size());
+ VerticesContain(vertices, Point(0, 0));
+ VerticesContain(vertices, Point(0, 100));
+ EXPECT_TRUE(AreValidVertices(vertices));
+ }
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, NumericRangeSetDouble) {
+ using DoubleRangeSet = NumericRangeSet<double>;
+ // Unconstrained set.
hbos_chromium 2017/03/09 11:34:22 Here and elsewhere: "unconstrained" -> "universal"
Guido Urdaneta 2017/03/09 17:55:43 Done.
+ DoubleRangeSet set;
+ EXPECT_EQ(0.0, set.Min());
+ EXPECT_EQ(HUGE_VAL, set.Max());
+ EXPECT_FALSE(set.IsEmpty());
+
+ // Constrained set.
+ const double kMin = 1.0;
+ const double kMax = 10.0;
+ set = DoubleRangeSet(kMin, kMax);
+ EXPECT_EQ(kMin, set.Min());
+ EXPECT_EQ(kMax, set.Max());
+ EXPECT_FALSE(set.IsEmpty());
+
+ // Empty set.
+ set = DoubleRangeSet(kMax, kMin);
+ EXPECT_TRUE(set.IsEmpty());
+
+ // Intersection.
+ set = DoubleRangeSet(kMin, kMax);
+ const double kMin2 = 5.0;
+ const double kMax2 = 20.0;
+ auto intersection = set.Intersection(DoubleRangeSet(kMin2, kMax2));
+ EXPECT_EQ(kMin2, intersection.Min());
+ EXPECT_EQ(kMax, intersection.Max());
+ EXPECT_FALSE(intersection.IsEmpty());
+
+ // Empty intersection.
+ intersection = set.Intersection(DoubleRangeSet(kMax + 1, HUGE_VAL));
+ EXPECT_TRUE(intersection.IsEmpty());
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetString) {
+ // Unconstrained set.
+ using StringSet = DiscreteSet<std::string>;
+ StringSet set = StringSet::UniversalSet();
+ EXPECT_TRUE(set.Contains("arbitrary"));
+ EXPECT_TRUE(set.Contains("strings"));
+ EXPECT_FALSE(set.IsEmpty());
+ EXPECT_TRUE(set.is_universal());
+ EXPECT_FALSE(set.HasExplicitElements());
+
+ // Constrained set.
+ set = StringSet(std::vector<std::string>({"a", "b", "c"}));
+ EXPECT_TRUE(set.Contains("a"));
+ EXPECT_TRUE(set.Contains("b"));
+ EXPECT_TRUE(set.Contains("c"));
+ EXPECT_FALSE(set.Contains("d"));
+ EXPECT_FALSE(set.IsEmpty());
+ EXPECT_FALSE(set.is_universal());
+ EXPECT_TRUE(set.HasExplicitElements());
+ EXPECT_EQ(std::string("a"), set.FirstElement());
+
+ // Empty set.
+ set = StringSet::EmptySet();
+ EXPECT_FALSE(set.Contains("a"));
+ EXPECT_FALSE(set.Contains("b"));
+ EXPECT_TRUE(set.IsEmpty());
+ EXPECT_FALSE(set.is_universal());
+ EXPECT_FALSE(set.HasExplicitElements());
+
+ // Intersection.
+ set = StringSet(std::vector<std::string>({"a", "b", "c"}));
+ StringSet set2 = StringSet(std::vector<std::string>({"b", "c", "d"}));
+ auto intersection = set.Intersection(set2);
+ EXPECT_FALSE(intersection.Contains("a"));
+ EXPECT_TRUE(intersection.Contains("b"));
+ EXPECT_TRUE(intersection.Contains("c"));
+ EXPECT_FALSE(intersection.Contains("d"));
+ EXPECT_FALSE(intersection.IsEmpty());
+ EXPECT_FALSE(intersection.is_universal());
+ EXPECT_TRUE(intersection.HasExplicitElements());
+ EXPECT_EQ(std::string("b"), intersection.FirstElement());
+
+ // Empty intersection.
+ set2 = StringSet(std::vector<std::string>({"d", "e", "f"}));
+ intersection = set.Intersection(set2);
+ EXPECT_FALSE(intersection.Contains("a"));
+ EXPECT_FALSE(intersection.Contains("b"));
+ EXPECT_FALSE(intersection.Contains("c"));
+ EXPECT_FALSE(intersection.Contains("d"));
+ EXPECT_TRUE(intersection.IsEmpty());
+ EXPECT_FALSE(intersection.is_universal());
+ EXPECT_FALSE(intersection.HasExplicitElements());
+}
+
+TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetBool) {
+ using BoolSet = DiscreteSet<bool>;
+ // Unconstrained set.
+ BoolSet set = BoolSet::UniversalSet();
+ EXPECT_TRUE(set.Contains(true));
+ EXPECT_TRUE(set.Contains(false));
+ EXPECT_FALSE(set.IsEmpty());
+ EXPECT_TRUE(set.is_universal());
+ EXPECT_FALSE(set.HasExplicitElements());
+
+ // Constrained set.
+ set = BoolSet({true});
+ EXPECT_TRUE(set.Contains(true));
+ EXPECT_FALSE(set.Contains(false));
+ EXPECT_FALSE(set.IsEmpty());
+ EXPECT_FALSE(set.is_universal());
+ EXPECT_TRUE(set.HasExplicitElements());
+ EXPECT_TRUE(set.FirstElement());
+
+ set = BoolSet({false});
+ EXPECT_FALSE(set.Contains(true));
+ EXPECT_TRUE(set.Contains(false));
+ EXPECT_FALSE(set.IsEmpty());
+ EXPECT_FALSE(set.is_universal());
+ EXPECT_TRUE(set.HasExplicitElements());
+ EXPECT_FALSE(set.FirstElement());
+
+ // Empty set.
+ set = BoolSet::EmptySet();
+ EXPECT_FALSE(set.Contains(true));
+ EXPECT_FALSE(set.Contains(false));
+ EXPECT_TRUE(set.IsEmpty());
+ EXPECT_FALSE(set.is_universal());
+ EXPECT_FALSE(set.HasExplicitElements());
+
+ // Intersection.
+ set = BoolSet::UniversalSet();
+ auto intersection = set.Intersection(BoolSet({true}));
+ EXPECT_TRUE(intersection.Contains(true));
+ EXPECT_FALSE(intersection.Contains(false));
+ intersection = set.Intersection(set);
+ EXPECT_TRUE(intersection.Contains(true));
+ EXPECT_TRUE(intersection.Contains(true));
+
+ // Empty intersection.
+ set = BoolSet({true});
+ intersection = set.Intersection(BoolSet({false}));
+ EXPECT_TRUE(intersection.IsEmpty());
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698