forked from mirrors/gstreamer-rs
gstreamer: bufferlist: Implement buffer foreach functions around ControlFlow
enum
This makes it clearer than a plain `bool` or `Result<Option<Buffer>, Option<Buffer>>`. Also pass a `&Buffer` instead of a `&BufferRef` to the immutable foreach function to allow taking references of the buffer outside the scope of the closure by cloning instead of requiring a full copy.
This commit is contained in:
parent
15fbb17a09
commit
c965217e54
1 changed files with 29 additions and 24 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use glib::translate::{from_glib, from_glib_full, from_glib_none, IntoGlib};
|
use glib::translate::{from_glib, from_glib_full, from_glib_none, IntoGlib};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::ops::ControlFlow;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use crate::Buffer;
|
use crate::Buffer;
|
||||||
|
@ -106,16 +107,16 @@ impl BufferListRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(alias = "gst_buffer_list_foreach")]
|
#[doc(alias = "gst_buffer_list_foreach")]
|
||||||
pub fn foreach<F: FnMut(&BufferRef, u32) -> bool>(&self, func: F) -> bool {
|
pub fn foreach<F: FnMut(&Buffer, u32) -> ControlFlow<(), ()>>(&self, func: F) -> bool {
|
||||||
unsafe extern "C" fn trampoline<F: FnMut(&BufferRef, u32) -> bool>(
|
unsafe extern "C" fn trampoline<F: FnMut(&Buffer, u32) -> ControlFlow<(), ()>>(
|
||||||
buffer: *mut *mut ffi::GstBuffer,
|
buffer: *mut *mut ffi::GstBuffer,
|
||||||
idx: u32,
|
idx: u32,
|
||||||
user_data: glib::ffi::gpointer,
|
user_data: glib::ffi::gpointer,
|
||||||
) -> glib::ffi::gboolean {
|
) -> glib::ffi::gboolean {
|
||||||
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)(BufferRef::from_ptr(*buffer), idx);
|
let res = (*func)(&Buffer::from_glib_borrow(*buffer), idx);
|
||||||
|
|
||||||
res.into_glib()
|
matches!(res, ControlFlow::Continue(_)).into_glib()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -129,34 +130,40 @@ impl BufferListRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn foreach_mut<F: FnMut(Buffer, u32) -> Result<Option<Buffer>, Option<Buffer>>>(
|
pub fn foreach_mut<F: FnMut(Buffer, u32) -> ControlFlow<Option<Buffer>, Option<Buffer>>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
func: F,
|
func: F,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
unsafe extern "C" fn trampoline<
|
unsafe extern "C" fn trampoline<
|
||||||
F: FnMut(Buffer, u32) -> Result<Option<Buffer>, Option<Buffer>>,
|
F: FnMut(Buffer, u32) -> ControlFlow<Option<Buffer>, Option<Buffer>>,
|
||||||
>(
|
>(
|
||||||
buffer: *mut *mut ffi::GstBuffer,
|
buffer: *mut *mut ffi::GstBuffer,
|
||||||
idx: u32,
|
idx: u32,
|
||||||
user_data: glib::ffi::gpointer,
|
user_data: glib::ffi::gpointer,
|
||||||
) -> glib::ffi::gboolean {
|
) -> glib::ffi::gboolean {
|
||||||
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)(Buffer::from_glib_full(*buffer), idx);
|
let res = (*func)(
|
||||||
|
Buffer::from_glib_full(
|
||||||
|
ptr::replace(buffer, ptr::null_mut::<ffi::GstBuffer>()) as *mut ffi::GstBuffer
|
||||||
|
),
|
||||||
|
idx,
|
||||||
|
);
|
||||||
|
|
||||||
match res {
|
let (cont, res_buffer) = match res {
|
||||||
Ok(None) | Err(None) => {
|
ControlFlow::Continue(res_buffer) => (true, res_buffer),
|
||||||
|
ControlFlow::Break(res_buffer) => (false, res_buffer),
|
||||||
|
};
|
||||||
|
|
||||||
|
match res_buffer {
|
||||||
|
None => {
|
||||||
*buffer = ptr::null_mut();
|
*buffer = ptr::null_mut();
|
||||||
res.is_ok().into_glib()
|
|
||||||
}
|
}
|
||||||
Ok(Some(b)) => {
|
Some(new_buffer) => {
|
||||||
*buffer = b.into_ptr();
|
*buffer = new_buffer.into_ptr();
|
||||||
glib::ffi::GTRUE
|
|
||||||
}
|
|
||||||
Err(Some(b)) => {
|
|
||||||
*buffer = b.into_ptr();
|
|
||||||
glib::ffi::GFALSE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cont.into_glib()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -328,8 +335,7 @@ mod tests {
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
buffer_list.foreach(|buffer, idx| {
|
buffer_list.foreach(|buffer, idx| {
|
||||||
res.push((buffer.pts(), idx));
|
res.push((buffer.pts(), idx));
|
||||||
|
ControlFlow::Continue(())
|
||||||
true
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -363,13 +369,13 @@ mod tests {
|
||||||
res.push((buffer.pts(), idx));
|
res.push((buffer.pts(), idx));
|
||||||
|
|
||||||
if let Some(ClockTime::ZERO) = buffer.pts() {
|
if let Some(ClockTime::ZERO) = buffer.pts() {
|
||||||
Ok(Some(buffer))
|
ControlFlow::Continue(Some(buffer))
|
||||||
} else if let Some(ClockTime::SECOND) = buffer.pts() {
|
} else if let Some(ClockTime::SECOND) = buffer.pts() {
|
||||||
Ok(None)
|
ControlFlow::Continue(None)
|
||||||
} else {
|
} else {
|
||||||
let mut new_buffer = Buffer::new();
|
let mut new_buffer = Buffer::new();
|
||||||
new_buffer.get_mut().unwrap().set_pts(3 * ClockTime::SECOND);
|
new_buffer.get_mut().unwrap().set_pts(3 * ClockTime::SECOND);
|
||||||
Ok(Some(new_buffer))
|
ControlFlow::Continue(Some(new_buffer))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -385,8 +391,7 @@ mod tests {
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
buffer_list.foreach(|buffer, idx| {
|
buffer_list.foreach(|buffer, idx| {
|
||||||
res.push((buffer.pts(), idx));
|
res.push((buffer.pts(), idx));
|
||||||
|
ControlFlow::Continue(())
|
||||||
true
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
Loading…
Reference in a new issue