brainwires_hardware/camera/
types.rs1use serde::{Deserialize, Serialize};
2use thiserror::Error;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct CameraDevice {
7 pub index: u32,
9 pub name: String,
11 pub description: Option<String>,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
17pub struct Resolution {
18 pub width: u32,
20 pub height: u32,
22}
23
24impl Resolution {
25 pub fn new(width: u32, height: u32) -> Self {
27 Self { width, height }
28 }
29}
30
31impl std::fmt::Display for Resolution {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 write!(f, "{}x{}", self.width, self.height)
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
39pub struct FrameRate {
40 pub numerator: u32,
42 pub denominator: u32,
44}
45
46impl FrameRate {
47 pub fn fps(fps: u32) -> Self {
49 Self {
50 numerator: fps,
51 denominator: 1,
52 }
53 }
54
55 pub fn as_f64(&self) -> f64 {
57 self.numerator as f64 / self.denominator.max(1) as f64
58 }
59}
60
61impl std::fmt::Display for FrameRate {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 write!(f, "{:.1} fps", self.as_f64())
64 }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
69pub enum PixelFormat {
70 Rgb,
72 Bgr,
74 Rgba,
76 Yuv422,
78 Mjpeg,
80 Unknown,
82}
83
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
86pub struct CameraFormat {
87 pub resolution: Resolution,
89 pub frame_rate: FrameRate,
91 pub pixel_format: PixelFormat,
93}
94
95impl CameraFormat {
96 pub fn new(resolution: Resolution, frame_rate: FrameRate, pixel_format: PixelFormat) -> Self {
98 Self {
99 resolution,
100 frame_rate,
101 pixel_format,
102 }
103 }
104
105 pub fn hd_1080p() -> Self {
107 Self::new(
108 Resolution::new(1920, 1080),
109 FrameRate::fps(30),
110 PixelFormat::Mjpeg,
111 )
112 }
113
114 pub fn hd_720p() -> Self {
116 Self::new(
117 Resolution::new(1280, 720),
118 FrameRate::fps(30),
119 PixelFormat::Mjpeg,
120 )
121 }
122
123 pub fn vga() -> Self {
125 Self::new(
126 Resolution::new(640, 480),
127 FrameRate::fps(30),
128 PixelFormat::Mjpeg,
129 )
130 }
131}
132
133#[derive(Debug, Clone)]
135pub struct CameraFrame {
136 pub width: u32,
138 pub height: u32,
140 pub format: PixelFormat,
142 pub data: Vec<u8>,
144 pub timestamp_ms: u64,
146}
147
148impl CameraFrame {
149 pub fn bytes_per_pixel(&self) -> u32 {
151 match self.format {
152 PixelFormat::Rgb | PixelFormat::Bgr => 3,
153 PixelFormat::Rgba => 4,
154 PixelFormat::Yuv422 => 2,
155 PixelFormat::Mjpeg | PixelFormat::Unknown => 0,
156 }
157 }
158}
159
160#[derive(Debug, Error)]
162pub enum CameraError {
163 #[error("no camera found at index {0}")]
165 NotFound(u32),
166 #[error("failed to open camera {index}: {reason}")]
168 OpenFailed {
169 index: u32,
171 reason: String,
173 },
174 #[error("failed to capture frame: {0}")]
176 CaptureFailed(String),
177 #[error("format not supported: {0:?}")]
179 FormatNotSupported(CameraFormat),
180 #[error("camera error: {0}")]
182 Other(String),
183}