1use std::{marker::PhantomData, ptr::NonNull};
2
3use libcamera_sys::*;
4
5use crate::{
6 geometry::{Size, SizeRange},
7 pixel_format::{PixelFormat, PixelFormats},
8 utils::Immutable,
9};
10
11#[derive(Debug, Clone, Copy)]
15pub enum StreamRole {
16 Raw,
17 StillCapture,
18 VideoRecording,
19 ViewFinder,
20}
21
22impl TryFrom<libcamera_stream_role::Type> for StreamRole {
23 type Error = ();
24
25 fn try_from(value: libcamera_stream_role::Type) -> Result<Self, Self::Error> {
26 match value {
27 libcamera_stream_role::LIBCAMERA_STREAM_ROLE_RAW => Ok(StreamRole::Raw),
28 libcamera_stream_role::LIBCAMERA_STREAM_ROLE_STILL_CAPTURE => Ok(StreamRole::StillCapture),
29 libcamera_stream_role::LIBCAMERA_STREAM_ROLE_VIDEO_RECORDING => Ok(StreamRole::VideoRecording),
30 libcamera_stream_role::LIBCAMERA_STREAM_ROLE_VIEW_FINDER => Ok(StreamRole::ViewFinder),
31 _ => Err(()),
32 }
33 }
34}
35
36impl From<StreamRole> for libcamera_stream_role::Type {
37 fn from(role: StreamRole) -> Self {
38 match role {
39 StreamRole::Raw => libcamera_stream_role::LIBCAMERA_STREAM_ROLE_RAW,
40 StreamRole::StillCapture => libcamera_stream_role::LIBCAMERA_STREAM_ROLE_STILL_CAPTURE,
41 StreamRole::VideoRecording => libcamera_stream_role::LIBCAMERA_STREAM_ROLE_VIDEO_RECORDING,
42 StreamRole::ViewFinder => libcamera_stream_role::LIBCAMERA_STREAM_ROLE_VIEW_FINDER,
43 }
44 }
45}
46
47pub struct StreamFormatsRef<'d> {
49 ptr: NonNull<libcamera_stream_formats_t>,
50 _phantom: PhantomData<&'d ()>,
51}
52
53impl StreamFormatsRef<'_> {
54 pub(crate) unsafe fn from_ptr(ptr: NonNull<libcamera_stream_formats_t>) -> Self {
55 Self {
56 ptr,
57 _phantom: Default::default(),
58 }
59 }
60
61 pub fn pixel_formats(&self) -> Immutable<PixelFormats> {
63 Immutable(unsafe {
64 PixelFormats::from_ptr(NonNull::new(libcamera_stream_formats_pixel_formats(self.ptr.as_ptr())).unwrap())
65 })
66 }
67
68 pub fn sizes(&self, pixel_format: PixelFormat) -> Vec<Size> {
70 let sizes = unsafe { libcamera_stream_formats_sizes(self.ptr.as_ptr(), &pixel_format.0) };
71 let len = unsafe { libcamera_sizes_size(sizes) };
72
73 (0..len)
74 .map(|i| Size::from(unsafe { *libcamera_sizes_at(sizes, i as _) }))
75 .collect()
76 }
77
78 pub fn range(&self, pixel_format: PixelFormat) -> SizeRange {
80 SizeRange::from(unsafe { libcamera_stream_formats_range(self.ptr.as_ptr(), &pixel_format.0) })
81 }
82}
83
84impl core::fmt::Debug for StreamFormatsRef<'_> {
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 let mut map = f.debug_map();
87 for pixel_format in self.pixel_formats().into_iter() {
88 map.entry(&pixel_format, &self.sizes(pixel_format));
89 }
90 map.finish()
91 }
92}
93
94pub struct StreamConfigurationRef<'d> {
95 ptr: NonNull<libcamera_stream_configuration_t>,
96 _phantom: PhantomData<&'d ()>,
97}
98
99impl StreamConfigurationRef<'_> {
100 pub(crate) unsafe fn from_ptr(ptr: NonNull<libcamera_stream_configuration_t>) -> Self {
101 Self {
102 ptr,
103 _phantom: Default::default(),
104 }
105 }
106
107 pub fn get_pixel_format(&self) -> PixelFormat {
108 PixelFormat(unsafe { self.ptr.as_ref() }.pixel_format)
109 }
110
111 pub fn set_pixel_format(&mut self, pixel_format: PixelFormat) {
112 unsafe { self.ptr.as_mut() }.pixel_format = pixel_format.0;
113 }
114
115 pub fn get_size(&self) -> Size {
116 unsafe { self.ptr.as_ref() }.size.into()
117 }
118
119 pub fn set_size(&mut self, size: Size) {
120 unsafe { self.ptr.as_mut() }.size = size.into()
121 }
122
123 pub fn get_stride(&self) -> u32 {
124 unsafe { self.ptr.as_ref() }.stride
125 }
126
127 pub fn set_stride(&mut self, stride: u32) {
128 unsafe { self.ptr.as_mut() }.stride = stride
129 }
130
131 pub fn get_frame_size(&self) -> u32 {
132 unsafe { self.ptr.as_ref() }.frame_size
133 }
134
135 pub fn set_frame_size(&mut self, frame_size: u32) {
136 unsafe { self.ptr.as_mut() }.frame_size = frame_size
137 }
138
139 pub fn get_buffer_count(&self) -> u32 {
140 unsafe { self.ptr.as_ref() }.buffer_count
141 }
142
143 pub fn set_buffer_count(&mut self, buffer_count: u32) {
144 unsafe { self.ptr.as_mut() }.buffer_count = buffer_count;
145 }
146
147 pub fn stream(&self) -> Option<Stream> {
153 let stream = unsafe { libcamera_stream_configuration_stream(self.ptr.as_ptr()) };
154 NonNull::new(stream).map(|p| unsafe { Stream::from_ptr(p) })
157 }
158
159 pub fn formats(&self) -> StreamFormatsRef<'_> {
161 unsafe {
162 StreamFormatsRef::from_ptr(
163 NonNull::new(libcamera_stream_configuration_formats(self.ptr.as_ptr()).cast_mut()).unwrap(),
164 )
165 }
166 }
167}
168
169impl core::fmt::Debug for StreamConfigurationRef<'_> {
170 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
171 f.debug_struct("StreamConfigurationRef")
172 .field("pixel_format", &self.get_pixel_format())
173 .field("size", &self.get_size())
174 .field("stride", &self.get_stride())
175 .field("frame_size", &self.get_frame_size())
176 .field("buffer_count", &self.get_buffer_count())
177 .finish()
178 }
179}
180
181#[derive(Clone, Copy, Hash, PartialEq, Eq)]
185pub struct Stream {
186 pub(crate) ptr: NonNull<libcamera_stream_t>,
191}
192
193impl Stream {
194 pub(crate) unsafe fn from_ptr(ptr: NonNull<libcamera_stream_t>) -> Self {
195 Self { ptr }
196 }
197}
198
199unsafe impl Send for Stream {}