1 // Copyright 2024 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 use anyhow::anyhow;
6 use std::cell::RefCell;
7 use std::convert::Infallible;
8 use std::rc::Rc;
9 use std::sync::Arc;
10 use thiserror::Error;
11
12 use v4l2r::bindings::v4l2_format;
13 use v4l2r::device::queue::direction;
14 use v4l2r::device::queue::direction::Capture;
15 use v4l2r::device::queue::direction::Output;
16 use v4l2r::device::queue::dqbuf::DqBuffer;
17 use v4l2r::device::queue::qbuf::QBuffer;
18 use v4l2r::device::queue::BuffersAllocated;
19 use v4l2r::device::queue::CaptureQueueable;
20 use v4l2r::device::queue::CreateQueueError;
21 use v4l2r::device::queue::GetFreeBufferError;
22 use v4l2r::device::queue::GetFreeCaptureBuffer;
23 use v4l2r::device::queue::GetFreeOutputBuffer;
24 use v4l2r::device::queue::Queue;
25 use v4l2r::device::queue::QueueInit;
26 use v4l2r::device::queue::RequestBuffersError;
27 use v4l2r::device::AllocatedQueue;
28 use v4l2r::device::Device;
29 use v4l2r::device::Stream;
30 use v4l2r::device::TryDequeue;
31 use v4l2r::ioctl::GFmtError;
32 use v4l2r::ioctl::IoctlConvertError;
33 use v4l2r::ioctl::QBufIoctlError;
34 use v4l2r::ioctl::SFmtError;
35 use v4l2r::ioctl::StreamOnError;
36 use v4l2r::memory::BufferHandles;
37 use v4l2r::memory::Memory;
38 use v4l2r::memory::MemoryType;
39 use v4l2r::memory::MmapHandle;
40 use v4l2r::memory::PlaneHandle;
41 use v4l2r::nix::sys::time::TimeVal;
42 use v4l2r::Format;
43 use v4l2r::PlaneLayout;
44
45 use crate::decoder::stateless::DecodeError;
46 use crate::decoder::stateless::NewStatelessDecoderError;
47 use crate::decoder::stateless::StatelessBackendError;
48 use crate::utils::buffer_size_for_area;
49 use crate::video_frame::V4l2VideoFrame;
50 use crate::video_frame::VideoFrame;
51 use crate::Fourcc;
52 use crate::Resolution;
53
54 //TODO: handle memory backends other than mmap
55 //TODO: handle video formats other than h264
56 //TODO: handle synced buffers in Streaming state
57 #[derive(Default)]
58 enum V4l2OutputQueueHandle<T: v4l2r::device::queue::direction::Direction> {
59 Init(Queue<T, QueueInit>),
60 Streaming(Rc<Queue<T, BuffersAllocated<Vec<MmapHandle>>>>),
61 #[default]
62 Unknown,
63 }
64
65 #[derive(Default)]
66 enum V4l2CaptureQueueHandle<T: v4l2r::device::queue::direction::Direction, V: VideoFrame> {
67 Init(Queue<T, QueueInit>),
68 Streaming(Rc<Queue<T, BuffersAllocated<V4l2VideoFrame<V>>>>),
69 #[default]
70 Unknown,
71 }
72
73 #[derive(Debug, Error)]
74 pub enum QueueError {
75 #[error("unable to create queue.")]
76 Creation,
77 #[error("failed to get format for queue.")]
78 FormatGet,
79 #[error("failed to set format for queue.")]
80 FormatSet,
81 #[error("failed requesting buffers.")]
82 RequestBuffers,
83 #[error("unable to stream on.")]
84 StreamOn,
85 #[error("driver does not support {0}.")]
86 UnsupportedPixelFormat(Fourcc),
87 #[error("operation can not be performed in this state.")]
88 State,
89 #[error("no buffer to dequeue.")]
90 BufferDequeue,
91 #[error("failed to queue buffer.")]
92 BufferQueue,
93 #[error("requested {0} buffers, only {1} allocated")]
94 NotEnoughRequestedBuffers(usize, usize),
95 #[error("failed to stream off.")]
96 StreamOff,
97 #[error("failed to get queue handle.")]
98 QueueHandle,
99 #[error("failed to free buffers.")]
100 FreeBuffer,
101 #[error("failed to reset OUTPUT queue.")]
102 ResetOutputQueue,
103 #[error("failed to reset CAPTURE queue.")]
104 ResetCaptureQueue,
105 }
106
107 impl From<QueueError> for DecodeError {
from(err: QueueError) -> Self108 fn from(err: QueueError) -> Self {
109 DecodeError::BackendError(StatelessBackendError::Other(anyhow::anyhow!(err)))
110 }
111 }
112
113 impl<B: BufferHandles> From<v4l2r::device::queue::qbuf::QueueError<B>> for QueueError {
from(_err: v4l2r::device::queue::qbuf::QueueError<B>) -> Self114 fn from(_err: v4l2r::device::queue::qbuf::QueueError<B>) -> Self {
115 QueueError::BufferQueue
116 }
117 }
118
119 impl From<CreateQueueError> for QueueError {
from(_err: CreateQueueError) -> Self120 fn from(_err: CreateQueueError) -> Self {
121 QueueError::Creation
122 }
123 }
124
125 impl From<GFmtError> for QueueError {
from(_err: GFmtError) -> Self126 fn from(_err: GFmtError) -> Self {
127 QueueError::FormatGet
128 }
129 }
130
131 impl From<SFmtError> for QueueError {
from(_err: SFmtError) -> Self132 fn from(_err: SFmtError) -> Self {
133 QueueError::FormatSet
134 }
135 }
136
137 impl From<RequestBuffersError> for QueueError {
from(_err: RequestBuffersError) -> Self138 fn from(_err: RequestBuffersError) -> Self {
139 QueueError::RequestBuffers
140 }
141 }
142
143 impl From<StreamOnError> for QueueError {
from(_err: StreamOnError) -> Self144 fn from(_err: StreamOnError) -> Self {
145 QueueError::StreamOn
146 }
147 }
148
149 impl From<GetFreeBufferError> for QueueError {
from(_err: GetFreeBufferError) -> Self150 fn from(_err: GetFreeBufferError) -> Self {
151 QueueError::BufferDequeue
152 }
153 }
154
155 impl From<IoctlConvertError<QBufIoctlError, Infallible>> for QueueError {
from(_err: IoctlConvertError<QBufIoctlError, Infallible>) -> Self156 fn from(_err: IoctlConvertError<QBufIoctlError, Infallible>) -> Self {
157 QueueError::BufferQueue
158 }
159 }
160
check_requested_buffer_count(requested: u32, received: usize) -> Result<(), QueueError>161 fn check_requested_buffer_count(requested: u32, received: usize) -> Result<(), QueueError> {
162 if received < requested as usize {
163 return Err(QueueError::NotEnoughRequestedBuffers(requested as usize, received));
164 }
165 Ok(())
166 }
167
168 //TODO: handle memory backends other than mmap
169 pub struct V4l2OutputBuffer {
170 queue: V4l2OutputQueue,
171 handle: QBuffer<
172 Output,
173 Vec<MmapHandle>,
174 Vec<MmapHandle>,
175 Rc<Queue<Output, BuffersAllocated<Vec<MmapHandle>>>>,
176 >,
177 length: usize,
178 }
179
180 impl V4l2OutputBuffer {
new( queue: V4l2OutputQueue, handle: QBuffer< Output, Vec<MmapHandle>, Vec<MmapHandle>, Rc<Queue<Output, BuffersAllocated<Vec<MmapHandle>>>>, >, ) -> Self181 fn new(
182 queue: V4l2OutputQueue,
183 handle: QBuffer<
184 Output,
185 Vec<MmapHandle>,
186 Vec<MmapHandle>,
187 Rc<Queue<Output, BuffersAllocated<Vec<MmapHandle>>>>,
188 >,
189 ) -> Self {
190 Self { queue, handle, length: 0 }
191 }
index(&self) -> usize192 pub fn index(&self) -> usize {
193 self.handle.index()
194 }
length(&self) -> usize195 pub fn length(&self) -> usize {
196 self.length
197 }
write(&mut self, data: &[u8]) -> &mut Self198 pub fn write(&mut self, data: &[u8]) -> &mut Self {
199 let mut mapping = self.handle.get_plane_mapping(0).expect("Failed to mmap output buffer");
200
201 mapping.as_mut()[self.length..self.length + data.len()].copy_from_slice(data);
202 self.length += data.len();
203
204 drop(mapping);
205 self
206 }
submit(self, timestamp: u64, request_fd: i32) -> Result<(), QueueError>207 pub fn submit(self, timestamp: u64, request_fd: i32) -> Result<(), QueueError> {
208 let handle = &*self.queue.handle.borrow();
209 match handle {
210 V4l2OutputQueueHandle::Streaming(_) => {
211 self.handle
212 .set_timestamp(TimeVal::new(/* FIXME: sec */ 0, timestamp as i64))
213 .set_request(request_fd)
214 .queue(&[self.length])?;
215 Ok(())
216 }
217 _ => Err(QueueError::State),
218 }
219 }
220 }
221
222 #[derive(Clone)]
223 pub struct V4l2OutputQueue {
224 handle: Rc<RefCell<V4l2OutputQueueHandle<direction::Output>>>,
225 }
226
227 const NUM_OUTPUT_BUFFERS: u32 = 2;
228 impl V4l2OutputQueue {
new(device: Arc<Device>) -> Result<Self, NewStatelessDecoderError>229 pub fn new(device: Arc<Device>) -> Result<Self, NewStatelessDecoderError> {
230 let handle = Queue::get_output_mplane_queue(device)
231 .map_err(|_| NewStatelessDecoderError::DriverInitialization)?;
232 log::debug!("output queue created");
233 let handle = Rc::new(RefCell::new(V4l2OutputQueueHandle::Init(handle)));
234 Ok(Self { handle })
235 }
236
reset(&mut self, device: Arc<Device>) -> Result<(), QueueError>237 pub fn reset(&mut self, device: Arc<Device>) -> Result<(), QueueError> {
238 let handle = self.handle.take();
239 let (ret, handle) = match handle {
240 V4l2OutputQueueHandle::Streaming(handle) => {
241 handle.stream_off().map_err(|_| QueueError::StreamOff)?;
242 (Rc::into_inner(handle).ok_or(QueueError::QueueHandle)?)
243 .free_buffers()
244 .map_err(|_| QueueError::FreeBuffer)?;
245
246 let queue_handle = Queue::get_output_mplane_queue(device.clone())
247 .map_err(|_| QueueError::QueueHandle);
248
249 (Ok(()), V4l2OutputQueueHandle::Init(queue_handle?))
250 }
251 _ => (Err(QueueError::State), handle),
252 };
253 self.handle.replace(handle);
254 ret
255 }
256
initialize( &mut self, fourcc: Fourcc, resolution: Resolution, ) -> Result<&mut Self, QueueError>257 pub fn initialize(
258 &mut self,
259 fourcc: Fourcc,
260 resolution: Resolution,
261 ) -> Result<&mut Self, QueueError> {
262 self.handle.replace(match self.handle.take() {
263 V4l2OutputQueueHandle::Init(mut handle) => {
264 let (width, height) = resolution.into();
265 handle
266 .change_format()?
267 .set_size(width as usize, height as usize)
268 .set_pixelformat(fourcc)
269 .set_planes_layout(vec![PlaneLayout {
270 sizeimage: buffer_size_for_area(width, height),
271 ..Default::default()
272 }])
273 .apply::<v4l2_format>()?;
274
275 let format: Format = handle.get_format()?;
276 if format.pixelformat != fourcc.into() {
277 return Err(QueueError::UnsupportedPixelFormat(fourcc));
278 }
279
280 let handle = handle.request_buffers_generic::<Vec<MmapHandle>>(
281 MemoryType::Mmap,
282 NUM_OUTPUT_BUFFERS,
283 )?;
284
285 check_requested_buffer_count(NUM_OUTPUT_BUFFERS, handle.num_free_buffers())?;
286
287 handle.stream_on()?;
288
289 V4l2OutputQueueHandle::Streaming(handle.into())
290 }
291 _ => return Err(QueueError::State),
292 });
293 Ok(self)
294 }
295
num_free_buffers(&self) -> usize296 pub fn num_free_buffers(&self) -> usize {
297 let handle = &*self.handle.borrow();
298 match handle {
299 V4l2OutputQueueHandle::Streaming(handle) => handle.num_free_buffers(),
300 _ => 0,
301 }
302 }
alloc_buffer(&self) -> Result<V4l2OutputBuffer, DecodeError>303 pub fn alloc_buffer(&self) -> Result<V4l2OutputBuffer, DecodeError> {
304 let handle = &*self.handle.borrow();
305 match handle {
306 V4l2OutputQueueHandle::Streaming(handle) => match handle.try_get_free_buffer() {
307 Ok(buffer) => Ok(V4l2OutputBuffer::new(self.clone(), buffer)),
308 Err(_) => Err(DecodeError::NotEnoughOutputBuffers(1)),
309 },
310 _ => Err(DecodeError::DecoderError(anyhow!("Invalid hardware handle"))),
311 }
312 }
dequeue_buffer(&self) -> Result<(), QueueError>313 pub fn dequeue_buffer(&self) -> Result<(), QueueError> {
314 let handle = &*self.handle.borrow();
315 match handle {
316 V4l2OutputQueueHandle::Streaming(handle) => {
317 handle.try_dequeue().map_err(|_| QueueError::BufferDequeue)?;
318 Ok(())
319 }
320 _ => Err(QueueError::State),
321 }
322 }
323 }
324
325 pub struct V4l2CaptureBuffer<V: VideoFrame> {
326 pub frame: Arc<V>,
327 handle: DqBuffer<Capture, V4l2VideoFrame<V>>,
328 }
329
330 impl<V: VideoFrame> V4l2CaptureBuffer<V> {
new(frame: Arc<V>, handle: DqBuffer<Capture, V4l2VideoFrame<V>>) -> Self331 fn new(frame: Arc<V>, handle: DqBuffer<Capture, V4l2VideoFrame<V>>) -> Self {
332 Self { frame, handle }
333 }
timestamp(&self) -> u64334 pub fn timestamp(&self) -> u64 {
335 self.handle.data.timestamp().tv_usec as u64
336 }
337 // TODO enable once upstream v4l2r has rolled
338 // pub fn has_error(&self) -> bool {
339 // self.handle.data.has_error() as u64
340 // }
341 }
342
343 pub struct V4l2CaptureQueue<V: VideoFrame> {
344 format: Format,
345 handle: RefCell<V4l2CaptureQueueHandle<direction::Capture, V>>,
346 num_buffers: u32,
347 device: Arc<Device>,
348 }
349
350 impl<V: VideoFrame> V4l2CaptureQueue<V> {
new(device: Arc<Device>) -> Result<Self, NewStatelessDecoderError>351 pub fn new(device: Arc<Device>) -> Result<Self, NewStatelessDecoderError> {
352 let handle = Queue::get_capture_mplane_queue(device.clone())
353 .map_err(|_| NewStatelessDecoderError::DriverInitialization)?;
354 log::debug!("capture queue created");
355 let handle = RefCell::new(V4l2CaptureQueueHandle::Init(handle));
356 Ok(Self { handle, num_buffers: 0, format: Default::default(), device: device })
357 }
358
reset(&mut self, device: Arc<Device>) -> Result<(), QueueError>359 pub fn reset(&mut self, device: Arc<Device>) -> Result<(), QueueError> {
360 let handle = self.handle.take();
361 let (ret, handle) = match handle {
362 V4l2CaptureQueueHandle::Streaming(handle) => {
363 handle.stream_off().map_err(|_| QueueError::StreamOff)?;
364 (Rc::into_inner(handle).ok_or(QueueError::QueueHandle)?)
365 .free_buffers()
366 .map_err(|_| QueueError::FreeBuffer)?;
367
368 let queue_handle = Queue::get_capture_mplane_queue(device.clone())
369 .map_err(|_| QueueError::QueueHandle);
370
371 (Ok(()), V4l2CaptureQueueHandle::Init(queue_handle?))
372 }
373 _ => (Err(QueueError::State), handle),
374 };
375 self.handle.replace(handle);
376 ret
377 }
378
initialize(&mut self, requested_num_buffers: u32) -> Result<&mut Self, QueueError>379 pub fn initialize(&mut self, requested_num_buffers: u32) -> Result<&mut Self, QueueError> {
380 // +2 due to HCMP1_HHI_A.h264 needing more
381 let requested_num_buffers = requested_num_buffers + 2;
382
383 self.handle.replace(match self.handle.take() {
384 V4l2CaptureQueueHandle::Init(handle) => {
385 // TODO: check if decoded format is supported.
386 self.format = handle.get_format()?;
387 // TODO: handle 10 bit format negotiation.
388 let handle = handle.request_buffers_generic::<V4l2VideoFrame<V>>(
389 <V::NativeHandle as PlaneHandle>::Memory::MEMORY_TYPE,
390 requested_num_buffers,
391 )?;
392
393 check_requested_buffer_count(requested_num_buffers, handle.num_free_buffers())?;
394
395 self.num_buffers = requested_num_buffers;
396
397 handle.stream_on()?;
398
399 V4l2CaptureQueueHandle::Streaming(handle.into())
400 }
401 _ => return Err(QueueError::State),
402 });
403
404 Ok(self)
405 }
406
dequeue_buffer(&self) -> Result<Option<V4l2CaptureBuffer<V>>, QueueError>407 pub fn dequeue_buffer(&self) -> Result<Option<V4l2CaptureBuffer<V>>, QueueError> {
408 let handle = &*self.handle.borrow();
409 match handle {
410 V4l2CaptureQueueHandle::Streaming(handle) => match handle.try_dequeue() {
411 Ok(mut buffer) => {
412 log::debug!("capture buffer {} dequeued", buffer.data.index());
413 // TODO handle buffer dequeuing successfully, but having an error
414 // buffer.data.has_error();
415 let mut frame = buffer.take_handles().expect("Missing handle on dequeue!").0;
416 frame.process_dqbuf(self.device.clone(), &self.format, &buffer.data);
417 Ok(Some(V4l2CaptureBuffer::new(Arc::new(frame), buffer)))
418 }
419 _ => Ok(None),
420 },
421 _ => Err(QueueError::State),
422 }
423 }
424
425 // TODO: Plumb in VideoFrames from external Gralloc frame pool instead of reallocating every
426 // frame every time.
queue_buffer(&self, frame: V) -> Result<(), QueueError>427 pub fn queue_buffer(&self, frame: V) -> Result<(), QueueError> {
428 let handle = &*self.handle.borrow();
429 match handle {
430 V4l2CaptureQueueHandle::Streaming(handle) => {
431 let buffer = handle.try_get_free_buffer()?;
432 log::debug!("capture buffer {} queued", buffer.index());
433 buffer.queue_with_handles(frame.into())?;
434 }
435 _ => return Err(QueueError::State),
436 }
437 Ok(())
438 }
439
num_free_buffers(&self) -> usize440 pub fn num_free_buffers(&self) -> usize {
441 let handle = &*self.handle.borrow();
442 match handle {
443 V4l2CaptureQueueHandle::Streaming(handle) => handle.num_free_buffers(),
444 _ => 0,
445 }
446 }
447 }
448