Skip to content

Commit

Permalink
[PTZ] Support 'boolean or DoubleConstraint' in getUserMedia
Browse files Browse the repository at this point in the history
This CL adds 'boolean or DoubleConstraint' support for pan, tilt, and
zoom constraints in getUserMedia. Spec says that `pan: true` is just
syntactic sugar for `pan: {}` and `pan: false` the same as pan being
undefined/not provided.

Spec: w3c/mediacapture-image#225
Change-Id: I0f5788ff91bceda14bc9cdad0852e1195755a3f4
Bug: 934063
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2210237
Reviewed-by: Guido Urdaneta <[email protected]>
Reviewed-by: Kentaro Hara <[email protected]>
Commit-Queue: François Beaufort <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#773060}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 62ee93390521249984d3d8102a309494eb6c7fdb
  • Loading branch information
beaufortfrancois authored and Commit Bot committed May 29, 2020
1 parent b0e208c commit f4ce728
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 69 deletions.
2 changes: 2 additions & 0 deletions blink/renderer/bindings/modules/v8/generated.gni
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/audio_context_latency_category_or_double.h",
"$bindings_modules_v8_output_dir/boolean_or_constrain_boolean_parameters.cc",
"$bindings_modules_v8_output_dir/boolean_or_constrain_boolean_parameters.h",
"$bindings_modules_v8_output_dir/boolean_or_double_or_constrain_double_range.cc",
"$bindings_modules_v8_output_dir/boolean_or_double_or_constrain_double_range.h",
"$bindings_modules_v8_output_dir/boolean_or_media_track_constraints.cc",
"$bindings_modules_v8_output_dir/boolean_or_media_track_constraints.h",
"$bindings_modules_v8_output_dir/canvas_image_source.cc",
Expand Down
35 changes: 29 additions & 6 deletions blink/renderer/modules/mediastream/media_constraints_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ MediaConstraints Create(ExecutionContext* context,
void CopyLongConstraint(const LongOrConstrainLongRange& blink_union_form,
NakedValueDisposition naked_treatment,
LongConstraint& web_form) {
web_form.SetIsPresent(true);
if (blink_union_form.IsLong()) {
switch (naked_treatment) {
case NakedValueDisposition::kTreatAsIdeal:
Expand Down Expand Up @@ -526,6 +527,7 @@ void CopyLongConstraint(const LongOrConstrainLongRange& blink_union_form,
void CopyDoubleConstraint(const DoubleOrConstrainDoubleRange& blink_union_form,
NakedValueDisposition naked_treatment,
DoubleConstraint& web_form) {
web_form.SetIsPresent(true);
if (blink_union_form.IsDouble()) {
switch (naked_treatment) {
case NakedValueDisposition::kTreatAsIdeal:
Expand All @@ -552,11 +554,31 @@ void CopyDoubleConstraint(const DoubleOrConstrainDoubleRange& blink_union_form,
}
}

void CopyBooleanOrDoubleConstraint(
const BooleanOrDoubleOrConstrainDoubleRange& blink_union_form,
NakedValueDisposition naked_treatment,
DoubleConstraint& web_form) {
if (blink_union_form.IsBoolean()) {
web_form.SetIsPresent(blink_union_form.GetAsBoolean());
return;
}
DoubleOrConstrainDoubleRange double_constraint;
if (blink_union_form.IsDouble()) {
double_constraint.SetDouble(blink_union_form.GetAsDouble());
} else {
DCHECK(blink_union_form.IsConstrainDoubleRange());
double_constraint.SetConstrainDoubleRange(
blink_union_form.GetAsConstrainDoubleRange());
}
CopyDoubleConstraint(double_constraint, naked_treatment, web_form);
}

void CopyStringConstraint(
const StringOrStringSequenceOrConstrainDOMStringParameters&
blink_union_form,
NakedValueDisposition naked_treatment,
StringConstraint& web_form) {
web_form.SetIsPresent(true);
if (blink_union_form.IsString()) {
switch (naked_treatment) {
case NakedValueDisposition::kTreatAsIdeal:
Expand Down Expand Up @@ -601,6 +623,7 @@ void CopyBooleanConstraint(
const BooleanOrConstrainBooleanParameters& blink_union_form,
NakedValueDisposition naked_treatment,
BooleanConstraint& web_form) {
web_form.SetIsPresent(true);
if (blink_union_form.IsBoolean()) {
switch (naked_treatment) {
case NakedValueDisposition::kTreatAsIdeal:
Expand Down Expand Up @@ -689,16 +712,16 @@ void CopyConstraintSet(const MediaTrackConstraintSet* constraints_in,
constraint_buffer.video_kind);
}
if (constraints_in->hasPan()) {
CopyDoubleConstraint(constraints_in->pan(), naked_treatment,
constraint_buffer.pan);
CopyBooleanOrDoubleConstraint(constraints_in->pan(), naked_treatment,
constraint_buffer.pan);
}
if (constraints_in->hasTilt()) {
CopyDoubleConstraint(constraints_in->tilt(), naked_treatment,
constraint_buffer.tilt);
CopyBooleanOrDoubleConstraint(constraints_in->tilt(), naked_treatment,
constraint_buffer.tilt);
}
if (constraints_in->hasZoom()) {
CopyDoubleConstraint(constraints_in->zoom(), naked_treatment,
constraint_buffer.zoom);
CopyBooleanOrDoubleConstraint(constraints_in->zoom(), naked_treatment,
constraint_buffer.zoom);
}
}

Expand Down
26 changes: 26 additions & 0 deletions blink/renderer/modules/mediastream/media_constraints_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,32 @@ TEST(MediaTrackConstraintsTest, ConstraintsToString) {

MediaConstraints null_constraints;
EXPECT_EQ("", null_constraints.ToString().Utf8());

MediaConstraints pan_constraints;
MediaTrackConstraintSetPlatform pan_basic;
Vector<MediaTrackConstraintSetPlatform> pan_advanced(static_cast<size_t>(1));
pan_basic.pan.SetIsPresent(false);
pan_advanced[0].pan.SetIsPresent(true);
pan_constraints.Initialize(pan_basic, pan_advanced);
EXPECT_EQ("{advanced: [{pan: {}}]}", pan_constraints.ToString().Utf8());

MediaConstraints tilt_constraints;
MediaTrackConstraintSetPlatform tilt_basic;
Vector<MediaTrackConstraintSetPlatform> tilt_advanced(static_cast<size_t>(1));
tilt_basic.tilt.SetIsPresent(false);
tilt_advanced[0].tilt.SetIsPresent(true);
tilt_constraints.Initialize(tilt_basic, tilt_advanced);
EXPECT_EQ("{advanced: [{tilt: {}}]}", tilt_constraints.ToString().Utf8());

MediaConstraints zoom_constraints;
MediaTrackConstraintSetPlatform zoom_basic;
Vector<MediaTrackConstraintSetPlatform> zoom_advanced(static_cast<size_t>(1));
zoom_basic.zoom.SetIsPresent(false);
zoom_advanced[0].zoom.SetIsPresent(true);
zoom_constraints.Initialize(zoom_basic, zoom_advanced);
EXPECT_EQ("{advanced: [{zoom: {}}]}", zoom_constraints.ToString().Utf8());

// TODO(crbug.com/1086338): Test other constraints with IsPresent.
}

TEST(MediaTrackConstraintsTest, ConvertWebConstraintsBasic) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ dictionary MediaTrackConstraintSet {
ConstrainDouble saturation;
ConstrainDouble sharpness;
ConstrainDouble focusDistance;
[RuntimeEnabled=MediaCapturePanTilt] ConstrainDouble pan;
[RuntimeEnabled=MediaCapturePanTilt] ConstrainDouble tilt;
ConstrainDouble zoom;
[RuntimeEnabled=MediaCapturePanTilt] (boolean or ConstrainDouble) pan;
[RuntimeEnabled=MediaCapturePanTilt] (boolean or ConstrainDouble) tilt;
(boolean or ConstrainDouble) zoom;
ConstrainBoolean torch;
// The "mandatory" and "_optional" members are retained for conformance
// with https://www.w3.org/TR/2013/WD-mediacapture-streams-20130903/
Expand Down
75 changes: 21 additions & 54 deletions blink/renderer/modules/mediastream/user_media_client_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1460,81 +1460,48 @@ TEST_F(UserMediaClientTest, PanConstraintRequestPanTiltZoomPermission) {
EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
CreateDefaultConstraints()));

blink::MockConstraintFactory exact_basic_factory;
exact_basic_factory.basic().pan.SetExact(1);
blink::MockConstraintFactory basic_factory;
basic_factory.basic().pan.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
exact_basic_factory.CreateMediaConstraints()));
basic_factory.CreateMediaConstraints()));

blink::MockConstraintFactory ideal_basic_factory;
ideal_basic_factory.basic().pan.SetIdeal(1);
blink::MockConstraintFactory advanced_factory;
auto& exact_advanced = advanced_factory.AddAdvanced();
exact_advanced.pan.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
ideal_basic_factory.CreateMediaConstraints()));

blink::MockConstraintFactory exact_advanced_factory;
auto& exact_advanced = exact_advanced_factory.AddAdvanced();
exact_advanced.pan.SetExact(1);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
exact_advanced_factory.CreateMediaConstraints()));

blink::MockConstraintFactory ideal_advanced_factory;
auto& ideal_advanced = ideal_advanced_factory.AddAdvanced();
ideal_advanced.pan.SetIdeal(1);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
ideal_advanced_factory.CreateMediaConstraints()));
advanced_factory.CreateMediaConstraints()));
}

TEST_F(UserMediaClientTest, TiltConstraintRequestPanTiltZoomPermission) {
EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
CreateDefaultConstraints()));

blink::MockConstraintFactory exact_basic_factory;
exact_basic_factory.basic().tilt.SetExact(1);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
exact_basic_factory.CreateMediaConstraints()));

blink::MockConstraintFactory ideal_basic_factory;
ideal_basic_factory.basic().tilt.SetIdeal(1);
blink::MockConstraintFactory basic_factory;
basic_factory.basic().tilt.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
ideal_basic_factory.CreateMediaConstraints()));
basic_factory.CreateMediaConstraints()));

blink::MockConstraintFactory exact_advanced_factory;
auto& exact_advanced = exact_advanced_factory.AddAdvanced();
exact_advanced.tilt.SetExact(1);
blink::MockConstraintFactory advanced_factory;
auto& exact_advanced = advanced_factory.AddAdvanced();
exact_advanced.tilt.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
exact_advanced_factory.CreateMediaConstraints()));

blink::MockConstraintFactory ideal_advanced_factory;
auto& ideal_advanced = ideal_advanced_factory.AddAdvanced();
ideal_advanced.tilt.SetIdeal(1);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
ideal_advanced_factory.CreateMediaConstraints()));
advanced_factory.CreateMediaConstraints()));
}

