forked from mirrors/gstreamer-rs
gstreamer: Add bindings to MiniObject together with casting functionality
This is only possible with 1.20 because gst_mini_object_get_type() was added then. Previous versions only provide bindings for the specific types, like Caps, Event, etc. Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/353
This commit is contained in:
parent
672b7abe1d
commit
1856d47a06
5 changed files with 110 additions and 7 deletions
|
@ -45,6 +45,7 @@ pub use crate::error::*;
|
|||
|
||||
#[macro_use]
|
||||
pub mod miniobject;
|
||||
pub use miniobject::{MiniObject, MiniObjectRef};
|
||||
pub mod message;
|
||||
pub use crate::message::{Message, MessageErrorDomain, MessageRef, MessageView};
|
||||
|
||||
|
@ -310,6 +311,8 @@ pub mod prelude {
|
|||
pub use crate::typefind::TypeFindImpl;
|
||||
pub use crate::value::GstValueExt;
|
||||
|
||||
pub use crate::miniobject::IsMiniObject;
|
||||
|
||||
pub use crate::tags::{CustomTag, Tag};
|
||||
|
||||
pub use muldiv::MulDiv;
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use glib::translate::*;
|
||||
|
||||
pub trait IsMiniObject:
|
||||
AsRef<Self::RefType> + FromGlibPtrFull<*mut Self::FfiType> + Send + Sync + 'static
|
||||
{
|
||||
type RefType;
|
||||
type FfiType;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! mini_object_wrapper (
|
||||
($name:ident, $ref_name:ident, $ffi_name:path) => {
|
||||
|
@ -10,6 +19,11 @@ macro_rules! mini_object_wrapper (
|
|||
#[repr(transparent)]
|
||||
pub struct $ref_name($ffi_name);
|
||||
|
||||
impl $crate::miniobject::IsMiniObject for $name {
|
||||
type RefType = $ref_name;
|
||||
type FfiType = $ffi_name;
|
||||
}
|
||||
|
||||
impl $name {
|
||||
pub unsafe fn from_glib_none(ptr: *const $ffi_name) -> Self {
|
||||
skip_assert_initialized!();
|
||||
|
@ -78,6 +92,12 @@ macro_rules! mini_object_wrapper (
|
|||
}
|
||||
}
|
||||
|
||||
pub fn upcast(self) -> $crate::miniobject::MiniObject {
|
||||
unsafe {
|
||||
from_glib_full(self.into_ptr() as *mut $crate::ffi::GstMiniObject)
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn into_ptr(self) -> *mut $ffi_name {
|
||||
let s = std::mem::ManuallyDrop::new(self);
|
||||
s.as_mut_ptr()
|
||||
|
@ -392,6 +412,18 @@ macro_rules! mini_object_wrapper (
|
|||
) as *const $ffi_name)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn upcast_ref(&self) -> &$crate::miniobject::MiniObjectRef {
|
||||
unsafe {
|
||||
&*(self.as_ptr() as *const $crate::miniobject::MiniObjectRef)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn upcast_mut(&mut self) -> &mut $crate::miniobject::MiniObjectRef {
|
||||
unsafe {
|
||||
&mut *(self.as_mut_ptr() as *mut $crate::miniobject::MiniObjectRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::glib::translate::GlibPtrDefault for $ref_name {
|
||||
|
@ -485,3 +517,43 @@ macro_rules! mini_object_wrapper (
|
|||
// immutable references from a mutable reference without borrowing via the value
|
||||
};
|
||||
);
|
||||
|
||||
#[cfg(not(any(feature = "v1_20", feature = "dox")))]
|
||||
mini_object_wrapper!(MiniObject, MiniObjectRef, ffi::GstMiniObject);
|
||||
|
||||
#[cfg(any(feature = "v1_20", feature = "dox"))]
|
||||
mini_object_wrapper!(MiniObject, MiniObjectRef, ffi::GstMiniObject, || {
|
||||
ffi::gst_mini_object_get_type()
|
||||
});
|
||||
|
||||
impl MiniObject {
|
||||
pub fn downcast<T: IsMiniObject + glib::StaticType>(self) -> Result<T, Self> {
|
||||
if self.type_().is_a(T::static_type()) {
|
||||
unsafe { Ok(from_glib_full(self.into_ptr() as *mut T::FfiType)) }
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MiniObjectRef {
|
||||
pub fn type_(&self) -> glib::Type {
|
||||
unsafe { from_glib((*self.as_ptr()).type_) }
|
||||
}
|
||||
|
||||
pub fn downcast_ref<T: IsMiniObject + glib::StaticType>(&self) -> Option<&T> {
|
||||
if self.type_().is_a(T::static_type()) {
|
||||
unsafe { Some(&*(self as *const Self as *const T)) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn downcast_mut<T: IsMiniObject + glib::StaticType>(&mut self) -> Option<&mut T> {
|
||||
if self.type_().is_a(T::static_type()) {
|
||||
unsafe { Some(&mut *(self as *mut Self as *mut T)) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
use crate::ffi;
|
||||
use crate::{
|
||||
Bin, Buffer, BufferList, Element, Event, FlowReturn, Message, Object, Pad, PadLinkReturn,
|
||||
Query, StateChange, StateChangeReturn, Tracer,
|
||||
Bin, Buffer, BufferList, Element, Event, FlowReturn, Message, MiniObject, Object, Pad,
|
||||
PadLinkReturn, Query, StateChange, StateChangeReturn, Tracer,
|
||||
};
|
||||
use glib::{prelude::*, subclass::prelude::*, translate::*};
|
||||
|
||||
|
@ -29,6 +29,14 @@ pub trait TracerImpl: TracerImplExt + ObjectImpl + Send + Sync {
|
|||
fn element_query_post(&self, ts: u64, element: &Element, query: &Query, success: bool) {}
|
||||
fn element_query_pre(&self, ts: u64, element: &Element, query: &Query) {}
|
||||
fn element_remove_pad(&self, ts: u64, element: &Element, pad: &Pad) {}
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Hook to be called before the GstMiniObject has been fully initialized.
|
||||
fn mini_object_created(&self, ts: u64, object: std::ptr::NonNull<ffi::GstMiniObject>) {}
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Hook to be called after the GstMiniObject has been finalized.
|
||||
fn mini_object_destroyed(&self, ts: u64, object: std::ptr::NonNull<ffi::GstMiniObject>) {}
|
||||
fn mini_object_reffed(&self, ts: u64, object: &MiniObject, new_refcount: i32) {}
|
||||
fn mini_object_unreffed(&self, ts: u64, object: &MiniObject, new_refcount: i32) {}
|
||||
fn object_created(&self, ts: u64, object: &Object) {}
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Hook to be called after the GstObject has been finalized.
|
||||
|
@ -169,11 +177,22 @@ define_tracer_hooks! {
|
|||
let p = Pad::from_glib_borrow(p);
|
||||
this.element_remove_pad(ts, &e, &p)
|
||||
};
|
||||
// TODO(#353): Missing bindings to `GstMiniObject`.
|
||||
// MiniObjectCreated,
|
||||
// MiniObjectDestroyed,
|
||||
// MiniObjectReffed,
|
||||
// MiniObjectUnreffed,
|
||||
// TODO: unclear what to do here as the `GstMiniObject` here is not fully initialized yet…
|
||||
MiniObjectCreated("mini-object-created") = |this, ts, o: *mut ffi::GstMiniObject| {
|
||||
this.mini_object_created(ts, std::ptr::NonNull::new_unchecked(o))
|
||||
};
|
||||
// TODO: unclear what to do here as the `GstMiniObject` here is no longer valid…
|
||||
MiniObjectDestroyed("mini-object-destroyed") = |this, ts, o: *mut ffi::GstMiniObject| {
|
||||
this.mini_object_destroyed(ts, std::ptr::NonNull::new_unchecked(o))
|
||||
};
|
||||
MiniObjectReffed("mini-object-reffed") = |this, ts, o: *mut ffi::GstMiniObject, rc: libc::c_int| {
|
||||
let o = MiniObject::from_glib_borrow(o);
|
||||
this.mini_object_reffed(ts, &o, rc as i32)
|
||||
};
|
||||
MiniObjectUnreffed("mini-object-unreffed") = |this, ts, o: *mut ffi::GstMiniObject, rc: libc::c_int| {
|
||||
let o = MiniObject::from_glib_borrow(o);
|
||||
this.mini_object_unreffed(ts, &o, rc as i32)
|
||||
};
|
||||
ObjectCreated("object-created") = |this, ts, o: *mut ffi::GstObject| {
|
||||
let o = Object::from_glib_borrow(o);
|
||||
this.object_created(ts, &o)
|
||||
|
|
|
@ -169,6 +169,13 @@ status = "generate"
|
|||
name = "steal"
|
||||
version = "1.18.3"
|
||||
|
||||
[[object]]
|
||||
name = "Gst.MiniObject"
|
||||
status = "generate"
|
||||
[[object.function]]
|
||||
name = "get_type"
|
||||
version = "1.20"
|
||||
|
||||
[[object]]
|
||||
name = "Gst.Memory"
|
||||
status = "generate"
|
||||
|
|
|
@ -5728,6 +5728,8 @@ extern "C" {
|
|||
//=========================================================================
|
||||
// GstMiniObject
|
||||
//=========================================================================
|
||||
#[cfg(any(feature = "v1_20", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
|
||||
pub fn gst_mini_object_get_type() -> GType;
|
||||
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))]
|
||||
|
|
Loading…
Reference in a new issue