Chromium Code Reviews| 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..fc66e235058735e50951680e67f85c927e71114f |
| --- /dev/null |
| +++ b/content/renderer/media/media_stream_constraints_util_sets_unittest.cc |
| @@ -0,0 +1,1301 @@ |
| +// 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 { |
| + |
| +int kUnconstrainedMaxDimension = ResolutionSet::kMaxConstrainedDimension + 1; |
| + |
| +// 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 (vertex.IsApproximatelyEqualTo(point)) { |
| + 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. |
| + 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. |
| + 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; |
| + 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 that use iterative numeric methods, it is less accurate in practice |
|
hta - Chromium
2017/03/03 11:02:36
Is this ("iterative numeric methods") a reference
Guido Urdaneta
2017/03/06 11:08:23
Done.
|
| +// than Point::ClosestPointInSegment(). |
| +// 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 |
|
hta - Chromium
2017/03/03 11:02:36
Why not let the anonymous namespace enclose the te
Guido Urdaneta
2017/03/06 11:08:23
One of the tests is friended by MediaStreamConstra
|
| + |
| +class MediaStreamConstraintsUtilSetsTest : public testing::Test { |
| + protected: |
| + using P = Point; |
| + MockConstraintFactory factory_; |
| +}; |
| + |
| +TEST_F(MediaStreamConstraintsUtilSetsTest, VertexListValidity) { |
|
hta - Chromium
2017/03/03 11:02:36
This actually tests a test harness function. Add a
Guido Urdaneta
2017/03/06 11:08:23
Done.
|
| + 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::DistanceToPoint(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::DistanceToPoint(kZero, P(50, 50))); |
| + EXPECT_EQ(P::DistanceToPoint(P(50, 50), kZero), |
| + P::DistanceToPoint(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::DistanceToPoint(P(4, 0), P(0, 3))); |
| + EXPECT_EQ(75 * 75, P::DistanceToPoint(P(100, 0), P(25, 0))); |
| + EXPECT_EQ(75 * 75, P::DistanceToPoint(P(0, 100), P(0, 25))); |
| + EXPECT_EQ(5 * 5 + 9 * 9, P::DistanceToPoint(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.HasMinHeight()); |
| + EXPECT_FALSE(set.HasMaxHeight()); |
| + EXPECT_FALSE(set.HasMinWidth()); |
| + EXPECT_FALSE(set.HasMaxWidth()); |
| + EXPECT_FALSE(set.HasMinAspectRatio()); |
| + EXPECT_FALSE(set.HasMaxAspectRatio()); |
| + EXPECT_TRUE(set.IsHeightUnconstrained()); |
| + EXPECT_TRUE(set.IsWidthUnconstrained()); |
| + EXPECT_TRUE(set.IsAspectRatioUnconstrained()); |
| + 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_TRUE(set.HasMinHeight()); |
| + EXPECT_TRUE(set.HasMaxHeight()); |
| + EXPECT_FALSE(set.HasMinWidth()); |
| + EXPECT_FALSE(set.HasMaxWidth()); |
| + EXPECT_FALSE(set.HasMinAspectRatio()); |
| + EXPECT_FALSE(set.HasMaxAspectRatio()); |
| + EXPECT_FALSE(set.IsHeightUnconstrained()); |
| + EXPECT_TRUE(set.IsWidthUnconstrained()); |
| + EXPECT_TRUE(set.IsAspectRatioUnconstrained()); |
| + 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.HasMinHeight()); |
| + EXPECT_TRUE(set.HasMaxHeight()); |
| + EXPECT_FALSE(set.HasMinWidth()); |
| + EXPECT_FALSE(set.HasMaxWidth()); |
| + EXPECT_FALSE(set.HasMinAspectRatio()); |
| + EXPECT_FALSE(set.HasMaxAspectRatio()); |
| + EXPECT_FALSE(set.IsHeightUnconstrained()); |
| + EXPECT_TRUE(set.IsWidthUnconstrained()); |
| + EXPECT_TRUE(set.IsAspectRatioUnconstrained()); |
| + EXPECT_FALSE(set.IsHeightEmpty()); |
| + EXPECT_FALSE(set.IsWidthEmpty()); |
| + EXPECT_FALSE(set.IsAspectRatioEmpty()); |
| + |
| + set = ResolutionSet::FromHeight(100, kUnconstrainedMaxDimension); |
| + 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_TRUE(set.HasMinHeight()); |
| + EXPECT_FALSE(set.HasMaxHeight()); |
| + EXPECT_FALSE(set.HasMinWidth()); |
| + EXPECT_FALSE(set.HasMaxWidth()); |
| + EXPECT_FALSE(set.HasMinAspectRatio()); |
| + EXPECT_FALSE(set.HasMaxAspectRatio()); |
| + EXPECT_FALSE(set.IsHeightUnconstrained()); |
| + EXPECT_TRUE(set.IsWidthUnconstrained()); |
| + EXPECT_TRUE(set.IsAspectRatioUnconstrained()); |
| + 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.HasMinHeight()); |
| + EXPECT_FALSE(set.HasMaxHeight()); |
| + EXPECT_TRUE(set.HasMinWidth()); |
| + EXPECT_TRUE(set.HasMaxWidth()); |
| + EXPECT_FALSE(set.HasMinAspectRatio()); |
| + EXPECT_FALSE(set.HasMaxAspectRatio()); |
| + EXPECT_TRUE(set.IsHeightUnconstrained()); |
| + EXPECT_FALSE(set.IsWidthUnconstrained()); |
| + EXPECT_TRUE(set.IsAspectRatioUnconstrained()); |
| + 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.HasMinHeight()); |
| + EXPECT_FALSE(set.HasMaxHeight()); |
| + EXPECT_FALSE(set.HasMinWidth()); |
| + EXPECT_TRUE(set.HasMaxWidth()); |
| + EXPECT_FALSE(set.HasMinAspectRatio()); |
| + EXPECT_FALSE(set.HasMaxAspectRatio()); |
| + EXPECT_TRUE(set.IsHeightUnconstrained()); |
| + EXPECT_FALSE(set.IsWidthUnconstrained()); |
| + EXPECT_TRUE(set.IsAspectRatioUnconstrained()); |
| + EXPECT_FALSE(set.IsHeightEmpty()); |
| + EXPECT_FALSE(set.IsWidthEmpty()); |
| + EXPECT_FALSE(set.IsAspectRatioEmpty()); |
| + |
| + set = ResolutionSet::FromWidth(100, kUnconstrainedMaxDimension); |
| + 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.HasMinHeight()); |
| + EXPECT_FALSE(set.HasMaxHeight()); |
| + EXPECT_TRUE(set.HasMinWidth()); |
| + EXPECT_FALSE(set.HasMaxWidth()); |
| + EXPECT_FALSE(set.HasMinAspectRatio()); |
| + EXPECT_FALSE(set.HasMaxAspectRatio()); |
| + EXPECT_TRUE(set.IsHeightUnconstrained()); |
| + EXPECT_FALSE(set.IsWidthUnconstrained()); |
| + EXPECT_TRUE(set.IsAspectRatioUnconstrained()); |
| + 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.HasMinHeight()); |
| + EXPECT_FALSE(set.HasMaxHeight()); |
| + EXPECT_FALSE(set.HasMinWidth()); |
| + EXPECT_FALSE(set.HasMaxWidth()); |
| + EXPECT_TRUE(set.HasMinAspectRatio()); |
| + EXPECT_TRUE(set.HasMaxAspectRatio()); |
| + EXPECT_TRUE(set.IsHeightUnconstrained()); |
| + EXPECT_TRUE(set.IsWidthUnconstrained()); |
| + EXPECT_FALSE(set.IsAspectRatioUnconstrained()); |
| + 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.HasMinHeight()); |
| + EXPECT_FALSE(set.HasMaxHeight()); |
| + EXPECT_FALSE(set.HasMinWidth()); |
| + EXPECT_FALSE(set.HasMaxWidth()); |
| + EXPECT_FALSE(set.HasMinAspectRatio()); |
| + EXPECT_TRUE(set.HasMaxAspectRatio()); |
| + EXPECT_TRUE(set.IsHeightUnconstrained()); |
| + EXPECT_TRUE(set.IsWidthUnconstrained()); |
| + EXPECT_FALSE(set.IsAspectRatioUnconstrained()); |
| + 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.HasMinHeight()); |
| + EXPECT_FALSE(set.HasMaxHeight()); |
| + EXPECT_FALSE(set.HasMinWidth()); |
| + EXPECT_FALSE(set.HasMaxWidth()); |
| + EXPECT_TRUE(set.HasMinAspectRatio()); |
| + EXPECT_FALSE(set.HasMaxAspectRatio()); |
| + EXPECT_TRUE(set.IsHeightUnconstrained()); |
| + EXPECT_TRUE(set.IsWidthUnconstrained()); |
| + EXPECT_FALSE(set.IsAspectRatioUnconstrained()); |
| + 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)); |
| + |
| + // It should not contain any point in the vicinity of the included point. |
| + 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)); |
| + |
| + // // Intersection with either of the original sets should return the initial |
| + // // intersection. |
| + // EXPECT_EQ(intersection, intersection.Intersection(set1)); |
| + // EXPECT_EQ(intersection, intersection.Intersection(set2)); |
| +} |
| + |
| +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)); |
| + |
| + // // Intersection with either of the original sets should return the initial |
| + // // intersection. |
| + // EXPECT_EQ(intersection, intersection.Intersection(set1)); |
| + // EXPECT_EQ(intersection, intersection.Intersection(set2)); |
| +} |
| + |
| +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, ResolutionClosestPointToPointSet) { |
| + 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, ResolutionClosestPointToLineSet) { |
| + { |
| + 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); |
| + EXPECT_TRUE(expected.IsApproximatelyEqualTo(actual)); |
| + } |
| + } |
| + } |
| + } |
| +} |
| + |
| +TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionClosestPointToGeneralSet) { |
| + // 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)}; |
| + 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_TRUE(expected.IsApproximatelyEqualTo(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_TRUE(expected.IsApproximatelyEqualTo(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); |
| + |
| + 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_DOUBLE_EQ(kIdealHeight, point.height()); |
| + } |
| + |
| + // Ideal width. |
| + { |
| + factory_.Reset(); |
| + factory_.basic().width.setIdeal(kIdealWidth); |
| + Point point = set.SelectClosestPointToIdeal( |
| + factory_.CreateWebMediaConstraints().basic()); |
| + EXPECT_DOUBLE_EQ(kIdealWidth, point.width()); |
| + EXPECT_DOUBLE_EQ(kIdealWidth / MediaStreamVideoSource::kDefaultAspectRatio, |
| + point.height()); |
| + } |
| + |
| + // 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_DOUBLE_EQ(kIdealHeight, point.height()); |
| + EXPECT_DOUBLE_EQ(kIdealWidth, point.width()); |
| + } |
| + |
| + // 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_DOUBLE_EQ(kIdealHeight, point.height()); |
| + EXPECT_DOUBLE_EQ(kIdealHeight * kIdealAspectRatio, point.width()); |
| + } |
| + |
| + // 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_DOUBLE_EQ(kIdealWidth, point.width()); |
| + EXPECT_DOUBLE_EQ(kIdealWidth / kIdealAspectRatio, point.height()); |
| + } |
| + |
| + // 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_DOUBLE_EQ(kIdealHeight, point.height()); |
| + EXPECT_DOUBLE_EQ(kIdealWidth, point.width()); |
| + } |
| +} |
| + |
| +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); |
| + |
| + 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_DOUBLE_EQ(kVertex1.height(), point.height()); |
| + EXPECT_DOUBLE_EQ(kVertex1.width(), point.height()); |
| + } |
| + |
| + // Ideal width. |
| + { |
| + factory_.Reset(); |
| + factory_.basic().width.setIdeal(kIdealWidth); |
| + Point point = set.SelectClosestPointToIdeal( |
| + factory_.CreateWebMediaConstraints().basic()); |
| + EXPECT_DOUBLE_EQ(kVertex3.height(), point.height()); |
| + EXPECT_DOUBLE_EQ(kVertex3.width(), point.width()); |
| + } |
| + |
| + // Ideal aspect ratio. |
| + { |
| + factory_.Reset(); |
| + factory_.basic().aspectRatio.setIdeal(kIdealAspectRatio); |
| + Point point = set.SelectClosestPointToIdeal( |
| + factory_.CreateWebMediaConstraints().basic()); |
| + EXPECT_DOUBLE_EQ(kVertex2.height(), point.height()); |
| + EXPECT_DOUBLE_EQ(kVertex2.width(), 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()); |
| + Point expected = set.ClosestPointTo(Point(kIdealHeight, kIdealWidth)); |
| + EXPECT_DOUBLE_EQ(expected.height(), point.height()); |
| + EXPECT_DOUBLE_EQ(expected.width(), point.width()); |
| + } |
| + |
| + // 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_DOUBLE_EQ(expected.height(), point.height()); |
| + EXPECT_DOUBLE_EQ(expected.width(), point.width()); |
| + } |
| + |
| + // 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_DOUBLE_EQ(expected.height(), point.height()); |
| + EXPECT_DOUBLE_EQ(expected.width(), point.width()); |
| + } |
| + |
| + // 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()); |
| + Point expected = set.ClosestPointTo(Point(kIdealHeight, kIdealWidth)); |
| + EXPECT_DOUBLE_EQ(expected.height(), point.height()); |
| + EXPECT_DOUBLE_EQ(expected.width(), point.width()); |
| + } |
| +} |
| + |
| +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); |
| + |
| + 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_DOUBLE_EQ(kVertex3.height(), point.height()); |
| + EXPECT_DOUBLE_EQ(kVertex3.width(), point.height()); |
| + } |
| + |
| + // 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_DOUBLE_EQ(kVertex1.height(), point.height()); |
| + EXPECT_DOUBLE_EQ(kVertex1.width(), point.width()); |
| + } |
| + |
| + // 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_DOUBLE_EQ( |
| + MediaStreamVideoSource::kDefaultWidth / kVertex1.AspectRatio(), |
| + point.height()); |
| + EXPECT_DOUBLE_EQ(MediaStreamVideoSource::kDefaultWidth, point.width()); |
| + } |
| +} |
| + |
| +TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionVertices) { |
| + // 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, kUnconstrainedMaxDimension, 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, kUnconstrainedMaxDimension, 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, kUnconstrainedMaxDimension, 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. |
| + 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; |
| + EXPECT_TRUE(set.Contains("arbitrary")); |
| + EXPECT_TRUE(set.Contains("strings")); |
| + EXPECT_FALSE(set.IsEmpty()); |
| + EXPECT_TRUE(set.is_unconstrained()); |
| + EXPECT_FALSE(set.IsNonEmptyFinite()); |
| + |
| + // 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_unconstrained()); |
| + EXPECT_TRUE(set.IsNonEmptyFinite()); |
| + 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_unconstrained()); |
| + EXPECT_FALSE(set.IsNonEmptyFinite()); |
| + |
| + // 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_unconstrained()); |
| + EXPECT_TRUE(intersection.IsNonEmptyFinite()); |
| + 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_unconstrained()); |
| + EXPECT_FALSE(intersection.IsNonEmptyFinite()); |
| +} |
| + |
| +TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetBool) { |
| + using BoolSet = DiscreteSet<bool>; |
| + // Unconstrained set. |
| + BoolSet set; |
| + EXPECT_TRUE(set.Contains(true)); |
| + EXPECT_TRUE(set.Contains(false)); |
| + EXPECT_FALSE(set.IsEmpty()); |
| + EXPECT_TRUE(set.is_unconstrained()); |
| + EXPECT_FALSE(set.IsNonEmptyFinite()); |
| + |
| + // Constrained set. |
| + set = BoolSet({true}); |
| + EXPECT_TRUE(set.Contains(true)); |
| + EXPECT_FALSE(set.Contains(false)); |
| + EXPECT_FALSE(set.IsEmpty()); |
| + EXPECT_FALSE(set.is_unconstrained()); |
| + EXPECT_TRUE(set.IsNonEmptyFinite()); |
| + 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_unconstrained()); |
| + EXPECT_TRUE(set.IsNonEmptyFinite()); |
| + 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_unconstrained()); |
| + EXPECT_FALSE(set.IsNonEmptyFinite()); |
| + |
| + // Intersection. |
| + set = BoolSet(); |
| + 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 |