Skip to content

Commit

Permalink
Upgrade to gstreamer-rs 0.15
Browse files Browse the repository at this point in the history
Fixes: #326
  • Loading branch information
ceyusa committed Jan 14, 2020
1 parent f6d62ea commit 4491e75
Show file tree
Hide file tree
Showing 18 changed files with 318 additions and 237 deletions.
320 changes: 198 additions & 122 deletions Cargo.lock

Large diffs are not rendered by default.

19 changes: 9 additions & 10 deletions backends/gstreamer/Cargo.toml
Expand Up @@ -21,7 +21,7 @@ log = "0.4"
version = "0.2"

[dependencies.glib]
version = "0.8"
version = "0.9"

[dependencies.glib-sys]
version = "0.9"
Expand All @@ -31,29 +31,28 @@ version = "0.8"
features = ["v1_8"]

[dependencies.gstreamer]
version = "0.14"
features = ["subclassing"]
version = "0.15"

[dependencies.gstreamer-app]
version = "0.14"
version = "0.15"

[dependencies.gstreamer-audio]
version = "0.14"
version = "0.15"

[dependencies.gstreamer-base]
version = "0.14"
version = "0.15"

[dependencies.gstreamer-player]
version = "0.14"
version = "0.15"

[dependencies.gstreamer-sdp]
version = "0.14"
version = "0.15"

[dependencies.gstreamer-webrtc]
version = "0.14"
version = "0.15"

[dependencies.gstreamer-video]
version = "0.14"
version = "0.15"

