Commit 37893cef authored by Guido Urdaneta's avatar Guido Urdaneta Committed by Commit Bot

Add extra utilities to content::media_constraints

This CL adds:
* NumericRangeSet::Contains().
* NumericRangeSet::EmptySet().
* ResolutionSet::FromNativeResolution().

These utilities are in preparation for supporting the resizeMode
constrainable property in getUserMedia() and applyConstraints().

Drive-by: minor fixes/improvements.

Bug: 854980
Change-Id: I858f406308aa9bba40521d5e740219b72e2c8a48
Reviewed-on: https://chromium-review.googlesource.com/c/1308133Reviewed-by: default avatarHenrik Boström <hbos@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604574}
parent 70822530
......@@ -43,7 +43,7 @@ bool IsGreaterOrEqual(double d1, double d2) {
return d1 > d2 || AreApproximatelyEqual(d1, d2);
}
int ToValidDimension(long dimension) {
int ToValidDimension(int dimension) {
if (dimension > ResolutionSet::kMaxDimension)
return ResolutionSet::kMaxDimension;
if (dimension < 0)
......@@ -470,6 +470,15 @@ ResolutionSet ResolutionSet::FromExactAspectRatio(double value) {
return ResolutionSet(0, kMaxDimension, 0, kMaxDimension, value, value);
}
// static
ResolutionSet ResolutionSet::FromExactResolution(int width, int height) {
double aspect_ratio = ToValidAspectRatio(static_cast<double>(width) / height);
return ResolutionSet(ToValidDimension(height), ToValidDimension(height),
ToValidDimension(width), ToValidDimension(width),
std::isnan(aspect_ratio) ? 0.0 : aspect_ratio,
std::isnan(aspect_ratio) ? HUGE_VAL : aspect_ratio);
}
std::vector<Point> ResolutionSet::ComputeVertices() const {
std::vector<Point> vertices;
// Add vertices in counterclockwise order
......
......@@ -32,7 +32,7 @@ class NumericRangeSet {
public:
NumericRangeSet() = default;
NumericRangeSet(base::Optional<T> min, base::Optional<T> max)
: min_(min), max_(max) {}
: min_(std::move(min)), max_(std::move(max)) {}
NumericRangeSet(const NumericRangeSet& other) = default;
NumericRangeSet& operator=(const NumericRangeSet& other) = default;
~NumericRangeSet() = default;
......@@ -53,6 +53,10 @@ class NumericRangeSet {
return NumericRangeSet(min, max);
}
bool Contains(T value) const {
return (!Min() || value >= *Min()) && (!Max() || value <= *Max());
}
// Creates a NumericRangeSet based on the minimum and maximum values of
// |constraint| and a client-provided range of valid values.
// If the range given in |constraint| has empty intersection with the range
......@@ -82,6 +86,8 @@ class NumericRangeSet {
: base::Optional<T>());
}
static NumericRangeSet<T> EmptySet() { return NumericRangeSet(1, 0); }
private:
base::Optional<T> min_;
base::Optional<T> max_;
......@@ -335,6 +341,9 @@ class CONTENT_EXPORT ResolutionSet {
static ResolutionSet FromAspectRatio(double min, double max);
static ResolutionSet FromExactAspectRatio(double value);
// Returns a ResolutionSet containing only the specified width and height.
static ResolutionSet FromExactResolution(int width, int height);
// Returns a ResolutionCandidateSet initialized with |constraint_set|'s
// width, height and aspectRatio constraints.
static ResolutionSet FromConstraintSet(
......@@ -394,7 +403,7 @@ class CONTENT_EXPORT ResolutionSet {
};
// Scalar multiplication for Points.
ResolutionSet::Point CONTENT_EXPORT operator*(double d,
CONTENT_EXPORT ResolutionSet::Point operator*(double d,
const ResolutionSet::Point& p);
} // namespace media_constraints
......
......@@ -15,6 +15,7 @@ namespace content {
namespace media_constraints {
using Point = ResolutionSet::Point;
using BoolSet = DiscreteSet<bool>;
namespace {
......@@ -1121,6 +1122,34 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, ResolutionVertices) {
}
}
TEST_F(MediaStreamConstraintsUtilSetsTest, ExactResolution) {
const int kExactWidth = 640;
const int kExactHeight = 480;
ResolutionSet set =
ResolutionSet::FromExactResolution(kExactWidth, kExactHeight);
EXPECT_TRUE(set.ContainsPoint(kExactHeight, kExactWidth));
EXPECT_FALSE(set.ContainsPoint(kExactHeight - 1, kExactWidth - 1));
EXPECT_FALSE(set.ContainsPoint(kExactHeight - 1, kExactWidth));
EXPECT_FALSE(set.ContainsPoint(kExactHeight - 1, kExactWidth + 1));
EXPECT_FALSE(set.ContainsPoint(kExactHeight, kExactWidth - 1));
EXPECT_FALSE(set.ContainsPoint(kExactHeight, kExactWidth + 1));
EXPECT_FALSE(set.ContainsPoint(kExactHeight + 1, kExactWidth - 1));
EXPECT_FALSE(set.ContainsPoint(kExactHeight + 1, kExactWidth));
EXPECT_FALSE(set.ContainsPoint(kExactHeight + 1, kExactWidth + 1));
EXPECT_FALSE(set.ContainsPoint(1, 1));
EXPECT_FALSE(set.ContainsPoint(2000, 2000));
EXPECT_FALSE(set.IsHeightEmpty());
EXPECT_FALSE(set.IsWidthEmpty());
EXPECT_FALSE(set.IsAspectRatioEmpty());
}
TEST_F(MediaStreamConstraintsUtilSetsTest, ZeroExactResolution) {
ResolutionSet set = ResolutionSet::FromExactResolution(0, 0);
EXPECT_TRUE(set.ContainsPoint(0, 0));
EXPECT_EQ(set.min_aspect_ratio(), 0.0);
EXPECT_EQ(set.max_aspect_ratio(), HUGE_VAL);
}
TEST_F(MediaStreamConstraintsUtilSetsTest, NumericRangeSetDouble) {
using DoubleRangeSet = NumericRangeSet<double>;
// Open set.
......@@ -1128,6 +1157,10 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, NumericRangeSetDouble) {
EXPECT_FALSE(set.Min().has_value());
EXPECT_FALSE(set.Max().has_value());
EXPECT_FALSE(set.IsEmpty());
EXPECT_TRUE(set.Contains(0.0));
EXPECT_TRUE(set.Contains(1.0));
EXPECT_TRUE(set.Contains(HUGE_VAL));
EXPECT_TRUE(set.Contains(-1.0));
// Constrained set.
const double kMin = 1.0;
......@@ -1136,10 +1169,27 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, NumericRangeSetDouble) {
EXPECT_EQ(kMin, *set.Min());
EXPECT_EQ(kMax, *set.Max());
EXPECT_FALSE(set.IsEmpty());
EXPECT_FALSE(set.Contains(0.0));
EXPECT_TRUE(set.Contains(1.0));
EXPECT_TRUE(set.Contains(10.0));
EXPECT_FALSE(set.Contains(HUGE_VAL));
EXPECT_FALSE(set.Contains(-1.0));
// Empty set.
// If the lower bound is greater than the upper bound, the set is empty.
set = DoubleRangeSet(kMax, kMin);
EXPECT_TRUE(set.IsEmpty());
EXPECT_FALSE(set.Contains(0.0));
EXPECT_FALSE(set.Contains(1.0));
EXPECT_FALSE(set.Contains(HUGE_VAL));
EXPECT_FALSE(set.Contains(-1.0));
// An explicit empty set is empty.
set = DoubleRangeSet::EmptySet();
EXPECT_TRUE(set.IsEmpty());
EXPECT_FALSE(set.Contains(0.0));
EXPECT_FALSE(set.Contains(1.0));
EXPECT_FALSE(set.Contains(HUGE_VAL));
EXPECT_FALSE(set.Contains(-1.0));
// Intersection.
set = DoubleRangeSet(kMin, kMax);
......@@ -1151,9 +1201,8 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, NumericRangeSetDouble) {
EXPECT_FALSE(intersection.IsEmpty());
// Intersection with partially open sets.
set = DoubleRangeSet(base::Optional<double>(), kMax);
intersection =
set.Intersection(DoubleRangeSet(kMin2, base::Optional<double>()));
set = DoubleRangeSet(base::nullopt, kMax);
intersection = set.Intersection(DoubleRangeSet(kMin2, base::nullopt));
EXPECT_EQ(kMin2, *intersection.Min());
EXPECT_EQ(kMax, *intersection.Max());
EXPECT_FALSE(intersection.IsEmpty());
......@@ -1161,6 +1210,10 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, NumericRangeSetDouble) {
// Empty intersection.
intersection = set.Intersection(DoubleRangeSet(kMax + 1, HUGE_VAL));
EXPECT_TRUE(intersection.IsEmpty());
// Intersection with empty set.
intersection = set.Intersection(DoubleRangeSet::EmptySet());
EXPECT_TRUE(intersection.IsEmpty());
}
TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetString) {
......@@ -1218,7 +1271,6 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetString) {
}
TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetBool) {
using BoolSet = DiscreteSet<bool>;
// Universal set.
BoolSet set = BoolSet::UniversalSet();
EXPECT_TRUE(set.Contains(true));
......
......@@ -170,7 +170,7 @@
assert_equals(typeof(settings.width), "number",
"width should exist and it should be a number.");
assert_true(Number.isInteger(settings.width), "width should be an integer.");
assert_greater_than_equal(settings.width, 0);
assert_greater_than_equal(settings.width, 0);;
}, 'width is reported by getSettings() for getUserMedia() video tracks');
promise_test(async t => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment