From dd7b69b6d8876ca3073c8ea6aeca007073ca3425 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 12 Feb 2019 15:55:40 -0800 Subject: [PATCH 1/3] Add support for basic MediaTrackConstraints --- components/script/dom/mediadevices.rs | 45 ++++++++++-- .../script/dom/webidls/MediaDevices.webidl | 68 +++++++++---------- 2 files changed, 75 insertions(+), 38 deletions(-) diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs index 60b99c7fb23..313efa3b13d 100644 --- a/components/script/dom/mediadevices.rs +++ b/components/script/dom/mediadevices.rs @@ -4,6 +4,8 @@ use crate::dom::bindings::codegen::Bindings::MediaDevicesBinding::MediaStreamConstraints; use crate::dom::bindings::codegen::Bindings::MediaDevicesBinding::{self, MediaDevicesMethods}; +use crate::dom::bindings::codegen::UnionTypes::BooleanOrMediaTrackConstraints; +use crate::dom::bindings::codegen::UnionTypes::ClampedUnsignedLongOrConstrainULongRange as ConstrainULong; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; @@ -12,6 +14,7 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::mediastream::MediaStream; use crate::dom::promise::Promise; use dom_struct::dom_struct; +use servo_media::streams::capture::{Constrain, ConstrainRange, MediaTrackConstraintSet}; use servo_media::ServoMedia; use std::rc::Rc; @@ -42,13 +45,13 @@ impl MediaDevicesMethods for MediaDevices { let p = Promise::new(&self.global()); let media = ServoMedia::get().unwrap(); let mut tracks = vec![]; - if constraints.audio { - if let Some(audio) = media.create_audioinput_stream(Default::default()) { + if let Some(constraints) = convert_constraints(&constraints.audio) { + if let Some(audio) = media.create_audioinput_stream(constraints) { tracks.push(audio) } } - if constraints.video { - if let Some(video) = media.create_videoinput_stream(Default::default()) { + if let Some(constraints) = convert_constraints(&constraints.video) { + if let Some(video) = media.create_videoinput_stream(constraints) { tracks.push(video) } } @@ -57,3 +60,37 @@ impl MediaDevicesMethods for MediaDevices { p } } + +fn convert_constraints(js: &BooleanOrMediaTrackConstraints) -> Option { + match js { + BooleanOrMediaTrackConstraints::Boolean(false) => None, + BooleanOrMediaTrackConstraints::Boolean(true) => Some(Default::default()), + BooleanOrMediaTrackConstraints::MediaTrackConstraints(ref c) => { + Some(MediaTrackConstraintSet { + height: convert_culong(&c.parent.height), + width: convert_culong(&c.parent.width), + ..Default::default() + }) + }, + } +} + +fn convert_culong(js: &ConstrainULong) -> Option> { + match js { + ConstrainULong::ClampedUnsignedLong(val) => Some(Constrain::Value(*val)), + ConstrainULong::ConstrainULongRange(ref range) => { + if range.parent.min.is_some() || range.parent.max.is_some() { + Some(Constrain::Range(ConstrainRange { + min: range.parent.min, + max: range.parent.max, + ideal: range.ideal, + })) + } else if let Some(exact) = range.exact { + Some(Constrain::Value(exact)) + } else { + // the unspecified case is treated as all three being none + None + } + }, + } +} diff --git a/components/script/dom/webidls/MediaDevices.webidl b/components/script/dom/webidls/MediaDevices.webidl index 7fa30e0b916..4c3a7dedbd2 100644 --- a/components/script/dom/webidls/MediaDevices.webidl +++ b/components/script/dom/webidls/MediaDevices.webidl @@ -23,10 +23,10 @@ partial interface MediaDevices { dictionary MediaStreamConstraints { - // (boolean or MediaTrackConstraints) video = false; - // (boolean or MediaTrackConstraints) audio = false; - boolean video = false; - boolean audio = false; + (boolean or MediaTrackConstraints) video; + // (boolean or MediaTrackConstraints) video = false; + (boolean or MediaTrackConstraints) audio; + // (boolean or MediaTrackConstraints) audio = false; }; // dictionary DoubleRange { @@ -39,15 +39,15 @@ dictionary MediaStreamConstraints { // double ideal; // }; -// dictionary ULongRange { -// [Clamp] unsigned long max; -// [Clamp] unsigned long min; -// }; +dictionary ULongRange { + [Clamp] unsigned long max; + [Clamp] unsigned long min; +}; -// dictionary ConstrainULongRange : ULongRange { -// [Clamp] unsigned long exact; -// [Clamp] unsigned long ideal; -// }; +dictionary ConstrainULongRange : ULongRange { + [Clamp] unsigned long exact; + [Clamp] unsigned long ideal; +}; // dictionary ConstrainBooleanParameters { // boolean exact; @@ -59,30 +59,30 @@ dictionary MediaStreamConstraints { // (DOMString or sequence) ideal; // }; -// dictionary MediaTrackConstraints : MediaTrackConstraintSet { -// sequence advanced; -// }; +dictionary MediaTrackConstraints : MediaTrackConstraintSet { + sequence advanced; +}; -// typedef ([Clamp] unsigned long or ConstrainULongRange) ConstrainULong; +typedef ([Clamp] unsigned long or ConstrainULongRange) ConstrainULong; // typedef (double or ConstrainDoubleRange) ConstrainDouble; // typedef (boolean or ConstrainBooleanParameters) ConstrainBoolean; // typedef (DOMString or sequence or ConstrainDOMStringParameters) ConstrainDOMString; -// dictionary MediaTrackConstraintSet { -// ConstrainULong width; -// ConstrainULong height; -// ConstrainDouble aspectRatio; -// ConstrainDouble frameRate; -// ConstrainDOMString facingMode; -// ConstrainDOMString resizeMode; -// ConstrainDouble volume; -// ConstrainULong sampleRate; -// ConstrainULong sampleSize; -// ConstrainBoolean echoCancellation; -// ConstrainBoolean autoGainControl; -// ConstrainBoolean noiseSuppression; -// ConstrainDouble latency; -// ConstrainULong channelCount; -// ConstrainDOMString deviceId; -// ConstrainDOMString groupId; -// }; +dictionary MediaTrackConstraintSet { + ConstrainULong width; + ConstrainULong height; + // ConstrainDouble aspectRatio; + // ConstrainDouble frameRate; + // ConstrainDOMString facingMode; + // ConstrainDOMString resizeMode; + // ConstrainDouble volume; + // ConstrainULong sampleRate; + // ConstrainULong sampleSize; + // ConstrainBoolean echoCancellation; + // ConstrainBoolean autoGainControl; + // ConstrainBoolean noiseSuppression; + // ConstrainDouble latency; + // ConstrainULong channelCount; + // ConstrainDOMString deviceId; + // ConstrainDOMString groupId; +}; From caa05948bf250944b259a5a95a8e6ef1db6a947b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 12 Feb 2019 18:24:44 -0800 Subject: [PATCH 2/3] Add aspect/frameRate/sampleRate parameters --- .../dom/bindings/codegen/CodegenRust.py | 1 + components/script/dom/mediadevices.rs | 25 ++++++++++++++++++- .../script/dom/webidls/MediaDevices.webidl | 24 +++++++++--------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index dea6e104213..1bd01651e76 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -2379,6 +2379,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config): 'crate::dom::bindings::conversions::root_from_handlevalue', 'std::ptr::NonNull', 'crate::dom::bindings::mozmap::MozMap', + 'crate::dom::bindings::num::Finite', 'crate::dom::bindings::root::DomRoot', 'crate::dom::bindings::str::ByteString', 'crate::dom::bindings::str::DOMString', diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs index 313efa3b13d..b89762c3779 100644 --- a/components/script/dom/mediadevices.rs +++ b/components/script/dom/mediadevices.rs @@ -6,6 +6,7 @@ use crate::dom::bindings::codegen::Bindings::MediaDevicesBinding::MediaStreamCon use crate::dom::bindings::codegen::Bindings::MediaDevicesBinding::{self, MediaDevicesMethods}; use crate::dom::bindings::codegen::UnionTypes::BooleanOrMediaTrackConstraints; use crate::dom::bindings::codegen::UnionTypes::ClampedUnsignedLongOrConstrainULongRange as ConstrainULong; +use crate::dom::bindings::codegen::UnionTypes::DoubleOrConstrainDoubleRange as ConstrainDouble; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; @@ -69,7 +70,9 @@ fn convert_constraints(js: &BooleanOrMediaTrackConstraints) -> Option Option> { }, } } + +fn convert_cdouble(js: &ConstrainDouble) -> Option> { + match js { + ConstrainDouble::Double(val) => Some(Constrain::Value(**val)), + ConstrainDouble::ConstrainDoubleRange(ref range) => { + if range.parent.min.is_some() || range.parent.max.is_some() { + Some(Constrain::Range(ConstrainRange { + min: range.parent.min.map(|x| *x), + max: range.parent.max.map(|x| *x), + ideal: range.ideal.map(|x| *x), + })) + } else if let Some(exact) = range.exact { + Some(Constrain::Value(*exact)) + } else { + // the unspecified case is treated as all three being none + None + } + }, + } +} diff --git a/components/script/dom/webidls/MediaDevices.webidl b/components/script/dom/webidls/MediaDevices.webidl index 4c3a7dedbd2..e439a80c512 100644 --- a/components/script/dom/webidls/MediaDevices.webidl +++ b/components/script/dom/webidls/MediaDevices.webidl @@ -29,15 +29,15 @@ dictionary MediaStreamConstraints { // (boolean or MediaTrackConstraints) audio = false; }; -// dictionary DoubleRange { -// double max; -// double min; -// }; +dictionary DoubleRange { + double max; + double min; +}; -// dictionary ConstrainDoubleRange : DoubleRange { -// double exact; -// double ideal; -// }; +dictionary ConstrainDoubleRange : DoubleRange { + double exact; + double ideal; +}; dictionary ULongRange { [Clamp] unsigned long max; @@ -64,19 +64,19 @@ dictionary MediaTrackConstraints : MediaTrackConstraintSet { }; typedef ([Clamp] unsigned long or ConstrainULongRange) ConstrainULong; -// typedef (double or ConstrainDoubleRange) ConstrainDouble; +typedef (double or ConstrainDoubleRange) ConstrainDouble; // typedef (boolean or ConstrainBooleanParameters) ConstrainBoolean; // typedef (DOMString or sequence or ConstrainDOMStringParameters) ConstrainDOMString; dictionary MediaTrackConstraintSet { ConstrainULong width; ConstrainULong height; - // ConstrainDouble aspectRatio; - // ConstrainDouble frameRate; + ConstrainDouble aspectRatio; + ConstrainDouble frameRate; // ConstrainDOMString facingMode; // ConstrainDOMString resizeMode; // ConstrainDouble volume; - // ConstrainULong sampleRate; + ConstrainULong sampleRate; // ConstrainULong sampleSize; // ConstrainBoolean echoCancellation; // ConstrainBoolean autoGainControl; From ce635b715bc61d82e3d5bafb2964c960e7cc5f9c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 12 Feb 2019 18:38:38 -0800 Subject: [PATCH 3/3] Add support for default dict values being boolean, use in MediaStreamConstraints --- components/script/dom/bindings/codegen/CodegenRust.py | 10 +++++++++- components/script/dom/webidls/MediaDevices.webidl | 6 ++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 1bd01651e76..fe88275bf20 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -747,7 +747,15 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, for memberType in type.unroll().flatMemberTypes if memberType.isDictionary() ] - if dictionaries: + if defaultValue and not isinstance(defaultValue, IDLNullValue): + tag = defaultValue.type.tag() + if tag is IDLType.Tags.bool: + default = "%s::Boolean(%s)" % ( + union_native_type(type), + "true" if defaultValue.value else "false") + else: + raise("We don't currently support default values that aren't null or boolean") + elif dictionaries: if defaultValue: assert isinstance(defaultValue, IDLNullValue) dictionary, = dictionaries diff --git a/components/script/dom/webidls/MediaDevices.webidl b/components/script/dom/webidls/MediaDevices.webidl index e439a80c512..866e1e964d0 100644 --- a/components/script/dom/webidls/MediaDevices.webidl +++ b/components/script/dom/webidls/MediaDevices.webidl @@ -23,10 +23,8 @@ partial interface MediaDevices { dictionary MediaStreamConstraints { - (boolean or MediaTrackConstraints) video; - // (boolean or MediaTrackConstraints) video = false; - (boolean or MediaTrackConstraints) audio; - // (boolean or MediaTrackConstraints) audio = false; + (boolean or MediaTrackConstraints) video = false; + (boolean or MediaTrackConstraints) audio = false; }; dictionary DoubleRange {