Skip to main content

camera_stream/
types.rs

1use arrayvec::ArrayVec;
2
3/// Maximum number of frame rate ranges per format descriptor.
4const MAX_FRAME_RATE_RANGES: usize = 8;
5
6/// Pixel formats encountered across platforms.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[non_exhaustive]
9pub enum PixelFormat {
10    Nv12,
11    Yuyv,
12    Uyvy,
13    Bgra32,
14    Jpeg,
15}
16
17/// Pixel dimensions of a frame.
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub struct Size {
20    pub width: u32,
21    pub height: u32,
22}
23
24/// A rational number (numerator / denominator).
25///
26/// Used to represent frame rates (e.g. 30000/1000 = 30 fps) and
27/// frame durations (e.g. 1000/30000 ≈ 0.033 s).
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29pub struct Ratio {
30    pub numerator: u32,
31    pub denominator: u32,
32}
33
34impl Ratio {
35    pub fn as_f64(&self) -> f64 {
36        self.numerator as f64 / self.denominator as f64
37    }
38}
39
40/// Range of supported frame rates.
41#[derive(Debug, Clone, Copy, PartialEq)]
42pub struct FrameRateRange {
43    pub min: Ratio,
44    pub max: Ratio,
45}
46
47/// Describes a supported camera format.
48#[derive(Debug, Clone, PartialEq)]
49pub struct FormatDescriptor {
50    pub pixel_format: PixelFormat,
51    pub size: Size,
52    frame_rate_ranges: ArrayVec<FrameRateRange, MAX_FRAME_RATE_RANGES>,
53}
54
55impl FormatDescriptor {
56    /// Create descriptors for a given format, automatically splitting across
57    /// multiple [`FormatDescriptor`] values if the number of frame rate
58    /// ranges exceeds the inline capacity.
59    ///
60    /// Most formats have only a handful of frame rate ranges, so this
61    /// typically yields a single descriptor.
62    pub(crate) fn from_ranges(
63        pixel_format: PixelFormat,
64        size: Size,
65        frame_rate_ranges: impl IntoIterator<Item = FrameRateRange>,
66    ) -> impl Iterator<Item = Self> {
67        let mut iter = frame_rate_ranges.into_iter();
68        core::iter::from_fn(move || {
69            let mut chunk = ArrayVec::new();
70            for range in iter.by_ref() {
71                chunk.push(range);
72                if chunk.is_full() {
73                    break;
74                }
75            }
76            if chunk.is_empty() {
77                None
78            } else {
79                Some(FormatDescriptor {
80                    pixel_format,
81                    size,
82                    frame_rate_ranges: chunk,
83                })
84            }
85        })
86    }
87
88    /// The frame rate ranges supported by this format.
89    pub fn frame_rate_ranges(&self) -> &[FrameRateRange] {
90        &self.frame_rate_ranges
91    }
92}
93
94/// Configuration for opening a camera stream.
95#[derive(Debug, Clone)]
96pub struct StreamConfig {
97    pub pixel_format: PixelFormat,
98    pub size: Size,
99    pub frame_rate: Ratio,
100}