Skip to main content

v4l/
frameinterval.rs

1use std::convert::TryFrom;
2use std::fmt;
3
4use crate::{format::FourCC, fraction::Fraction};
5use crate::{v4l_sys, v4l_sys::*};
6
7#[derive(Debug)]
8/// Format description as returned by [`crate::v4l2::vidioc::VIDIOC_ENUM_FRAMEINTERVALS`]
9pub struct FrameInterval {
10    pub index: u32,
11    pub fourcc: FourCC,
12    pub width: u32,
13    pub height: u32,
14    pub typ: u32,
15    pub interval: FrameIntervalEnum,
16}
17
18impl fmt::Display for FrameInterval {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        self.interval.fmt(f)
21    }
22}
23
24#[derive(Debug)]
25pub enum FrameIntervalEnum {
26    Discrete(Fraction),
27    Stepwise(Stepwise),
28}
29
30impl fmt::Display for FrameIntervalEnum {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        match self {
33            FrameIntervalEnum::Discrete(val) => write!(f, "Discrete({})", val)?,
34            FrameIntervalEnum::Stepwise(val) => write!(f, "Stepwise({})", val)?,
35        }
36
37        Ok(())
38    }
39}
40
41impl TryFrom<v4l2_frmivalenum> for FrameIntervalEnum {
42    type Error = String;
43
44    fn try_from(desc: v4l2_frmivalenum) -> Result<Self, Self::Error> {
45        unsafe {
46            // Unsafe because of access to union __bindgen_anon_1
47            match desc.type_ {
48                v4l_sys::v4l2_frmivaltypes_V4L2_FRMIVAL_TYPE_DISCRETE => Ok(
49                    FrameIntervalEnum::Discrete(Fraction::from(desc.__bindgen_anon_1.discrete)),
50                ),
51                v4l_sys::v4l2_frmivaltypes_V4L2_FRMIVAL_TYPE_CONTINUOUS
52                | v4l_sys::v4l2_frmivaltypes_V4L2_FRMIVAL_TYPE_STEPWISE => Ok({
53                    FrameIntervalEnum::Stepwise(Stepwise {
54                        min: Fraction::from(desc.__bindgen_anon_1.stepwise.min),
55                        max: Fraction::from(desc.__bindgen_anon_1.stepwise.max),
56                        step: Fraction::from(desc.__bindgen_anon_1.stepwise.step),
57                    })
58                }),
59                typ => Err(format!("Unknown frame size type: {}", typ)),
60            }
61        }
62    }
63}
64
65#[derive(Debug)]
66pub struct Stepwise {
67    /// Minimum frame interval (in seconds).
68    pub min: Fraction,
69    /// Maximum frame interval (in seconds).
70    pub max: Fraction,
71    /// Frame interval step size (in seconds).
72    pub step: Fraction,
73}
74
75impl fmt::Display for Stepwise {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        write!(f, "{} - {} with step {}", self.min, self.max, self.step)?;
78        Ok(())
79    }
80}
81
82impl TryFrom<v4l2_frmivalenum> for FrameInterval {
83    type Error = String;
84
85    fn try_from(desc: v4l2_frmivalenum) -> Result<Self, Self::Error> {
86        Ok(FrameInterval {
87            index: desc.index,
88            fourcc: FourCC::from(desc.pixel_format),
89            width: desc.width,
90            height: desc.height,
91            typ: desc.type_,
92            interval: FrameIntervalEnum::try_from(desc)?,
93        })
94    }
95}