1 //! Operations specific to UserPtr-type buffers.
2 
3 use super::*;
4 use crate::bindings;
5 
6 pub struct UserPtr;
7 
8 impl Memory for UserPtr {
9     const MEMORY_TYPE: MemoryType = MemoryType::UserPtr;
10     type RawBacking = core::ffi::c_ulong;
11 
get_plane_buffer_backing( m: &bindings::v4l2_plane__bindgen_ty_1, ) -> &Self::RawBacking12     unsafe fn get_plane_buffer_backing(
13         m: &bindings::v4l2_plane__bindgen_ty_1,
14     ) -> &Self::RawBacking {
15         &m.userptr
16     }
17 
get_single_planar_buffer_backing( m: &bindings::v4l2_buffer__bindgen_ty_1, ) -> &Self::RawBacking18     unsafe fn get_single_planar_buffer_backing(
19         m: &bindings::v4l2_buffer__bindgen_ty_1,
20     ) -> &Self::RawBacking {
21         &m.userptr
22     }
23 
get_plane_buffer_backing_mut( m: &mut bindings::v4l2_plane__bindgen_ty_1, ) -> &mut Self::RawBacking24     unsafe fn get_plane_buffer_backing_mut(
25         m: &mut bindings::v4l2_plane__bindgen_ty_1,
26     ) -> &mut Self::RawBacking {
27         &mut m.userptr
28     }
29 
get_single_planar_buffer_backing_mut( m: &mut bindings::v4l2_buffer__bindgen_ty_1, ) -> &mut Self::RawBacking30     unsafe fn get_single_planar_buffer_backing_mut(
31         m: &mut bindings::v4l2_buffer__bindgen_ty_1,
32     ) -> &mut Self::RawBacking {
33         &mut m.userptr
34     }
35 }
36 
37 impl Imported for UserPtr {}
38 
39 /// Handle for a USERPTR plane. These buffers are backed by userspace-allocated
40 /// memory, which translates well into Rust's slice of `u8`s. Since slices also
41 /// carry size information, we know that we are not passing unallocated areas
42 /// of the address-space to the kernel.
43 ///
44 /// USERPTR buffers have the particularity that the `length` field of `struct
45 /// v4l2_buffer` must be set before doing a `QBUF` ioctl. This handle struct
46 /// also takes care of that.
47 #[derive(Debug)]
48 pub struct UserPtrHandle<T: AsRef<[u8]> + Debug + Send + 'static>(pub T);
49 
50 impl<T: AsRef<[u8]> + Debug + Send + Clone> Clone for UserPtrHandle<T> {
clone(&self) -> Self51     fn clone(&self) -> Self {
52         UserPtrHandle(self.0.clone())
53     }
54 }
55 
56 impl<T: AsRef<[u8]> + Debug + Send + 'static> AsRef<[u8]> for UserPtrHandle<T> {
as_ref(&self) -> &[u8]57     fn as_ref(&self) -> &[u8] {
58         self.0.as_ref()
59     }
60 }
61 
62 impl<T: AsRef<[u8]> + Debug + Send> From<T> for UserPtrHandle<T> {
from(buffer: T) -> Self63     fn from(buffer: T) -> Self {
64         UserPtrHandle(buffer)
65     }
66 }
67 
68 impl<T: AsRef<[u8]> + Debug + Send + 'static> PlaneHandle for UserPtrHandle<T> {
69     type Memory = UserPtr;
70 
fill_v4l2_plane(&self, plane: &mut bindings::v4l2_plane)71     fn fill_v4l2_plane(&self, plane: &mut bindings::v4l2_plane) {
72         let slice = AsRef::<[u8]>::as_ref(&self.0);
73 
74         plane.m.userptr = slice.as_ptr() as std::os::raw::c_ulong;
75         plane.length = slice.len() as u32;
76     }
77 }
78