1 use std::{ 2 collections::VecDeque, 3 fmt::Debug, 4 sync::{Arc, Mutex, Weak}, 5 task::Wake, 6 }; 7 8 use log::error; 9 10 use crate::{ 11 bindings, 12 device::poller::Waker, 13 memory::{BufferHandles, MmapHandle, PrimitiveBufferHandles}, 14 Format, 15 }; 16 17 use thiserror::Error; 18 19 use super::qbuf::{ 20 get_free::{GetFreeBufferError, GetFreeCaptureBuffer}, 21 get_indexed::{GetCaptureBufferByIndex, TryGetBufferError}, 22 CaptureQueueableProvider, 23 }; 24 25 #[derive(Debug, Error)] 26 pub enum GetSuitableBufferError { 27 #[error("error while calling try_get_free_buffer(): {0}")] 28 TryGetFree(#[from] GetFreeBufferError), 29 #[error("error while calling try_get_buffer(): {0}")] 30 TryGetIndexed(#[from] TryGetBufferError), 31 } 32 33 pub trait HandlesProvider: Send + 'static { 34 type HandleType: BufferHandles; 35 36 /// Request a set of handles. Returns `None` if no handle is currently 37 /// available. If that is the case, `waker` will be signaled when handles 38 /// are available again. get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType>39 fn get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType>; 40 get_suitable_buffer_for<'a, Q>( &self, _handles: &Self::HandleType, queue: &'a Q, ) -> Result< <Q as CaptureQueueableProvider<'a, Self::HandleType>>::Queueable, GetSuitableBufferError, > where Q: GetCaptureBufferByIndex<'a, Self::HandleType> + GetFreeCaptureBuffer<'a, Self::HandleType>,41 fn get_suitable_buffer_for<'a, Q>( 42 &self, 43 _handles: &Self::HandleType, 44 queue: &'a Q, 45 ) -> Result< 46 <Q as CaptureQueueableProvider<'a, Self::HandleType>>::Queueable, 47 GetSuitableBufferError, 48 > 49 where 50 Q: GetCaptureBufferByIndex<'a, Self::HandleType> 51 + GetFreeCaptureBuffer<'a, Self::HandleType>, 52 { 53 Ok(queue.try_get_free_buffer()?) 54 } 55 } 56 57 /// `HandleProvider`s on the heap are `HandleProvider`s too. 58 impl<P: HandlesProvider> HandlesProvider for Box<P> { 59 type HandleType = P::HandleType; 60 get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType>61 fn get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType> { 62 self.as_ref().get_handles(waker) 63 } 64 get_suitable_buffer_for<'a, Q>( &self, handles: &Self::HandleType, queue: &'a Q, ) -> Result< <Q as CaptureQueueableProvider<'a, Self::HandleType>>::Queueable, GetSuitableBufferError, > where Q: GetCaptureBufferByIndex<'a, Self::HandleType> + GetFreeCaptureBuffer<'a, Self::HandleType>,65 fn get_suitable_buffer_for<'a, Q>( 66 &self, 67 handles: &Self::HandleType, 68 queue: &'a Q, 69 ) -> Result< 70 <Q as CaptureQueueableProvider<'a, Self::HandleType>>::Queueable, 71 GetSuitableBufferError, 72 > 73 where 74 Q: GetCaptureBufferByIndex<'a, Self::HandleType> 75 + GetFreeCaptureBuffer<'a, Self::HandleType>, 76 { 77 self.as_ref().get_suitable_buffer_for(handles, queue) 78 } 79 } 80 81 impl<P: HandlesProvider + Sync> HandlesProvider for Arc<P> { 82 type HandleType = P::HandleType; 83 get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType>84 fn get_handles(&self, waker: &Arc<Waker>) -> Option<Self::HandleType> { 85 self.as_ref().get_handles(waker) 86 } 87 get_suitable_buffer_for<'a, Q>( &self, handles: &Self::HandleType, queue: &'a Q, ) -> Result< <Q as CaptureQueueableProvider<'a, Self::HandleType>>::Queueable, GetSuitableBufferError, > where Q: GetCaptureBufferByIndex<'a, Self::HandleType> + GetFreeCaptureBuffer<'a, Self::HandleType>,88 fn get_suitable_buffer_for<'a, Q>( 89 &self, 90 handles: &Self::HandleType, 91 queue: &'a Q, 92 ) -> Result< 93 <Q as CaptureQueueableProvider<'a, Self::HandleType>>::Queueable, 94 GetSuitableBufferError, 95 > 96 where 97 Q: GetCaptureBufferByIndex<'a, Self::HandleType> 98 + GetFreeCaptureBuffer<'a, Self::HandleType>, 99 { 100 self.as_ref().get_suitable_buffer_for(handles, queue) 101 } 102 } 103 104 pub struct MmapProvider(Vec<MmapHandle>); 105 106 impl MmapProvider { new(format: &Format) -> Self107 pub fn new(format: &Format) -> Self { 108 Self(vec![Default::default(); format.plane_fmt.len()]) 109 } 110 } 111 112 impl HandlesProvider for MmapProvider { 113 type HandleType = Vec<MmapHandle>; 114 get_handles(&self, _waker: &Arc<Waker>) -> Option<Self::HandleType>115 fn get_handles(&self, _waker: &Arc<Waker>) -> Option<Self::HandleType> { 116 Some(self.0.clone()) 117 } 118 } 119 120 /// Internals of `PooledHandlesProvider`, which acts just as a protected wrapper 121 /// around this structure. 122 struct PooledHandlesProviderInternal<H: BufferHandles> { 123 buffers: VecDeque<H>, 124 waker: Option<Arc<Waker>>, 125 } 126 127 unsafe impl<H: BufferHandles> Send for PooledHandlesProviderInternal<H> {} 128 129 /// A handles provider that recycles buffers from a fixed set in a pool. 130 /// Provided `PooledHandles` will not be recycled for as long as the instance is 131 /// alive. Once it is dropped, it the underlying buffer returns into the pool to 132 /// be reused later. 133 pub struct PooledHandlesProvider<H: BufferHandles> { 134 d: Arc<Mutex<PooledHandlesProviderInternal<H>>>, 135 } 136 137 impl<H: BufferHandles> PooledHandlesProvider<H> { 138 /// Create a new `PooledMemoryProvider`, using the set in `buffers`. new<B: IntoIterator<Item = H>>(buffers: B) -> Self139 pub fn new<B: IntoIterator<Item = H>>(buffers: B) -> Self { 140 Self { 141 d: Arc::new(Mutex::new(PooledHandlesProviderInternal { 142 buffers: buffers.into_iter().collect(), 143 waker: None, 144 })), 145 } 146 } 147 } 148 149 impl<H: BufferHandles> HandlesProvider for PooledHandlesProvider<H> { 150 type HandleType = PooledHandles<H>; 151 get_handles(&self, waker: &Arc<Waker>) -> Option<PooledHandles<H>>152 fn get_handles(&self, waker: &Arc<Waker>) -> Option<PooledHandles<H>> { 153 let mut d = self.d.lock().unwrap(); 154 match d.buffers.pop_front() { 155 Some(handles) => Some(PooledHandles::new(&self.d, handles)), 156 None => { 157 d.waker = Some(Arc::clone(waker)); 158 None 159 } 160 } 161 } 162 } 163 164 /// A set of buffer handles provided by `PooledHandlesProvider`. The handles 165 /// will remain out of the pool as long as this instance is alive, i.e. the 166 /// handles will be recycled when it is dropped. 167 pub struct PooledHandles<H: BufferHandles> { 168 // Use of Option is necessary here because of Drop implementation, but the 169 // Option will always be Some() 170 handles: Option<H>, 171 provider: Weak<Mutex<PooledHandlesProviderInternal<H>>>, 172 } 173 174 impl<H: BufferHandles> PooledHandles<H> { new(provider: &Arc<Mutex<PooledHandlesProviderInternal<H>>>, handles: H) -> Self175 fn new(provider: &Arc<Mutex<PooledHandlesProviderInternal<H>>>, handles: H) -> Self { 176 Self { 177 handles: Some(handles), 178 provider: Arc::downgrade(provider), 179 } 180 } 181 handles(&self) -> &H182 pub fn handles(&self) -> &H { 183 self.handles.as_ref().unwrap() 184 } 185 } 186 187 impl<H: BufferHandles + Debug> Debug for PooledHandles<H> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result188 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 189 self.handles.fmt(f) 190 } 191 } 192 193 impl<H: BufferHandles> Drop for PooledHandles<H> { 194 /// Return the handles to the pool if it still exists, otherwise the handles 195 /// themselves are destroyed. drop(&mut self)196 fn drop(&mut self) { 197 match self.provider.upgrade() { 198 None => (), 199 Some(provider) => { 200 let mut provider = provider.lock().unwrap(); 201 provider.buffers.push_back(self.handles.take().unwrap()); 202 if let Some(waker) = provider.waker.take() { 203 waker.wake(); 204 } 205 } 206 } 207 } 208 } 209 210 impl<H: BufferHandles> BufferHandles for PooledHandles<H> { 211 type SupportedMemoryType = H::SupportedMemoryType; 212 len(&self) -> usize213 fn len(&self) -> usize { 214 self.handles.as_ref().unwrap().len() 215 } 216 fill_v4l2_plane(&self, index: usize, plane: &mut bindings::v4l2_plane)217 fn fill_v4l2_plane(&self, index: usize, plane: &mut bindings::v4l2_plane) { 218 self.handles.as_ref().unwrap().fill_v4l2_plane(index, plane); 219 } 220 } 221 222 impl<H: PrimitiveBufferHandles> PrimitiveBufferHandles for PooledHandles<H> { 223 type HandleType = H::HandleType; 224 const MEMORY_TYPE: Self::SupportedMemoryType = H::MEMORY_TYPE; 225 } 226