aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlmediaelement.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/htmlmediaelement.rs')
-rw-r--r--components/script/dom/htmlmediaelement.rs64
1 files changed, 43 insertions, 21 deletions
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 5afc2deb381..d10801c5779 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -79,7 +79,8 @@ use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseLis
use net_traits::{NetworkError, ResourceFetchTiming, ResourceTimingType};
use script_layout_interface::HTMLMediaData;
use servo_config::pref;
-use servo_media::player::frame::{Frame, FrameRenderer};
+use servo_media::player::audio::AudioRenderer;
+use servo_media::player::video::{VideoFrame, VideoFrameRenderer};
use servo_media::player::{PlaybackState, Player, PlayerError, PlayerEvent, SeekLock, StreamType};
use servo_media::{ClientContextId, ServoMedia, SupportsMediaType};
use servo_url::ServoUrl;
@@ -100,10 +101,10 @@ enum FrameStatus {
Unlocked,
}
-struct FrameHolder(FrameStatus, Frame);
+struct FrameHolder(FrameStatus, VideoFrame);
impl FrameHolder {
- fn new(frame: Frame) -> FrameHolder {
+ fn new(frame: VideoFrame) -> FrameHolder {
FrameHolder(FrameStatus::Unlocked, frame)
}
@@ -119,7 +120,7 @@ impl FrameHolder {
};
}
- fn set(&mut self, new_frame: Frame) {
+ fn set(&mut self, new_frame: VideoFrame) {
if self.0 == FrameStatus::Unlocked {
self.1 = new_frame
};
@@ -137,7 +138,7 @@ impl FrameHolder {
}
}
- fn get_frame(&self) -> Frame {
+ fn get_frame(&self) -> VideoFrame {
self.1.clone()
}
}
@@ -170,8 +171,8 @@ impl MediaFrameRenderer {
}
}
-impl FrameRenderer for MediaFrameRenderer {
- fn render(&mut self, frame: Frame) {
+impl VideoFrameRenderer for MediaFrameRenderer {
+ fn render(&mut self, frame: VideoFrame) {
let mut txn = Transaction::new();
if let Some(old_image_key) = mem::replace(&mut self.very_old_frame, self.old_frame.take()) {
@@ -325,7 +326,9 @@ pub struct HTMLMediaElement {
#[ignore_malloc_size_of = "servo_media"]
player: DomRefCell<Option<Arc<Mutex<dyn Player>>>>,
#[ignore_malloc_size_of = "Arc"]
- frame_renderer: Arc<Mutex<MediaFrameRenderer>>,
+ video_renderer: Arc<Mutex<MediaFrameRenderer>>,
+ #[ignore_malloc_size_of = "Arc"]
+ audio_renderer: DomRefCell<Option<Arc<Mutex<dyn AudioRenderer>>>>,
/// https://html.spec.whatwg.org/multipage/#show-poster-flag
show_poster: Cell<bool>,
/// https://html.spec.whatwg.org/multipage/#dom-media-duration
@@ -410,9 +413,10 @@ impl HTMLMediaElement {
pending_play_promises: Default::default(),
in_flight_play_promises_queue: Default::default(),
player: Default::default(),
- frame_renderer: Arc::new(Mutex::new(MediaFrameRenderer::new(
+ video_renderer: Arc::new(Mutex::new(MediaFrameRenderer::new(
document.window().get_webrender_api_sender(),
))),
+ audio_renderer: Default::default(),
show_poster: Cell::new(true),
duration: Cell::new(f64::NAN),
playback_position: Cell::new(0.),
@@ -1293,7 +1297,7 @@ impl HTMLMediaElement {
// Step 6.
if let ImageResponse::Loaded(image, _) = image {
- self.frame_renderer
+ self.video_renderer
.lock()
.unwrap()
.render_poster_frame(image);
@@ -1325,11 +1329,14 @@ impl HTMLMediaElement {
let window = window_from_node(self);
let (action_sender, action_receiver) = ipc::channel::<PlayerEvent>().unwrap();
- let renderer: Option<Arc<Mutex<dyn FrameRenderer>>> = match self.media_type_id() {
+ let video_renderer: Option<Arc<Mutex<dyn VideoFrameRenderer>>> = match self.media_type_id()
+ {
HTMLMediaElementTypeId::HTMLAudioElement => None,
- HTMLMediaElementTypeId::HTMLVideoElement => Some(self.frame_renderer.clone()),
+ HTMLMediaElementTypeId::HTMLVideoElement => Some(self.video_renderer.clone()),
};
+ let audio_renderer = self.audio_renderer.borrow().as_ref().map(|r| r.clone());
+
let pipeline_id = window
.pipeline_id()
.expect("Cannot create player outside of a pipeline");
@@ -1339,7 +1346,8 @@ impl HTMLMediaElement {
&client_context_id,
stream_type,
action_sender,
- renderer,
+ video_renderer,
+ audio_renderer,
Box::new(window.get_player_context()),
);
@@ -1385,7 +1393,7 @@ impl HTMLMediaElement {
.unwrap_or((0, None));
self.id.set(player_id);
- self.frame_renderer.lock().unwrap().player_id = Some(player_id);
+ self.video_renderer.lock().unwrap().player_id = Some(player_id);
if let Some(image_receiver) = image_receiver {
let trusted_node = Trusted::new(self);
@@ -1400,11 +1408,11 @@ impl HTMLMediaElement {
if let Err(err) = task_source.queue_with_canceller(
task!(handle_glplayer_message: move || {
trace!("GLPlayer message {:?}", msg);
- let frame_renderer = this.root().frame_renderer.clone();
+ let video_renderer = this.root().video_renderer.clone();
match msg {
GLPlayerMsgForward::Lock(sender) => {
- frame_renderer
+ video_renderer
.lock()
.unwrap()
.current_frame_holder
@@ -1415,7 +1423,7 @@ impl HTMLMediaElement {
});
},
GLPlayerMsgForward::Unlock() => {
- frame_renderer
+ video_renderer
.lock()
.unwrap()
.current_frame_holder
@@ -1527,7 +1535,7 @@ impl HTMLMediaElement {
)));
self.upcast::<EventTarget>().fire_event(atom!("error"));
},
- PlayerEvent::FrameUpdated => {
+ PlayerEvent::VideoFrameUpdated => {
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
},
PlayerEvent::MetadataUpdated(ref metadata) => {
@@ -1855,12 +1863,26 @@ impl HTMLMediaElement {
}
}
- pub fn get_current_frame(&self) -> Option<Frame> {
- match self.frame_renderer.lock().unwrap().current_frame_holder {
+ pub fn get_current_frame(&self) -> Option<VideoFrame> {
+ match self.video_renderer.lock().unwrap().current_frame_holder {
Some(ref holder) => Some(holder.get_frame()),
None => return None,
}
}
+
+ /// By default the audio is rendered through the audio sink automatically
+ /// selected by the servo-media Player instance. However, in some cases, like
+ /// the WebAudio MediaElementAudioSourceNode, we need to set a custom audio
+ /// renderer.
+ pub fn set_audio_renderer(&self, audio_renderer: Arc<Mutex<dyn AudioRenderer>>) {
+ *self.audio_renderer.borrow_mut() = Some(audio_renderer);
+ if let Some(ref player) = *self.player.borrow() {
+ if let Err(e) = player.lock().unwrap().stop() {
+ eprintln!("Could not stop player {:?}", e);
+ }
+ self.media_element_load_algorithm();
+ }
+ }
}
// XXX Placeholder for [https://github.com/servo/servo/issues/22293]
@@ -2365,7 +2387,7 @@ impl LayoutHTMLMediaElementHelpers for LayoutDom<HTMLMediaElement> {
fn data(&self) -> HTMLMediaData {
let media = unsafe { &*self.unsafe_get() };
HTMLMediaData {
- current_frame: media.frame_renderer.lock().unwrap().current_frame.clone(),
+ current_frame: media.video_renderer.lock().unwrap().current_frame.clone(),
}
}
}