forked from mirrors/gstreamer-rs
gstreamer/bufferlist: Add bindings for foreach() and foreach_mut()
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/273
This commit is contained in:
parent
275d93e3d2
commit
f01b590a0c
1 changed files with 147 additions and 1 deletions
|
@ -7,9 +7,10 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use glib;
|
use glib;
|
||||||
use glib::translate::{from_glib_full, from_glib_none};
|
use glib::translate::{from_glib, from_glib_full, from_glib_none, ToGlib};
|
||||||
use gst_sys;
|
use gst_sys;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
use Buffer;
|
use Buffer;
|
||||||
use BufferRef;
|
use BufferRef;
|
||||||
|
@ -99,6 +100,70 @@ impl BufferListRef {
|
||||||
pub fn iter_owned(&self) -> IterOwned {
|
pub fn iter_owned(&self) -> IterOwned {
|
||||||
IterOwned::new(self)
|
IterOwned::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn foreach<F: FnMut(&BufferRef, u32) -> bool>(&self, func: F) -> bool {
|
||||||
|
unsafe extern "C" fn trampoline<F: FnMut(&BufferRef, u32) -> bool>(
|
||||||
|
buffer: *mut *mut gst_sys::GstBuffer,
|
||||||
|
idx: u32,
|
||||||
|
user_data: glib_sys::gpointer,
|
||||||
|
) -> glib_sys::gboolean {
|
||||||
|
let func = user_data as *const _ as usize as *mut F;
|
||||||
|
let res = (*func)(BufferRef::from_ptr(*buffer), idx);
|
||||||
|
|
||||||
|
res.to_glib()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let func_ptr: &F = &func;
|
||||||
|
|
||||||
|
from_glib(gst_sys::gst_buffer_list_foreach(
|
||||||
|
self.as_ptr() as *mut _,
|
||||||
|
Some(trampoline::<F>),
|
||||||
|
func_ptr as *const _ as usize as *mut _,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn foreach_mut<F: FnMut(Buffer, u32) -> Result<Option<Buffer>, Option<Buffer>>>(
|
||||||
|
&mut self,
|
||||||
|
func: F,
|
||||||
|
) -> bool {
|
||||||
|
unsafe extern "C" fn trampoline<
|
||||||
|
F: FnMut(Buffer, u32) -> Result<Option<Buffer>, Option<Buffer>>,
|
||||||
|
>(
|
||||||
|
buffer: *mut *mut gst_sys::GstBuffer,
|
||||||
|
idx: u32,
|
||||||
|
user_data: glib_sys::gpointer,
|
||||||
|
) -> glib_sys::gboolean {
|
||||||
|
let func = user_data as *const _ as usize as *mut F;
|
||||||
|
let res = (*func)(Buffer::from_glib_full(*buffer), idx);
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Ok(None) | Err(None) => {
|
||||||
|
*buffer = ptr::null_mut();
|
||||||
|
res.is_ok().to_glib()
|
||||||
|
}
|
||||||
|
Ok(Some(b)) => {
|
||||||
|
*buffer = b.into_ptr();
|
||||||
|
glib_sys::GTRUE
|
||||||
|
}
|
||||||
|
Err(Some(b)) => {
|
||||||
|
*buffer = b.into_ptr();
|
||||||
|
glib_sys::GFALSE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let func_ptr: &F = &func;
|
||||||
|
|
||||||
|
from_glib(gst_sys::gst_buffer_list_foreach(
|
||||||
|
self.as_ptr() as *mut _,
|
||||||
|
Some(trampoline::<F>),
|
||||||
|
func_ptr as *const _ as usize as *mut _,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BufferList {
|
impl Default for BufferList {
|
||||||
|
@ -198,3 +263,84 @@ define_iter!(Iter, &'a BufferRef, |list: &'a BufferListRef, idx| {
|
||||||
define_iter!(IterOwned, Buffer, |list: &BufferListRef, idx| {
|
define_iter!(IterOwned, Buffer, |list: &BufferListRef, idx| {
|
||||||
list.get_owned(idx)
|
list.get_owned(idx)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_foreach() {
|
||||||
|
::init().unwrap();
|
||||||
|
|
||||||
|
let mut buffer_list = BufferList::new();
|
||||||
|
{
|
||||||
|
let buffer_list = buffer_list.get_mut().unwrap();
|
||||||
|
let mut buffer = Buffer::new();
|
||||||
|
buffer.get_mut().unwrap().set_pts(::ClockTime::from(0));
|
||||||
|
buffer_list.add(buffer);
|
||||||
|
|
||||||
|
let mut buffer = Buffer::new();
|
||||||
|
buffer.get_mut().unwrap().set_pts(::SECOND);
|
||||||
|
buffer_list.add(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut res = vec![];
|
||||||
|
buffer_list.foreach(|buffer, idx| {
|
||||||
|
res.push((buffer.get_pts(), idx));
|
||||||
|
|
||||||
|
true
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(res, &[(::ClockTime::from(0), 0), (::SECOND, 1)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_foreach_mut() {
|
||||||
|
::init().unwrap();
|
||||||
|
|
||||||
|
let mut buffer_list = BufferList::new();
|
||||||
|
{
|
||||||
|
let buffer_list = buffer_list.get_mut().unwrap();
|
||||||
|
let mut buffer = Buffer::new();
|
||||||
|
buffer.get_mut().unwrap().set_pts(::ClockTime::from(0));
|
||||||
|
buffer_list.add(buffer);
|
||||||
|
|
||||||
|
let mut buffer = Buffer::new();
|
||||||
|
buffer.get_mut().unwrap().set_pts(::SECOND);
|
||||||
|
buffer_list.add(buffer);
|
||||||
|
|
||||||
|
let mut buffer = Buffer::new();
|
||||||
|
buffer.get_mut().unwrap().set_pts(2 * ::SECOND);
|
||||||
|
buffer_list.add(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut res = vec![];
|
||||||
|
buffer_list.get_mut().unwrap().foreach_mut(|buffer, idx| {
|
||||||
|
res.push((buffer.get_pts(), idx));
|
||||||
|
|
||||||
|
if buffer.get_pts() == ::ClockTime::from(0) {
|
||||||
|
Ok(Some(buffer))
|
||||||
|
} else if buffer.get_pts() == ::SECOND {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
let mut new_buffer = Buffer::new();
|
||||||
|
new_buffer.get_mut().unwrap().set_pts(3 * ::SECOND);
|
||||||
|
Ok(Some(new_buffer))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
res,
|
||||||
|
&[(::ClockTime::from(0), 0), (::SECOND, 1), (2 * ::SECOND, 1)]
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut res = vec![];
|
||||||
|
buffer_list.foreach(|buffer, idx| {
|
||||||
|
res.push((buffer.get_pts(), idx));
|
||||||
|
|
||||||
|
true
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(res, &[(::ClockTime::from(0), 0), (3 * ::SECOND, 1)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue