Skip to content

Commit

Permalink
Auto merge of #27143 - Manishearth:streamnodes, r=ferjm
Browse files Browse the repository at this point in the history
Implement MediaStreamAudioDestinationNode, MediaStreamAudioSourceNode, MediaStreamTrackAudioSourceNode

Progress in #26097

This is a draft since we need the data channels stuff to land first

(also I need to make sure we're passing WPT)
  • Loading branch information
bors-servo committed Jul 3, 2020
2 parents ee56d5d + 3b3e2e0 commit 4504eeb
Show file tree
Hide file tree
Showing 21 changed files with 348 additions and 213 deletions.
24 changes: 12 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions components/script/dom/audiocontext.rs
Expand Up @@ -9,6 +9,7 @@ use crate::dom::bindings::codegen::Bindings::AudioContextBinding::{
use crate::dom::bindings::codegen::Bindings::AudioContextBinding::{
AudioContextOptions, AudioTimestamp,
};
use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::AudioNodeOptions;
use crate::dom::bindings::codegen::Bindings::BaseAudioContextBinding::AudioContextState;
use crate::dom::bindings::codegen::Bindings::BaseAudioContextBinding::BaseAudioContextBinding::BaseAudioContextMethods;
use crate::dom::bindings::codegen::UnionTypes::AudioContextLatencyCategoryOrDouble;
Expand All @@ -20,6 +21,11 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::DomRoot;
use crate::dom::htmlmediaelement::HTMLMediaElement;
use crate::dom::mediaelementaudiosourcenode::MediaElementAudioSourceNode;
use crate::dom::mediastream::MediaStream;
use crate::dom::mediastreamaudiodestinationnode::MediaStreamAudioDestinationNode;
use crate::dom::mediastreamaudiosourcenode::MediaStreamAudioSourceNode;
use crate::dom::mediastreamtrack::MediaStreamTrack;
use crate::dom::mediastreamtrackaudiosourcenode::MediaStreamTrackAudioSourceNode;
use crate::dom::promise::Promise;
use crate::dom::window::Window;
use crate::realms::InRealm;
Expand Down Expand Up @@ -254,6 +260,33 @@ impl AudioContextMethods for AudioContext {
let window = global.as_window();
MediaElementAudioSourceNode::new(window, self, media_element)
}

/// https://webaudio.github.io/web-audio-api/#dom-audiocontext-createmediastreamsource
fn CreateMediaStreamSource(
&self,
stream: &MediaStream,
) -> Fallible<DomRoot<MediaStreamAudioSourceNode>> {
let global = self.global();
let window = global.as_window();
MediaStreamAudioSourceNode::new(window, self, stream)
}

/// https://webaudio.github.io/web-audio-api/#dom-audiocontext-createmediastreamtracksource
fn CreateMediaStreamTrackSource(
&self,
track: &MediaStreamTrack,
) -> Fallible<DomRoot<MediaStreamTrackAudioSourceNode>> {
let global = self.global();
let window = global.as_window();
MediaStreamTrackAudioSourceNode::new(window, self, track)
}

/// https://webaudio.github.io/web-audio-api/#dom-audiocontext-createmediastreamdestination
fn CreateMediaStreamDestination(&self) -> Fallible<DomRoot<MediaStreamAudioDestinationNode>> {
let global = self.global();
let window = global.as_window();
MediaStreamAudioDestinationNode::new(window, self, &AudioNodeOptions::empty())
}
}

impl From<AudioContextLatencyCategory> for LatencyCategory {
Expand Down
12 changes: 12 additions & 0 deletions components/script/dom/mediastream.rs
Expand Up @@ -13,6 +13,7 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::mediastreamtrack::MediaStreamTrack;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use servo_media::streams::registry::MediaStreamId;
use servo_media::streams::MediaStreamType;

#[dom_struct]
Expand All @@ -34,6 +35,17 @@ impl MediaStream {
reflect_dom_object(Box::new(MediaStream::new_inherited()), global)
}

pub fn new_single(
global: &GlobalScope,
id: MediaStreamId,
ty: MediaStreamType,
) -> DomRoot<MediaStream> {
let this = Self::new(global);
let track = MediaStreamTrack::new(global, id, ty);
this.AddTrack(&track);
this
}

pub fn Constructor(global: &Window) -> Fallible<DomRoot<MediaStream>> {
Ok(MediaStream::new(&global.global()))
}
Expand Down
81 changes: 81 additions & 0 deletions components/script/dom/mediastreamaudiodestinationnode.rs
@@ -0,0 +1,81 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::dom::audiocontext::AudioContext;
use crate::dom::audionode::AudioNode;
use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::AudioNodeOptions;
use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
ChannelCountMode, ChannelInterpretation,
};
use crate::dom::bindings::codegen::Bindings::MediaStreamAudioDestinationNodeBinding::MediaStreamAudioDestinationNodeMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::mediastream::MediaStream;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use servo_media::audio::node::AudioNodeInit;
use servo_media::streams::MediaStreamType;
use servo_media::ServoMedia;

#[dom_struct]
pub struct MediaStreamAudioDestinationNode {
node: AudioNode,
stream: Dom<MediaStream>,
}

impl MediaStreamAudioDestinationNode {
#[allow(unrooted_must_root)]
pub fn new_inherited(
context: &AudioContext,
options: &AudioNodeOptions,
) -> Fallible<MediaStreamAudioDestinationNode> {
let media = ServoMedia::get().unwrap();
let (socket, id) = media.create_stream_and_socket(MediaStreamType::Audio);
let stream = MediaStream::new_single(&context.global(), id, MediaStreamType::Audio);
let node_options = options.unwrap_or(
2,
ChannelCountMode::Explicit,
ChannelInterpretation::Speakers,
);
let node = AudioNode::new_inherited(
AudioNodeInit::MediaStreamDestinationNode(socket),
&context.upcast(),
node_options,
1, // inputs
0, // outputs
)?;
Ok(MediaStreamAudioDestinationNode {
node,
stream: Dom::from_ref(&stream),
})
}

#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &AudioContext,
options: &AudioNodeOptions,
) -> Fallible<DomRoot<MediaStreamAudioDestinationNode>> {
let node = MediaStreamAudioDestinationNode::new_inherited(context, options)?;
Ok(reflect_dom_object(Box::new(node), window))
}

#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
context: &AudioContext,
options: &AudioNodeOptions,
) -> Fallible<DomRoot<MediaStreamAudioDestinationNode>> {
MediaStreamAudioDestinationNode::new(window, context, options)
}
}

impl MediaStreamAudioDestinationNodeMethods for MediaStreamAudioDestinationNode {
/// https://webaudio.github.io/web-audio-api/#dom-mediastreamaudiodestinationnode-stream
fn Stream(&self) -> DomRoot<MediaStream> {
DomRoot::from_ref(&self.stream)
}
}
76 changes: 76 additions & 0 deletions components/script/dom/mediastreamaudiosourcenode.rs
@@ -0,0 +1,76 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::dom::audiocontext::AudioContext;
use crate::dom::audionode::AudioNode;
use crate::dom::bindings::codegen::Bindings::MediaStreamAudioSourceNodeBinding::{
MediaStreamAudioSourceNodeMethods, MediaStreamAudioSourceOptions,
};
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::mediastream::MediaStream;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use servo_media::audio::node::AudioNodeInit;
use servo_media::streams::MediaStreamType;

#[dom_struct]
pub struct MediaStreamAudioSourceNode {
node: AudioNode,
stream: Dom<MediaStream>,
}

impl MediaStreamAudioSourceNode {
#[allow(unrooted_must_root)]
pub fn new_inherited(
context: &AudioContext,
stream: &MediaStream,
) -> Fallible<MediaStreamAudioSourceNode> {
let track = stream
.get_tracks()
.iter()
.find(|t| t.ty() == MediaStreamType::Audio)
.ok_or(Error::InvalidState)?
.id();
let node = AudioNode::new_inherited(
AudioNodeInit::MediaStreamSourceNode(track),
&context.upcast(),
Default::default(),
0, // inputs
1, // outputs
)?;
Ok(MediaStreamAudioSourceNode {
node,
stream: Dom::from_ref(&stream),
})
}

#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &AudioContext,
stream: &MediaStream,
) -> Fallible<DomRoot<MediaStreamAudioSourceNode>> {
let node = MediaStreamAudioSourceNode::new_inherited(context, stream)?;
Ok(reflect_dom_object(Box::new(node), window))
}

#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
context: &AudioContext,
options: &MediaStreamAudioSourceOptions,
) -> Fallible<DomRoot<MediaStreamAudioSourceNode>> {
MediaStreamAudioSourceNode::new(window, context, &options.mediaStream)
}
}

impl MediaStreamAudioSourceNodeMethods for MediaStreamAudioSourceNode {
/// https://webaudio.github.io/web-audio-api/#dom-MediaStreamAudioSourceNode-stream
fn MediaStream(&self) -> DomRoot<MediaStream> {
DomRoot::from_ref(&self.stream)
}
}

0 comments on commit 4504eeb

Please sign in to comment.