1 //! Operations specific to DMABuf-type buffers. 2 use log::warn; 3 4 use super::*; 5 use crate::{bindings, ioctl}; 6 use std::os::fd::RawFd; 7 use std::os::unix::io::{AsFd, AsRawFd}; 8 9 pub struct DmaBuf; 10 11 pub type DmaBufferHandles<T> = Vec<DmaBufHandle<T>>; 12 13 impl Memory for DmaBuf { 14 const MEMORY_TYPE: MemoryType = MemoryType::DmaBuf; 15 type RawBacking = RawFd; 16 get_plane_buffer_backing( m: &bindings::v4l2_plane__bindgen_ty_1, ) -> &Self::RawBacking17 unsafe fn get_plane_buffer_backing( 18 m: &bindings::v4l2_plane__bindgen_ty_1, 19 ) -> &Self::RawBacking { 20 &m.fd 21 } 22 get_single_planar_buffer_backing( m: &bindings::v4l2_buffer__bindgen_ty_1, ) -> &Self::RawBacking23 unsafe fn get_single_planar_buffer_backing( 24 m: &bindings::v4l2_buffer__bindgen_ty_1, 25 ) -> &Self::RawBacking { 26 &m.fd 27 } 28 get_plane_buffer_backing_mut( m: &mut bindings::v4l2_plane__bindgen_ty_1, ) -> &mut Self::RawBacking29 unsafe fn get_plane_buffer_backing_mut( 30 m: &mut bindings::v4l2_plane__bindgen_ty_1, 31 ) -> &mut Self::RawBacking { 32 &mut m.fd 33 } 34 get_single_planar_buffer_backing_mut( m: &mut bindings::v4l2_buffer__bindgen_ty_1, ) -> &mut Self::RawBacking35 unsafe fn get_single_planar_buffer_backing_mut( 36 m: &mut bindings::v4l2_buffer__bindgen_ty_1, 37 ) -> &mut Self::RawBacking { 38 &mut m.fd 39 } 40 } 41 42 impl Imported for DmaBuf {} 43 44 pub trait DmaBufSource: AsRawFd + AsFd + Debug + Send { len(&self) -> u6445 fn len(&self) -> u64; 46 47 /// Make Clippy happy. is_empty(&self) -> bool48 fn is_empty(&self) -> bool { 49 self.len() == 0 50 } 51 } 52 53 impl DmaBufSource for std::fs::File { len(&self) -> u6454 fn len(&self) -> u64 { 55 match self.metadata() { 56 Err(_) => { 57 warn!("Failed to compute File size for use as DMABuf, using 0..."); 58 0 59 } 60 Ok(m) => m.len(), 61 } 62 } 63 } 64 65 /// Handle for a DMABUF plane. Any type that can provide a file descriptor is 66 /// valid. 67 #[derive(Debug)] 68 pub struct DmaBufHandle<T: DmaBufSource>(pub T); 69 70 impl<T: DmaBufSource> From<T> for DmaBufHandle<T> { from(dmabuf: T) -> Self71 fn from(dmabuf: T) -> Self { 72 DmaBufHandle(dmabuf) 73 } 74 } 75 76 impl<T: DmaBufSource + 'static> PlaneHandle for DmaBufHandle<T> { 77 type Memory = DmaBuf; 78 fill_v4l2_plane(&self, plane: &mut bindings::v4l2_plane)79 fn fill_v4l2_plane(&self, plane: &mut bindings::v4l2_plane) { 80 plane.m.fd = self.0.as_raw_fd(); 81 plane.length = self.0.len() as u32; 82 } 83 } 84 85 impl<T: DmaBufSource> DmaBufHandle<T> { map(&self) -> Result<PlaneMapping, ioctl::MmapError>86 pub fn map(&self) -> Result<PlaneMapping, ioctl::MmapError> { 87 let len = self.0.len(); 88 89 ioctl::mmap(&self.0, 0, len as u32) 90 } 91 } 92