gstreamer-base: add parent_xxx impl for all vfunc

This commit is contained in:
François Laignel 2019-02-02 17:11:30 +01:00 committed by Sebastian Dröge
parent fcb46ee5bf
commit 37b717c020
3 changed files with 521 additions and 59 deletions

View file

@ -23,12 +23,12 @@ use BaseSink;
use BaseSinkClass; use BaseSinkClass;
pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static { pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static {
fn start(&self, _element: &BaseSink) -> Result<(), gst::ErrorMessage> { fn start(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> {
Ok(()) self.parent_start(element)
} }
fn stop(&self, _element: &BaseSink) -> Result<(), gst::ErrorMessage> { fn stop(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> {
Ok(()) self.parent_stop(element)
} }
fn render( fn render(
@ -39,10 +39,10 @@ pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static {
fn prepare( fn prepare(
&self, &self,
_element: &BaseSink, element: &BaseSink,
_buffer: &gst::BufferRef, buffer: &gst::BufferRef,
) -> Result<gst::FlowSuccess, gst::FlowError> { ) -> Result<gst::FlowSuccess, gst::FlowError> {
Ok(gst::FlowSuccess::Ok) self.parent_prepare(element, buffer)
} }
fn render_list( fn render_list(
@ -50,10 +50,7 @@ pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static {
element: &BaseSink, element: &BaseSink,
list: &gst::BufferListRef, list: &gst::BufferListRef,
) -> Result<gst::FlowSuccess, gst::FlowError> { ) -> Result<gst::FlowSuccess, gst::FlowError> {
for buffer in list.iter() { self.parent_render_list(element, list)
self.render(element, buffer)?;
}
Ok(gst::FlowSuccess::Ok)
} }
fn prepare_list( fn prepare_list(
@ -61,10 +58,7 @@ pub trait BaseSinkImpl: ElementImpl + Send + Sync + 'static {
element: &BaseSink, element: &BaseSink,
list: &gst::BufferListRef, list: &gst::BufferListRef,
) -> Result<gst::FlowSuccess, gst::FlowError> { ) -> Result<gst::FlowSuccess, gst::FlowError> {
for buffer in list.iter() { self.parent_prepare_list(element, list)
self.prepare(element, buffer)?;
}
Ok(gst::FlowSuccess::Ok)
} }
fn query(&self, element: &BaseSink, query: &mut gst::QueryRef) -> bool { 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) self.parent_fixate(element, caps)
} }
fn unlock(&self, _element: &BaseSink) -> Result<(), gst::ErrorMessage> { fn unlock(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> {
Ok(()) self.parent_unlock(element)
} }
fn unlock_stop(&self, _element: &BaseSink) -> Result<(), gst::ErrorMessage> { fn unlock_stop(&self, element: &BaseSink) -> Result<(), gst::ErrorMessage> {
Ok(()) 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<gst::FlowSuccess, gst::FlowError> {
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<gst::FlowSuccess, gst::FlowError> {
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<gst::FlowSuccess, gst::FlowError> {
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<gst::FlowSuccess, gst::FlowError> {
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 { 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<T: ObjectSubclass + BaseSinkImpl> IsSubclassable<T> for BaseSinkClass unsafe impl<T: ObjectSubclass + BaseSinkImpl> IsSubclassable<T> for BaseSinkClass

View file

@ -23,30 +23,30 @@ use BaseSrc;
use BaseSrcClass; use BaseSrcClass;
pub trait BaseSrcImpl: ElementImpl + Send + Sync + 'static { pub trait BaseSrcImpl: ElementImpl + Send + Sync + 'static {
fn start(&self, _element: &BaseSrc) -> Result<(), gst::ErrorMessage> { fn start(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> {
Ok(()) self.parent_start(element)
} }
fn stop(&self, _element: &BaseSrc) -> Result<(), gst::ErrorMessage> { fn stop(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> {
Ok(()) self.parent_stop(element)
} }
fn is_seekable(&self, _element: &BaseSrc) -> bool { fn is_seekable(&self, element: &BaseSrc) -> bool {
false self.parent_is_seekable(element)
} }
fn get_size(&self, _element: &BaseSrc) -> Option<u64> { fn get_size(&self, element: &BaseSrc) -> Option<u64> {
None self.parent_get_size(element)
} }
fn fill( fn fill(
&self, &self,
_element: &BaseSrc, element: &BaseSrc,
_offset: u64, offset: u64,
_length: u32, length: u32,
_buffer: &mut gst::BufferRef, buffer: &mut gst::BufferRef,
) -> Result<gst::FlowSuccess, gst::FlowError> { ) -> Result<gst::FlowSuccess, gst::FlowError> {
unimplemented!() self.parent_fill(element, offset, length, buffer)
} }
fn create( fn create(
@ -86,12 +86,106 @@ pub trait BaseSrcImpl: ElementImpl + Send + Sync + 'static {
self.parent_fixate(element, caps) self.parent_fixate(element, caps)
} }
fn unlock(&self, _element: &BaseSrc) -> Result<(), gst::ErrorMessage> { fn unlock(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> {
Ok(()) self.parent_unlock(element)
} }
fn unlock_stop(&self, _element: &BaseSrc) -> Result<(), gst::ErrorMessage> { fn unlock_stop(&self, element: &BaseSrc) -> Result<(), gst::ErrorMessage> {
Ok(()) 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<u64> {
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<gst::FlowSuccess, gst::FlowError> {
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( 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<T: ObjectSubclass + BaseSrcImpl> IsSubclassable<T> for BaseSrcClass unsafe impl<T: ObjectSubclass + BaseSrcImpl> IsSubclassable<T> for BaseSrcClass

View file

@ -21,12 +21,12 @@ use BaseTransform;
use BaseTransformClass; use BaseTransformClass;
pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static { pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static {
fn start(&self, _element: &BaseTransform) -> Result<(), gst::ErrorMessage> { fn start(&self, element: &BaseTransform) -> Result<(), gst::ErrorMessage> {
Ok(()) self.parent_start(element)
} }
fn stop(&self, _element: &BaseTransform) -> Result<(), gst::ErrorMessage> { fn stop(&self, element: &BaseTransform) -> Result<(), gst::ErrorMessage> {
Ok(()) self.parent_stop(element)
} }
fn transform_caps( fn transform_caps(
@ -49,13 +49,8 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static {
self.parent_fixate_caps(element, direction, caps, othercaps) self.parent_fixate_caps(element, direction, caps, othercaps)
} }
fn set_caps( fn set_caps(&self, element: &BaseTransform, incaps: &gst::Caps, outcaps: &gst::Caps) -> bool {
&self, self.parent_set_caps(element, incaps, outcaps)
_element: &BaseTransform,
_incaps: &gst::Caps,
_outcaps: &gst::Caps,
) -> bool {
true
} }
fn accept_caps( fn accept_caps(
@ -87,8 +82,8 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static {
self.parent_transform_size(element, direction, caps, size, othercaps) self.parent_transform_size(element, direction, caps, size, othercaps)
} }
fn get_unit_size(&self, _element: &BaseTransform, _caps: &gst::Caps) -> Option<usize> { fn get_unit_size(&self, element: &BaseTransform, caps: &gst::Caps) -> Option<usize> {
unimplemented!(); self.parent_get_unit_size(element, caps)
} }
fn sink_event(&self, element: &BaseTransform, event: gst::Event) -> bool { fn sink_event(&self, element: &BaseTransform, event: gst::Event) -> bool {
@ -101,27 +96,67 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static {
fn transform( fn transform(
&self, &self,
_element: &BaseTransform, element: &BaseTransform,
_inbuf: &gst::Buffer, inbuf: &gst::Buffer,
_outbuf: &mut gst::BufferRef, outbuf: &mut gst::BufferRef,
) -> Result<gst::FlowSuccess, gst::FlowError> { ) -> Result<gst::FlowSuccess, gst::FlowError> {
unimplemented!(); self.parent_transform(element, inbuf, outbuf)
} }
fn transform_ip( fn transform_ip(
&self, &self,
_element: &BaseTransform, element: &BaseTransform,
_buf: &mut gst::BufferRef, buf: &mut gst::BufferRef,
) -> Result<gst::FlowSuccess, gst::FlowError> { ) -> Result<gst::FlowSuccess, gst::FlowError> {
unimplemented!(); self.parent_transform_ip(element, buf)
} }
fn transform_ip_passthrough( fn transform_ip_passthrough(
&self, &self,
_element: &BaseTransform, element: &BaseTransform,
_buf: &gst::BufferRef, buf: &gst::BufferRef,
) -> Result<gst::FlowSuccess, gst::FlowError> { ) -> Result<gst::FlowSuccess, gst::FlowError> {
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( 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( fn parent_accept_caps(
&self, &self,
element: &BaseTransform, 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<usize> {
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 { fn parent_sink_event(&self, element: &BaseTransform, event: gst::Event) -> bool {
unsafe { unsafe {
let data = self.get_type_data(); let data = self.get_type_data();
@ -268,6 +356,92 @@ pub trait BaseTransformImpl: ElementImpl + Send + Sync + 'static {
.unwrap_or(true) .unwrap_or(true)
} }
} }
fn parent_transform(
&self,
element: &BaseTransform,
inbuf: &gst::Buffer,
outbuf: &mut gst::BufferRef,
) -> Result<gst::FlowSuccess, gst::FlowError> {
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<gst::FlowSuccess, gst::FlowError> {
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<gst::FlowSuccess, gst::FlowError> {
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)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]