1 use crate::{ 2 device::queue::{ 3 direction::{Capture, Direction, Output}, 4 qbuf::{ 5 CaptureQueueable, CaptureQueueableProvider, OutputQueueable, OutputQueueableProvider, 6 QBuffer, QueueResult, 7 }, 8 BuffersAllocated, Queue, 9 }, 10 memory::DmaBufHandle, 11 }; 12 use crate::{ 13 memory::MmapHandle, 14 memory::{BufferHandles, MemoryType, UserPtrHandle}, 15 }; 16 use std::{fmt::Debug, fs::File}; 17 18 /// Supported memory types for `GenericBufferHandles`. 19 /// TODO: This should be renamed to "DynamicBufferHandles", and be constructed 20 /// on-the-fly using a macro. 21 #[derive(Debug, Clone, Copy, PartialEq)] 22 pub enum GenericSupportedMemoryType { 23 Mmap, 24 UserPtr, 25 DmaBuf, 26 } 27 28 impl From<GenericSupportedMemoryType> for MemoryType { from(mem_type: GenericSupportedMemoryType) -> Self29 fn from(mem_type: GenericSupportedMemoryType) -> Self { 30 match mem_type { 31 GenericSupportedMemoryType::Mmap => MemoryType::Mmap, 32 GenericSupportedMemoryType::UserPtr => MemoryType::UserPtr, 33 GenericSupportedMemoryType::DmaBuf => MemoryType::DmaBuf, 34 } 35 } 36 } 37 38 /// Buffer handle capable of holding either MMAP or UserPtr handles. Useful 39 /// for cases when we want to decide the memory type of a queue at runtime. 40 #[derive(Debug)] 41 pub enum GenericBufferHandles { 42 Mmap(Vec<MmapHandle>), 43 User(Vec<UserPtrHandle<Vec<u8>>>), 44 DmaBuf(Vec<DmaBufHandle<File>>), 45 } 46 47 impl From<Vec<MmapHandle>> for GenericBufferHandles { from(m: Vec<MmapHandle>) -> Self48 fn from(m: Vec<MmapHandle>) -> Self { 49 Self::Mmap(m) 50 } 51 } 52 53 impl From<Vec<UserPtrHandle<Vec<u8>>>> for GenericBufferHandles { from(u: Vec<UserPtrHandle<Vec<u8>>>) -> Self54 fn from(u: Vec<UserPtrHandle<Vec<u8>>>) -> Self { 55 Self::User(u) 56 } 57 } 58 59 impl From<Vec<DmaBufHandle<File>>> for GenericBufferHandles { from(d: Vec<DmaBufHandle<File>>) -> Self60 fn from(d: Vec<DmaBufHandle<File>>) -> Self { 61 Self::DmaBuf(d) 62 } 63 } 64 65 impl BufferHandles for GenericBufferHandles { 66 type SupportedMemoryType = GenericSupportedMemoryType; 67 len(&self) -> usize68 fn len(&self) -> usize { 69 match self { 70 GenericBufferHandles::Mmap(m) => m.len(), 71 GenericBufferHandles::User(u) => u.len(), 72 GenericBufferHandles::DmaBuf(d) => d.len(), 73 } 74 } 75 fill_v4l2_plane(&self, index: usize, plane: &mut crate::bindings::v4l2_plane)76 fn fill_v4l2_plane(&self, index: usize, plane: &mut crate::bindings::v4l2_plane) { 77 match self { 78 GenericBufferHandles::Mmap(m) => m.fill_v4l2_plane(index, plane), 79 GenericBufferHandles::User(u) => u.fill_v4l2_plane(index, plane), 80 GenericBufferHandles::DmaBuf(d) => d.fill_v4l2_plane(index, plane), 81 } 82 } 83 } 84 85 /// A QBuffer that holds either MMAP or UserPtr handles, depending on which 86 /// memory type has been selected for the queue at runtime. 87 pub enum GenericQBuffer<'a, D: Direction> { 88 Mmap(QBuffer<'a, D, Vec<MmapHandle>, GenericBufferHandles>), 89 User(QBuffer<'a, D, Vec<UserPtrHandle<Vec<u8>>>, GenericBufferHandles>), 90 DmaBuf(QBuffer<'a, D, Vec<DmaBufHandle<File>>, GenericBufferHandles>), 91 } 92 93 impl<'a, D: Direction> From<QBuffer<'a, D, Vec<MmapHandle>, GenericBufferHandles>> 94 for GenericQBuffer<'a, D> 95 { from(qb: QBuffer<'a, D, Vec<MmapHandle>, GenericBufferHandles>) -> Self96 fn from(qb: QBuffer<'a, D, Vec<MmapHandle>, GenericBufferHandles>) -> Self { 97 GenericQBuffer::Mmap(qb) 98 } 99 } 100 101 impl<'a, D: Direction> From<QBuffer<'a, D, Vec<UserPtrHandle<Vec<u8>>>, GenericBufferHandles>> 102 for GenericQBuffer<'a, D> 103 { from(qb: QBuffer<'a, D, Vec<UserPtrHandle<Vec<u8>>>, GenericBufferHandles>) -> Self104 fn from(qb: QBuffer<'a, D, Vec<UserPtrHandle<Vec<u8>>>, GenericBufferHandles>) -> Self { 105 GenericQBuffer::User(qb) 106 } 107 } 108 109 impl<'a, D: Direction> From<QBuffer<'a, D, Vec<DmaBufHandle<File>>, GenericBufferHandles>> 110 for GenericQBuffer<'a, D> 111 { from(qb: QBuffer<'a, D, Vec<DmaBufHandle<File>>, GenericBufferHandles>) -> Self112 fn from(qb: QBuffer<'a, D, Vec<DmaBufHandle<File>>, GenericBufferHandles>) -> Self { 113 GenericQBuffer::DmaBuf(qb) 114 } 115 } 116 117 /// Any CAPTURE GenericQBuffer implements CaptureQueueable. 118 impl CaptureQueueable<GenericBufferHandles> for GenericQBuffer<'_, Capture> { queue_with_handles( self, handles: GenericBufferHandles, ) -> QueueResult<(), GenericBufferHandles>119 fn queue_with_handles( 120 self, 121 handles: GenericBufferHandles, 122 ) -> QueueResult<(), GenericBufferHandles> { 123 match self { 124 GenericQBuffer::Mmap(m) => m.queue_with_handles(handles), 125 GenericQBuffer::User(u) => u.queue_with_handles(handles), 126 GenericQBuffer::DmaBuf(d) => d.queue_with_handles(handles), 127 } 128 } 129 } 130 131 /// Any OUTPUT GenericQBuffer implements OutputQueueable. 132 impl OutputQueueable<GenericBufferHandles> for GenericQBuffer<'_, Output> { queue_with_handles( self, handles: GenericBufferHandles, bytes_used: &[usize], ) -> QueueResult<(), GenericBufferHandles>133 fn queue_with_handles( 134 self, 135 handles: GenericBufferHandles, 136 bytes_used: &[usize], 137 ) -> QueueResult<(), GenericBufferHandles> { 138 match self { 139 GenericQBuffer::Mmap(m) => m.queue_with_handles(handles, bytes_used), 140 GenericQBuffer::User(u) => u.queue_with_handles(handles, bytes_used), 141 GenericQBuffer::DmaBuf(d) => d.queue_with_handles(handles, bytes_used), 142 } 143 } 144 } 145 146 impl<'a> CaptureQueueableProvider<'a, GenericBufferHandles> 147 for Queue<Capture, BuffersAllocated<GenericBufferHandles>> 148 { 149 type Queueable = GenericQBuffer<'a, Capture>; 150 } 151 152 impl<'a> OutputQueueableProvider<'a, GenericBufferHandles> 153 for Queue<Output, BuffersAllocated<GenericBufferHandles>> 154 { 155 type Queueable = GenericQBuffer<'a, Output>; 156 } 157