1use super::stream::Stream;
2
3use spa::buffer::meta::Metadata;
4use spa::buffer::Data;
5use std::convert::TryFrom;
6use std::ptr::NonNull;
7
8pub struct Buffer<'s> {
9 buf: NonNull<pw_sys::pw_buffer>,
10
11 stream: &'s Stream,
14}
15
16impl Buffer<'_> {
17 pub(crate) unsafe fn from_raw(
18 buf: *mut pw_sys::pw_buffer,
19 stream: &Stream,
20 ) -> Option<Buffer<'_>> {
21 NonNull::new(buf).map(|buf| Buffer { buf, stream })
22 }
23
24 pub fn datas_mut(&mut self) -> &mut [Data] {
25 let buffer: *mut spa_sys::spa_buffer = unsafe { self.buf.as_ref().buffer };
26
27 let slice_of_data = if !buffer.is_null()
28 && unsafe { (*buffer).n_datas > 0 && !(*buffer).datas.is_null() }
29 {
30 unsafe {
31 let datas = (*buffer).datas as *mut Data;
32 std::slice::from_raw_parts_mut(datas, usize::try_from((*buffer).n_datas).unwrap())
33 }
34 } else {
35 &mut []
36 };
37
38 slice_of_data
39 }
40
41 pub fn find_meta<T>(&self) -> Option<&T>
42 where
43 T: Metadata,
44 {
45 let buffer: *mut spa_sys::spa_buffer = unsafe { self.buf.as_ref().buffer };
46 if !buffer.is_null() && unsafe { (*buffer).n_metas != 0 } {
47 unsafe {
48 match T::META_TYPE {
49 spa_sys::SPA_META_VideoDamage => {
50 let meta_data =
51 spa_sys::spa_buffer_find_meta(buffer, T::META_TYPE) as *const T;
52 if !meta_data.is_null() {
53 return Some(&*meta_data);
54 }
55 }
56 _ => {
57 let meta_data = spa_sys::spa_buffer_find_meta_data(
58 buffer,
59 T::META_TYPE,
60 std::mem::size_of::<T>(),
61 ) as *const T;
62 if !meta_data.is_null() {
63 return Some(&*meta_data);
64 }
65 }
66 }
67 }
68 }
69 None
70 }
71
72 #[cfg(feature = "v0_3_49")]
73 pub fn requested(&self) -> u64 {
74 unsafe { self.buf.as_ref().requested }
75 }
76}
77
78impl Drop for Buffer<'_> {
79 fn drop(&mut self) {
80 unsafe {
81 self.stream.queue_raw_buffer(self.buf.as_ptr());
82 }
83 }
84}