Update prepare_output_buffer's type signature

Update prepare_output_buffer's type signature to correctly reflect
whether it gets to work with a writable or readable buffer.
This commit is contained in:
Sanchayan Maity 2021-10-05 19:12:16 +05:30
parent 757530bd8a
commit b13f2060dc

View file

@ -105,7 +105,7 @@ pub trait BaseTransformImpl: BaseTransformImplExt + ElementImpl {
fn prepare_output_buffer( fn prepare_output_buffer(
&self, &self,
element: &Self::Type, element: &Self::Type,
inbuf: &gst::BufferRef, inbuf: InputBuffer,
) -> Result<PrepareOutputBufferSuccess, gst::FlowError> { ) -> Result<PrepareOutputBufferSuccess, gst::FlowError> {
self.parent_prepare_output_buffer(element, inbuf) self.parent_prepare_output_buffer(element, inbuf)
} }
@ -235,7 +235,7 @@ pub trait BaseTransformImplExt: ObjectSubclass {
fn parent_prepare_output_buffer( fn parent_prepare_output_buffer(
&self, &self,
element: &Self::Type, element: &Self::Type,
inbuf: &gst::BufferRef, inbuf: InputBuffer,
) -> Result<PrepareOutputBufferSuccess, gst::FlowError>; ) -> Result<PrepareOutputBufferSuccess, gst::FlowError>;
fn parent_transform( fn parent_transform(
@ -562,11 +562,15 @@ impl<T: BaseTransformImpl> BaseTransformImplExt for T {
fn parent_prepare_output_buffer( fn parent_prepare_output_buffer(
&self, &self,
element: &Self::Type, element: &Self::Type,
inbuf: &gst::BufferRef, inbuf: InputBuffer,
) -> Result<PrepareOutputBufferSuccess, gst::FlowError> { ) -> Result<PrepareOutputBufferSuccess, gst::FlowError> {
unsafe { unsafe {
let data = Self::type_data(); let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstBaseTransformClass; let parent_class = data.as_ref().parent_class() as *mut ffi::GstBaseTransformClass;
let buf = match inbuf {
InputBuffer::Readable(inbuf_r) => inbuf_r.as_ptr(),
InputBuffer::Writable(inbuf_w) => inbuf_w.as_mut_ptr(),
};
(*parent_class) (*parent_class)
.prepare_output_buffer .prepare_output_buffer
.map(|f| { .map(|f| {
@ -574,11 +578,11 @@ impl<T: BaseTransformImpl> BaseTransformImplExt for T {
// FIXME: Wrong signature in FFI // FIXME: Wrong signature in FFI
gst::FlowSuccess::try_from_glib(f( gst::FlowSuccess::try_from_glib(f(
element.unsafe_cast_ref::<BaseTransform>().to_glib_none().0, element.unsafe_cast_ref::<BaseTransform>().to_glib_none().0,
inbuf.as_ptr() as *mut gst::ffi::GstBuffer, buf as *mut gst::ffi::GstBuffer,
(&mut outbuf) as *mut *mut gst::ffi::GstBuffer as *mut gst::ffi::GstBuffer, (&mut outbuf) as *mut *mut gst::ffi::GstBuffer as *mut gst::ffi::GstBuffer,
)) ))
.map(|_| { .map(|_| {
if outbuf == inbuf.as_ptr() as *mut _ { if outbuf == buf as *mut _ {
PrepareOutputBufferSuccess::InputBuffer PrepareOutputBufferSuccess::InputBuffer
} else { } else {
PrepareOutputBufferSuccess::Buffer(from_glib_full(outbuf)) PrepareOutputBufferSuccess::Buffer(from_glib_full(outbuf))
@ -884,6 +888,12 @@ pub enum PrepareOutputBufferSuccess {
InputBuffer, InputBuffer,
} }
#[derive(Debug)]
pub enum InputBuffer<'a> {
Writable(&'a mut gst::BufferRef),
Readable(&'a gst::BufferRef),
}
unsafe extern "C" fn base_transform_start<T: BaseTransformImpl>( unsafe extern "C" fn base_transform_start<T: BaseTransformImpl>(
ptr: *mut ffi::GstBaseTransform, ptr: *mut ffi::GstBaseTransform,
) -> glib::ffi::gboolean { ) -> glib::ffi::gboolean {
@ -1093,14 +1103,31 @@ unsafe extern "C" fn base_transform_prepare_output_buffer<T: BaseTransformImpl>(
// FIXME: Wrong signature in FFI // FIXME: Wrong signature in FFI
let outbuf = outbuf as *mut *mut gst::ffi::GstBuffer; let outbuf = outbuf as *mut *mut gst::ffi::GstBuffer;
let is_passthrough: bool = from_glib(ffi::gst_base_transform_is_passthrough(ptr));
let is_in_place: bool = from_glib(ffi::gst_base_transform_is_in_place(ptr));
let writable = is_in_place
&& !is_passthrough
&& gst::ffi::gst_mini_object_is_writable(inbuf as *mut _) != glib::ffi::GFALSE;
let buffer = match writable {
false => InputBuffer::Readable(gst::BufferRef::from_ptr(inbuf)),
true => InputBuffer::Writable(gst::BufferRef::from_mut_ptr(inbuf)),
};
gst::panic_to_error!(&wrap, imp.panicked(), gst::FlowReturn::Error, { gst::panic_to_error!(&wrap, imp.panicked(), gst::FlowReturn::Error, {
match imp.prepare_output_buffer(wrap.unsafe_cast_ref(), gst::BufferRef::from_ptr(inbuf)) { match imp.prepare_output_buffer(wrap.unsafe_cast_ref(), buffer) {
Ok(PrepareOutputBufferSuccess::InputBuffer) => { Ok(PrepareOutputBufferSuccess::InputBuffer) => {
assert!(
is_passthrough || is_in_place,
"Returning InputBuffer only allowed for passthrough or in-place mode"
);
*outbuf = inbuf; *outbuf = inbuf;
gst::FlowReturn::Ok gst::FlowReturn::Ok
} }
Ok(PrepareOutputBufferSuccess::Buffer(buf)) => { Ok(PrepareOutputBufferSuccess::Buffer(buf)) => {
assert!(
!is_passthrough,
"Returning Buffer not allowed for passthrough mode"
);
*outbuf = buf.into_ptr(); *outbuf = buf.into_ptr();
gst::FlowReturn::Ok gst::FlowReturn::Ok
} }