Skip to content

Commit 934042b

Browse files
Copilotvsem-azamat
andcommitted
Improve vdo crate based on PR AxisCommunications#153 feedback
Co-authored-by: vsem-azamat <[email protected]>
1 parent fc5798e commit 934042b

File tree

6 files changed

+29
-416
lines changed

6 files changed

+29
-416
lines changed

crates/vdo/src/buffer.rs

Lines changed: 16 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
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
73
use std::ptr;
84
use std::slice;
@@ -13,43 +9,12 @@ use crate::format::FrameType;
139
use 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-
/// ```
3812
pub struct Buffer {
3913
ptr: *mut RawVdoBuffer,
4014
stream_ptr: *mut RawVdoStream,
41-
mapped_data: *mut std::ffi::c_void,
4215
}
4316

4417
impl 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

192117
impl 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
213132
unsafe impl Send for Buffer {}
214133

215134
impl 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.
230147
pub struct StandaloneBuffer {
231148
ptr: *mut RawVdoBuffer,
232-
mapped_data: *mut std::ffi::c_void,
233149
}
234150

235151
impl 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

320208
impl 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

Comments
 (0)