From 9e3aa98da4cd9f8e90dcb16b1b1a2b8a6583bcd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Wed, 3 Oct 2018 10:38:39 +0200 Subject: [PATCH 1/3] Expose Player errors --- backends/gstreamer/src/lib.rs | 4 + backends/gstreamer/src/player.rs | 198 +++++++++++++++++-------------- examples/player/main.rs | 16 +-- examples/simple_player.rs | 12 +- player/src/lib.rs | 31 ++--- servo-media/src/lib.rs | 7 +- 6 files changed, 147 insertions(+), 121 deletions(-) diff --git a/backends/gstreamer/src/lib.rs b/backends/gstreamer/src/lib.rs index 5c45f341..bd8aecae 100644 --- a/backends/gstreamer/src/lib.rs +++ b/backends/gstreamer/src/lib.rs @@ -32,6 +32,10 @@ pub enum BackendError { PadLinkFailed, PipelineBusError(String), PipelineFailed(&'static str), + PlayerError, // XXX add player error + PlayerPushDataFailed, + PlayerEOSFailed, + PlayerSourceSetupFailed, SetPropertyFailed(&'static str), StateChangeFailed, } diff --git a/backends/gstreamer/src/player.rs b/backends/gstreamer/src/player.rs index d2f280f3..8984c18a 100644 --- a/backends/gstreamer/src/player.rs +++ b/backends/gstreamer/src/player.rs @@ -1,3 +1,4 @@ +use super::BackendError; use glib; use glib::*; use gst; @@ -148,30 +149,33 @@ impl GStreamerPlayer { } } - fn setup(&self) -> Result<(), ()> { + fn setup(&self) -> Result<(), BackendError> { if self.inner.borrow().is_some() { return Ok(()); } + let player = gst_player::Player::new( /* video renderer */ None, /* signal dispatcher */ None, ); + player .set_property("uri", &Value::from("appsrc://")) - .or_else(|_| Err(()))?; + .map_err(|e| BackendError::SetPropertyFailed(e.0))?; // Disable periodic position updates for now. let mut config = player.get_config(); config.set_position_update_interval(0u32); - player.set_config(config).or_else(|_| Err(()))?; + player + .set_config(config) + .map_err(|e| BackendError::SetPropertyFailed(e.0))?; - let video_sink = gst::ElementFactory::make("appsink", None).ok_or_else(|| ())?; + let video_sink = gst::ElementFactory::make("appsink", None) + .ok_or(BackendError::ElementCreationFailed("appsink"))?; let pipeline = player.get_pipeline(); pipeline .set_property("video-sink", &video_sink.to_value()) - .or_else(|_| Err(()))?; - let video_sink = video_sink - .dynamic_cast::() - .or_else(|_| Err(()))?; + .map_err(|e| BackendError::SetPropertyFailed(e.0))?; + let video_sink = video_sink.dynamic_cast::().unwrap(); video_sink.set_caps(&gst::Caps::new_simple( "video/x-raw", &[ @@ -198,18 +202,14 @@ impl GStreamerPlayer { .unwrap() .player .connect_end_of_stream(move |_| { - let inner = &inner_clone; - let guard = inner.lock().unwrap(); - - guard.notify(PlayerEvent::EndOfStream); + let inner = inner_clone.lock().unwrap(); + inner.notify(PlayerEvent::EndOfStream); }); let inner_clone = inner.clone(); inner.lock().unwrap().player.connect_error(move |_, _| { - let inner = &inner_clone; - let guard = inner.lock().unwrap(); - - guard.notify(PlayerEvent::Error); + let inner = inner_clone.lock().unwrap(); + inner.notify(PlayerEvent::Error); }); let inner_clone = inner.clone(); @@ -225,10 +225,8 @@ impl GStreamerPlayer { _ => None, }; if let Some(v) = state { - let inner = &inner_clone; - let guard = inner.lock().unwrap(); - - guard.notify(PlayerEvent::StateChanged(v)); + let inner = inner_clone.lock().unwrap(); + inner.notify(PlayerEvent::StateChanged(v)); } }); @@ -238,13 +236,11 @@ impl GStreamerPlayer { .unwrap() .player .connect_media_info_updated(move |_, info| { - let inner = &inner_clone; - let mut guard = inner.lock().unwrap(); - + let mut inner = inner_clone.lock().unwrap(); if let Ok(metadata) = metadata_from_media_info(info) { - if guard.last_metadata.as_ref() != Some(&metadata) { - guard.last_metadata = Some(metadata.clone()); - guard.notify(PlayerEvent::MetadataUpdated(metadata)); + if inner.last_metadata.as_ref() != Some(&metadata) { + inner.last_metadata = Some(metadata.clone()); + inner.notify(PlayerEvent::MetadataUpdated(metadata)); } } }); @@ -278,8 +274,8 @@ impl GStreamerPlayer { .build(), ); - let inner_clone = inner.clone(); - let (receiver, error_id) = { + let (receiver, error_handler_id) = { + let inner_clone = inner.clone(); let mut inner = inner.lock().unwrap(); let pipeline = inner.player.get_pipeline(); @@ -287,70 +283,82 @@ impl GStreamerPlayer { let sender = Arc::new(Mutex::new(sender)); let sender_clone = sender.clone(); - pipeline + if pipeline .connect("source-setup", false, move |args| { + let source = args[1].get::(); + if source.is_none() { + let _ = sender + .lock() + .unwrap() + .send(Err(BackendError::PlayerSourceSetupFailed)); + return None; + } + let source = source.unwrap(); let mut inner = inner_clone.lock().unwrap(); - - if let Some(source) = args[1].get::() { - let appsrc = source - .clone() - .dynamic_cast::() - .expect("Source element is expected to be an appsrc!"); - - appsrc.set_property_format(gst::Format::Bytes); - if inner.input_size > 0 { - appsrc.set_size(inner.input_size as i64); - } - - let sender_clone = sender.clone(); - - let need_data_id = Arc::new(Mutex::new(None)); - let need_data_id_clone = need_data_id.clone(); - *need_data_id.lock().unwrap() = Some( - appsrc - .connect("need-data", false, move |args| { - let _ = sender_clone.lock().unwrap().send(Ok(())); - if let Some(id) = need_data_id_clone.lock().unwrap().take() { - glib::signal::signal_handler_disconnect( - &args[0].get::().unwrap(), - id, - ); - } - None - }) - .unwrap(), - ); - - inner.set_app_src(appsrc); - } else { - let _ = sender.lock().unwrap().send(Err(())); + let appsrc = source + .clone() + .dynamic_cast::() + .expect("Source element is expected to be an appsrc!"); + + appsrc.set_property_format(gst::Format::Bytes); + if inner.input_size > 0 { + appsrc.set_size(inner.input_size as i64); } + let sender_clone = sender.clone(); + + let need_data_id = Arc::new(Mutex::new(None)); + let need_data_id_clone = need_data_id.clone(); + *need_data_id.lock().unwrap() = Some( + appsrc + .connect("need-data", false, move |args| { + let _ = sender_clone.lock().unwrap().send(Ok(())); + if let Some(id) = need_data_id_clone.lock().unwrap().take() { + glib::signal::signal_handler_disconnect( + &args[0].get::().unwrap(), + id, + ); + } + None + }) + .unwrap(), + ); + + inner.set_app_src(appsrc); + None }) - .unwrap(); + .is_err() + { + let _ = sender_clone + .lock() + .unwrap() + .send(Err(BackendError::PlayerSourceSetupFailed)); + } - let error_id = inner.player.connect_error(move |_, _| { - let _ = sender_clone.lock().unwrap().send(Err(())); + let error_handler_id = inner.player.connect_error(move |player, _error| { + let _ = sender_clone + .lock() + .unwrap() + .send(Err(BackendError::PlayerError)); + player.stop(); }); inner.pause(); - (receiver, error_id) + (receiver, error_handler_id) }; - glib::signal::signal_handler_disconnect(&inner.lock().unwrap().player, error_id); - - match receiver.recv().unwrap() { - Ok(_) => return Ok(()), - Err(_) => return Err(()), - }; + let result = receiver.recv().unwrap(); + glib::signal::signal_handler_disconnect(&inner.lock().unwrap().player, error_handler_id); + result } } impl Player for GStreamerPlayer { - fn register_event_handler(&self, sender: IpcSender) { - let _ = self.setup(); + type Error = BackendError; + fn register_event_handler(&self, sender: IpcSender) -> Result<(), BackendError> { + self.setup()?; let inner = self.inner.borrow(); inner .as_ref() @@ -358,10 +366,11 @@ impl Player for GStreamerPlayer { .lock() .unwrap() .register_event_handler(sender); + Ok(()) } - fn register_frame_renderer(&self, renderer: Arc>) { - let _ = self.setup(); + fn register_frame_renderer(&self, renderer: Arc>) -> Result<(), BackendError> { + self.setup()?; let inner = self.inner.borrow(); inner .as_ref() @@ -369,10 +378,11 @@ impl Player for GStreamerPlayer { .lock() .unwrap() .register_frame_renderer(renderer); + Ok(()) } - fn set_input_size(&self, size: u64) { - let _ = self.setup(); + fn set_input_size(&self, size: u64) -> Result<(), BackendError> { + self.setup()?; // Keep inner's .set_input_size() to proxy its value, since it // could be set by the user before calling .setup() let inner = self.inner.borrow(); @@ -385,41 +395,45 @@ impl Player for GStreamerPlayer { appsrc.set_size(-1); // live source } } + Ok(()) } - fn play(&self) { - let _ = self.setup(); + fn play(&self) -> Result<(), BackendError> { + self.setup()?; let inner = self.inner.borrow(); inner.as_ref().unwrap().lock().unwrap().play(); + Ok(()) } - fn pause(&self) { - let _ = self.setup(); + fn pause(&self) -> Result<(), BackendError> { + self.setup()?; let inner = self.inner.borrow(); inner.as_ref().unwrap().lock().unwrap().pause(); + Ok(()) } - fn stop(&self) { - let _ = self.setup(); + fn stop(&self) -> Result<(), BackendError> { + self.setup()?; let inner = self.inner.borrow(); inner.as_ref().unwrap().lock().unwrap().stop(); + Ok(()) } - fn push_data(&self, data: Vec) -> Result<(), ()> { - let _ = self.setup(); + fn push_data(&self, data: Vec) -> Result<(), BackendError> { + self.setup()?; let inner = self.inner.borrow(); let mut inner = inner.as_ref().unwrap().lock().unwrap(); if let Some(ref mut appsrc) = inner.appsrc { - let buffer = gst::Buffer::from_slice(data).ok_or_else(|| ())?; + let buffer = gst::Buffer::from_slice(data).ok_or_else(|| BackendError::PlayerPushDataFailed)?; if appsrc.push_buffer(buffer) == gst::FlowReturn::Ok { return Ok(()); } } - Err(()) + Err(BackendError::PlayerPushDataFailed) } - fn end_of_stream(&self) -> Result<(), ()> { - let _ = self.setup(); + fn end_of_stream(&self) -> Result<(), BackendError> { + self.setup()?; let inner = self.inner.borrow(); let mut inner = inner.as_ref().unwrap().lock().unwrap(); if let Some(ref mut appsrc) = inner.appsrc { @@ -427,6 +441,6 @@ impl Player for GStreamerPlayer { return Ok(()); } } - Err(()) + Err(BackendError::PlayerEOSFailed) } } diff --git a/examples/player/main.rs b/examples/player/main.rs index faabe669..032b570f 100644 --- a/examples/player/main.rs +++ b/examples/player/main.rs @@ -14,6 +14,7 @@ use gleam::gl; use ipc_channel::ipc; use servo_media::player::frame::{Frame, FrameRenderer}; use servo_media::player::{Player, PlayerEvent}; +use servo_media::Error as ServoMediaError; use servo_media::ServoMedia; use std::env; use std::fs::File; @@ -30,7 +31,7 @@ use webrender::api::*; mod ui; struct PlayerWrapper { - player: Arc>>, + player: Arc>>>, shutdown: Arc, } @@ -40,9 +41,9 @@ impl PlayerWrapper { let player = Arc::new(Mutex::new(servo_media.create_player())); let file = File::open(&path).unwrap(); let metadata = file.metadata().unwrap(); - player.lock().unwrap().set_input_size(metadata.len()); + player.lock().unwrap().set_input_size(metadata.len()).unwrap(); let (sender, receiver) = ipc::channel().unwrap(); - player.lock().unwrap().register_event_handler(sender); + player.lock().unwrap().register_event_handler(sender).unwrap(); let player_ = player.clone(); let player__ = player.clone(); let shutdown = Arc::new(AtomicBool::new(false)); @@ -103,18 +104,18 @@ impl PlayerWrapper { PlayerEvent::FrameUpdated => eprint!("."), } } - player.lock().unwrap().stop(); + player.lock().unwrap().stop().unwrap(); shutdown.store(true, Ordering::Relaxed); }) .unwrap(); - player.lock().unwrap().play(); + player.lock().unwrap().play().unwrap(); PlayerWrapper { player, shutdown } } fn shutdown(&self) { - self.player.lock().unwrap().stop(); + self.player.lock().unwrap().stop().unwrap(); self.shutdown.store(true, Ordering::Relaxed); } @@ -122,7 +123,8 @@ impl PlayerWrapper { self.player .lock() .unwrap() - .register_frame_renderer(renderer); + .register_frame_renderer(renderer) + .unwrap(); } } diff --git a/examples/simple_player.rs b/examples/simple_player.rs index 238742d7..25d9d037 100644 --- a/examples/simple_player.rs +++ b/examples/simple_player.rs @@ -27,7 +27,7 @@ fn run_example(servo_media: Arc) { }; let (sender, receiver) = ipc::channel().unwrap(); - player.lock().unwrap().register_event_handler(sender); + player.lock().unwrap().register_event_handler(sender).unwrap(); let path = Path::new(filename); let display = path.display(); @@ -38,7 +38,7 @@ fn run_example(servo_media: Arc) { }; if let Ok(metadata) = file.metadata() { - player.lock().unwrap().set_input_size(metadata.len()); + player.lock().unwrap().set_input_size(metadata.len()).unwrap(); } let player_clone = Arc::clone(&player); @@ -55,13 +55,11 @@ fn run_example(servo_media: Arc) { break; } Ok(size) => { - if let Err(_) = player + player .lock() .unwrap() .push_data(Vec::from(&buffer[0..size])) - { - break; - } + .unwrap() } Err(e) => { eprintln!("Error: {}", e); @@ -71,7 +69,7 @@ fn run_example(servo_media: Arc) { } }); - player.lock().unwrap().play(); + player.lock().unwrap().play().unwrap(); while let Ok(event) = receiver.recv() { match event { diff --git a/player/src/lib.rs b/player/src/lib.rs index fc059119..944dc613 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -6,6 +6,7 @@ pub mod frame; pub mod metadata; use ipc_channel::ipc::IpcSender; +use std::fmt::Debug; use std::sync::{Arc, Mutex}; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -26,29 +27,31 @@ pub enum PlayerEvent { } pub trait Player: Send { - fn register_event_handler(&self, sender: IpcSender); - fn register_frame_renderer(&self, renderer: Arc>); + type Error: Debug; + fn register_event_handler(&self, sender: IpcSender) -> Result<(), Self::Error>; + fn register_frame_renderer(&self, renderer: Arc>) -> Result<(), Self::Error>; - fn play(&self); - fn pause(&self); - fn stop(&self); + fn play(&self) -> Result<(), Self::Error>; + fn pause(&self) -> Result<(), Self::Error>; + fn stop(&self) -> Result<(), Self::Error>; - fn set_input_size(&self, size: u64); - fn push_data(&self, data: Vec) -> Result<(), ()>; - fn end_of_stream(&self) -> Result<(), ()>; + fn set_input_size(&self, size: u64) -> Result<(), Self::Error>; + fn push_data(&self, data: Vec) -> Result<(), Self::Error>; + fn end_of_stream(&self) -> Result<(), Self::Error>; } pub struct DummyPlayer {} impl Player for DummyPlayer { - fn register_event_handler(&self, _: IpcSender) {} - fn register_frame_renderer(&self, _: Arc>) {} + type Error = (); + fn register_event_handler(&self, _: IpcSender) -> Result<(), ()> { Ok(()) } + fn register_frame_renderer(&self, _: Arc>) -> Result<(), ()> { Ok(()) } - fn play(&self) {} - fn pause(&self) {} - fn stop(&self) {} + fn play(&self) -> Result<(), ()> { Ok(()) } + fn pause(&self) -> Result<(), ()> { Ok(()) } + fn stop(&self) -> Result<(), ()> { Ok(()) } - fn set_input_size(&self, _: u64) {} + fn set_input_size(&self, _: u64) -> Result<(), ()> { Ok(()) } fn push_data(&self, _: Vec) -> Result<(), ()> { Err(()) } diff --git a/servo-media/src/lib.rs b/servo-media/src/lib.rs index d47aa4e2..2748c194 100644 --- a/servo-media/src/lib.rs +++ b/servo-media/src/lib.rs @@ -45,6 +45,11 @@ pub type Backend = servo_media_gstreamer::GStreamerBackend; #[cfg(not(any(target_os = "android", target_arch = "x86_64")))] pub type Backend = DummyBackend; +#[cfg(any(target_os = "android", target_arch = "x86_64"))] +pub type Error = servo_media_gstreamer::BackendError; +#[cfg(not(any(target_os = "android", target_arch = "x86_64")))] +pub type Error = (); + impl ServoMedia { pub fn new() -> Self { Backend::init(); @@ -67,7 +72,7 @@ impl ServoMedia { AudioContext::new(options) } - pub fn create_player(&self) -> Box { + pub fn create_player(&self) -> Box> { Box::new(Backend::make_player()) } } From 49ca2783e7d894d4bd528516c7c09f008fe9cd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Wed, 3 Oct 2018 10:39:32 +0200 Subject: [PATCH 2/3] rustfmt examples --- backends/gstreamer/src/player.rs | 8 +- examples/audio_decoder.rs | 6 +- examples/biquad.rs | 11 ++- examples/channels.rs | 5 +- examples/channelsum.rs | 5 +- examples/offline_context.rs | 21 ++++-- examples/panner.rs | 7 +- examples/params.rs | 5 +- examples/params_connect.rs | 14 ++-- examples/params_connect2.rs | 11 +-- examples/params_settarget.rs | 5 +- examples/play.rs | 5 +- examples/play_noise.rs | 6 +- examples/player/main.rs | 14 +++- examples/player/ui.rs | 125 +++++++++++++++---------------- examples/simple_player.rs | 25 ++++--- 16 files changed, 161 insertions(+), 112 deletions(-) diff --git a/backends/gstreamer/src/player.rs b/backends/gstreamer/src/player.rs index 8984c18a..ca158a40 100644 --- a/backends/gstreamer/src/player.rs +++ b/backends/gstreamer/src/player.rs @@ -369,7 +369,10 @@ impl Player for GStreamerPlayer { Ok(()) } - fn register_frame_renderer(&self, renderer: Arc>) -> Result<(), BackendError> { + fn register_frame_renderer( + &self, + renderer: Arc>, + ) -> Result<(), BackendError> { self.setup()?; let inner = self.inner.borrow(); inner @@ -424,7 +427,8 @@ impl Player for GStreamerPlayer { let inner = self.inner.borrow(); let mut inner = inner.as_ref().unwrap().lock().unwrap(); if let Some(ref mut appsrc) = inner.appsrc { - let buffer = gst::Buffer::from_slice(data).ok_or_else(|| BackendError::PlayerPushDataFailed)?; + let buffer = + gst::Buffer::from_slice(data).ok_or_else(|| BackendError::PlayerPushDataFailed)?; if appsrc.push_buffer(buffer) == gst::FlowReturn::Ok { return Ok(()); } diff --git a/examples/audio_decoder.rs b/examples/audio_decoder.rs index d7601434..011e81d9 100644 --- a/examples/audio_decoder.rs +++ b/examples/audio_decoder.rs @@ -53,8 +53,10 @@ fn run_example(servo_media: Arc) { println!("Decoding audio"); receiver.recv().unwrap(); println!("Audio decoded"); - let buffer_source = - context.create_node(AudioNodeInit::AudioBufferSourceNode(Default::default()), Default::default()); + let buffer_source = context.create_node( + AudioNodeInit::AudioBufferSourceNode(Default::default()), + Default::default(), + ); let dest = context.dest_node(); context.connect_ports(buffer_source.output(0), dest.input(0)); context.message_node( diff --git a/examples/biquad.rs b/examples/biquad.rs index 9691818c..147292c0 100644 --- a/examples/biquad.rs +++ b/examples/biquad.rs @@ -1,8 +1,10 @@ extern crate servo_media; -use servo_media::audio::biquad_filter_node::{BiquadFilterNodeMessage, BiquadFilterNodeOptions, FilterType}; -use servo_media::audio::oscillator_node::OscillatorNodeOptions; +use servo_media::audio::biquad_filter_node::{ + BiquadFilterNodeMessage, BiquadFilterNodeOptions, FilterType, +}; use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage}; +use servo_media::audio::oscillator_node::OscillatorNodeOptions; use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; @@ -43,11 +45,12 @@ fn run_example(servo_media: Arc) { thread::sleep(time::Duration::from_millis(2200)); context.message_node( biquad, - AudioNodeMessage::BiquadFilterNode(BiquadFilterNodeMessage::SetFilterType(FilterType::BandPass)), + AudioNodeMessage::BiquadFilterNode(BiquadFilterNodeMessage::SetFilterType( + FilterType::BandPass, + )), ); thread::sleep(time::Duration::from_millis(1000)); - } fn main() { diff --git a/examples/channels.rs b/examples/channels.rs index 5150b445..816a3b1d 100644 --- a/examples/channels.rs +++ b/examples/channels.rs @@ -17,7 +17,10 @@ fn run_example(servo_media: Arc) { options.gain = 0.7; let gain = context.create_node(AudioNodeInit::GainNode(options), Default::default()); let options = ChannelNodeOptions { channels: 2 }; - let merger = context.create_node(AudioNodeInit::ChannelMergerNode(options), Default::default()); + let merger = context.create_node( + AudioNodeInit::ChannelMergerNode(options), + Default::default(), + ); let dest = context.dest_node(); context.connect_ports(osc.output(0), gain.input(0)); diff --git a/examples/channelsum.rs b/examples/channelsum.rs index b4b92f9f..e7c71d53 100644 --- a/examples/channelsum.rs +++ b/examples/channelsum.rs @@ -20,7 +20,10 @@ fn run_example(servo_media: Arc) { let gain = context.create_node(AudioNodeInit::GainNode(options), Default::default()); let options = ChannelNodeOptions { channels: 2 }; - let merger = context.create_node(AudioNodeInit::ChannelMergerNode(options), Default::default()); + let merger = context.create_node( + AudioNodeInit::ChannelMergerNode(options), + Default::default(), + ); let dest = context.dest_node(); context.connect_ports(osc.output(0), merger.input(0)); diff --git a/examples/offline_context.rs b/examples/offline_context.rs index 33641cb7..9a7fcc08 100644 --- a/examples/offline_context.rs +++ b/examples/offline_context.rs @@ -5,9 +5,9 @@ use servo_media::audio::buffer_source_node::AudioBufferSourceNodeMessage; use servo_media::audio::context::{AudioContextOptions, OfflineAudioContextOptions}; use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage}; use servo_media::ServoMedia; -use std::{thread, time}; -use std::sync::{Arc, Mutex}; use std::sync::mpsc; +use std::sync::{Arc, Mutex}; +use std::{thread, time}; fn run_example(servo_media: Arc) { // Create offline context to process 1024 blocks of a oscillator node produced @@ -22,10 +22,16 @@ fn run_example(servo_media: Arc) { let (sender, receiver) = mpsc::channel(); let sender = Mutex::new(sender); context.set_eos_callback(Box::new(move |buffer| { - processed_audio.lock().unwrap().extend_from_slice((*buffer).as_ref()); + processed_audio + .lock() + .unwrap() + .extend_from_slice((*buffer).as_ref()); sender.lock().unwrap().send(()).unwrap(); })); - let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default()), Default::default()); + let osc = context.create_node( + AudioNodeInit::OscillatorNode(Default::default()), + Default::default(), + ); let dest = context.dest_node(); context.connect_ports(osc.output(0), dest.input(0)); context.message_node( @@ -39,8 +45,10 @@ fn run_example(servo_media: Arc) { let _ = context.close(); // Create audio context to play the processed audio. let context = servo_media.create_audio_context(Default::default()); - let buffer_source = - context.create_node(AudioNodeInit::AudioBufferSourceNode(Default::default()), Default::default()); + let buffer_source = context.create_node( + AudioNodeInit::AudioBufferSourceNode(Default::default()), + Default::default(), + ); let dest = context.dest_node(); context.connect_ports(buffer_source.output(0), dest.input(0)); context.message_node( @@ -56,7 +64,6 @@ fn run_example(servo_media: Arc) { let _ = context.resume(); thread::sleep(time::Duration::from_millis(5000)); let _ = context.close(); - } fn main() { diff --git a/examples/panner.rs b/examples/panner.rs index 1dc217ff..5e6a7bbf 100644 --- a/examples/panner.rs +++ b/examples/panner.rs @@ -1,7 +1,7 @@ extern crate servo_media; -use servo_media::audio::panner_node::PannerNodeOptions; use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage}; +use servo_media::audio::panner_node::PannerNodeOptions; use servo_media::audio::param::{ParamDir, ParamType, RampKind, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; @@ -11,7 +11,10 @@ fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); let dest = context.dest_node(); let listener = context.listener(); - let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default()), Default::default()); + let osc = context.create_node( + AudioNodeInit::OscillatorNode(Default::default()), + Default::default(), + ); let mut options = PannerNodeOptions::default(); options.cone_outer_angle = 0.; options.position_x = 100.; diff --git a/examples/params.rs b/examples/params.rs index 3d2f1943..37d02052 100644 --- a/examples/params.rs +++ b/examples/params.rs @@ -10,7 +10,10 @@ use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); let dest = context.dest_node(); - let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default()), Default::default()); + let osc = context.create_node( + AudioNodeInit::OscillatorNode(Default::default()), + Default::default(), + ); let mut options = GainNodeOptions::default(); options.gain = 0.5; let gain = context.create_node(AudioNodeInit::GainNode(options), Default::default()); diff --git a/examples/params_connect.rs b/examples/params_connect.rs index 9cdd015b..7827325b 100644 --- a/examples/params_connect.rs +++ b/examples/params_connect.rs @@ -1,9 +1,7 @@ extern crate servo_media; +use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage}; use servo_media::audio::oscillator_node::OscillatorNodeOptions; -use servo_media::audio::node::{ - AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage, -}; use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; @@ -14,8 +12,14 @@ fn run_example(servo_media: Arc) { let mut options = OscillatorNodeOptions::default(); options.freq = 2.0; let lfo = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default()); - let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default()), Default::default()); - let gain = context.create_node(AudioNodeInit::GainNode(Default::default()), Default::default()); + let osc = context.create_node( + AudioNodeInit::OscillatorNode(Default::default()), + Default::default(), + ); + let gain = context.create_node( + AudioNodeInit::GainNode(Default::default()), + Default::default(), + ); let dest = context.dest_node(); context.connect_ports(lfo.output(0), gain.param(ParamType::Gain)); context.connect_ports(gain.output(0), dest.input(0)); diff --git a/examples/params_connect2.rs b/examples/params_connect2.rs index e1c54364..27fce8ef 100644 --- a/examples/params_connect2.rs +++ b/examples/params_connect2.rs @@ -1,10 +1,8 @@ extern crate servo_media; -use servo_media::audio::oscillator_node::OscillatorNodeOptions; use servo_media::audio::gain_node::GainNodeOptions; -use servo_media::audio::node::{ - AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage, -}; +use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage, AudioScheduledSourceNodeMessage}; +use servo_media::audio::oscillator_node::OscillatorNodeOptions; use servo_media::audio::param::{ParamType, RampKind, UserAutomationEvent}; use servo_media::ServoMedia; use std::sync::Arc; @@ -15,7 +13,10 @@ fn run_example(servo_media: Arc) { let mut options = OscillatorNodeOptions::default(); options.freq = 2.0; let lfo = context.create_node(AudioNodeInit::OscillatorNode(options), Default::default()); - let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default()), Default::default()); + let osc = context.create_node( + AudioNodeInit::OscillatorNode(Default::default()), + Default::default(), + ); let mut options = GainNodeOptions::default(); options.gain = 100.; let gain = context.create_node(AudioNodeInit::GainNode(options), Default::default()); diff --git a/examples/params_settarget.rs b/examples/params_settarget.rs index 462631ac..fd126003 100644 --- a/examples/params_settarget.rs +++ b/examples/params_settarget.rs @@ -9,7 +9,10 @@ use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); let dest = context.dest_node(); - let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default()), Default::default()); + let osc = context.create_node( + AudioNodeInit::OscillatorNode(Default::default()), + Default::default(), + ); context.connect_ports(osc.output(0), dest.input(0)); let _ = context.resume(); context.message_node( diff --git a/examples/play.rs b/examples/play.rs index c9a05ae7..a12824d6 100644 --- a/examples/play.rs +++ b/examples/play.rs @@ -11,7 +11,10 @@ use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); - let osc = context.create_node(AudioNodeInit::OscillatorNode(Default::default()), Default::default()); + let osc = context.create_node( + AudioNodeInit::OscillatorNode(Default::default()), + Default::default(), + ); let mut options = GainNodeOptions::default(); options.gain = 0.5; let gain = context.create_node(AudioNodeInit::GainNode(options), Default::default()); diff --git a/examples/play_noise.rs b/examples/play_noise.rs index 34045553..58fdec3e 100644 --- a/examples/play_noise.rs +++ b/examples/play_noise.rs @@ -10,8 +10,10 @@ use std::{thread, time}; fn run_example(servo_media: Arc) { let context = servo_media.create_audio_context(Default::default()); - let buffer_source = - context.create_node(AudioNodeInit::AudioBufferSourceNode(Default::default()), Default::default()); + let buffer_source = context.create_node( + AudioNodeInit::AudioBufferSourceNode(Default::default()), + Default::default(), + ); let dest = context.dest_node(); context.connect_ports(buffer_source.output(0), dest.input(0)); let mut buffers = vec![Vec::with_capacity(4096), Vec::with_capacity(4096)]; diff --git a/examples/player/main.rs b/examples/player/main.rs index 032b570f..70d2e336 100644 --- a/examples/player/main.rs +++ b/examples/player/main.rs @@ -31,7 +31,7 @@ use webrender::api::*; mod ui; struct PlayerWrapper { - player: Arc>>>, + player: Arc>>>, shutdown: Arc, } @@ -41,9 +41,17 @@ impl PlayerWrapper { let player = Arc::new(Mutex::new(servo_media.create_player())); let file = File::open(&path).unwrap(); let metadata = file.metadata().unwrap(); - player.lock().unwrap().set_input_size(metadata.len()).unwrap(); + player + .lock() + .unwrap() + .set_input_size(metadata.len()) + .unwrap(); let (sender, receiver) = ipc::channel().unwrap(); - player.lock().unwrap().register_event_handler(sender).unwrap(); + player + .lock() + .unwrap() + .register_event_handler(sender) + .unwrap(); let player_ = player.clone(); let player__ = player.clone(); let shutdown = Arc::new(AtomicBool::new(false)); diff --git a/examples/player/ui.rs b/examples/player/ui.rs index fa89cf14..20b241e8 100644 --- a/examples/player/ui.rs +++ b/examples/player/ui.rs @@ -13,8 +13,8 @@ use std::env; use std::path::PathBuf; use std::sync::{Arc, Mutex}; use webrender; -use winit; use webrender::api::*; +use winit; struct Notifier { events_proxy: winit::EventsLoopProxy, @@ -38,11 +38,13 @@ impl RenderNotifier for Notifier { let _ = self.events_proxy.wakeup(); } - fn new_frame_ready(&self, - _: DocumentId, - _scrolled: bool, - _composite_needed: bool, - _render_time: Option) { + fn new_frame_ready( + &self, + _: DocumentId, + _scrolled: bool, + _composite_needed: bool, + _render_time: Option, + ) { self.wake_up(); } } @@ -84,12 +86,7 @@ pub trait Example { pipeline_id: PipelineId, document_id: DocumentId, ); - fn on_event( - &self, - winit::WindowEvent, - &RenderApi, - DocumentId, - ) -> bool { + fn on_event(&self, winit::WindowEvent, &RenderApi, DocumentId) -> bool { false } fn needs_repaint(&self) -> bool { @@ -98,12 +95,13 @@ pub trait Example { fn get_image_handlers( &self, _gl: &gl::Gl, - ) -> (Option>, - Option>) { + ) -> ( + Option>, + Option>, + ) { (None, None) } - fn draw_custom(&self, _gl: &gl::Gl) { - } + fn draw_custom(&self, _gl: &gl::Gl) {} } pub fn main_wrapper( @@ -120,17 +118,18 @@ pub fn main_wrapper( }; let mut events_loop = winit::EventsLoop::new(); - let context_builder = glutin::ContextBuilder::new() - .with_gl(glutin::GlRequest::GlThenGles { - opengl_version: (3, 2), - opengles_version: (3, 0), - }); + let context_builder = glutin::ContextBuilder::new().with_gl(glutin::GlRequest::GlThenGles { + opengl_version: (3, 2), + opengles_version: (3, 0), + }); let window_builder = winit::WindowBuilder::new() .with_title(E::TITLE) .with_multitouch() - .with_dimensions(winit::dpi::LogicalSize::new(E::WIDTH as f64, E::HEIGHT as f64)); - let window = glutin::GlWindow::new(window_builder, context_builder, &events_loop) - .unwrap(); + .with_dimensions(winit::dpi::LogicalSize::new( + E::WIDTH as f64, + E::HEIGHT as f64, + )); + let window = glutin::GlWindow::new(window_builder, context_builder, &events_loop).unwrap(); unsafe { window.make_current().ok(); @@ -198,13 +197,7 @@ pub fn main_wrapper( pipeline_id, document_id, ); - txn.set_display_list( - epoch, - None, - layout_size, - builder.finalize(), - true, - ); + txn.set_display_list(epoch, None, layout_size, builder.finalize(), true); txn.set_root_pipeline(pipeline_id); txn.generate_frame(); api.send_transaction(document_id, txn); @@ -220,33 +213,44 @@ pub fn main_wrapper( .. } => return winit::ControlFlow::Break, winit::Event::WindowEvent { - event: winit::WindowEvent::KeyboardInput { - input: winit::KeyboardInput { - state: winit::ElementState::Pressed, - virtual_keycode: Some(key), + event: + winit::WindowEvent::KeyboardInput { + input: + winit::KeyboardInput { + state: winit::ElementState::Pressed, + virtual_keycode: Some(key), + .. + }, .. }, - .. - }, .. } => match key { winit::VirtualKeyCode::Escape => return winit::ControlFlow::Break, - winit::VirtualKeyCode::P => renderer.toggle_debug_flags(webrender::DebugFlags::PROFILER_DBG), - winit::VirtualKeyCode::O => renderer.toggle_debug_flags(webrender::DebugFlags::RENDER_TARGET_DBG), - winit::VirtualKeyCode::I => renderer.toggle_debug_flags(webrender::DebugFlags::TEXTURE_CACHE_DBG), - winit::VirtualKeyCode::S => renderer.toggle_debug_flags(webrender::DebugFlags::COMPACT_PROFILER), + winit::VirtualKeyCode::P => { + renderer.toggle_debug_flags(webrender::DebugFlags::PROFILER_DBG) + } + winit::VirtualKeyCode::O => { + renderer.toggle_debug_flags(webrender::DebugFlags::RENDER_TARGET_DBG) + } + winit::VirtualKeyCode::I => { + renderer.toggle_debug_flags(webrender::DebugFlags::TEXTURE_CACHE_DBG) + } + winit::VirtualKeyCode::S => { + renderer.toggle_debug_flags(webrender::DebugFlags::COMPACT_PROFILER) + } winit::VirtualKeyCode::Q => renderer.toggle_debug_flags( - webrender::DebugFlags::GPU_TIME_QUERIES | webrender::DebugFlags::GPU_SAMPLE_QUERIES + webrender::DebugFlags::GPU_TIME_QUERIES + | webrender::DebugFlags::GPU_SAMPLE_QUERIES, ), winit::VirtualKeyCode::Key1 => txn.set_window_parameters( framebuffer_size, DeviceUintRect::new(DeviceUintPoint::zero(), framebuffer_size), - 1.0 + 1.0, ), winit::VirtualKeyCode::Key2 => txn.set_window_parameters( framebuffer_size, DeviceUintRect::new(DeviceUintPoint::zero(), framebuffer_size), - 2.0 + 2.0, ), winit::VirtualKeyCode::M => api.notify_memory_pressure(), #[cfg(feature = "capture")] @@ -256,28 +260,25 @@ pub fn main_wrapper( // based on "shift" modifier, when `glutin` is updated. let bits = CaptureBits::all(); api.save_capture(path, bits); - }, + } _ => { let win_event = match global_event { winit::Event::WindowEvent { event, .. } => event, - _ => unreachable!() + _ => unreachable!(), }; - custom_event = example.lock().unwrap().on_event( - win_event, - &api, - document_id, - ) - }, + custom_event = example + .lock() + .unwrap() + .on_event(win_event, &api, document_id) + } }, - winit::Event::WindowEvent { event, .. } => custom_event = example.lock().unwrap().on_event( - event, - &api, - document_id, - ), + winit::Event::WindowEvent { event, .. } => { + custom_event = example.lock().unwrap().on_event(event, &api, document_id) + } _ => (), }; - if custom_event || example.lock().unwrap().needs_repaint() { + if custom_event || example.lock().unwrap().needs_repaint() { let mut builder = DisplayListBuilder::new(pipeline_id, layout_size); example.lock().unwrap().render( @@ -288,13 +289,7 @@ pub fn main_wrapper( pipeline_id, document_id, ); - txn.set_display_list( - epoch, - None, - layout_size, - builder.finalize(), - true, - ); + txn.set_display_list(epoch, None, layout_size, builder.finalize(), true); txn.generate_frame(); } api.send_transaction(document_id, txn); diff --git a/examples/simple_player.rs b/examples/simple_player.rs index 25d9d037..27a33eb2 100644 --- a/examples/simple_player.rs +++ b/examples/simple_player.rs @@ -27,7 +27,11 @@ fn run_example(servo_media: Arc) { }; let (sender, receiver) = ipc::channel().unwrap(); - player.lock().unwrap().register_event_handler(sender).unwrap(); + player + .lock() + .unwrap() + .register_event_handler(sender) + .unwrap(); let path = Path::new(filename); let display = path.display(); @@ -38,7 +42,11 @@ fn run_example(servo_media: Arc) { }; if let Ok(metadata) = file.metadata() { - player.lock().unwrap().set_input_size(metadata.len()).unwrap(); + player + .lock() + .unwrap() + .set_input_size(metadata.len()) + .unwrap(); } let player_clone = Arc::clone(&player); @@ -54,13 +62,11 @@ fn run_example(servo_media: Arc) { println!("finished pushing data"); break; } - Ok(size) => { - player - .lock() - .unwrap() - .push_data(Vec::from(&buffer[0..size])) - .unwrap() - } + Ok(size) => player + .lock() + .unwrap() + .push_data(Vec::from(&buffer[0..size])) + .unwrap(), Err(e) => { eprintln!("Error: {}", e); break; @@ -102,4 +108,3 @@ fn main() { run_example(servo_media); } } - From 7c83cc7728327fd3f4fab5e143d0d51b1d2b8579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Wed, 3 Oct 2018 11:35:15 +0200 Subject: [PATCH 3/3] Add PlayerError description and improve code readability --- backends/gstreamer/src/lib.rs | 2 +- backends/gstreamer/src/player.rs | 98 ++++++++++++++++---------------- examples/simple_player.rs | 2 +- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/backends/gstreamer/src/lib.rs b/backends/gstreamer/src/lib.rs index bd8aecae..e004b077 100644 --- a/backends/gstreamer/src/lib.rs +++ b/backends/gstreamer/src/lib.rs @@ -32,7 +32,7 @@ pub enum BackendError { PadLinkFailed, PipelineBusError(String), PipelineFailed(&'static str), - PlayerError, // XXX add player error + PlayerError(String), PlayerPushDataFailed, PlayerEOSFailed, PlayerSourceSetupFailed, diff --git a/backends/gstreamer/src/player.rs b/backends/gstreamer/src/player.rs index ca158a40..4abf9d64 100644 --- a/backends/gstreamer/src/player.rs +++ b/backends/gstreamer/src/player.rs @@ -10,6 +10,7 @@ use servo_media_player::frame::{Frame, FrameRenderer}; use servo_media_player::metadata::Metadata; use servo_media_player::{PlaybackState, Player, PlayerEvent}; use std::cell::RefCell; +use std::error::Error; use std::sync::mpsc; use std::sync::{Arc, Mutex}; use std::time; @@ -283,64 +284,65 @@ impl GStreamerPlayer { let sender = Arc::new(Mutex::new(sender)); let sender_clone = sender.clone(); - if pipeline - .connect("source-setup", false, move |args| { - let source = args[1].get::(); - if source.is_none() { - let _ = sender - .lock() - .unwrap() - .send(Err(BackendError::PlayerSourceSetupFailed)); - return None; - } - let source = source.unwrap(); - let mut inner = inner_clone.lock().unwrap(); - let appsrc = source - .clone() - .dynamic_cast::() - .expect("Source element is expected to be an appsrc!"); - - appsrc.set_property_format(gst::Format::Bytes); - if inner.input_size > 0 { - appsrc.set_size(inner.input_size as i64); - } + let connect_result = pipeline.connect("source-setup", false, move |args| { + let source = args[1].get::(); + if source.is_none() { + let _ = sender + .lock() + .unwrap() + .send(Err(BackendError::PlayerSourceSetupFailed)); + return None; + } + let source = source.unwrap(); + let mut inner = inner_clone.lock().unwrap(); + let appsrc = source + .clone() + .dynamic_cast::() + .expect("Source element is expected to be an appsrc!"); + + appsrc.set_property_format(gst::Format::Bytes); + if inner.input_size > 0 { + appsrc.set_size(inner.input_size as i64); + } - let sender_clone = sender.clone(); - - let need_data_id = Arc::new(Mutex::new(None)); - let need_data_id_clone = need_data_id.clone(); - *need_data_id.lock().unwrap() = Some( - appsrc - .connect("need-data", false, move |args| { - let _ = sender_clone.lock().unwrap().send(Ok(())); - if let Some(id) = need_data_id_clone.lock().unwrap().take() { - glib::signal::signal_handler_disconnect( - &args[0].get::().unwrap(), - id, - ); - } - None - }) - .unwrap(), - ); - - inner.set_app_src(appsrc); - - None - }) - .is_err() - { + let sender_clone = sender.clone(); + + let need_data_id = Arc::new(Mutex::new(None)); + let need_data_id_clone = need_data_id.clone(); + *need_data_id.lock().unwrap() = Some( + appsrc + .connect("need-data", false, move |args| { + let _ = sender_clone.lock().unwrap().send(Ok(())); + if let Some(id) = need_data_id_clone.lock().unwrap().take() { + glib::signal::signal_handler_disconnect( + &args[0].get::().unwrap(), + id, + ); + } + None + }) + .unwrap(), + ); + + inner.set_app_src(appsrc); + + None + }); + + if connect_result.is_err() { let _ = sender_clone .lock() .unwrap() .send(Err(BackendError::PlayerSourceSetupFailed)); } - let error_handler_id = inner.player.connect_error(move |player, _error| { + let error_handler_id = inner.player.connect_error(move |player, error| { let _ = sender_clone .lock() .unwrap() - .send(Err(BackendError::PlayerError)); + .send(Err(BackendError::PlayerError( + error.description().to_string(), + ))); player.stop(); }); diff --git a/examples/simple_player.rs b/examples/simple_player.rs index 27a33eb2..8f5e6c80 100644 --- a/examples/simple_player.rs +++ b/examples/simple_player.rs @@ -100,7 +100,7 @@ fn run_example(servo_media: Arc) { shutdown.store(true, Ordering::Relaxed); let _ = t.join(); - player.lock().unwrap().stop(); + player.lock().unwrap().stop().unwrap(); } fn main() {