From 37b717c0209be10e025b91bdcd3b98ce929d87fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Laignel?= Date: Sat, 2 Feb 2019 17:11:30 +0100 Subject: [PATCH] gstreamer-base: add parent_xxx impl for all vfunc --- gstreamer-base/src/subclass/base_sink.rs | 192 +++++++++++++-- gstreamer-base/src/subclass/base_src.rs | 168 +++++++++++-- gstreamer-base/src/subclass/base_transform.rs | 220 ++++++++++++++++-- 3 files changed, 521 insertions(+), 59 deletions(-) diff --git a/gstreamer-base/src/subclass/base_sink.rs b/gstreamer-base/src/subclass/base_sink.rs index 04a49b9fc..da592166f 100644 --- a/gstreamer-base/src/subclass/base_sink.rs +++ b/gstreamer-base/src/subclass/base_sink.rs @@ -23,12 +23,12 @@ use BaseSink; use BaseSinkClass; pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static { - fn start(&self, _element: &BaseSink) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn start(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> { + self.parent_start(element) } - fn stop(&self, _element: &BaseSink) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn stop(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> { + self.parent_stop(element) } fn render( @@ -39,10 +39,10 @@ pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static { fn prepare( &self, - _element: &BaseSink, - _buffer: &gst::BufferRef, + element: &BaseSink, + buffer: &gst::BufferRef, ) -> Result { - Ok(gst::FlowSuccess::Ok) + self.parent_prepare(element, buffer) } fn render_list( @@ -50,10 +50,7 @@ pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static { element: &BaseSink, list: &gst::BufferListRef, ) -> Result { - for buffer in list.iter() { - self.render(element, buffer)?; - } - Ok(gst::FlowSuccess::Ok) + self.parent_render_list(element, list) } fn prepare_list( @@ -61,10 +58,7 @@ pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static { element: &BaseSink, list: &gst::BufferListRef, ) -> Result { - for buffer in list.iter() { - self.prepare(element, buffer)?; - } - Ok(gst::FlowSuccess::Ok) + self.parent_prepare_list(element, list) } fn query(&self, element: &BaseSink, query: &mut gst::QueryRef) -> bool { @@ -87,12 +81,132 @@ pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static { self.parent_fixate(element, caps) } - fn unlock(&self, _element: &BaseSink) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn unlock(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> { + self.parent_unlock(element) } - fn unlock_stop(&self, _element: &BaseSink) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn unlock_stop(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> { + self.parent_unlock_stop(element) + } + + fn parent_start(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSinkClass; + (*parent_class) + .start + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::StateChange, + ["Parent function `start` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + + fn parent_stop(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSinkClass; + (*parent_class) + .stop + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::StateChange, + ["Parent function `stop` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + + fn parent_render( + &self, + element: &BaseSink, + buffer: &gst::BufferRef, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSinkClass; + (*parent_class) + .render + .map(|f| { + gst::FlowReturn::from_glib(f(element.to_glib_none().0, buffer.as_mut_ptr())) + }) + .unwrap_or(gst::FlowReturn::Ok) + .into_result() + } + } + + fn parent_prepare( + &self, + element: &BaseSink, + buffer: &gst::BufferRef, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSinkClass; + (*parent_class) + .prepare + .map(|f| from_glib(f(element.to_glib_none().0, buffer.as_mut_ptr()))) + .unwrap_or(gst::FlowReturn::Ok) + .into_result() + } + } + + fn parent_render_list( + &self, + element: &BaseSink, + list: &gst::BufferListRef, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSinkClass; + (*parent_class) + .render_list + .map(|f| { + gst::FlowReturn::from_glib(f(element.to_glib_none().0, list.as_mut_ptr())) + .into_result() + }) + .unwrap_or_else(|| { + for buffer in list.iter() { + self.render(element, buffer)?; + } + Ok(gst::FlowSuccess::Ok) + }) + } + } + + fn parent_prepare_list( + &self, + element: &BaseSink, + list: &gst::BufferListRef, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSinkClass; + (*parent_class) + .prepare_list + .map(|f| { + gst::FlowReturn::from_glib(f(element.to_glib_none().0, list.as_mut_ptr())) + .into_result() + }) + .unwrap_or_else(|| { + for buffer in list.iter() { + self.prepare(element, buffer)?; + } + Ok(gst::FlowSuccess::Ok) + }) + } } fn parent_query(&self, element: &BaseSink, query: &mut gst::QueryRef) -> bool { @@ -170,6 +284,46 @@ pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static { } } } + + fn parent_unlock(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSinkClass; + (*parent_class) + .unlock + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::Failed, + ["Parent function `unlock` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + + fn parent_unlock_stop(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSinkClass; + (*parent_class) + .unlock_stop + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::Failed, + ["Parent function `unlock_stop` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } } unsafe impl IsSubclassable for BaseSinkClass diff --git a/gstreamer-base/src/subclass/base_src.rs b/gstreamer-base/src/subclass/base_src.rs index 77b1c955e..ef5622b15 100644 --- a/gstreamer-base/src/subclass/base_src.rs +++ b/gstreamer-base/src/subclass/base_src.rs @@ -23,30 +23,30 @@ use BaseSrc; use BaseSrcClass; pub trait BaseSrcImpl: ElementImpl + Send + Sync + 'static { - fn start(&self, _element: &BaseSrc) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn start(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> { + self.parent_start(element) } - fn stop(&self, _element: &BaseSrc) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn stop(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> { + self.parent_stop(element) } - fn is_seekable(&self, _element: &BaseSrc) -> bool { - false + fn is_seekable(&self, element: &BaseSrc) -> bool { + self.parent_is_seekable(element) } - fn get_size(&self, _element: &BaseSrc) -> Option { - None + fn get_size(&self, element: &BaseSrc) -> Option { + self.parent_get_size(element) } fn fill( &self, - _element: &BaseSrc, - _offset: u64, - _length: u32, - _buffer: &mut gst::BufferRef, + element: &BaseSrc, + offset: u64, + length: u32, + buffer: &mut gst::BufferRef, ) -> Result { - unimplemented!() + self.parent_fill(element, offset, length, buffer) } fn create( @@ -86,12 +86,106 @@ pub trait BaseSrcImpl: ElementImpl + Send + Sync + 'static { self.parent_fixate(element, caps) } - fn unlock(&self, _element: &BaseSrc) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn unlock(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> { + self.parent_unlock(element) } - fn unlock_stop(&self, _element: &BaseSrc) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn unlock_stop(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> { + self.parent_unlock_stop(element) + } + + fn parent_start(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSrcClass; + (*parent_class) + .start + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::StateChange, + ["Parent function `start` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + + fn parent_stop(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSrcClass; + (*parent_class) + .stop + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::StateChange, + ["Parent function `stop` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + + fn parent_is_seekable(&self, element: &BaseSrc) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSrcClass; + (*parent_class) + .is_seekable + .map(|f| from_glib(f(element.to_glib_none().0))) + .unwrap_or(false) + } + } + + fn parent_get_size(&self, element: &BaseSrc) -> Option { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSrcClass; + (*parent_class) + .get_size + .map(|f| { + let mut size = 0; + if from_glib(f(element.to_glib_none().0, &mut size)) { + Some(size) + } else { + None + } + }) + .unwrap_or(None) + } + } + + fn parent_fill( + &self, + element: &BaseSrc, + offset: u64, + length: u32, + buffer: &mut gst::BufferRef, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSrcClass; + (*parent_class) + .fill + .map(|f| { + gst::FlowReturn::from_glib(f( + element.to_glib_none().0, + offset, + length, + buffer.as_mut_ptr(), + )) + }) + .unwrap_or(gst::FlowReturn::NotSupported) + .into_result() + } } fn parent_create( @@ -222,6 +316,46 @@ pub trait BaseSrcImpl: ElementImpl + Send + Sync + 'static { } } } + + fn parent_unlock(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSrcClass; + (*parent_class) + .unlock + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::Failed, + ["Parent function `unlock` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + + fn parent_unlock_stop(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseSrcClass; + (*parent_class) + .unlock_stop + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::Failed, + ["Parent function `unlock_stop` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } } unsafe impl IsSubclassable for BaseSrcClass diff --git a/gstreamer-base/src/subclass/base_transform.rs b/gstreamer-base/src/subclass/base_transform.rs index 7f9c531cc..5167289cb 100644 --- a/gstreamer-base/src/subclass/base_transform.rs +++ b/gstreamer-base/src/subclass/base_transform.rs @@ -21,12 +21,12 @@ use BaseTransform; use BaseTransformClass; pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static { - fn start(&self, _element: &BaseTransform) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn start(&self, element: &BaseTransform) -> Result<(), gst::ErrorMessage> { + self.parent_start(element) } - fn stop(&self, _element: &BaseTransform) -> Result<(), gst::ErrorMessage> { - Ok(()) + fn stop(&self, element: &BaseTransform) -> Result<(), gst::ErrorMessage> { + self.parent_stop(element) } fn transform_caps( @@ -49,13 +49,8 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static { self.parent_fixate_caps(element, direction, caps, othercaps) } - fn set_caps( - &self, - _element: &BaseTransform, - _incaps: &gst::Caps, - _outcaps: &gst::Caps, - ) -> bool { - true + fn set_caps(&self, element: &BaseTransform, incaps: &gst::Caps, outcaps: &gst::Caps) -> bool { + self.parent_set_caps(element, incaps, outcaps) } fn accept_caps( @@ -87,8 +82,8 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static { self.parent_transform_size(element, direction, caps, size, othercaps) } - fn get_unit_size(&self, _element: &BaseTransform, _caps: &gst::Caps) -> Option { - unimplemented!(); + fn get_unit_size(&self, element: &BaseTransform, caps: &gst::Caps) -> Option { + self.parent_get_unit_size(element, caps) } fn sink_event(&self, element: &BaseTransform, event: gst::Event) -> bool { @@ -101,27 +96,67 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static { fn transform( &self, - _element: &BaseTransform, - _inbuf: &gst::Buffer, - _outbuf: &mut gst::BufferRef, + element: &BaseTransform, + inbuf: &gst::Buffer, + outbuf: &mut gst::BufferRef, ) -> Result { - unimplemented!(); + self.parent_transform(element, inbuf, outbuf) } fn transform_ip( &self, - _element: &BaseTransform, - _buf: &mut gst::BufferRef, + element: &BaseTransform, + buf: &mut gst::BufferRef, ) -> Result { - unimplemented!(); + self.parent_transform_ip(element, buf) } fn transform_ip_passthrough( &self, - _element: &BaseTransform, - _buf: &gst::BufferRef, + element: &BaseTransform, + buf: &gst::BufferRef, ) -> Result { - unimplemented!(); + self.parent_transform_ip_passthrough(element, buf) + } + + fn parent_start(&self, element: &BaseTransform) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseTransformClass; + (*parent_class) + .start + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::StateChange, + ["Parent function `start` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + + fn parent_stop(&self, element: &BaseTransform) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseTransformClass; + (*parent_class) + .stop + .map(|f| { + if from_glib(f(element.to_glib_none().0)) { + Ok(()) + } else { + Err(gst_error_msg!( + gst::CoreError::StateChange, + ["Parent function `stop` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } } fn parent_transform_caps( @@ -170,6 +205,28 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static { } } + fn parent_set_caps( + &self, + element: &BaseTransform, + incaps: &gst::Caps, + outcaps: &gst::Caps, + ) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseTransformClass; + (*parent_class) + .set_caps + .map(|f| { + from_glib(f( + element.to_glib_none().0, + incaps.to_glib_none().0, + outcaps.to_glib_none().0, + )) + }) + .unwrap_or(true) + } + } + fn parent_accept_caps( &self, element: &BaseTransform, @@ -247,6 +304,37 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static { } } + fn parent_get_unit_size(&self, element: &BaseTransform, caps: &gst::Caps) -> Option { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseTransformClass; + let f = (*parent_class).get_unit_size.unwrap_or_else(|| { + if !element.is_in_place() { + unimplemented!(concat!( + "Missing parent function `get_unit_size`. Required because ", + "transform element doesn't operate in-place" + )) + } else { + unreachable!(concat!( + "parent `get_unit_size` called ", + "while transform element operates in-place" + )) + } + }); + + let mut size = 0; + if from_glib(f( + element.to_glib_none().0, + caps.to_glib_none().0, + &mut size, + )) { + Some(size) + } else { + None + } + } + } + fn parent_sink_event(&self, element: &BaseTransform, event: gst::Event) -> bool { unsafe { let data = self.get_type_data(); @@ -268,6 +356,92 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static { .unwrap_or(true) } } + + fn parent_transform( + &self, + element: &BaseTransform, + inbuf: &gst::Buffer, + outbuf: &mut gst::BufferRef, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseTransformClass; + (*parent_class) + .transform + .map(|f| { + from_glib(f( + element.to_glib_none().0, + inbuf.to_glib_none().0, + outbuf.as_mut_ptr(), + )) + }) + .unwrap_or_else(|| { + if !element.is_in_place() { + gst::FlowReturn::NotSupported + } else { + unreachable!(concat!( + "parent `transform` called ", + "while transform element operates in-place" + )); + } + }) + .into_result() + } + } + + fn parent_transform_ip( + &self, + element: &BaseTransform, + buf: &mut gst::BufferRef, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseTransformClass; + let f = (*parent_class).transform_ip.unwrap_or_else(|| { + if element.is_in_place() { + panic!(concat!( + "Missing parent function `transform_ip`. Required because ", + "transform element operates in-place" + )); + } else { + unreachable!(concat!( + "parent `transform` called ", + "while transform element doesn't operate in-place" + )); + } + }); + + gst::FlowReturn::from_glib(f(element.to_glib_none().0, &mut buf.as_mut_ptr())) + .into_result() + } + } + + fn parent_transform_ip_passthrough( + &self, + element: &BaseTransform, + buf: &gst::BufferRef, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBaseTransformClass; + let f = (*parent_class).transform_ip.unwrap_or_else(|| { + if element.is_in_place() { + panic!(concat!( + "Missing parent function `transform_ip`. Required because ", + "transform element operates in-place (passthrough mode)" + )); + } else { + unreachable!(concat!( + "parent `transform_ip` called ", + "while transform element doesn't operate in-place (passthrough mode)" + )); + } + }); + + gst::FlowReturn::from_glib(f(element.to_glib_none().0, &mut buf.as_mut_ptr())) + .into_result() + } + } } #[derive(Copy, Clone, Debug, PartialEq, Eq)]