forked from mirrors/gstreamer-rs
gstreamer/base_transform: Add support for implementing prepare_output_buffer()
This requires some acrobatics due to inconsistent ownership handling of the buffers on the C side.
This commit is contained in:
parent
71497e77de
commit
e0a71563ba
1 changed files with 88 additions and 0 deletions
|
@ -102,6 +102,14 @@ pub trait BaseTransformImpl: BaseTransformImplExt + ElementImpl + Send + Sync +
|
||||||
self.parent_src_event(element, event)
|
self.parent_src_event(element, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn prepare_output_buffer(
|
||||||
|
&self,
|
||||||
|
element: &BaseTransform,
|
||||||
|
inbuf: &gst::BufferRef,
|
||||||
|
) -> Result<PreparedOutputBuffer, gst::FlowError> {
|
||||||
|
self.parent_prepare_output_buffer(element, inbuf)
|
||||||
|
}
|
||||||
|
|
||||||
fn transform(
|
fn transform(
|
||||||
&self,
|
&self,
|
||||||
element: &BaseTransform,
|
element: &BaseTransform,
|
||||||
|
@ -221,6 +229,12 @@ pub trait BaseTransformImplExt {
|
||||||
|
|
||||||
fn parent_src_event(&self, element: &BaseTransform, event: gst::Event) -> bool;
|
fn parent_src_event(&self, element: &BaseTransform, event: gst::Event) -> bool;
|
||||||
|
|
||||||
|
fn parent_prepare_output_buffer(
|
||||||
|
&self,
|
||||||
|
element: &BaseTransform,
|
||||||
|
inbuf: &gst::BufferRef,
|
||||||
|
) -> Result<PreparedOutputBuffer, gst::FlowError>;
|
||||||
|
|
||||||
fn parent_transform(
|
fn parent_transform(
|
||||||
&self,
|
&self,
|
||||||
element: &BaseTransform,
|
element: &BaseTransform,
|
||||||
|
@ -534,6 +548,41 @@ impl<T: BaseTransformImpl + ObjectImpl> BaseTransformImplExt for T {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent_prepare_output_buffer(
|
||||||
|
&self,
|
||||||
|
element: &BaseTransform,
|
||||||
|
inbuf: &gst::BufferRef,
|
||||||
|
) -> Result<PreparedOutputBuffer, gst::FlowError> {
|
||||||
|
unsafe {
|
||||||
|
let data = self.get_type_data();
|
||||||
|
let parent_class =
|
||||||
|
data.as_ref().get_parent_class() as *mut gst_base_sys::GstBaseTransformClass;
|
||||||
|
(*parent_class)
|
||||||
|
.prepare_output_buffer
|
||||||
|
.map(|f| {
|
||||||
|
let mut outbuf: *mut gst_sys::GstBuffer = ptr::null_mut();
|
||||||
|
// FIXME: Wrong signature in FFI
|
||||||
|
let res = from_glib(f(
|
||||||
|
element.to_glib_none().0,
|
||||||
|
inbuf.as_ptr() as *mut gst_sys::GstBuffer,
|
||||||
|
(&mut outbuf) as *mut *mut gst_sys::GstBuffer as *mut gst_sys::GstBuffer,
|
||||||
|
));
|
||||||
|
|
||||||
|
match gst::FlowReturn::into_result(res) {
|
||||||
|
Err(err) => Err(err),
|
||||||
|
Ok(_) => {
|
||||||
|
if outbuf == inbuf.as_ptr() as *mut _ {
|
||||||
|
Ok(PreparedOutputBuffer::InputBuffer)
|
||||||
|
} else {
|
||||||
|
Ok(PreparedOutputBuffer::Buffer(from_glib_full(outbuf)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or(Err(gst::FlowError::NotSupported))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parent_transform(
|
fn parent_transform(
|
||||||
&self,
|
&self,
|
||||||
element: &BaseTransform,
|
element: &BaseTransform,
|
||||||
|
@ -792,6 +841,7 @@ where
|
||||||
klass.query = Some(base_transform_query::<T>);
|
klass.query = Some(base_transform_query::<T>);
|
||||||
klass.transform_size = Some(base_transform_transform_size::<T>);
|
klass.transform_size = Some(base_transform_transform_size::<T>);
|
||||||
klass.get_unit_size = Some(base_transform_get_unit_size::<T>);
|
klass.get_unit_size = Some(base_transform_get_unit_size::<T>);
|
||||||
|
klass.prepare_output_buffer = Some(base_transform_prepare_output_buffer::<T>);
|
||||||
klass.sink_event = Some(base_transform_sink_event::<T>);
|
klass.sink_event = Some(base_transform_sink_event::<T>);
|
||||||
klass.src_event = Some(base_transform_src_event::<T>);
|
klass.src_event = Some(base_transform_src_event::<T>);
|
||||||
klass.transform_meta = Some(base_transform_transform_meta::<T>);
|
klass.transform_meta = Some(base_transform_transform_meta::<T>);
|
||||||
|
@ -849,6 +899,12 @@ pub enum GeneratedOutput {
|
||||||
Dropped,
|
Dropped,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum PreparedOutputBuffer {
|
||||||
|
Buffer(gst::Buffer),
|
||||||
|
InputBuffer,
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn base_transform_start<T: ObjectSubclass>(
|
unsafe extern "C" fn base_transform_start<T: ObjectSubclass>(
|
||||||
ptr: *mut gst_base_sys::GstBaseTransform,
|
ptr: *mut gst_base_sys::GstBaseTransform,
|
||||||
) -> glib_sys::gboolean
|
) -> glib_sys::gboolean
|
||||||
|
@ -1079,6 +1135,38 @@ where
|
||||||
.to_glib()
|
.to_glib()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn base_transform_prepare_output_buffer<T: ObjectSubclass>(
|
||||||
|
ptr: *mut gst_base_sys::GstBaseTransform,
|
||||||
|
inbuf: *mut gst_sys::GstBuffer,
|
||||||
|
outbuf: *mut gst_sys::GstBuffer,
|
||||||
|
) -> gst_sys::GstFlowReturn
|
||||||
|
where
|
||||||
|
T: BaseTransformImpl,
|
||||||
|
T::Instance: PanicPoison,
|
||||||
|
{
|
||||||
|
let instance = &*(ptr as *mut T::Instance);
|
||||||
|
let imp = instance.get_impl();
|
||||||
|
let wrap: BaseTransform = from_glib_borrow(ptr);
|
||||||
|
|
||||||
|
// FIXME: Wrong signature in FFI
|
||||||
|
let outbuf = outbuf as *mut *mut gst_sys::GstBuffer;
|
||||||
|
|
||||||
|
gst_panic_to_error!(&wrap, &instance.panicked(), gst::FlowReturn::Error, {
|
||||||
|
match imp.prepare_output_buffer(&wrap, gst::BufferRef::from_ptr(inbuf)) {
|
||||||
|
Ok(PreparedOutputBuffer::InputBuffer) => {
|
||||||
|
*outbuf = inbuf;
|
||||||
|
gst::FlowReturn::Ok
|
||||||
|
}
|
||||||
|
Ok(PreparedOutputBuffer::Buffer(buf)) => {
|
||||||
|
*outbuf = buf.into_ptr();
|
||||||
|
gst::FlowReturn::Ok
|
||||||
|
}
|
||||||
|
Err(err) => err.into(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.to_glib()
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn base_transform_sink_event<T: ObjectSubclass>(
|
unsafe extern "C" fn base_transform_sink_event<T: ObjectSubclass>(
|
||||||
ptr: *mut gst_base_sys::GstBaseTransform,
|
ptr: *mut gst_base_sys::GstBaseTransform,
|
||||||
event: *mut gst_sys::GstEvent,
|
event: *mut gst_sys::GstEvent,
|
||||||
|
|
Loading…
Reference in a new issue