1use std::convert::TryFrom;
2use std::fmt;
3
4use crate::format::FourCC;
5use crate::sys::*;
6
7#[derive(Debug)]
8pub struct FrameSize {
10 pub index: u32,
11 pub fourcc: FourCC,
12 pub typ: u32,
13 pub size: FrameSizeEnum,
14}
15
16impl fmt::Display for FrameSize {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 self.size.fmt(f)
19 }
20}
21
22#[derive(Debug)]
23pub enum FrameSizeEnum {
24 Discrete(Discrete),
25 Stepwise(Stepwise),
26}
27
28impl FrameSizeEnum {
29 pub fn to_discrete(self) -> impl IntoIterator<Item = Discrete> {
30 match self {
31 Self::Discrete(discrete) => vec![discrete],
32 Self::Stepwise(stepwise) => {
33 let mut discrete = Vec::new();
34
35 for width in (stepwise.min_width..=stepwise.max_width).step_by(stepwise.step_width as usize) {
36 for height in (stepwise.min_height..=stepwise.max_height).step_by(stepwise.step_height as usize) {
37 discrete.push(Discrete { width, height });
38 }
39 }
40
41 discrete
42 }
43 }
44 }
45}
46
47impl fmt::Display for FrameSizeEnum {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 match self {
50 FrameSizeEnum::Discrete(val) => write!(f, "Discrete({})", val)?,
51 FrameSizeEnum::Stepwise(val) => write!(f, "Stepwise({})", val)?,
52 }
53
54 Ok(())
55 }
56}
57
58impl TryFrom<v4l2_frmsizeenum> for FrameSizeEnum {
59 type Error = String;
60
61 fn try_from(desc: v4l2_frmsizeenum) -> Result<Self, Self::Error> {
62 unsafe {
63 #[allow(non_upper_case_globals)]
65 match desc.type_ {
66 v4l2_frmsizetypes_V4L2_FRMSIZE_TYPE_DISCRETE => Ok({
67 FrameSizeEnum::Discrete(Discrete {
68 width: desc.__bindgen_anon_1.discrete.width,
69 height: desc.__bindgen_anon_1.discrete.height,
70 })
71 }),
72 v4l2_frmsizetypes_V4L2_FRMSIZE_TYPE_STEPWISE | v4l2_frmsizetypes_V4L2_FRMSIZE_TYPE_CONTINUOUS => Ok({
73 FrameSizeEnum::Stepwise(Stepwise {
74 min_width: desc.__bindgen_anon_1.stepwise.min_width,
75 max_width: desc.__bindgen_anon_1.stepwise.max_width,
76 step_width: desc.__bindgen_anon_1.stepwise.step_width,
77 min_height: desc.__bindgen_anon_1.stepwise.min_height,
78 max_height: desc.__bindgen_anon_1.stepwise.max_height,
79 step_height: desc.__bindgen_anon_1.stepwise.step_height,
80 })
81 }),
82 typ => Err(format!("Unknown frame size type: {}", typ)),
83 }
84 }
85 }
86}
87
88#[derive(Debug)]
89pub struct Discrete {
90 pub width: u32,
92 pub height: u32,
94}
95
96impl fmt::Display for Discrete {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 write!(f, "{}x{}", self.width, self.height)?;
99 Ok(())
100 }
101}
102
103#[derive(Debug)]
104pub struct Stepwise {
105 pub min_width: u32,
107 pub max_width: u32,
109 pub step_width: u32,
111 pub min_height: u32,
113 pub max_height: u32,
115 pub step_height: u32,
117}
118
119impl fmt::Display for Stepwise {
120 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121 write!(
122 f,
123 "{}x{} - {}x{} with step {}/{}",
124 self.min_width, self.min_height, self.max_width, self.max_height, self.step_width, self.step_height,
125 )?;
126 Ok(())
127 }
128}
129
130impl TryFrom<v4l2_frmsizeenum> for FrameSize {
131 type Error = String;
132
133 fn try_from(desc: v4l2_frmsizeenum) -> Result<Self, Self::Error> {
134 Ok(FrameSize {
135 index: desc.index,
136 typ: desc.type_,
137 fourcc: FourCC::from(desc.pixel_format),
138 size: FrameSizeEnum::try_from(desc)?,
139 })
140 }
141}