diff --git a/Cargo.lock b/Cargo.lock index 7fa4aa93..4ccc7914 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,7 +83,7 @@ name = "examples" version = "0.1.0" dependencies = [ "rand 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "servo_media 0.1.0", + "servo-media 0.1.0", ] [[package]] @@ -420,7 +420,26 @@ dependencies = [ ] [[package]] -name = "servo_media" +name = "servo-media" +version = "0.1.0" +dependencies = [ + "servo-media-audio 0.1.0", + "servo-media-gstreamer 0.1.0", +] + +[[package]] +name = "servo-media-audio" +version = "0.1.0" +dependencies = [ + "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_media_derive 0.1.0", + "smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "servo-media-gstreamer" version = "0.1.0" dependencies = [ "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -428,10 +447,8 @@ dependencies = [ "gstreamer-app 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-audio 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "servo_media_derive 0.1.0", - "smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "servo-media-audio 0.1.0", "zip 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index 07f18d87..c267ce76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] -members = ["servo-media", "servo-media-derive", "examples"] +members = ["servo-media", "servo-media-derive", "audio", "backends/gstreamer", "examples"] license = "MPL-2.0" diff --git a/audio/Cargo.toml b/audio/Cargo.toml new file mode 100644 index 00000000..bd82c711 --- /dev/null +++ b/audio/Cargo.toml @@ -0,0 +1,24 @@ +[package] +authors = ["Fernando Jiménez Moreno "] +license = "MPL-2.0" +name = "servo-media-audio" +version = "0.1.0" + + +[lib] +name = "servo_media_audio" + +[dependencies] +smallvec = "0.6.1" +servo_media_derive = { path = "../servo-media-derive" } + +[dependencies.petgraph] +version = "0.4.12" +features = ["stable_graph"] + +[dependencies.byte-slice-cast] +version = "0.1" + + +[dependencies.num-traits] +version = "0.1" diff --git a/servo-media/src/audio/block.rs b/audio/src/block.rs similarity index 99% rename from servo-media/src/audio/block.rs rename to audio/src/block.rs index fcc2288a..ffa1f803 100644 --- a/servo-media/src/audio/block.rs +++ b/audio/src/block.rs @@ -1,6 +1,6 @@ use std::f32::consts::SQRT_2; -use audio::node::ChannelInterpretation; -use audio::graph::PortIndex; +use node::ChannelInterpretation; +use graph::PortIndex; use byte_slice_cast::*; use smallvec::SmallVec; use std::ops::*; diff --git a/servo-media/src/audio/buffer_source_node.rs b/audio/src/buffer_source_node.rs similarity index 96% rename from servo-media/src/audio/buffer_source_node.rs rename to audio/src/buffer_source_node.rs index 3b7a2dcb..d8fd2fcf 100644 --- a/servo-media/src/audio/buffer_source_node.rs +++ b/audio/src/buffer_source_node.rs @@ -1,7 +1,7 @@ -use audio::node::{AudioNodeType, ChannelInfo}; -use audio::block::{Block, Chunk, Tick, FRAMES_PER_BLOCK}; -use audio::node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; -use audio::param::{Param, ParamType}; +use node::{AudioNodeType, ChannelInfo}; +use block::{Block, Chunk, Tick, FRAMES_PER_BLOCK}; +use node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; +use param::{Param, ParamType}; /// Control messages directed to AudioBufferSourceNodes. #[derive(Debug, Clone)] diff --git a/servo-media/src/audio/channel_node.rs b/audio/src/channel_node.rs similarity index 92% rename from servo-media/src/audio/channel_node.rs rename to audio/src/channel_node.rs index 4d3b126b..5ad7548a 100644 --- a/servo-media/src/audio/channel_node.rs +++ b/audio/src/channel_node.rs @@ -1,8 +1,8 @@ -use audio::block::FRAMES_PER_BLOCK_USIZE; -use audio::node::AudioNodeType; -use audio::node::{AudioNodeEngine, ChannelCountMode, ChannelInfo, ChannelInterpretation}; -use audio::block::{Block, Chunk}; -use audio::node::BlockInfo; +use block::FRAMES_PER_BLOCK_USIZE; +use node::AudioNodeType; +use node::{AudioNodeEngine, ChannelCountMode, ChannelInfo, ChannelInterpretation}; +use block::{Block, Chunk}; +use node::BlockInfo; #[derive(Copy, Clone, Debug)] pub struct ChannelNodeOptions { diff --git a/servo-media/src/audio/context.rs b/audio/src/context.rs similarity index 89% rename from servo-media/src/audio/context.rs rename to audio/src/context.rs index 5ff64e18..c9f61e14 100644 --- a/servo-media/src/audio/context.rs +++ b/audio/src/context.rs @@ -1,18 +1,14 @@ -use audio::decoder::{AudioDecoder, AudioDecoderCallbacks, AudioDecoderOptions}; -use audio::graph::{AudioGraph, InputPort, NodeId, OutputPort, PortId}; -use audio::node::{AudioNodeMessage, AudioNodeInit}; -use audio::render_thread::AudioRenderThread; -use audio::render_thread::AudioRenderThreadMsg; +use AudioBackend; +use std::marker::PhantomData; +use decoder::{AudioDecoder, AudioDecoderCallbacks, AudioDecoderOptions}; +use graph::{AudioGraph, InputPort, NodeId, OutputPort, PortId}; +use node::{AudioNodeMessage, AudioNodeInit}; +use render_thread::AudioRenderThread; +use render_thread::AudioRenderThreadMsg; use std::cell::Cell; use std::sync::mpsc::{self, Sender}; use std::thread::Builder; -#[cfg(feature = "gst")] -use backends::gstreamer::audio_decoder::GStreamerAudioDecoder; - -#[cfg(not(feature = "gst"))] -use backends::dummy::audio_decoder::DummyAudioDecoder; - /// Describes the state of the audio context on the control thread. #[derive(Clone, Copy, Debug, PartialEq)] pub enum ProcessingState { @@ -102,7 +98,7 @@ impl Default for AudioContextOptions { } /// Representation of an audio context on the control thread. -pub struct AudioContext { +pub struct AudioContext { /// Rendering thread communication channel. sender: Sender, /// State of the audio context on the control thread. @@ -112,9 +108,10 @@ pub struct AudioContext { /// The identifier of an AudioDestinationNode with a single input /// representing the final destination for all audio. dest_node: NodeId, + backend: PhantomData, } -impl AudioContext { +impl AudioContext { /// Constructs a new audio context. pub fn new(options: AudioContextOptions) -> Self { let options = match options { @@ -130,7 +127,7 @@ impl AudioContext { Builder::new() .name("AudioRenderThread".to_owned()) .spawn(move || { - AudioRenderThread::start(receiver, sender_, options.sample_rate, graph) + AudioRenderThread::::start(receiver, sender_, options.sample_rate, graph) .expect("Could not start AudioRenderThread"); }) .unwrap(); @@ -139,6 +136,7 @@ impl AudioContext { state: Cell::new(ProcessingState::Suspended), sample_rate, dest_node, + backend: PhantomData, } } @@ -227,11 +225,7 @@ impl AudioContext { Builder::new() .name("AudioDecoder".to_owned()) .spawn(move || { - #[cfg(not(feature = "gst"))] - let audio_decoder = DummyAudioDecoder {}; - - #[cfg(feature = "gst")] - let audio_decoder = GStreamerAudioDecoder::new(); + let audio_decoder = B::make_decoder(); audio_decoder.decode(data, callbacks, Some(options)); }) @@ -239,7 +233,7 @@ impl AudioContext { } } -impl Drop for AudioContext { +impl Drop for AudioContext { fn drop(&mut self) { let (tx, _) = mpsc::channel(); let _ = self.sender.send(AudioRenderThreadMsg::Close(tx)); diff --git a/servo-media/src/audio/decoder.rs b/audio/src/decoder.rs similarity index 93% rename from servo-media/src/audio/decoder.rs rename to audio/src/decoder.rs index d82689be..74e1f91b 100644 --- a/servo-media/src/audio/decoder.rs +++ b/audio/src/decoder.rs @@ -96,3 +96,9 @@ impl Default for AudioDecoderOptions { pub trait AudioDecoder { fn decode(&self, data: Vec, callbacks: AudioDecoderCallbacks, options: Option); } + +pub struct DummyAudioDecoder; + +impl AudioDecoder for DummyAudioDecoder { + fn decode(&self, _: Vec, _: AudioDecoderCallbacks, _: Option) {} +} diff --git a/servo-media/src/audio/destination_node.rs b/audio/src/destination_node.rs similarity index 87% rename from servo-media/src/audio/destination_node.rs rename to audio/src/destination_node.rs index 7fe3757e..a4ac02cc 100644 --- a/servo-media/src/audio/destination_node.rs +++ b/audio/src/destination_node.rs @@ -1,6 +1,6 @@ -use audio::node::{AudioNodeType, ChannelCountMode, ChannelInfo}; -use audio::node::{AudioNodeEngine, BlockInfo}; -use audio::block::Chunk; +use node::{AudioNodeType, ChannelCountMode, ChannelInfo}; +use node::{AudioNodeEngine, BlockInfo}; +use block::Chunk; #[derive(AudioNodeCommon)] pub(crate) struct DestinationNode { diff --git a/servo-media/src/audio/gain_node.rs b/audio/src/gain_node.rs similarity index 88% rename from servo-media/src/audio/gain_node.rs rename to audio/src/gain_node.rs index 498fd3db..b06554ca 100644 --- a/servo-media/src/audio/gain_node.rs +++ b/audio/src/gain_node.rs @@ -1,9 +1,9 @@ -use audio::node::{AudioNodeType, ChannelInfo}; -use audio::block::Chunk; -use audio::block::Tick; -use audio::node::AudioNodeEngine; -use audio::node::BlockInfo; -use audio::param::{Param, ParamType}; +use node::{AudioNodeType, ChannelInfo}; +use block::Chunk; +use block::Tick; +use node::AudioNodeEngine; +use node::BlockInfo; +use param::{Param, ParamType}; #[derive(Copy, Clone, Debug)] pub struct GainNodeOptions { diff --git a/servo-media/src/audio/graph.rs b/audio/src/graph.rs similarity index 99% rename from servo-media/src/audio/graph.rs rename to audio/src/graph.rs index efdb08ee..dd56d87b 100644 --- a/servo-media/src/audio/graph.rs +++ b/audio/src/graph.rs @@ -1,7 +1,7 @@ use smallvec::SmallVec; -use audio::block::{Block, Chunk}; -use audio::destination_node::DestinationNode; -use audio::node::{AudioNodeEngine, BlockInfo, ChannelCountMode}; +use block::{Block, Chunk}; +use destination_node::DestinationNode; +use node::{AudioNodeEngine, BlockInfo, ChannelCountMode}; use petgraph::Direction; use petgraph::graph::DefaultIx; use petgraph::stable_graph::NodeIndex; diff --git a/audio/src/lib.rs b/audio/src/lib.rs new file mode 100644 index 00000000..22315543 --- /dev/null +++ b/audio/src/lib.rs @@ -0,0 +1,49 @@ +#![feature(fnbox)] + +#[macro_use] +extern crate servo_media_derive; + +extern crate byte_slice_cast; +extern crate num_traits; +extern crate petgraph; +extern crate smallvec; +#[macro_use] +pub mod macros; + +pub mod block; +pub mod buffer_source_node; +pub mod channel_node; +pub mod context; +pub mod decoder; +pub mod destination_node; +pub mod gain_node; +pub mod graph; +pub mod node; +pub mod oscillator_node; +pub mod param; +pub mod render_thread; +pub mod sink; + + +pub trait AudioBackend { + type Decoder: decoder::AudioDecoder; + type Sink: sink::AudioSink; + fn make_decoder() -> Self::Decoder; + fn make_sink() -> Result; + fn init(); +} + +pub struct DummyBackend {} + +impl AudioBackend for DummyBackend { + type Decoder = decoder::DummyAudioDecoder; + type Sink = sink::DummyAudioSink; + fn make_decoder() -> Self::Decoder { + decoder::DummyAudioDecoder + } + + fn make_sink() -> Result { + Ok(sink::DummyAudioSink) + } + fn init() {} +} \ No newline at end of file diff --git a/servo-media/src/audio/macros.rs b/audio/src/macros.rs similarity index 83% rename from servo-media/src/audio/macros.rs rename to audio/src/macros.rs index 74dae718..a7ff531c 100644 --- a/servo-media/src/audio/macros.rs +++ b/audio/src/macros.rs @@ -5,9 +5,9 @@ macro_rules! make_message_handler( $node:ident: $handler:ident ),+ ) => ( - fn message_specific(&mut self, msg: ::audio::node::AudioNodeMessage, sample_rate: f32) { + fn message_specific(&mut self, msg: ::node::AudioNodeMessage, sample_rate: f32) { match msg { - $(::audio::node::AudioNodeMessage::$node(m) => self.$handler(m, sample_rate)),+, + $(::node::AudioNodeMessage::$node(m) => self.$handler(m, sample_rate)),+, _ => (), } } diff --git a/audio/src/mod.rs b/audio/src/mod.rs new file mode 100644 index 00000000..e69de29b diff --git a/servo-media/src/audio/node.rs b/audio/src/node.rs similarity index 94% rename from servo-media/src/audio/node.rs rename to audio/src/node.rs index 61bba7d8..70422a13 100644 --- a/servo-media/src/audio/node.rs +++ b/audio/src/node.rs @@ -1,10 +1,10 @@ -use audio::param::{Param, ParamType, ParamRate, UserAutomationEvent}; -use audio::channel_node::ChannelNodeOptions; -use audio::block::{Chunk, Tick}; -use audio::buffer_source_node::{AudioBufferSourceNodeMessage, AudioBufferSourceNodeOptions}; -use audio::gain_node::GainNodeOptions; -use audio::oscillator_node::OscillatorNodeOptions; use std::sync::mpsc::Sender; +use param::{Param, ParamRate, ParamType, UserAutomationEvent}; +use channel_node::ChannelNodeOptions; +use block::{Chunk, Tick}; +use buffer_source_node::{AudioBufferSourceNodeMessage, AudioBufferSourceNodeOptions}; +use gain_node::GainNodeOptions; +use oscillator_node::OscillatorNodeOptions; /// Information required to construct an audio node #[derive(Debug, Clone)] diff --git a/servo-media/src/audio/oscillator_node.rs b/audio/src/oscillator_node.rs similarity index 95% rename from servo-media/src/audio/oscillator_node.rs rename to audio/src/oscillator_node.rs index 2b7b7515..789bfcf7 100644 --- a/servo-media/src/audio/oscillator_node.rs +++ b/audio/src/oscillator_node.rs @@ -1,7 +1,7 @@ -use audio::node::{AudioNodeType, ChannelInfo}; -use audio::block::{Chunk, Tick}; -use audio::node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; -use audio::param::{Param, ParamType}; +use node::{AudioNodeType, ChannelInfo}; +use block::{Chunk, Tick}; +use node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, BlockInfo}; +use param::{Param, ParamType}; use num_traits::cast::NumCast; #[derive(Copy, Clone, Debug)] diff --git a/servo-media/src/audio/param.rs b/audio/src/param.rs similarity index 99% rename from servo-media/src/audio/param.rs rename to audio/src/param.rs index 6018f8e7..1b3f26b1 100644 --- a/servo-media/src/audio/param.rs +++ b/audio/src/param.rs @@ -1,5 +1,5 @@ -use audio::block::Tick; -use audio::node::BlockInfo; +use block::Tick; +use node::BlockInfo; #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] pub enum ParamType { diff --git a/servo-media/src/audio/render_thread.rs b/audio/src/render_thread.rs similarity index 87% rename from servo-media/src/audio/render_thread.rs rename to audio/src/render_thread.rs index 75eeab8b..5994a285 100644 --- a/servo-media/src/audio/render_thread.rs +++ b/audio/src/render_thread.rs @@ -1,22 +1,17 @@ -use audio::block::{Chunk, Tick, FRAMES_PER_BLOCK}; -use audio::buffer_source_node::AudioBufferSourceNode; -use audio::channel_node::{ChannelMergerNode, ChannelSplitterNode}; -use audio::context::{ProcessingState, StateChangeResult}; -use audio::destination_node::DestinationNode; -use audio::gain_node::GainNode; -use audio::graph::{AudioGraph, InputPort, NodeId, OutputPort, PortId}; -use audio::node::BlockInfo; -use audio::node::{AudioNodeEngine, AudioNodeInit, AudioNodeMessage}; -use audio::oscillator_node::OscillatorNode; -use audio::sink::AudioSink; +use AudioBackend; +use block::{Chunk, Tick, FRAMES_PER_BLOCK}; +use buffer_source_node::AudioBufferSourceNode; +use channel_node::{ChannelMergerNode, ChannelSplitterNode}; +use context::{ProcessingState, StateChangeResult}; +use destination_node::DestinationNode; +use gain_node::GainNode; +use graph::{AudioGraph, InputPort, NodeId, OutputPort, PortId}; +use node::BlockInfo; +use node::{AudioNodeEngine, AudioNodeInit, AudioNodeMessage}; +use oscillator_node::OscillatorNode; +use sink::AudioSink; use std::sync::mpsc::{Receiver, Sender}; -#[cfg(feature = "gst")] -use backends::gstreamer::audio_sink::GStreamerAudioSink; - -#[cfg(not(feature = "gst"))] -use backends::dummy::audio_sink::DummyAudioSink; - #[derive(Debug)] pub enum AudioRenderThreadMsg { CreateNode(AudioNodeInit, Sender), @@ -35,16 +30,16 @@ pub enum AudioRenderThreadMsg { DisconnectOutputBetweenTo(PortId, PortId), } -pub struct AudioRenderThread { +pub struct AudioRenderThread { pub graph: AudioGraph, - pub sink: Box, + pub sink: B::Sink, pub state: ProcessingState, pub sample_rate: f32, pub current_time: f64, pub current_frame: Tick, } -impl AudioRenderThread { +impl AudioRenderThread { /// Start the audio render thread pub fn start( event_queue: Receiver, @@ -52,15 +47,12 @@ impl AudioRenderThread { sample_rate: f32, graph: AudioGraph, ) -> Result<(), ()> { - #[cfg(not(feature = "gst"))] - let sink = DummyAudioSink {}; - #[cfg(feature = "gst")] - let sink = GStreamerAudioSink::new()?; + let sink = B::make_sink()?; let mut graph = Self { graph, - sink: Box::new(sink), + sink, state: ProcessingState::Suspended, sample_rate, current_time: 0., diff --git a/audio/src/sink.rs b/audio/src/sink.rs new file mode 100644 index 00000000..5047294f --- /dev/null +++ b/audio/src/sink.rs @@ -0,0 +1,35 @@ +use block::Chunk; +use render_thread::AudioRenderThreadMsg; +use std::sync::mpsc::Sender; + +pub trait AudioSink { + fn init( + &self, + sample_rate: f32, + render_thread_channel: Sender, + ) -> Result<(), ()>; + fn play(&self) -> Result<(), ()>; + fn stop(&self) -> Result<(), ()>; + fn has_enough_data(&self) -> bool; + fn push_data(&self, chunk: Chunk) -> Result<(), ()>; +} + +pub struct DummyAudioSink; + +impl AudioSink for DummyAudioSink { + fn init(&self, _: f32, _: Sender) -> Result<(), ()> { + Ok(()) + } + fn play(&self) -> Result<(), ()> { + Ok(()) + } + fn stop(&self) -> Result<(), ()> { + Ok(()) + } + fn has_enough_data(&self) -> bool { + true + } + fn push_data(&self, _: Chunk) -> Result<(), ()> { + Ok(()) + } +} diff --git a/backends/gstreamer/Cargo.toml b/backends/gstreamer/Cargo.toml new file mode 100644 index 00000000..6e6de856 --- /dev/null +++ b/backends/gstreamer/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "servo-media-gstreamer" +version = "0.1.0" +authors = ["Manish Goregaokar "] + + +[build-dependencies] +regex = "1.0" +zip = "0.3.1" + +[dependencies.byte-slice-cast] +version = "0.1" + +[dependencies.gstreamer] +version = "0.11" + +[dependencies.gstreamer-app] +version = "0.11.2" + +[dependencies.gstreamer-audio] +version = "0.11" + +[dependencies.num-traits] +version = "0.1" + +[dependencies.servo-media-audio] +path = "../../audio" diff --git a/servo-media/build.rs b/backends/gstreamer/build.rs similarity index 100% rename from servo-media/build.rs rename to backends/gstreamer/build.rs diff --git a/servo-media/src/backends/gstreamer/audio_decoder.rs b/backends/gstreamer/src/audio_decoder.rs similarity index 98% rename from servo-media/src/backends/gstreamer/audio_decoder.rs rename to backends/gstreamer/src/audio_decoder.rs index d1cca275..44cc7a16 100644 --- a/servo-media/src/backends/gstreamer/audio_decoder.rs +++ b/backends/gstreamer/src/audio_decoder.rs @@ -1,6 +1,6 @@ use super::gst_app::{AppSink, AppSinkCallbacks, AppSrc}; use super::gst_audio; -use audio::decoder::{AudioDecoder, AudioDecoderCallbacks, AudioDecoderOptions}; +use servo_media_audio::decoder::{AudioDecoder, AudioDecoderCallbacks, AudioDecoderOptions}; use byte_slice_cast::*; use gst; use gst::buffer::{MappedBuffer, Readable}; diff --git a/servo-media/src/backends/gstreamer/audio_sink.rs b/backends/gstreamer/src/audio_sink.rs similarity index 96% rename from servo-media/src/backends/gstreamer/audio_sink.rs rename to backends/gstreamer/src/audio_sink.rs index 686dd84b..ea8718a1 100644 --- a/servo-media/src/backends/gstreamer/audio_sink.rs +++ b/backends/gstreamer/src/audio_sink.rs @@ -1,8 +1,8 @@ -use super::gst_app::{AppSrc, AppSrcCallbacks}; -use super::gst_audio; -use audio::block::{Chunk, FRAMES_PER_BLOCK}; -use audio::render_thread::AudioRenderThreadMsg; -use audio::sink::AudioSink; +use gst_app::{AppSrc, AppSrcCallbacks}; +use gst_audio; +use servo_media_audio::block::{Chunk, FRAMES_PER_BLOCK}; +use servo_media_audio::render_thread::AudioRenderThreadMsg; +use servo_media_audio::sink::AudioSink; use byte_slice_cast::*; use gst; use gst::prelude::*; diff --git a/backends/gstreamer/src/lib.rs b/backends/gstreamer/src/lib.rs new file mode 100644 index 00000000..83d43fcd --- /dev/null +++ b/backends/gstreamer/src/lib.rs @@ -0,0 +1,31 @@ + + +extern crate gstreamer_app as gst_app; +extern crate gstreamer_audio as gst_audio; +extern crate gstreamer as gst; + +extern crate servo_media_audio; + +extern crate num_traits; +extern crate byte_slice_cast; + +use servo_media_audio::AudioBackend; + +pub mod audio_decoder; +pub mod audio_sink; + +pub struct GStreamerBackend; + +impl AudioBackend for GStreamerBackend { + type Decoder = audio_decoder::GStreamerAudioDecoder; + type Sink = audio_sink::GStreamerAudioSink; + fn make_decoder() -> Self::Decoder { + audio_decoder::GStreamerAudioDecoder::new() + } + fn make_sink() -> Result { + audio_sink::GStreamerAudioSink::new() + } + fn init() { + gst::init().unwrap(); + } +} \ No newline at end of file diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 2ea07b87..d9f6e17e 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -5,7 +5,7 @@ license = "MPL-2.0" [dependencies] rand = "0.5.0" -servo_media = { path = "../servo-media", features = ["gst"] } +servo-media = { path = "../servo-media" } [[bin]] name = "audio_decoder" diff --git a/servo-media-derive/src/lib.rs b/servo-media-derive/src/lib.rs index b01bbece..6cf94863 100644 --- a/servo-media-derive/src/lib.rs +++ b/servo-media-derive/src/lib.rs @@ -16,7 +16,7 @@ pub fn audio_scheduled_source_node(input: TokenStream) -> TokenStream { fn impl_audio_scheduled_source_node(ast: &syn::DeriveInput) -> quote::Tokens { let name = &ast.ident; quote! { - use audio::node::AudioScheduledSourceNode; + use node::AudioScheduledSourceNode; impl #name { pub fn should_play_at(&self, tick: Tick) -> (bool, bool) { @@ -68,12 +68,12 @@ pub fn channel_info(input: TokenStream) -> TokenStream { let ast = syn::parse_derive_input(&s).unwrap(); let name = &ast.ident; let gen = quote! { - impl ::audio::node::AudioNodeCommon for #name { - fn channel_info(&self) -> &::audio::node::ChannelInfo { + impl ::node::AudioNodeCommon for #name { + fn channel_info(&self) -> &::node::ChannelInfo { &self.channel_info } - fn channel_info_mut(&mut self) -> &mut ::audio::node::ChannelInfo { + fn channel_info_mut(&mut self) -> &mut ::node::ChannelInfo { &mut self.channel_info } } diff --git a/servo-media/Cargo.toml b/servo-media/Cargo.toml index 6868fd9d..7b916c92 100644 --- a/servo-media/Cargo.toml +++ b/servo-media/Cargo.toml @@ -1,38 +1,14 @@ [package] -authors = ["Fernando Jiménez Moreno "] -license = "MPL-2.0" -name = "servo_media" +name = "servo-media" version = "0.1.0" +authors = ["Manish Goregaokar "] -[build-dependencies] -regex = "1.0" -zip = "0.3.1" - -[dependencies] -byte-slice-cast = "0.1" -num-traits = "0.1" -smallvec = "0.6.1" -servo_media_derive = { path = "../servo-media-derive" } - -[dependencies.petgraph] -version = "0.4.12" -features = ["stable_graph"] - -[dependencies.gstreamer] -optional = true -version = "0.11" - -[dependencies.gstreamer-app] -optional = true -version = "0.11.2" +[lib] +name = "servo_media" -[dependencies.gstreamer-audio] -optional = true -version = "0.11" +[dependencies.servo-media-audio] +path = "../audio" -[features] -default = [] -gst = ["gstreamer", "gstreamer-audio", "gstreamer-app"] -[lib] -name = "servo_media" +[target.'cfg(not(target_os = "android"))'.dependencies.servo-media-gstreamer] +path = "../backends/gstreamer" diff --git a/servo-media/src/audio/mod.rs b/servo-media/src/audio/mod.rs deleted file mode 100644 index 8bc2e32e..00000000 --- a/servo-media/src/audio/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[macro_use] -pub mod macros; - -pub mod block; -pub mod buffer_source_node; -pub mod channel_node; -pub mod context; -pub mod decoder; -pub mod destination_node; -pub mod gain_node; -pub mod graph; -pub mod node; -pub mod oscillator_node; -pub mod param; -pub mod render_thread; -pub mod sink; diff --git a/servo-media/src/audio/sink.rs b/servo-media/src/audio/sink.rs deleted file mode 100644 index d0ee3450..00000000 --- a/servo-media/src/audio/sink.rs +++ /dev/null @@ -1,15 +0,0 @@ -use audio::block::Chunk; -use audio::render_thread::AudioRenderThreadMsg; -use std::sync::mpsc::Sender; - -pub trait AudioSink { - fn init( - &self, - sample_rate: f32, - render_thread_channel: Sender, - ) -> Result<(), ()>; - fn play(&self) -> Result<(), ()>; - fn stop(&self) -> Result<(), ()>; - fn has_enough_data(&self) -> bool; - fn push_data(&self, chunk: Chunk) -> Result<(), ()>; -} diff --git a/servo-media/src/backends/gstreamer/mod.rs b/servo-media/src/backends/gstreamer/mod.rs deleted file mode 100644 index aab71930..00000000 --- a/servo-media/src/backends/gstreamer/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -extern crate gstreamer_app as gst_app; -extern crate gstreamer_audio as gst_audio; - -pub mod audio_decoder; -pub mod audio_sink; diff --git a/servo-media/src/backends/mod.rs b/servo-media/src/backends/mod.rs deleted file mode 100644 index c1cac4a6..00000000 --- a/servo-media/src/backends/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[cfg(not(feature = "gst"))] -pub mod dummy; -#[cfg(feature = "gst")] -pub mod gstreamer; diff --git a/servo-media/src/lib.rs b/servo-media/src/lib.rs index 7fd0df29..6b4d6853 100644 --- a/servo-media/src/lib.rs +++ b/servo-media/src/lib.rs @@ -1,35 +1,26 @@ -#![feature(fnbox)] - +pub extern crate servo_media_audio as audio; +#[cfg(not(target_os = "android"))] +extern crate servo_media_gstreamer; use std::sync::{self, Once}; use std::sync::{Arc, Mutex}; -#[macro_use] -extern crate servo_media_derive; - -#[cfg(feature = "gst")] -extern crate gstreamer as gst; - -extern crate byte_slice_cast; -extern crate num_traits; - -extern crate petgraph; -extern crate smallvec; - -#[macro_use] -pub mod audio; -mod backends; +use audio::AudioBackend; use audio::context::{AudioContext, AudioContextOptions}; -pub struct ServoMedia {} +pub struct ServoMedia; static INITIALIZER: Once = sync::ONCE_INIT; static mut INSTANCE: *mut Mutex>> = 0 as *mut _; +#[cfg(not(target_os = "android"))] +pub type Backend = servo_media_gstreamer::GStreamerBackend; +#[cfg(target_os = "android")] +pub type Backend = audio::DummyBackend; + impl ServoMedia { pub fn new() -> Self { - #[cfg(feature = "gst")] - gst::init().unwrap(); + Backend::init(); Self {} } @@ -45,7 +36,8 @@ impl ServoMedia { } } - pub fn create_audio_context(&self, options: AudioContextOptions) -> AudioContext { + + pub fn create_audio_context(&self, options: AudioContextOptions) -> AudioContext { AudioContext::new(options) } }