1use arrayvec::ArrayVec;
2
3const MAX_FRAME_RATE_RANGES: usize = 8;
5
6#[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#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub struct Size {
20 pub width: u32,
21 pub height: u32,
22}
23
24#[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#[derive(Debug, Clone, Copy, PartialEq)]
39pub struct FrameRateRange {
40 pub min: FrameRate,
41 pub max: FrameRate,
42}
43
44#[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 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 pub fn frame_rate_ranges(&self) -> &[FrameRateRange] {
87 &self.frame_rate_ranges
88 }
89}
90
91#[derive(Debug, Clone)]
93pub struct StreamConfig {
94 pub pixel_format: PixelFormat,
95 pub size: Size,
96 pub frame_rate: FrameRate,
97}