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/// Frame rate as a rational number.
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
26pub struct FrameRate {
27    pub numerator: u32,
28    pub denominator: u32,
29}
30
31impl FrameRate {
32    pub fn as_f64(&self) -> f64 {
33        self.numerator as f64 / self.denominator as f64
34    }
35}
36
37/// Range of supported frame rates.
38#[derive(Debug, Clone, Copy, PartialEq)]
39pub struct FrameRateRange {
40    pub min: FrameRate,
41    pub max: FrameRate,
42}
43
44/// Describes a supported camera format.
45#[derive(Debug, Clone, PartialEq)]
46pub struct FormatDescriptor {
47    pub pixel_format: PixelFormat,
48    pub size: Size,
49    frame_rate_ranges: ArrayVec<FrameRateRange, MAX_FRAME_RATE_RANGES>,
50}
51
52impl FormatDescriptor {
53    /// Create descriptors for a given format, automatically splitting across
54    /// multiple [`FormatDescriptor`] values if the number of frame rate
55    /// ranges exceeds the inline capacity.
56    ///
57    /// Most formats have only a handful of frame rate ranges, so this
58    /// typically yields a single descriptor.
59    pub(crate) fn from_ranges(
60        pixel_format: PixelFormat,
61        size: Size,
62        frame_rate_ranges: impl IntoIterator<Item = FrameRateRange>,
63    ) -> impl Iterator<Item = Self> {
64        let mut iter = frame_rate_ranges.into_iter();
65        core::iter::from_fn(move || {
66            let mut chunk = ArrayVec::new();
67            for range in iter.by_ref() {
68                chunk.push(range);
69                if chunk.is_full() {
70                    break;
71                }
72            }
73            if chunk.is_empty() {
74                None
75            } else {
76                Some(FormatDescriptor {
77                    pixel_format,
78                    size,
79                    frame_rate_ranges: chunk,
80                })
81            }
82        })
83    }
84
85    /// The frame rate ranges supported by this format.
86    pub fn frame_rate_ranges(&self) -> &[FrameRateRange] {
87        &self.frame_rate_ranges
88    }
89}
90
91/// Configuration for opening a camera stream.
92#[derive(Debug, Clone)]
93pub struct StreamConfig {
94    pub pixel_format: PixelFormat,
95    pub size: Size,
96    pub frame_rate: FrameRate,
97}