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