TEST_F(UserMediaClientTest, ZoomConstraintRequestPanTiltZoomPermission) {
EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
CreateDefaultConstraints()));

blink::MockConstraintFactory exact_basic_factory;
exact_basic_factory.basic().zoom.SetExact(1);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
exact_basic_factory.CreateMediaConstraints()));

blink::MockConstraintFactory ideal_basic_factory;
ideal_basic_factory.basic().zoom.SetIdeal(1);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
ideal_basic_factory.CreateMediaConstraints()));

blink::MockConstraintFactory exact_advanced_factory;
auto& exact_advanced = exact_advanced_factory.AddAdvanced();
exact_advanced.zoom.SetExact(1);
blink::MockConstraintFactory basic_factory;
basic_factory.basic().zoom.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
exact_advanced_factory.CreateMediaConstraints()));
basic_factory.CreateMediaConstraints()));

blink::MockConstraintFactory ideal_advanced_factory;
auto& ideal_advanced = ideal_advanced_factory.AddAdvanced();
ideal_advanced.zoom.SetIdeal(1);
blink::MockConstraintFactory advanced_factory;
auto& exact_advanced = advanced_factory.AddAdvanced();
exact_advanced.zoom.SetIsPresent(true);
EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
ideal_advanced_factory.CreateMediaConstraints()));
advanced_factory.CreateMediaConstraints()));
}

} // namespace blink
10 changes: 5 additions & 5 deletions blink/renderer/modules/mediastream/user_media_processor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -812,15 +812,15 @@ bool UserMediaProcessor::IsPanTiltZoomPermissionRequested(
if (!RuntimeEnabledFeatures::MediaCapturePanTiltEnabled())
return false;

if (!constraints.Basic().pan.IsEmpty() ||
!constraints.Basic().tilt.IsEmpty() ||
!constraints.Basic().zoom.IsEmpty()) {
if (constraints.Basic().pan.IsPresent() ||
constraints.Basic().tilt.IsPresent() ||
constraints.Basic().zoom.IsPresent()) {
return true;
}

for (const auto& advanced_set : constraints.Advanced()) {
if (!advanced_set.pan.IsEmpty() || !advanced_set.tilt.IsEmpty() ||
!advanced_set.zoom.IsEmpty()) {
if (advanced_set.pan.IsPresent() || advanced_set.tilt.IsPresent() ||
advanced_set.zoom.IsPresent()) {
return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion blink/renderer/platform/mediastream/media_constraints.cc
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ String MediaTrackConstraintSetPlatform::ToString() const {
StringBuilder builder;
bool first = true;
for (auto* const constraint : AllConstraints()) {
if (!constraint->IsEmpty()) {
if (constraint->IsPresent()) {
if (!first)
builder.Append(", ");
builder.Append(constraint->GetName());
Expand Down
5 changes: 5 additions & 0 deletions blink/renderer/platform/mediastream/media_constraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ class PLATFORM_EXPORT BaseConstraint {
public:
explicit BaseConstraint(const char* name);
virtual ~BaseConstraint();

bool IsPresent() const { return is_present_ || !IsEmpty(); }
void SetIsPresent(bool is_present) { is_present_ = is_present; }

virtual bool IsEmpty() const = 0;
bool HasMandatory() const;
virtual bool HasMin() const { return false; }
Expand All @@ -59,6 +63,7 @@ class PLATFORM_EXPORT BaseConstraint {

private:
const char* name_;
bool is_present_ = false;
};

// Note this class refers to the "long" WebIDL definition which is
Expand Down

0 comments on commit f4ce728

Please sign in to comment.