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)]
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#[derive(Debug, Clone, Copy, PartialEq)]
42pub struct FrameRateRange {
43 pub min: Ratio,
44 pub max: Ratio,
45}
46
47#[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 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 pub fn frame_rate_ranges(&self) -> &[FrameRateRange] {
90 &self.frame_rate_ranges
91 }
92}
93
94#[derive(Debug, Clone)]
96pub struct StreamConfig {
97 pub pixel_format: PixelFormat,
98 pub size: Size,
99 pub frame_rate: Ratio,
100}