[dependencies.ipc-channel]
version = "0.12"
Expand Down
56 changes: 28 additions & 28 deletions backends/gstreamer/audio_decoder.rs
Expand Up @@ -36,17 +36,17 @@ impl AudioDecoder for GStreamerAudioDecoder {
let callbacks = Arc::new(callbacks);

let appsrc = match gst::ElementFactory::make("appsrc", None) {
Some(appsrc) => appsrc,
None => {
Ok(appsrc) => appsrc,
_ => {
return callbacks.error(AudioDecoderError::Backend(
"appsrc creation failed".to_owned(),
));
}
};

let decodebin = match gst::ElementFactory::make("decodebin", None) {
Some(decodebin) => decodebin,
None => {
Ok(decodebin) => decodebin,
_ => {
return callbacks.error(AudioDecoderError::Backend(
"decodebin creation failed".to_owned(),
));
Expand Down Expand Up @@ -133,8 +133,8 @@ impl AudioDecoder for GStreamerAudioDecoder {
}

let sample_audio_info = match gst_audio::AudioInfo::from_caps(&caps) {
Some(sample_audio_info) => sample_audio_info,
None => {
Ok(sample_audio_info) => sample_audio_info,
_ => {
callbacks.error(AudioDecoderError::Backend("AudioInfo failed".to_owned()));
let _ = sender.lock().unwrap().send(());
return;
Expand All @@ -144,22 +144,22 @@ impl AudioDecoder for GStreamerAudioDecoder {
callbacks.ready(channels);

let insert_deinterleave = || -> Result<(), AudioDecoderError> {
let convert = gst::ElementFactory::make("audioconvert", None).ok_or(
AudioDecoderError::Backend("audioconvert creation failed".to_owned()),
)?;
let convert = gst::ElementFactory::make("audioconvert", None).map_err(|_| {
AudioDecoderError::Backend("audioconvert creation failed".to_owned())
})?;
convert
.set_property("mix-matrix", &gst::Array::new(&[]).to_value())
.expect("mix-matrix property didn't work");
let resample = gst::ElementFactory::make("audioresample", None).ok_or(
AudioDecoderError::Backend("audioresample creation failed".to_owned()),
)?;
let filter = gst::ElementFactory::make("capsfilter", None).ok_or(
AudioDecoderError::Backend("capsfilter creation failed".to_owned()),
)?;
let resample = gst::ElementFactory::make("audioresample", None).map_err(|_| {
AudioDecoderError::Backend("audioresample creation failed".to_owned())
})?;
let filter = gst::ElementFactory::make("capsfilter", None).map_err(|_| {
AudioDecoderError::Backend("capsfilter creation failed".to_owned())
})?;
let deinterleave = gst::ElementFactory::make("deinterleave", Some("deinterleave"))
.ok_or(AudioDecoderError::Backend(
"deinterleave creation failed".to_owned(),
))?;
.map_err(|_| {
AudioDecoderError::Backend("deinterleave creation failed".to_owned())
})?;

deinterleave
.set_property("keep-positions", &true.to_value())
Expand All @@ -183,12 +183,12 @@ impl AudioDecoder for GStreamerAudioDecoder {
}
};
let insert_sink = || -> Result<(), AudioDecoderError> {
let queue = gst::ElementFactory::make("queue", None).ok_or(
AudioDecoderError::Backend("queue creation failed".to_owned()),
)?;
let sink = gst::ElementFactory::make("appsink", None).ok_or(
AudioDecoderError::Backend("appsink creation failed".to_owned()),
)?;
let queue = gst::ElementFactory::make("queue", None).map_err(|_| {
AudioDecoderError::Backend("queue creation failed".to_owned())
})?;
let sink = gst::ElementFactory::make("appsink", None).map_err(|_| {
AudioDecoderError::Backend("appsink creation failed".to_owned())
})?;
let appsink = sink.clone().dynamic_cast::<gst_app::AppSink>().unwrap();
sink.set_property("sync", &false.to_value())
.expect("appsink doesn't handle expected 'sync' property");
Expand All @@ -198,15 +198,15 @@ impl AudioDecoder for GStreamerAudioDecoder {
gst_app::AppSinkCallbacks::new()
.new_sample(move |appsink| {
let sample =
appsink.pull_sample().ok_or(gst::FlowError::Eos)?;
appsink.pull_sample().map_err(|_| gst::FlowError::Eos)?;
let buffer = sample.get_buffer_owned().ok_or_else(|| {
callbacks_.error(AudioDecoderError::InvalidSample);
gst::FlowError::Error
})?;

let audio_info = sample
.get_caps()
.and_then(|caps| gst_audio::AudioInfo::from_caps(caps))
.and_then(|caps| gst_audio::AudioInfo::from_caps(caps).ok())
.ok_or_else(|| {
callbacks_.error(AudioDecoderError::Backend(
"Could not get caps from sample".to_owned(),
Expand Down Expand Up @@ -278,10 +278,10 @@ impl AudioDecoder for GStreamerAudioDecoder {
}
let audio_info = audio_info_builder
.build()
.ok_or(AudioDecoderError::Backend("AudioInfo failed".to_owned()))?;
.map_err(|_| AudioDecoderError::Backend("AudioInfo failed".to_owned()))?;
let caps = audio_info
.to_caps()
.ok_or(AudioDecoderError::Backend("AudioInfo failed".to_owned()))?;
.map_err(|_| AudioDecoderError::Backend("AudioInfo failed".to_owned()))?;
filter
.set_property("caps", &caps)
.expect("capsfilter doesn't have expected 'caps' property");
Expand Down
21 changes: 9 additions & 12 deletions backends/gstreamer/audio_sink.rs
Expand Up @@ -29,7 +29,7 @@ impl GStreamerAudioSink {
gst::init().map_err(|_| AudioSinkError::Backend("GStreamer init failed".to_owned()))?;

let appsrc = gst::ElementFactory::make("appsrc", None)
.ok_or(AudioSinkError::Backend("appsrc creation failed".to_owned()))?;
.map_err(|_| AudioSinkError::Backend("appsrc creation failed".to_owned()))?;
let appsrc = appsrc.downcast::<AppSrc>().unwrap();
Ok(Self {
pipeline: gst::Pipeline::new(None),
Expand All @@ -49,8 +49,8 @@ impl GStreamerAudioSink {
channels.into(),
)
.build()
.ok_or(AudioSinkError::Backend("AudioInfo failed".to_owned()))?;
self.appsrc.set_caps(audio_info.to_caps().as_ref());
.map_err(|_| AudioSinkError::Backend("AudioInfo failed".to_owned()))?;
self.appsrc.set_caps(audio_info.to_caps().ok().as_ref());
*self.audio_info.borrow_mut() = Some(audio_info);
Ok(())
}
Expand Down Expand Up @@ -95,15 +95,12 @@ impl AudioSink for GStreamerAudioSink {
.unwrap();

let appsrc = self.appsrc.as_ref().clone().upcast();
let resample = gst::ElementFactory::make("audioresample", None).ok_or(
AudioSinkError::Backend("audioresample creation failed".to_owned()),
)?;
let convert = gst::ElementFactory::make("audioconvert", None).ok_or(
AudioSinkError::Backend("audioconvert creation failed".to_owned()),
)?;
let sink = gst::ElementFactory::make("autoaudiosink", None).ok_or(
AudioSinkError::Backend("autoaudiosink creation failed".to_owned()),
)?;
let resample = gst::ElementFactory::make("audioresample", None)
.map_err(|_| AudioSinkError::Backend("audioresample creation failed".to_owned()))?;
let convert = gst::ElementFactory::make("audioconvert", None)
.map_err(|_| AudioSinkError::Backend("audioconvert creation failed".to_owned()))?;
let sink = gst::ElementFactory::make("autoaudiosink", None)
.map_err(|_| AudioSinkError::Backend("autoaudiosink creation failed".to_owned()))?;
self.pipeline
.add_many(&[&appsrc, &resample, &convert, &sink])
.map_err(|e| AudioSinkError::Backend(e.to_string()))?;
Expand Down
2 changes: 1 addition & 1 deletion backends/gstreamer/media_capture.rs
Expand Up @@ -136,7 +136,7 @@ impl GstMediaDevices {
let _ = self.monitor.remove_filter(f);
}
if let Some(d) = devices.get(0) {
let element = d.create_element(None)?;
let element = d.create_element(None).ok()?;
Some(GstMediaTrack { element })
} else {
None
Expand Down
2 changes: 1 addition & 1 deletion backends/gstreamer/media_stream_source.rs
Expand Up @@ -235,7 +235,7 @@ mod imp {
impl ObjectImpl for ServoMediaStreamSrc {
glib_object_impl!();

fn get_property(&self, _: &glib::Object, id: usize) -> Result<gst::Value, ()> {
fn get_property(&self, _: &glib::Object, id: usize) -> Result<glib::Value, ()> {
// We have a single property: is-live
if id != 0 {
return Err(());
Expand Down
22 changes: 9 additions & 13 deletions backends/gstreamer/player.rs
Expand Up @@ -22,7 +22,6 @@ use servo_media_streams::registry::{get_stream, MediaStreamId};
use servo_media_traits::{BackendMsg, ClientContextId, MediaInstance};
use source::{register_servo_src, ServoSrc};
use std::cell::RefCell;
use std::error::Error;
use std::ops::Range;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{self, Sender};
Expand Down Expand Up @@ -346,7 +345,7 @@ impl SeekChannel {
self.sender.clone()
}

fn await(&self) -> SeekLockMsg {
fn _await(&self) -> SeekLockMsg {
self.recv.recv().unwrap()
}
}
Expand Down Expand Up @@ -475,7 +474,7 @@ impl GStreamerPlayer {

if let Some(ref audio_renderer) = self.audio_renderer {
let audio_sink = gst::ElementFactory::make("appsink", None)
.ok_or(PlayerError::Backend("appsink creation failed".to_owned()))?;
.map_err(|_| PlayerError::Backend("appsink creation failed".to_owned()))?;

pipeline
.set_property("audio-sink", &audio_sink)
Expand All @@ -487,11 +486,11 @@ impl GStreamerPlayer {
gst_app::AppSinkCallbacks::new()
.new_preroll(|_| Ok(gst::FlowSuccess::Ok))
.new_sample(move |audio_sink| {
let sample = audio_sink.pull_sample().ok_or(gst::FlowError::Eos)?;
let sample = audio_sink.pull_sample().map_err(|_| gst::FlowError::Eos)?;
let buffer = sample.get_buffer_owned().ok_or(gst::FlowError::Error)?;
let audio_info = sample
.get_caps()
.and_then(|caps| gst_audio::AudioInfo::from_caps(caps))
.and_then(|caps| gst_audio::AudioInfo::from_caps(caps).ok())
.ok_or(gst::FlowError::Error)?;
let positions = audio_info.positions().ok_or(gst::FlowError::Error)?;
for position in positions.iter() {
Expand Down Expand Up @@ -662,7 +661,7 @@ impl GStreamerPlayer {
gst_app::AppSinkCallbacks::new()
.new_preroll(|_| Ok(gst::FlowSuccess::Ok))
.new_sample(move |video_sink| {
let sample = video_sink.pull_sample().ok_or(gst::FlowError::Eos)?;
let sample = video_sink.pull_sample().map_err(|_| gst::FlowError::Eos)?;
let frame = render
.lock()
.unwrap()
Expand All @@ -689,8 +688,8 @@ impl GStreamerPlayer {
let observer = self.observer.clone();
let connect_result = pipeline.connect("source-setup", false, move |args| {
let source = match args[1].get::<gst::Element>() {
Some(source) => source,
None => {
Ok(Some(source)) => source,
_ => {
let _ = notify!(
sender,
Err(PlayerError::Backend("Source setup failed".to_owned()))
Expand Down Expand Up @@ -749,7 +748,7 @@ impl GStreamerPlayer {
)
);
let (ret, ack_channel) =
seek_channel.lock().unwrap().await();
seek_channel.lock().unwrap()._await();
(ret, Some(ack_channel))
} else {
(true, None)
Expand Down Expand Up @@ -792,10 +791,7 @@ impl GStreamerPlayer {
}

let error_handler_id = inner.player.connect_error(move |player, error| {
let _ = notify!(
sender_clone,
Err(PlayerError::Backend(error.description().to_string()))
);
let _ = notify!(sender_clone, Err(PlayerError::Backend(error.to_string())));
player.stop();
});

Expand Down
7 changes: 4 additions & 3 deletions backends/gstreamer/registry_scanner.rs
@@ -1,5 +1,6 @@
use gst;
use std::collections::HashSet;
use std::str::FromStr;

lazy_static! {
// The GStreamer registry holds the metadata of the set of plugins available in the host.
Expand Down Expand Up @@ -247,12 +248,12 @@ impl GStreamerRegistryScanner {
}

fn has_element_for_media_type(factories: &Vec<gst::ElementFactory>, media_type: &str) -> bool {
match gst::caps::Caps::from_string(media_type) {
Some(caps) => {
match gst::caps::Caps::from_str(media_type) {
Ok(caps) => {
let matching_factories =
gst::ElementFactory::list_filter(&factories, &caps, gst::PadDirection::Sink, false);
matching_factories.len() > 0
}
None => false,
_ => false,
}
}
8 changes: 4 additions & 4 deletions backends/gstreamer/render-android/Cargo.toml
Expand Up @@ -8,17 +8,17 @@ name = "servo_media_gstreamer_render_android"
path = "lib.rs"

[dependencies.glib]
version = "0.8"
version = "0.9"

[dependencies.gstreamer]
version = "0.14"
version = "0.15"

[dependencies.gstreamer-gl]
version = "0.14"
version = "0.15"
features = ["egl"]

[dependencies.gstreamer-video]
version = "0.14"
version = "0.15"

[dependencies.servo-media-player]
path = "../../../player"
Expand Down
12 changes: 7 additions & 5 deletions backends/gstreamer/render-android/lib.rs
Expand Up @@ -77,7 +77,8 @@ impl RenderAndroid {
let display = match display_native {
NativeDisplay::Egl(display_native) => {
unsafe { gst_gl::GLDisplayEGL::new_with_egl_display(display_native) }
.and_then(|display| Some(display.upcast()))
.and_then(|display| Ok(display.upcast()))
.ok()
}
_ => None,
};
Expand Down Expand Up @@ -125,6 +126,7 @@ impl Render for RenderAndroid {
.get_property("context")
.or_else(|_| Err(()))?
.get::<gst_gl::GLContext>()
.unwrap_or_else(|_| None)
} else {
None
};
Expand All @@ -136,8 +138,8 @@ impl Render for RenderAndroid {
let is_external_oes = caps
.get_structure(0)
.and_then(|s| {
s.get::<&str>("texture-target").and_then(|target| {
if target == "external-oes" {
s.get::<&str>("texture-target").ok().and_then(|target| {
if target == Some("external-oes") {
Some(s)
} else {
None
Expand All @@ -146,7 +148,7 @@ impl Render for RenderAndroid {
})
.is_some();

let info = gst_video::VideoInfo::from_caps(caps).ok_or_else(|| ())?;
let info = gst_video::VideoInfo::from_caps(caps).map_err(|_| ())?;

if self.gst_context.lock().unwrap().is_some() {
if let Some(sync_meta) = buffer.get_meta::<gst_gl::GLSyncMeta>() {
Expand Down Expand Up @@ -191,7 +193,7 @@ impl Render for RenderAndroid {
}

let vsinkbin = gst::ElementFactory::make("glsinkbin", Some("servo-media-vsink"))
.ok_or(PlayerError::Backend("glupload creation failed".to_owned()))?;
.map_err(|_| PlayerError::Backend("glupload creation failed".to_owned()))?;

let caps = gst::Caps::builder("video/x-raw")
.features(&[&gst_gl::CAPS_FEATURE_MEMORY_GL_MEMORY])
Expand Down

0 comments on commit 4491e75

Please sign in to comment.