1- //! VDO Buffer - represents a video frame buffer with RAII memory management.
2- //!
3- //! Buffers are used to hold video frame data from VDO streams.
4- //! They implement RAII-style memory management, automatically releasing
5- //! resources when dropped.
1+ //! VDO Buffer - video frame buffer with RAII memory management.
62
73use std:: ptr;
84use std:: slice;
@@ -13,43 +9,12 @@ use crate::format::FrameType;
139use crate :: map:: Map ;
1410
1511/// A video buffer containing frame data.
16- ///
17- /// This struct provides safe access to video frame data and metadata.
18- /// When dropped, the buffer is automatically unreferenced, preventing memory leaks.
19- ///
20- /// # Example
21- ///
22- /// ```ignore
23- /// use vdo::Stream;
24- ///
25- /// let mut stream = Stream::new(&settings)?;
26- /// stream.start()?;
27- ///
28- /// // Get a buffer from the stream
29- /// let buffer = stream.get_buffer()?;
30- ///
31- /// // Access frame data
32- /// if let Some(data) = buffer.data() {
33- /// println!("Got {} bytes of frame data", data.len());
34- /// }
35- ///
36- /// // Buffer is automatically unreferenced when dropped
37- /// ```
3812pub struct Buffer {
3913 ptr : * mut RawVdoBuffer ,
4014 stream_ptr : * mut RawVdoStream ,
41- mapped_data : * mut std:: ffi:: c_void ,
4215}
4316
4417impl Buffer {
45- /// Creates a Buffer from raw pointers.
46- ///
47- /// # Safety
48- ///
49- /// The caller must ensure that:
50- /// - `buffer_ptr` is a valid pointer to a VdoBuffer
51- /// - `stream_ptr` is a valid pointer to the VdoStream that owns this buffer
52- /// - Ownership of the buffer is transferred to this struct
5318 pub ( crate ) unsafe fn from_raw (
5419 buffer_ptr : * mut RawVdoBuffer ,
5520 stream_ptr : * mut RawVdoStream ,
@@ -60,91 +25,68 @@ impl Buffer {
6025 Some ( Self {
6126 ptr : buffer_ptr,
6227 stream_ptr,
63- mapped_data : ptr:: null_mut ( ) ,
6428 } )
6529 }
6630 }
6731
68- /// Returns the buffer ID.
6932 pub fn id ( & self ) -> u32 {
7033 unsafe { vdo_sys:: vdo_buffer_get_id ( self . ptr ) }
7134 }
7235
73- /// Returns the file descriptor associated with this buffer.
7436 pub fn fd ( & self ) -> i32 {
7537 unsafe { vdo_sys:: vdo_buffer_get_fd ( self . ptr ) }
7638 }
7739
78- /// Returns the buffer capacity in bytes.
7940 pub fn capacity ( & self ) -> usize {
8041 unsafe { vdo_sys:: vdo_buffer_get_capacity ( self . ptr ) }
8142 }
8243
83- /// Returns the actual data size in bytes.
8444 pub fn size ( & self ) -> usize {
8545 unsafe { vdo_sys:: vdo_frame_get_size ( self . ptr ) }
8646 }
8747
88- /// Returns the buffer offset.
8948 pub fn offset ( & self ) -> i64 {
9049 unsafe { vdo_sys:: vdo_buffer_get_offset ( self . ptr ) }
9150 }
9251
93- /// Returns `true` if this buffer contains a complete frame.
9452 pub fn is_complete ( & self ) -> bool {
9553 unsafe { vdo_sys:: vdo_buffer_is_complete ( self . ptr ) != 0 }
9654 }
9755
98- /// Returns the frame type.
9956 pub fn frame_type ( & self ) -> Option < FrameType > {
10057 let raw = unsafe { vdo_sys:: vdo_frame_get_frame_type ( self . ptr ) } ;
10158 FrameType :: from_raw ( raw)
10259 }
10360
104- /// Returns `true` if this is a keyframe.
10561 pub fn is_keyframe ( & self ) -> bool {
10662 unsafe { vdo_sys:: vdo_frame_is_key ( self . ptr ) != 0 }
10763 }
10864
109- /// Returns the sequence number of this frame.
11065 pub fn sequence_number ( & self ) -> u32 {
11166 unsafe { vdo_sys:: vdo_frame_get_sequence_nbr ( self . ptr ) }
11267 }
11368
114- /// Returns the timestamp of this frame.
11569 pub fn timestamp ( & self ) -> u64 {
11670 unsafe { vdo_sys:: vdo_frame_get_timestamp ( self . ptr ) }
11771 }
11872
119- /// Returns the custom timestamp of this frame.
12073 pub fn custom_timestamp ( & self ) -> i64 {
12174 unsafe { vdo_sys:: vdo_frame_get_custom_timestamp ( self . ptr ) }
12275 }
12376
124- /// Returns `true` if this is the last buffer in a sequence.
12577 pub fn is_last ( & self ) -> bool {
12678 unsafe { vdo_sys:: vdo_frame_get_is_last_buffer ( self . ptr ) != 0 }
12779 }
12880
129- /// Returns extra metadata about this frame.
13081 pub fn extra_info ( & self ) -> Option < Map > {
13182 let ptr = unsafe { vdo_sys:: vdo_frame_get_extra_info ( self . ptr ) } ;
13283 unsafe { Map :: from_raw ( ptr) }
13384 }
13485
135- /// Maps the buffer memory for CPU access and returns a slice to the data.
136- ///
137- /// The data remains accessible until the buffer is dropped.
138- ///
139- /// # Returns
140- ///
141- /// Returns `None` if the buffer cannot be mapped.
142- pub fn data ( & mut self ) -> Option < & [ u8 ] > {
143- if self . mapped_data . is_null ( ) {
144- self . mapped_data = unsafe { vdo_sys:: vdo_frame_memmap ( self . ptr ) } ;
145- }
146-
147- if self . mapped_data . is_null ( ) {
86+ /// Returns a slice to the buffer data. Uses cached mmap internally.
87+ pub fn data ( & self ) -> Option < & [ u8 ] > {
88+ let data_ptr = unsafe { vdo_sys:: vdo_buffer_get_data ( self . ptr ) } ;
89+ if data_ptr. is_null ( ) {
14890 return None ;
14991 }
15092
@@ -153,20 +95,13 @@ impl Buffer {
15395 return Some ( & [ ] ) ;
15496 }
15597
156- Some ( unsafe { slice:: from_raw_parts ( self . mapped_data as * const u8 , size) } )
98+ Some ( unsafe { slice:: from_raw_parts ( data_ptr as * const u8 , size) } )
15799 }
158100
159- /// Returns a mutable reference to the mapped buffer data.
160- ///
161- /// # Returns
162- ///
163- /// Returns `None` if the buffer cannot be mapped.
101+ /// Returns a mutable slice to the buffer data.
164102 pub fn data_mut ( & mut self ) -> Option < & mut [ u8 ] > {
165- if self . mapped_data . is_null ( ) {
166- self . mapped_data = unsafe { vdo_sys:: vdo_frame_memmap ( self . ptr ) } ;
167- }
168-
169- if self . mapped_data . is_null ( ) {
103+ let data_ptr = unsafe { vdo_sys:: vdo_buffer_get_data ( self . ptr ) } ;
104+ if data_ptr. is_null ( ) {
170105 return None ;
171106 }
172107
@@ -175,31 +110,16 @@ impl Buffer {
175110 return Some ( & mut [ ] ) ;
176111 }
177112
178- Some ( unsafe { slice:: from_raw_parts_mut ( self . mapped_data as * mut u8 , size) } )
179- }
180-
181- /// Unmaps the buffer memory.
182- ///
183- /// This is called automatically when the buffer is dropped.
184- pub fn unmap ( & mut self ) {
185- if !self . mapped_data . is_null ( ) {
186- unsafe { vdo_sys:: vdo_frame_unmap ( self . ptr ) } ;
187- self . mapped_data = ptr:: null_mut ( ) ;
188- }
113+ Some ( unsafe { slice:: from_raw_parts_mut ( data_ptr as * mut u8 , size) } )
189114 }
190115}
191116
192117impl Drop for Buffer {
193118 fn drop ( & mut self ) {
194- // Unmap if mapped
195- self . unmap ( ) ;
196-
197- // Unref the buffer through the stream
198119 if !self . ptr . is_null ( ) && !self . stream_ptr . is_null ( ) {
199120 let mut ptr = self . ptr ;
200121 let mut error: * mut glib_sys:: GError = ptr:: null_mut ( ) ;
201122 unsafe {
202- // Ignore errors during drop - we can't do much about them
203123 let _ = vdo_sys:: vdo_stream_buffer_unref ( self . stream_ptr , & mut ptr, & mut error) ;
204124 if !error. is_null ( ) {
205125 glib_sys:: g_error_free ( error) ;
@@ -209,7 +129,6 @@ impl Drop for Buffer {
209129 }
210130}
211131
212- // SAFETY: Buffer can be sent between threads
213132unsafe impl Send for Buffer { }
214133
215134impl std:: fmt:: Debug for Buffer {
@@ -224,79 +143,56 @@ impl std::fmt::Debug for Buffer {
224143 }
225144}
226145
227- /// A standalone buffer not associated with a stream.
228- ///
229- /// Used for snapshots and other operations that don't require a stream.
146+ /// A standalone buffer not associated with a stream, used for snapshots.
230147pub struct StandaloneBuffer {
231148 ptr : * mut RawVdoBuffer ,
232- mapped_data : * mut std:: ffi:: c_void ,
233149}
234150
235151impl StandaloneBuffer {
236- /// Creates a StandaloneBuffer from a raw pointer.
237- ///
238- /// # Safety
239- ///
240- /// The caller must ensure that the pointer is valid and ownership is transferred.
241152 pub ( crate ) unsafe fn from_raw ( ptr : * mut RawVdoBuffer ) -> Option < Self > {
242153 if ptr. is_null ( ) {
243154 None
244155 } else {
245- Some ( Self {
246- ptr,
247- mapped_data : ptr:: null_mut ( ) ,
248- } )
156+ Some ( Self { ptr } )
249157 }
250158 }
251159
252- /// Returns the buffer ID.
253160 pub fn id ( & self ) -> u32 {
254161 unsafe { vdo_sys:: vdo_buffer_get_id ( self . ptr ) }
255162 }
256163
257- /// Returns the file descriptor associated with this buffer.
258164 pub fn fd ( & self ) -> i32 {
259165 unsafe { vdo_sys:: vdo_buffer_get_fd ( self . ptr ) }
260166 }
261167
262- /// Returns the buffer capacity in bytes.
263168 pub fn capacity ( & self ) -> usize {
264169 unsafe { vdo_sys:: vdo_buffer_get_capacity ( self . ptr ) }
265170 }
266171
267- /// Returns the actual data size in bytes.
268172 pub fn size ( & self ) -> usize {
269173 unsafe { vdo_sys:: vdo_frame_get_size ( self . ptr ) }
270174 }
271175
272- /// Returns the frame type.
273176 pub fn frame_type ( & self ) -> Option < FrameType > {
274177 let raw = unsafe { vdo_sys:: vdo_frame_get_frame_type ( self . ptr ) } ;
275178 FrameType :: from_raw ( raw)
276179 }
277180
278- /// Returns `true` if this is a keyframe.
279181 pub fn is_keyframe ( & self ) -> bool {
280182 unsafe { vdo_sys:: vdo_frame_is_key ( self . ptr ) != 0 }
281183 }
282184
283- /// Returns the sequence number of this frame.
284185 pub fn sequence_number ( & self ) -> u32 {
285186 unsafe { vdo_sys:: vdo_frame_get_sequence_nbr ( self . ptr ) }
286187 }
287188
288- /// Returns the timestamp of this frame.
289189 pub fn timestamp ( & self ) -> u64 {
290190 unsafe { vdo_sys:: vdo_frame_get_timestamp ( self . ptr ) }
291191 }
292192
293- /// Maps the buffer memory and returns a slice to the data.
294- pub fn data ( & mut self ) -> Option < & [ u8 ] > {
295- if self . mapped_data . is_null ( ) {
296- self . mapped_data = unsafe { vdo_sys:: vdo_frame_memmap ( self . ptr ) } ;
297- }
298-
299- if self . mapped_data . is_null ( ) {
193+ pub fn data ( & self ) -> Option < & [ u8 ] > {
194+ let data_ptr = unsafe { vdo_sys:: vdo_buffer_get_data ( self . ptr ) } ;
195+ if data_ptr. is_null ( ) {
300196 return None ;
301197 }
302198
@@ -305,24 +201,14 @@ impl StandaloneBuffer {
305201 return Some ( & [ ] ) ;
306202 }
307203
308- Some ( unsafe { slice:: from_raw_parts ( self . mapped_data as * const u8 , size) } )
309- }
310-
311- /// Unmaps the buffer memory.
312- pub fn unmap ( & mut self ) {
313- if !self . mapped_data . is_null ( ) {
314- unsafe { vdo_sys:: vdo_frame_unmap ( self . ptr ) } ;
315- self . mapped_data = ptr:: null_mut ( ) ;
316- }
204+ Some ( unsafe { slice:: from_raw_parts ( data_ptr as * const u8 , size) } )
317205 }
318206}
319207
320208impl Drop for StandaloneBuffer {
321209 fn drop ( & mut self ) {
322- self . unmap ( ) ;
323210 if !self . ptr . is_null ( ) {
324211 unsafe {
325- // Standalone buffers need to be unreffed via GObject
326212 gobject_sys:: g_object_unref ( self . ptr as * mut _ ) ;
327213 }
328214 }
0 commit comments