From 291f329fc3a751c899fdd050566c95a3640d0258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 5 Jul 2017 11:09:49 +0300 Subject: [PATCH] Add Element::add_many(), ::remove_many(), Bin::link_many(), ::unlink_many() --- examples/src/decodebin.rs | 40 +++++++++++++------------------------- gstreamer/src/bin.rs | 41 +++++++++++++++++++++++++++++++++++++++ gstreamer/src/element.rs | 30 ++++++++++++++++++++++++++++ gstreamer/src/lib.rs | 5 +++++ 4 files changed, 90 insertions(+), 26 deletions(-) create mode 100644 gstreamer/src/bin.rs create mode 100644 gstreamer/src/element.rs diff --git a/examples/src/decodebin.rs b/examples/src/decodebin.rs index a1a43cd02..a66a3c586 100644 --- a/examples/src/decodebin.rs +++ b/examples/src/decodebin.rs @@ -30,10 +30,8 @@ fn main() { gobject_ffi::g_object_set_property(src.to_glib_none().0, "location".to_glib_none().0, uri.to_glib_none().0); } - // TODO: Add Bin::add_many(), Element::link_many() - pipeline.add(&src).unwrap(); - pipeline.add(&decodebin).unwrap(); - src.link(&decodebin).unwrap(); + pipeline.add_many(&[&src, &decodebin]).unwrap(); + gst::Element::link_many(&[&src, &decodebin]).unwrap(); // Need to move a new reference into the closure let pipeline_clone = pipeline.clone(); @@ -55,19 +53,14 @@ fn main() { let convert = gst::ElementFactory::make("audioconvert", None).unwrap(); let resample = gst::ElementFactory::make("audioresample", None).unwrap(); let sink = gst::ElementFactory::make("autoaudiosink", None).unwrap(); - pipeline.add(&queue).unwrap(); - pipeline.add(&convert).unwrap(); - pipeline.add(&resample).unwrap(); - pipeline.add(&sink).unwrap(); - queue.link(&convert).unwrap(); - convert.link(&resample).unwrap(); - resample.link(&sink).unwrap(); + let elements = &[&queue, &convert, &resample, &sink]; + pipeline.add_many(elements).unwrap(); + gst::Element::link_many(elements).unwrap(); - queue.sync_state_with_parent().unwrap(); - convert.sync_state_with_parent().unwrap(); - resample.sync_state_with_parent().unwrap(); - sink.sync_state_with_parent().unwrap(); + for e in elements { + e.sync_state_with_parent().unwrap(); + } let sink_pad = queue.get_static_pad("sink").unwrap(); assert_eq!(src_pad.link(&sink_pad), gst::PadLinkReturn::Ok); @@ -76,19 +69,14 @@ fn main() { let convert = gst::ElementFactory::make("videoconvert", None).unwrap(); let scale = gst::ElementFactory::make("videoscale", None).unwrap(); let sink = gst::ElementFactory::make("autovideosink", None).unwrap(); - pipeline.add(&queue).unwrap(); - pipeline.add(&convert).unwrap(); - pipeline.add(&scale).unwrap(); - pipeline.add(&sink).unwrap(); - queue.link(&convert).unwrap(); - convert.link(&scale).unwrap(); - scale.link(&sink).unwrap(); + let elements = &[&queue, &convert, &scale, &sink]; + pipeline.add_many(elements).unwrap(); + gst::Element::link_many(elements).unwrap(); - queue.sync_state_with_parent().unwrap(); - convert.sync_state_with_parent().unwrap(); - scale.sync_state_with_parent().unwrap(); - sink.sync_state_with_parent().unwrap(); + for e in elements { + e.sync_state_with_parent().unwrap(); + } let sink_pad = queue.get_static_pad("sink").unwrap(); assert_eq!(src_pad.link(&sink_pad), gst::PadLinkReturn::Ok); diff --git a/gstreamer/src/bin.rs b/gstreamer/src/bin.rs new file mode 100644 index 000000000..84b2f28f7 --- /dev/null +++ b/gstreamer/src/bin.rs @@ -0,0 +1,41 @@ +use Bin; +use Element; + +use glib; +use glib::IsA; +use glib::translate::{ToGlibPtr, from_glib}; + +use ffi; + +pub trait BinExtManual { + fn add_many>(&self, elements: &[&E]) -> Result<(), glib::BoolError>; + fn remove_many>(&self, elements: &[&E]) -> Result<(), glib::BoolError>; +} + +impl> BinExtManual for O { + fn add_many>(&self, elements: &[&E]) -> Result<(), glib::BoolError> { + for e in elements { + unsafe { + let ret: bool = from_glib(ffi::gst_bin_add(self.to_glib_none().0, e.to_glib_none().0)); + if !ret { + return Err(glib::BoolError("Failed to add elements")); + } + } + } + + return Ok(()); + } + + fn remove_many>(&self, elements: &[&E]) -> Result<(), glib::BoolError> { + for e in elements { + unsafe { + let ret: bool = from_glib(ffi::gst_bin_remove(self.to_glib_none().0, e.to_glib_none().0)); + if !ret { + return Err(glib::BoolError("Failed to add elements")); + } + } + } + + return Ok(()); + } +} diff --git a/gstreamer/src/element.rs b/gstreamer/src/element.rs new file mode 100644 index 000000000..889d768d8 --- /dev/null +++ b/gstreamer/src/element.rs @@ -0,0 +1,30 @@ +use Element; + +use glib; +use glib::IsA; +use glib::translate::{ToGlibPtr, from_glib}; + +use ffi; + +impl Element { + pub fn link_many>(elements: &[&E]) -> Result<(), glib::BoolError> { + for (e1, e2) in elements.iter().zip(elements.iter().skip(1)) { + unsafe { + let ret: bool = from_glib(ffi::gst_element_link(e1.to_glib_none().0, e2.to_glib_none().0)); + if !ret { + return Err(glib::BoolError("Failed to link elements")); + } + } + } + + return Ok(()); + } + + pub fn unlink_many>(elements: &[&E]) { + for (e1, e2) in elements.iter().zip(elements.iter().skip(1)) { + unsafe { + ffi::gst_element_unlink(e1.to_glib_none().0, e2.to_glib_none().0); + } + } + } +} diff --git a/gstreamer/src/lib.rs b/gstreamer/src/lib.rs index dc328e4f5..b0dadc47a 100644 --- a/gstreamer/src/lib.rs +++ b/gstreamer/src/lib.rs @@ -31,6 +31,7 @@ pub use glib::{ mod auto; pub use auto::*; +pub use auto::traits::*; pub use auto::functions::{parse_launch, parse_bin_from_description}; pub mod miniobject; @@ -39,6 +40,10 @@ pub mod message; pub use message::Message; pub use message::MessageView; +mod element; +mod bin; +pub use bin::BinExtManual; + use std::ptr; pub fn init() -> Result<(), glib::Error> {