From 27385104d81e16a5b4869efe0ff9bb7c5498dd8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 14 Mar 2021 10:29:44 +0200 Subject: [PATCH] Update for glib interface API changes --- .../src/subclass/player_video_renderer.rs | 38 +++++- gstreamer/src/element.rs | 2 +- gstreamer/src/pad.rs | 2 +- gstreamer/src/subclass/child_proxy.rs | 117 +++++++++++++++--- gstreamer/src/subclass/preset.rs | 2 +- gstreamer/src/subclass/tag_setter.rs | 2 +- gstreamer/src/subclass/uri_handler.rs | 65 +++++++++- 7 files changed, 204 insertions(+), 24 deletions(-) diff --git a/gstreamer-player/src/subclass/player_video_renderer.rs b/gstreamer-player/src/subclass/player_video_renderer.rs index 1d13e5190..0249f72de 100644 --- a/gstreamer-player/src/subclass/player_video_renderer.rs +++ b/gstreamer-player/src/subclass/player_video_renderer.rs @@ -11,7 +11,7 @@ pub trait PlayerVideoRendererImpl: ObjectImpl { } unsafe impl IsImplementable for PlayerVideoRenderer { - fn interface_init(iface: &mut glib::Class) { + fn interface_init(iface: &mut glib::Interface) { let iface = iface.as_mut(); iface.create_video_sink = Some(video_renderer_create_video_sink::); @@ -20,6 +20,42 @@ unsafe impl IsImplementable for PlayerVideoRender fn instance_init(_instance: &mut glib::subclass::InitializingObject) {} } +pub trait PlayerVideoRendererImplExt: ObjectSubclass { + fn parent_create_video_sink( + &self, + video_renderer: &Self::Type, + player: &Player, + ) -> gst::Element; +} + +impl PlayerVideoRendererImplExt for T { + fn parent_create_video_sink( + &self, + video_renderer: &Self::Type, + player: &Player, + ) -> gst::Element { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data + .as_ref() + .get_parent_interface::() + as *const ffi::GstPlayerVideoRendererInterface; + + let func = (*parent_iface) + .create_video_sink + .expect("no parent \"create_video_sink\" implementation"); + let ret = func( + video_renderer + .unsafe_cast_ref::() + .to_glib_none() + .0, + player.to_glib_none().0, + ); + from_glib_none(ret) + } + } +} + unsafe extern "C" fn video_renderer_create_video_sink( video_renderer: *mut ffi::GstPlayerVideoRenderer, player: *mut ffi::GstPlayer, diff --git a/gstreamer/src/element.rs b/gstreamer/src/element.rs index 766961607..99b1c215d 100644 --- a/gstreamer/src/element.rs +++ b/gstreamer/src/element.rs @@ -878,7 +878,7 @@ pub unsafe trait ElementClassExt { } } -unsafe impl> ElementClassExt for glib::object::Class {} +unsafe impl + glib::object::IsClass> ElementClassExt for glib::object::Class {} pub static ELEMENT_METADATA_AUTHOR: Lazy<&'static str> = Lazy::new(|| unsafe { CStr::from_ptr(ffi::GST_ELEMENT_METADATA_AUTHOR) diff --git a/gstreamer/src/pad.rs b/gstreamer/src/pad.rs index 36ee3a0b3..8c84c8cd4 100644 --- a/gstreamer/src/pad.rs +++ b/gstreamer/src/pad.rs @@ -1624,7 +1624,7 @@ impl Pad { pub struct PadBuilder(pub(crate) T); -impl + IsA> PadBuilder { +impl + IsA + glib::object::IsClass> PadBuilder { pub fn new(name: Option<&str>, direction: crate::PadDirection) -> Self { assert_initialized_main_thread!(); diff --git a/gstreamer/src/subclass/child_proxy.rs b/gstreamer/src/subclass/child_proxy.rs index 94bcba82c..5438cc2df 100644 --- a/gstreamer/src/subclass/child_proxy.rs +++ b/gstreamer/src/subclass/child_proxy.rs @@ -8,32 +8,113 @@ use crate::ChildProxy; pub trait ChildProxyImpl: ObjectImpl + Send + Sync { fn get_child_by_name(&self, object: &Self::Type, name: &str) -> Option { - unsafe { - let type_ = ffi::gst_child_proxy_get_type(); - let iface = glib::gobject_ffi::g_type_default_interface_ref(type_) - as *mut ffi::GstChildProxyInterface; - assert!(!iface.is_null()); - - let ret = ((*iface).get_child_by_name.as_ref().unwrap())( - object.unsafe_cast_ref::().to_glib_none().0, - name.to_glib_none().0, - ); - - glib::gobject_ffi::g_type_default_interface_unref(iface as glib::ffi::gpointer); - - from_glib_full(ret) - } + self.parent_get_child_by_name(object, name) } fn get_child_by_index(&self, object: &Self::Type, index: u32) -> Option; fn get_children_count(&self, object: &Self::Type) -> u32; - fn child_added(&self, _object: &Self::Type, _child: &glib::Object, _name: &str) {} - fn child_removed(&self, _object: &Self::Type, _child: &glib::Object, _name: &str) {} + fn child_added(&self, object: &Self::Type, child: &glib::Object, name: &str) { + self.parent_child_added(object, child, name); + } + fn child_removed(&self, object: &Self::Type, child: &glib::Object, name: &str) { + self.parent_child_removed(object, child, name); + } +} + +pub trait ChildProxyImplExt: ObjectSubclass { + fn parent_get_child_by_name(&self, object: &Self::Type, name: &str) -> Option; + + fn parent_get_child_by_index(&self, object: &Self::Type, index: u32) -> Option; + fn parent_get_children_count(&self, object: &Self::Type) -> u32; + + fn parent_child_added(&self, _object: &Self::Type, _child: &glib::Object, _name: &str); + fn parent_child_removed(&self, _object: &Self::Type, _child: &glib::Object, _name: &str); +} + +impl ChildProxyImplExt for T { + fn parent_get_child_by_name(&self, object: &Self::Type, name: &str) -> Option { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().get_parent_interface::() + as *const ffi::GstChildProxyInterface; + + let func = (*parent_iface) + .get_child_by_name + .expect("no parent \"get_child_by_name\" implementation"); + let ret = func( + object.unsafe_cast_ref::().to_glib_none().0, + name.to_glib_none().0, + ); + from_glib_full(ret) + } + } + + fn parent_get_child_by_index(&self, object: &Self::Type, index: u32) -> Option { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().get_parent_interface::() + as *const ffi::GstChildProxyInterface; + + let func = (*parent_iface) + .get_child_by_index + .expect("no parent \"get_child_by_index\" implementation"); + let ret = func( + object.unsafe_cast_ref::().to_glib_none().0, + index, + ); + from_glib_full(ret) + } + } + + fn parent_get_children_count(&self, object: &Self::Type) -> u32 { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().get_parent_interface::() + as *const ffi::GstChildProxyInterface; + + let func = (*parent_iface) + .get_children_count + .expect("no parent \"get_children_count\" implementation"); + func(object.unsafe_cast_ref::().to_glib_none().0) + } + } + + fn parent_child_added(&self, object: &Self::Type, child: &glib::Object, name: &str) { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().get_parent_interface::() + as *const ffi::GstChildProxyInterface; + + if let Some(func) = (*parent_iface).child_added { + func( + object.unsafe_cast_ref::().to_glib_none().0, + child.to_glib_none().0, + name.to_glib_none().0, + ); + } + } + } + + fn parent_child_removed(&self, object: &Self::Type, child: &glib::Object, name: &str) { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().get_parent_interface::() + as *const ffi::GstChildProxyInterface; + + if let Some(func) = (*parent_iface).child_removed { + func( + object.unsafe_cast_ref::().to_glib_none().0, + child.to_glib_none().0, + name.to_glib_none().0, + ); + } + } + } } unsafe impl IsImplementable for ChildProxy { - fn interface_init(iface: &mut glib::Class) { + fn interface_init(iface: &mut glib::Interface) { let iface = iface.as_mut(); iface.get_child_by_name = Some(child_proxy_get_child_by_name::); diff --git a/gstreamer/src/subclass/preset.rs b/gstreamer/src/subclass/preset.rs index 9b99c8d0d..2c3ca85d4 100644 --- a/gstreamer/src/subclass/preset.rs +++ b/gstreamer/src/subclass/preset.rs @@ -7,7 +7,7 @@ use crate::Preset; pub trait PresetImpl: super::element::ElementImpl {} unsafe impl IsImplementable for Preset { - fn interface_init(_iface: &mut glib::Class) {} + fn interface_init(_iface: &mut glib::Interface) {} fn instance_init(_instance: &mut glib::subclass::InitializingObject) {} } diff --git a/gstreamer/src/subclass/tag_setter.rs b/gstreamer/src/subclass/tag_setter.rs index ac944a07a..b7b9153a3 100644 --- a/gstreamer/src/subclass/tag_setter.rs +++ b/gstreamer/src/subclass/tag_setter.rs @@ -7,6 +7,6 @@ use crate::TagSetter; pub trait TagSetterImpl: super::element::ElementImpl {} unsafe impl IsImplementable for TagSetter { - fn interface_init(_iface: &mut glib::Class) {} + fn interface_init(_iface: &mut glib::Interface) {} fn instance_init(_instance: &mut glib::subclass::InitializingObject) {} } diff --git a/gstreamer/src/subclass/uri_handler.rs b/gstreamer/src/subclass/uri_handler.rs index b464944d9..c2ce8480e 100644 --- a/gstreamer/src/subclass/uri_handler.rs +++ b/gstreamer/src/subclass/uri_handler.rs @@ -8,6 +8,8 @@ use glib::subclass::prelude::*; use crate::URIHandler; use crate::URIType; +use std::ptr; + pub trait URIHandlerImpl: super::element::ElementImpl { const URI_TYPE: URIType; fn get_protocols() -> &'static [&'static str]; @@ -15,13 +17,74 @@ pub trait URIHandlerImpl: super::element::ElementImpl { fn set_uri(&self, element: &Self::Type, uri: &str) -> Result<(), glib::Error>; } +pub trait URIHandlerImplExt: ObjectSubclass { + fn parent_get_protocols() -> Vec; + fn parent_get_uri(&self, element: &Self::Type) -> Option; + fn parent_set_uri(&self, element: &Self::Type, uri: &str) -> Result<(), glib::Error>; +} + +impl URIHandlerImplExt for T { + fn parent_get_protocols() -> Vec { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().get_parent_interface::() + as *const ffi::GstURIHandlerInterface; + + let func = (*parent_iface) + .get_protocols + .expect("no parent \"get_protocols\" implementation"); + let ret = func(Self::ParentType::static_type().to_glib()); + FromGlibPtrContainer::from_glib_none(ret) + } + } + + fn parent_get_uri(&self, element: &Self::Type) -> Option { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().get_parent_interface::() + as *const ffi::GstURIHandlerInterface; + + let func = (*parent_iface) + .get_uri + .expect("no parent \"get_uri\" implementation"); + let ret = func(element.unsafe_cast_ref::().to_glib_none().0); + from_glib_full(ret) + } + } + + fn parent_set_uri(&self, element: &Self::Type, uri: &str) -> Result<(), glib::Error> { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().get_parent_interface::() + as *const ffi::GstURIHandlerInterface; + + let func = (*parent_iface) + .set_uri + .expect("no parent \"set_uri\" implementation"); + + let mut err = ptr::null_mut(); + func( + element.unsafe_cast_ref::().to_glib_none().0, + uri.to_glib_none().0, + &mut err, + ); + + if !err.is_null() { + Err(from_glib_full(err)) + } else { + Ok(()) + } + } + } +} + // Send+Sync wrapper around a NULL-terminated C string array struct CStrV(*const *const libc::c_char); unsafe impl Send for CStrV {} unsafe impl Sync for CStrV {} unsafe impl IsImplementable for URIHandler { - fn interface_init(iface: &mut glib::Class) { + fn interface_init(iface: &mut glib::Interface) { let iface = iface.as_mut(); // Store the protocols in the interface data for later use