libcamera/
framebuffer_allocator.rs1use std::{
2 io,
3 ptr::NonNull,
4 sync::{Arc, Mutex},
5};
6
7use libcamera_sys::*;
8
9use crate::{camera::Camera, framebuffer::AsFrameBuffer, stream::Stream};
10
11struct FrameBufferAllocatorInstance {
14 ptr: NonNull<libcamera_framebuffer_allocator_t>,
15 allocated_streams: Vec<NonNull<libcamera_stream_t>>,
18}
19
20unsafe impl Send for FrameBufferAllocatorInstance {}
21
22impl Drop for FrameBufferAllocatorInstance {
23 fn drop(&mut self) {
24 for stream in self.allocated_streams.drain(..) {
26 unsafe {
27 libcamera_framebuffer_allocator_free(self.ptr.as_ptr(), stream.as_ptr());
28 }
29 }
30
31 unsafe { libcamera_framebuffer_allocator_destroy(self.ptr.as_ptr()) }
32 }
33}
34
35pub struct FrameBufferAllocator {
36 inner: Arc<Mutex<FrameBufferAllocatorInstance>>,
37}
38
39impl FrameBufferAllocator {
40 pub fn new(cam: &Camera<'_>) -> Self {
41 Self {
42 inner: Arc::new(Mutex::new(FrameBufferAllocatorInstance {
43 ptr: NonNull::new(unsafe { libcamera_framebuffer_allocator_create(cam.ptr.as_ptr()) }).unwrap(),
44 allocated_streams: Vec::new(),
45 })),
46 }
47 }
48
49 pub fn alloc(&mut self, stream: &Stream) -> io::Result<Vec<FrameBuffer>> {
52 let mut inner = self.inner.lock().unwrap();
53
54 let ret = unsafe { libcamera_framebuffer_allocator_allocate(inner.ptr.as_ptr(), stream.ptr.as_ptr()) };
55 if ret < 0 {
56 Err(io::Error::from_raw_os_error(ret))
57 } else {
58 inner.allocated_streams.push(stream.ptr);
59
60 let buffers = unsafe { libcamera_framebuffer_allocator_buffers(inner.ptr.as_ptr(), stream.ptr.as_ptr()) };
61
62 let len = unsafe { libcamera_framebuffer_list_size(buffers) };
63
64 Ok((0..len)
65 .map(|i| unsafe { libcamera_framebuffer_list_get(buffers, i) })
66 .map(|ptr| NonNull::new(ptr.cast_mut()).unwrap())
67 .map(|ptr| {
68 unsafe {
73 libcamera_framebuffer_metadata(ptr.as_ptr())
74 .cast_mut()
75 .cast::<u32>()
76 .write(u32::MAX)
77 };
78
79 FrameBuffer {
80 ptr,
81 _alloc: self.inner.clone(),
82 }
83 })
84 .collect())
85 }
86 }
87}
88
89pub struct FrameBuffer {
90 ptr: NonNull<libcamera_framebuffer_t>,
91 _alloc: Arc<Mutex<FrameBufferAllocatorInstance>>,
92}
93
94impl core::fmt::Debug for FrameBuffer {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 f.debug_struct("FrameBuffer")
97 .field("metadata", &self.metadata())
98 .field("planes", &self.planes())
99 .finish()
100 }
101}
102
103unsafe impl Send for FrameBuffer {}
104
105impl AsFrameBuffer for FrameBuffer {
106 unsafe fn ptr(&self) -> NonNull<libcamera_framebuffer_t> {
107 self.ptr
108 }
109}