diff --git a/Gir_Gst.toml b/Gir_Gst.toml index a5f3d4816..0740b7133 100644 --- a/Gir_Gst.toml +++ b/Gir_Gst.toml @@ -49,6 +49,8 @@ generate = [ "Gst.ProgressType", "Gst.BusSyncReply", "Gst.TagMergeMode", + "Gst.PadProbeType", + "Gst.PadProbeReturn", ] manual = [ @@ -259,6 +261,11 @@ status = "generate" # Caps is not a GObject ignore = true + [[object.function]] + name = "remove_probe" + # Don't use a ulong + ignore = true + [[object]] name = "Gst.Stream" status = "generate" diff --git a/gstreamer/src/auto/enums.rs b/gstreamer/src/auto/enums.rs index 48a5fc939..a9d5e08d0 100644 --- a/gstreamer/src/auto/enums.rs +++ b/gstreamer/src/auto/enums.rs @@ -711,6 +711,72 @@ impl SetValue for PadPresence { } } +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum PadProbeReturn { + Drop, + Ok, + Remove, + Pass, + Handled, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for PadProbeReturn { + type GlibType = ffi::GstPadProbeReturn; + + fn to_glib(&self) -> ffi::GstPadProbeReturn { + match *self { + PadProbeReturn::Drop => ffi::GST_PAD_PROBE_DROP, + PadProbeReturn::Ok => ffi::GST_PAD_PROBE_OK, + PadProbeReturn::Remove => ffi::GST_PAD_PROBE_REMOVE, + PadProbeReturn::Pass => ffi::GST_PAD_PROBE_PASS, + PadProbeReturn::Handled => ffi::GST_PAD_PROBE_HANDLED, + PadProbeReturn::__Unknown(value) => unsafe{std::mem::transmute(value)} + } + } +} + +#[doc(hidden)] +impl FromGlib for PadProbeReturn { + fn from_glib(value: ffi::GstPadProbeReturn) -> Self { + skip_assert_initialized!(); + match value as i32 { + 0 => PadProbeReturn::Drop, + 1 => PadProbeReturn::Ok, + 2 => PadProbeReturn::Remove, + 3 => PadProbeReturn::Pass, + 4 => PadProbeReturn::Handled, + value => PadProbeReturn::__Unknown(value), + } + } +} + +impl StaticType for PadProbeReturn { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_pad_probe_return_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for PadProbeReturn { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for PadProbeReturn { + unsafe fn from_value(value: &Value) -> Self { + from_glib(std::mem::transmute::(gobject_ffi::g_value_get_enum(value.to_glib_none().0))) + } +} + +impl SetValue for PadProbeReturn { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32) + } +} + #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub enum ParseError { Syntax, diff --git a/gstreamer/src/auto/flags.rs b/gstreamer/src/auto/flags.rs index 80aa4217a..fe7f243e7 100644 --- a/gstreamer/src/auto/flags.rs +++ b/gstreamer/src/auto/flags.rs @@ -8,6 +8,74 @@ use glib::value::{Value, SetValue, FromValue, FromValueOptional}; use gobject_ffi; use glib::translate::*; +bitflags! { + pub struct PadProbeType: u32 { + const PAD_PROBE_TYPE_INVALID = 0; + const PAD_PROBE_TYPE_IDLE = 1; + const PAD_PROBE_TYPE_BLOCK = 2; + const PAD_PROBE_TYPE_BUFFER = 16; + const PAD_PROBE_TYPE_BUFFER_LIST = 32; + const PAD_PROBE_TYPE_EVENT_DOWNSTREAM = 64; + const PAD_PROBE_TYPE_EVENT_UPSTREAM = 128; + const PAD_PROBE_TYPE_EVENT_FLUSH = 256; + const PAD_PROBE_TYPE_QUERY_DOWNSTREAM = 512; + const PAD_PROBE_TYPE_QUERY_UPSTREAM = 1024; + const PAD_PROBE_TYPE_PUSH = 4096; + const PAD_PROBE_TYPE_PULL = 8192; + const PAD_PROBE_TYPE_BLOCKING = 3; + const PAD_PROBE_TYPE_DATA_DOWNSTREAM = 112; + const PAD_PROBE_TYPE_DATA_UPSTREAM = 128; + const PAD_PROBE_TYPE_DATA_BOTH = 240; + const PAD_PROBE_TYPE_BLOCK_DOWNSTREAM = 114; + const PAD_PROBE_TYPE_BLOCK_UPSTREAM = 130; + const PAD_PROBE_TYPE_EVENT_BOTH = 192; + const PAD_PROBE_TYPE_QUERY_BOTH = 1536; + const PAD_PROBE_TYPE_ALL_BOTH = 1776; + const PAD_PROBE_TYPE_SCHEDULING = 12288; + } +} + +#[doc(hidden)] +impl ToGlib for PadProbeType { + type GlibType = ffi::GstPadProbeType; + + fn to_glib(&self) -> ffi::GstPadProbeType { + ffi::GstPadProbeType::from_bits_truncate(self.bits()) + } +} + +#[doc(hidden)] +impl FromGlib for PadProbeType { + fn from_glib(value: ffi::GstPadProbeType) -> PadProbeType { + skip_assert_initialized!(); + PadProbeType::from_bits_truncate(value.bits()) + } +} + +impl StaticType for PadProbeType { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_pad_probe_type_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for PadProbeType { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for PadProbeType { + unsafe fn from_value(value: &Value) -> Self { + from_glib(ffi::GstPadProbeType::from_bits_truncate(gobject_ffi::g_value_get_flags(value.to_glib_none().0))) + } +} + +impl SetValue for PadProbeType { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, this.to_glib().bits()) + } +} + bitflags! { pub struct SeekFlags: u32 { const SEEK_FLAG_NONE = 0; diff --git a/gstreamer/src/auto/mod.rs b/gstreamer/src/auto/mod.rs index 6c069c35d..b77d00f00 100644 --- a/gstreamer/src/auto/mod.rs +++ b/gstreamer/src/auto/mod.rs @@ -82,6 +82,7 @@ pub use self::enums::LibraryError; pub use self::enums::PadDirection; pub use self::enums::PadLinkReturn; pub use self::enums::PadPresence; +pub use self::enums::PadProbeReturn; pub use self::enums::ParseError; pub use self::enums::PluginError; pub use self::enums::ProgressType; @@ -98,6 +99,29 @@ pub use self::enums::URIError; pub use self::enums::URIType; mod flags; +pub use self::flags::PadProbeType; +pub use self::flags::PAD_PROBE_TYPE_INVALID; +pub use self::flags::PAD_PROBE_TYPE_IDLE; +pub use self::flags::PAD_PROBE_TYPE_BLOCK; +pub use self::flags::PAD_PROBE_TYPE_BUFFER; +pub use self::flags::PAD_PROBE_TYPE_BUFFER_LIST; +pub use self::flags::PAD_PROBE_TYPE_EVENT_DOWNSTREAM; +pub use self::flags::PAD_PROBE_TYPE_EVENT_UPSTREAM; +pub use self::flags::PAD_PROBE_TYPE_EVENT_FLUSH; +pub use self::flags::PAD_PROBE_TYPE_QUERY_DOWNSTREAM; +pub use self::flags::PAD_PROBE_TYPE_QUERY_UPSTREAM; +pub use self::flags::PAD_PROBE_TYPE_PUSH; +pub use self::flags::PAD_PROBE_TYPE_PULL; +pub use self::flags::PAD_PROBE_TYPE_BLOCKING; +pub use self::flags::PAD_PROBE_TYPE_DATA_DOWNSTREAM; +pub use self::flags::PAD_PROBE_TYPE_DATA_UPSTREAM; +pub use self::flags::PAD_PROBE_TYPE_DATA_BOTH; +pub use self::flags::PAD_PROBE_TYPE_BLOCK_DOWNSTREAM; +pub use self::flags::PAD_PROBE_TYPE_BLOCK_UPSTREAM; +pub use self::flags::PAD_PROBE_TYPE_EVENT_BOTH; +pub use self::flags::PAD_PROBE_TYPE_QUERY_BOTH; +pub use self::flags::PAD_PROBE_TYPE_ALL_BOTH; +pub use self::flags::PAD_PROBE_TYPE_SCHEDULING; pub use self::flags::SeekFlags; pub use self::flags::SEEK_FLAG_NONE; pub use self::flags::SEEK_FLAG_FLUSH; diff --git a/gstreamer/src/auto/pad.rs b/gstreamer/src/auto/pad.rs index 9cd941ccc..29bc2b1d2 100644 --- a/gstreamer/src/auto/pad.rs +++ b/gstreamer/src/auto/pad.rs @@ -20,7 +20,6 @@ use glib::signal::connect; use glib::translate::*; use glib_ffi; use gobject_ffi; -use libc; use std::boxed::Box as Box_; use std::mem; use std::mem::transmute; @@ -71,7 +70,7 @@ unsafe impl Sync for Pad {} pub trait PadExt { //fn activate_mode(&self, mode: /*Ignored*/PadMode, active: bool) -> bool; - //fn add_probe>>(&self, mask: /*Ignored*/PadProbeType, callback: /*Unknown conversion*//*Unimplemented*/PadProbeCallback, user_data: P, destroy_data: /*Unknown conversion*//*Unimplemented*/DestroyNotify) -> libc::c_ulong; + //fn add_probe>>(&self, mask: PadProbeType, callback: /*Unknown conversion*//*Unimplemented*/PadProbeCallback, user_data: P, destroy_data: /*Unknown conversion*//*Unimplemented*/DestroyNotify) -> libc::c_ulong; fn can_link>(&self, sinkpad: &P) -> bool; @@ -191,8 +190,6 @@ pub trait PadExt { fn query_position(&self, format: Format) -> Option; - fn remove_probe(&self, id: libc::c_ulong); - //fn send_event(&self, event: /*Ignored*/&mut Event) -> bool; //fn set_activate_function_full>>(&self, activate: /*Unknown conversion*//*Unimplemented*/PadActivateFunction, user_data: P, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify); @@ -249,7 +246,7 @@ impl + IsA> PadExt for O { // unsafe { TODO: call ffi::gst_pad_activate_mode() } //} - //fn add_probe>>(&self, mask: /*Ignored*/PadProbeType, callback: /*Unknown conversion*//*Unimplemented*/PadProbeCallback, user_data: P, destroy_data: /*Unknown conversion*//*Unimplemented*/DestroyNotify) -> libc::c_ulong { + //fn add_probe>>(&self, mask: PadProbeType, callback: /*Unknown conversion*//*Unimplemented*/PadProbeCallback, user_data: P, destroy_data: /*Unknown conversion*//*Unimplemented*/DestroyNotify) -> libc::c_ulong { // unsafe { TODO: call ffi::gst_pad_add_probe() } //} @@ -571,12 +568,6 @@ impl + IsA> PadExt for O { } } - fn remove_probe(&self, id: libc::c_ulong) { - unsafe { - ffi::gst_pad_remove_probe(self.to_glib_none().0, id); - } - } - //fn send_event(&self, event: /*Ignored*/&mut Event) -> bool { // unsafe { TODO: call ffi::gst_pad_send_event() } //} diff --git a/gstreamer/src/lib.rs b/gstreamer/src/lib.rs index 23c72501c..1fffa7ab1 100644 --- a/gstreamer/src/lib.rs +++ b/gstreamer/src/lib.rs @@ -61,8 +61,10 @@ pub use tags::*; mod element; mod bin; mod bus; +mod pad; mod gobject; pub use bin::BinExtManual; +pub use pad::PadExtManual; pub use gobject::GObjectExtManualGst; mod value; diff --git a/gstreamer/src/pad.rs b/gstreamer/src/pad.rs new file mode 100644 index 000000000..31d4a5751 --- /dev/null +++ b/gstreamer/src/pad.rs @@ -0,0 +1,118 @@ +// 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. + +use Pad; +use PadProbeType; +use PadProbeReturn; + +use std::cell::RefCell; +use std::mem::transmute; + +use glib::IsA; +use glib::translate::{ToGlib, from_glib, from_glib_none}; +use glib::source::CallbackGuard; +use glib_ffi::gpointer; + +use libc; + +use ffi; + +pub struct PadProbeId(libc::c_ulong); + +pub struct PadProbeInfo { + pub mask: PadProbeType, + pub id: PadProbeId, + pub offset: u64, + pub size: u32, + pub data: Option, +} + +pub enum PadProbeData { + // Buffer(&Buffer), + // BufferList(&BufferList), + // Query(&Query), + // Event(&Event), + Unknown, +} + +pub trait PadExtManual { + fn add_probe(&self, mask: PadProbeType, func: F) -> PadProbeId + where + F: FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static; + fn remove_probe(&self, id: PadProbeId); +} + +impl> PadExtManual for O { + fn add_probe(&self, mask: PadProbeType, func: F) -> PadProbeId + where + F: FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static, + { + unsafe { + let id = ffi::gst_pad_add_probe( + self.to_glib_none().0, + mask.to_glib(), + Some(trampoline_pad_probe), + into_raw_pad_probe(func), + Some(destroy_closure_pad_probe), + ); + + PadProbeId(id) + } + } + + fn remove_probe(&self, id: PadProbeId) { + unsafe { + ffi::gst_pad_remove_probe(self.to_glib_none().0, id.0 as libc::c_ulong); + } + } +} + +unsafe extern "C" fn trampoline_pad_probe( + pad: *mut ffi::GstPad, + info: *mut ffi::GstPadProbeInfo, + func: gpointer, +) -> ffi::GstPadProbeReturn { + let _guard = CallbackGuard::new(); + let func: &RefCell< + Box PadProbeReturn + Send + Sync + 'static>, + > = transmute(func); + + let mut probe_info = PadProbeInfo { + mask: from_glib((*info).type_), + id: PadProbeId((*info).id), + offset: (*info).offset, + size: (*info).size, + data: if (*info).data.is_null() { + None + } else { + Some(PadProbeData::Unknown) + }, + }; + + let ret = (&mut *func.borrow_mut())(&from_glib_none(pad), &mut probe_info).to_glib(); + + // TODO: Possibly replace info.data + + ret +} + +unsafe extern "C" fn destroy_closure_pad_probe(ptr: gpointer) { + let _guard = CallbackGuard::new(); + Box:: PadProbeReturn + Send + Sync + 'static>>>::from_raw(ptr as *mut _); +} + +fn into_raw_pad_probe< + F: FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static, +>( + func: F, +) -> gpointer { + let func: Box< + RefCell PadProbeReturn + Send + Sync + 'static>>, + > = Box::new(RefCell::new(Box::new(func))); + Box::into_raw(func) as gpointer +}