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