From 6ee12d49ee4afa696cf895782559a61a858a8f88 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 29 Apr 2021 18:13:37 +0200 Subject: [PATCH] gl: Add subclass implementation for GLBaseSrc, inheriting PushSrc --- gstreamer-gl/src/subclass/gl_base_src.rs | 156 +++++++++++++++++++++++ gstreamer-gl/src/subclass/mod.rs | 6 + 2 files changed, 162 insertions(+) create mode 100644 gstreamer-gl/src/subclass/gl_base_src.rs diff --git a/gstreamer-gl/src/subclass/gl_base_src.rs b/gstreamer-gl/src/subclass/gl_base_src.rs new file mode 100644 index 000000000..9a2e42d8a --- /dev/null +++ b/gstreamer-gl/src/subclass/gl_base_src.rs @@ -0,0 +1,156 @@ +use ffi::{GstGLBaseSrc, GstGLMemory}; + +use crate::prelude::*; + +use glib::translate::*; + +use gst::{result_from_gboolean, LoggableError, CAT_RUST}; +use gst_base::subclass::prelude::*; + +use crate::{GLBaseSrc, GLMemory, GLAPI}; + +pub trait GLBaseSrcImpl: GLBaseSrcImplExt + PushSrcImpl { + const SUPPORTED_GL_API: GLAPI; + + fn gl_start(&self, element: &Self::Type) -> Result<(), LoggableError> { + self.parent_gl_start(element) + } + + fn gl_stop(&self, element: &Self::Type) { + self.parent_gl_stop(element) + } + + fn fill_gl_memory(&self, element: &Self::Type, memory: &GLMemory) -> Result<(), LoggableError> { + self.parent_fill_gl_memory(element, memory) + } +} + +pub trait GLBaseSrcImplExt: ObjectSubclass { + fn parent_gl_start(&self, element: &Self::Type) -> Result<(), LoggableError>; + + fn parent_gl_stop(&self, element: &Self::Type); + + fn parent_fill_gl_memory( + &self, + element: &Self::Type, + memory: &GLMemory, + ) -> Result<(), LoggableError>; +} + +impl GLBaseSrcImplExt for T { + fn parent_gl_start(&self, element: &Self::Type) -> Result<(), LoggableError> { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstGLBaseSrcClass; + + (*parent_class) + .gl_start + .map(|f| { + result_from_gboolean!( + f(element.unsafe_cast_ref::().to_glib_none().0), + CAT_RUST, + "Parent function `gl_start` failed", + ) + }) + .unwrap_or(Ok(())) + } + } + + fn parent_gl_stop(&self, element: &Self::Type) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstGLBaseSrcClass; + + if let Some(f) = (*parent_class).gl_stop { + f(element.unsafe_cast_ref::().to_glib_none().0) + } + } + } + + fn parent_fill_gl_memory( + &self, + element: &Self::Type, + memory: &GLMemory, + ) -> Result<(), LoggableError> { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstGLBaseSrcClass; + + (*parent_class) + .fill_gl_memory + .map(|f| { + result_from_gboolean!( + f( + element.unsafe_cast_ref::().to_glib_none().0, + mut_override(memory.to_glib_none().0), + ), + CAT_RUST, + "Parent function `fill_gl_memory` failed", + ) + }) + .unwrap_or(Ok(())) + } + } +} + +unsafe impl IsSubclassable for GLBaseSrc { + fn class_init(klass: &mut glib::Class) { + >::class_init(klass); + let klass = klass.as_mut(); + klass.supported_gl_api = T::SUPPORTED_GL_API.into_glib(); + klass.gl_start = Some(gl_start::); + klass.gl_stop = Some(gl_stop::); + klass.fill_gl_memory = Some(fill_gl_memory::); + } + + fn instance_init(instance: &mut glib::subclass::InitializingObject) { + >::instance_init(instance) + } +} + +unsafe extern "C" fn gl_start(ptr: *mut GstGLBaseSrc) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.impl_(); + let wrap: Borrowed = from_glib_borrow(ptr); + + gst::panic_to_error!(&wrap, &imp.panicked(), false, { + match imp.gl_start(wrap.unsafe_cast_ref()) { + Ok(()) => true, + Err(err) => { + err.log_with_object(&*wrap); + false + } + } + }) + .into_glib() +} + +unsafe extern "C" fn gl_stop(ptr: *mut GstGLBaseSrc) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.impl_(); + let wrap: Borrowed = from_glib_borrow(ptr); + + gst::panic_to_error!(&wrap, &imp.panicked(), (), { + imp.gl_stop(wrap.unsafe_cast_ref()) + }) +} + +unsafe extern "C" fn fill_gl_memory( + ptr: *mut GstGLBaseSrc, + memory: *mut GstGLMemory, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.impl_(); + let wrap: Borrowed = from_glib_borrow(ptr); + + gst::panic_to_error!(&wrap, &imp.panicked(), false, { + match imp.fill_gl_memory(wrap.unsafe_cast_ref(), &from_glib_borrow(memory)) { + Ok(()) => true, + Err(err) => { + err.log_with_object(&*wrap); + false + } + } + }) + .into_glib() +} diff --git a/gstreamer-gl/src/subclass/mod.rs b/gstreamer-gl/src/subclass/mod.rs index 271fcb228..d12b1de16 100644 --- a/gstreamer-gl/src/subclass/mod.rs +++ b/gstreamer-gl/src/subclass/mod.rs @@ -1,4 +1,7 @@ mod gl_base_filter; +#[cfg(any(feature = "v1_18", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] +mod gl_base_src; mod gl_filter; pub use self::gl_filter::GLFilterMode; @@ -8,5 +11,8 @@ pub mod prelude { pub use gst_video::subclass::prelude::*; pub use super::gl_base_filter::{GLBaseFilterImpl, GLBaseFilterImplExt}; + #[cfg(any(feature = "v1_18", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] + pub use super::gl_base_src::{GLBaseSrcImpl, GLBaseSrcImplExt}; pub use super::gl_filter::{GLFilterImpl, GLFilterImplExt}; }