gstreamer: buffer: Implement meta foreach functions around ControlFlow enum

This makes it clearer than a plain `bool` or `Result<bool, bool>`.
This commit is contained in:
Sebastian Dröge 2021-11-22 15:40:36 +02:00
parent e0e17b8b25
commit 15fbb17a09

View file

@ -4,6 +4,7 @@ use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
use std::ops; use std::ops;
use std::ops::ControlFlow;
use std::ptr; use std::ptr;
use std::slice; use std::slice;
use std::u64; use std::u64;
@ -22,6 +23,12 @@ use glib::translate::{from_glib, from_glib_full, FromGlib, FromGlibPtrFull, Into
pub enum Readable {} pub enum Readable {}
pub enum Writable {} pub enum Writable {}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum BufferMetaForeachAction {
Keep,
Remove,
}
mini_object_wrapper!(Buffer, BufferRef, ffi::GstBuffer, || { mini_object_wrapper!(Buffer, BufferRef, ffi::GstBuffer, || {
ffi::gst_buffer_get_type() ffi::gst_buffer_get_type()
}); });
@ -434,8 +441,8 @@ impl BufferRef {
} }
#[doc(alias = "gst_buffer_foreach_meta")] #[doc(alias = "gst_buffer_foreach_meta")]
pub fn foreach_meta<F: FnMut(MetaRef<Meta>) -> bool>(&self, func: F) -> bool { pub fn foreach_meta<F: FnMut(MetaRef<Meta>) -> ControlFlow<(), ()>>(&self, func: F) -> bool {
unsafe extern "C" fn trampoline<F: FnMut(MetaRef<Meta>) -> bool>( unsafe extern "C" fn trampoline<F: FnMut(MetaRef<Meta>) -> ControlFlow<(), ()>>(
buffer: *mut ffi::GstBuffer, buffer: *mut ffi::GstBuffer,
meta: *mut *mut ffi::GstMeta, meta: *mut *mut ffi::GstMeta,
user_data: glib::ffi::gpointer, user_data: glib::ffi::gpointer,
@ -443,7 +450,7 @@ impl BufferRef {
let func = user_data as *const _ as usize as *mut F; let func = user_data as *const _ as usize as *mut F;
let res = (*func)(Meta::from_ptr(BufferRef::from_ptr(buffer), *meta)); let res = (*func)(Meta::from_ptr(BufferRef::from_ptr(buffer), *meta));
res.into_glib() matches!(res, ControlFlow::Continue(_)).into_glib()
} }
unsafe { unsafe {
@ -458,13 +465,17 @@ impl BufferRef {
} }
pub fn foreach_meta_mut< pub fn foreach_meta_mut<
F: FnMut(MetaRefMut<Meta, crate::meta::Iterated>) -> Result<bool, bool>, F: FnMut(
MetaRefMut<Meta, crate::meta::Iterated>,
) -> ControlFlow<BufferMetaForeachAction, BufferMetaForeachAction>,
>( >(
&mut self, &mut self,
func: F, func: F,
) -> bool { ) -> bool {
unsafe extern "C" fn trampoline< unsafe extern "C" fn trampoline<
F: FnMut(MetaRefMut<Meta, crate::meta::Iterated>) -> Result<bool, bool>, F: FnMut(
MetaRefMut<Meta, crate::meta::Iterated>,
) -> ControlFlow<BufferMetaForeachAction, BufferMetaForeachAction>,
>( >(
buffer: *mut ffi::GstBuffer, buffer: *mut ffi::GstBuffer,
meta: *mut *mut ffi::GstMeta, meta: *mut *mut ffi::GstMeta,
@ -473,13 +484,16 @@ impl BufferRef {
let func = user_data as *const _ as usize as *mut F; let func = user_data as *const _ as usize as *mut F;
let res = (*func)(Meta::from_mut_ptr(BufferRef::from_mut_ptr(buffer), *meta)); let res = (*func)(Meta::from_mut_ptr(BufferRef::from_mut_ptr(buffer), *meta));
match res { let (cont, action) = match res {
Ok(false) | Err(false) => { ControlFlow::Continue(action) => (true, action),
*meta = ptr::null_mut(); ControlFlow::Break(action) => (false, action),
res.is_ok().into_glib() };
}
Ok(true) | Err(true) => res.is_ok().into_glib(), if action == BufferMetaForeachAction::Remove {
*meta = ptr::null_mut();
} }
cont.into_glib()
} }
unsafe { unsafe {
@ -1381,7 +1395,7 @@ mod tests {
.downcast_ref::<crate::ReferenceTimestampMeta>() .downcast_ref::<crate::ReferenceTimestampMeta>()
.unwrap(); .unwrap();
res.push(meta.timestamp()); res.push(meta.timestamp());
true ControlFlow::Continue(())
}); });
assert_eq!(&[ClockTime::ZERO, ClockTime::SECOND][..], &res[..]); assert_eq!(&[ClockTime::ZERO, ClockTime::SECOND][..], &res[..]);
@ -1417,9 +1431,9 @@ mod tests {
.unwrap(); .unwrap();
res.push(meta.timestamp()); res.push(meta.timestamp());
if meta.timestamp() == ClockTime::SECOND { if meta.timestamp() == ClockTime::SECOND {
Ok(false) ControlFlow::Continue(BufferMetaForeachAction::Remove)
} else { } else {
Ok(true) ControlFlow::Continue(BufferMetaForeachAction::Keep)
} }
}); });
@ -1431,7 +1445,7 @@ mod tests {
.downcast_ref::<crate::ReferenceTimestampMeta>() .downcast_ref::<crate::ReferenceTimestampMeta>()
.unwrap(); .unwrap();
res.push(meta.timestamp()); res.push(meta.timestamp());
true ControlFlow::Continue(())
}); });
assert_eq!(&[ClockTime::ZERO][..], &res[..]); assert_eq!(&[ClockTime::ZERO][..], &res[..]);