as usize), Box_::into_raw(f) as *mut _)
+ }
+ }
+}
+
+unsafe extern "C" fn notify_timeout_trampoline(this: *mut ffi::GstDiscoverer, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer)
+where P: IsA {
+ callback_guard!();
+ let f: &&(Fn(&P) + Send + Sync + 'static) = transmute(f);
+ f(&Discoverer::from_glib_borrow(this).downcast_unchecked())
+}
diff --git a/gstreamer-pbutils/src/discoverer_stream_info.rs b/gstreamer-pbutils/src/discoverer_stream_info.rs
new file mode 100644
index 000000000..94705dab3
--- /dev/null
+++ b/gstreamer-pbutils/src/discoverer_stream_info.rs
@@ -0,0 +1,52 @@
+// Copyright (C) 2018 Thiago Santos
+// Sebastian Dröge
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use DiscovererStreamInfo;
+use DiscovererStreamInfoExt;
+
+pub struct DiscovererStreamInfoIter {
+ stream_info: Option,
+ direction_forward: bool
+}
+
+impl Iterator for DiscovererStreamInfoIter {
+ type Item = DiscovererStreamInfo;
+
+ fn next(&mut self) -> Option {
+ let current = self.stream_info.take();
+ self.stream_info = match ¤t {
+ &Some(ref c) => {
+ // Decide on the direction
+ if self.direction_forward {
+ c.get_next()
+ } else {
+ c.get_previous()
+ }
+ },
+ &None => None
+ };
+ current
+ }
+}
+
+impl DiscovererStreamInfo {
+ pub fn next_iter(&self) -> DiscovererStreamInfoIter {
+ DiscovererStreamInfoIter {
+ stream_info: self.get_next(),
+ direction_forward: true
+ }
+ }
+
+ pub fn previous_iter(&self) -> DiscovererStreamInfoIter {
+ DiscovererStreamInfoIter {
+ stream_info: self.get_previous(),
+ direction_forward: false
+ }
+ }
+}
diff --git a/gstreamer-pbutils/src/discoverer_video_info.rs b/gstreamer-pbutils/src/discoverer_video_info.rs
new file mode 100644
index 000000000..44f9964d3
--- /dev/null
+++ b/gstreamer-pbutils/src/discoverer_video_info.rs
@@ -0,0 +1,32 @@
+// Copyright (C) 2018 Thiago Santos
+// Sebastian Dröge
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use DiscovererVideoInfo;
+
+use gst;
+use ffi;
+use glib::translate::*;
+
+impl DiscovererVideoInfo {
+ pub fn get_framerate(&self) -> gst::Fraction {
+ unsafe {
+ gst::Fraction::new(
+ ffi::gst_discoverer_video_info_get_framerate_num(self.to_glib_none().0) as i32,
+ ffi::gst_discoverer_video_info_get_framerate_denom(self.to_glib_none().0) as i32)
+ }
+ }
+
+ pub fn get_par(&self) -> gst::Fraction {
+ unsafe {
+ gst::Fraction::new(
+ ffi::gst_discoverer_video_info_get_par_num(self.to_glib_none().0) as i32,
+ ffi::gst_discoverer_video_info_get_par_denom(self.to_glib_none().0) as i32)
+ }
+ }
+}
diff --git a/gstreamer-pbutils/src/lib.rs b/gstreamer-pbutils/src/lib.rs
new file mode 100644
index 000000000..b90245cad
--- /dev/null
+++ b/gstreamer-pbutils/src/lib.rs
@@ -0,0 +1,76 @@
+// Copyright (C) 2017 Sebastian Dröge
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_use]
+extern crate bitflags;
+extern crate libc;
+
+use std::sync::{Once, ONCE_INIT};
+
+#[macro_use]
+extern crate glib;
+extern crate glib_sys as glib_ffi;
+extern crate gobject_sys as gobject_ffi;
+extern crate gstreamer as gst;
+extern crate gstreamer_sys as gst_ffi;
+extern crate gstreamer_pbutils_sys as ffi;
+
+static PBUTILS_INIT: Once = ONCE_INIT;
+
+macro_rules! callback_guard {
+ () => (
+ let _guard = ::glib::CallbackGuard::new();
+ )
+}
+
+macro_rules! assert_initialized_main_thread {
+ () => (
+ if unsafe {::gst_ffi::gst_is_initialized()} != ::glib_ffi::GTRUE {
+ panic!("GStreamer has not been initialized. Call `gst::init` first.");
+ }
+ ::PBUTILS_INIT.call_once(|| {
+ unsafe{::ffi::gst_pb_utils_init()};
+ });
+ )
+}
+
+macro_rules! skip_assert_initialized {
+ () => (
+ )
+}
+
+pub use glib::{Cast, Continue, Error, IsA, StaticType, ToValue, Type, TypedValue, Value};
+
+#[cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
+#[cfg_attr(feature = "cargo-clippy", allow(transmute_ptr_to_ref))]
+#[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
+#[cfg_attr(feature = "cargo-clippy", allow(match_same_arms))]
+mod auto;
+pub use auto::*;
+
+mod discoverer;
+pub use discoverer::*;
+
+mod discoverer_stream_info;
+pub use discoverer_stream_info::*;
+
+mod discoverer_video_info;
+pub use discoverer_video_info::*;
+
+// Re-export all the traits in a prelude module, so that applications
+// can always "use gst::prelude::*" without getting conflicts
+pub mod prelude {
+ pub use glib::prelude::*;
+ pub use gst::prelude::*;
+
+ pub use discoverer::*;
+ pub use discoverer_stream_info::*;
+ pub use discoverer_video_info::*;
+
+ pub use auto::traits::*;
+}