Skip to main content

rustcv_core/
traits.rs

1use crate::builder::CameraConfig;
2use crate::error::Result;
3use crate::frame::Frame;
4use async_trait::async_trait;
5
6// --- 补全缺失的结构体定义 ---
7
8/// 设备基本信息
9#[derive(Debug, Clone, PartialEq)]
10pub struct DeviceInfo {
11    /// 对用户友好的显示名称 (e.g. "Logitech C920")
12    pub name: String,
13
14    /// 唯一硬件 ID (e.g. "/dev/video0" 或 USB 序列号)
15    /// 用于 Driver::open 的参数
16    pub id: String,
17
18    /// 后端类型标识 (e.g. "V4L2", "MediaFoundation")
19    pub backend: String,
20
21    /// 硬件总线信息 (可选,e.g. "usb-0000:00:14.0-1")
22    /// 用于高级拓扑识别
23    pub bus_info: Option<String>,
24}
25
26/// 硬件触发源配置
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct TriggerConfig {
29    /// 触发模式
30    pub mode: TriggerMode,
31
32    /// 触发源
33    pub source: TriggerSource,
34
35    /// 触发极性/边缘
36    pub polarity: TriggerPolarity,
37
38    /// 触发延迟 (微秒),硬件接收信号后延迟多久开始曝光
39    pub delay_us: u32,
40}
41
42impl Default for TriggerConfig {
43    fn default() -> Self {
44        Self {
45            mode: TriggerMode::Off,
46            source: TriggerSource::Software,
47            polarity: TriggerPolarity::RisingEdge,
48            delay_us: 0,
49        }
50    }
51}
52
53/// 触发模式枚举
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub enum TriggerMode {
56    /// 关闭触发,使用连续采集模式 (Free Run)
57    Off,
58    /// 标准触发模式 (一帧一触发)
59    Standard,
60    /// 脉宽控制曝光 (Bulb 模式,曝光时间由信号宽度决定)
61    Bulb,
62}
63
64/// 触发源枚举
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub enum TriggerSource {
67    /// 软件触发 (通过 API 调用触发)
68    Software,
69    /// 外部硬件线路 0 (GPIO / Opto-isolated Input)
70    Line0,
71    /// 外部硬件线路 1
72    Line1,
73    /// 外部硬件线路 2
74    Line2,
75    /// 外部硬件线路 3
76    Line3,
77}
78
79/// 触发极性/边缘枚举
80#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81pub enum TriggerPolarity {
82    /// 上升沿触发
83    RisingEdge,
84    /// 下降沿触发
85    FallingEdge,
86    /// 高电平触发 (Level)
87    HighLevel,
88    /// 低电平触发 (Level)
89    LowLevel,
90}
91
92// --- 核心 Trait 定义 (保持不变) ---
93
94/// 1. 驱动入口:设备枚举与管理
95pub trait Driver: Send + Sync {
96    /// 扫描总线,返回设备列表(含唯一 ID 和拓扑路径)
97    fn list_devices(&self) -> Result<Vec<DeviceInfo>>;
98
99    /// 打开设备
100    /// 返回分离的 Stream (数据面) 和 Controls (控制面)
101    fn open(&self, id: &str, config: CameraConfig) -> Result<(Box<dyn Stream>, DeviceControls)>;
102}
103
104/// 2. 数据面:流式获取
105/// 必须是 Send,以便在 Tokio 任务中运行
106#[async_trait]
107pub trait Stream: Send {
108    /// 启动采集 (Alloc buffers, Start DMA)
109    async fn start(&mut self) -> Result<()>;
110
111    /// 停止采集 (Release bandwidth)
112    async fn stop(&mut self) -> Result<()>;
113
114    /// 获取下一帧
115    /// 注意:这里返回的 Frame 生命周期绑定到 self (Stream)
116    /// 实现 Ring Buffer 的借用语义
117    async fn next_frame(&mut self) -> Result<Frame<'_>>;
118
119    /// 【逃生舱口】直接注入虚拟帧 (用于仿真)
120    #[cfg(feature = "simulation")]
121    async fn inject_frame(&mut self, frame: Frame<'_>) -> Result<()>;
122}
123
124/// 3. 控制面聚合体
125#[allow(missing_debug_implementations)]
126pub struct DeviceControls {
127    pub sensor: Box<dyn SensorControl>, // 传感器控制 (曝光, 增益)
128    pub lens: Box<dyn LensControl>,     // 镜头控制 (变焦, 对焦) - 独立锁
129    pub system: Box<dyn SystemControl>, // 系统控制 (复位, 触发)
130}
131
132/// 传感器控制 Trait
133pub trait SensorControl: Send + Sync {
134    fn set_exposure(&self, value_us: u32) -> Result<()>;
135    fn get_exposure(&self) -> Result<u32>;
136    // ... Gain, WhiteBalance 可以在此扩展
137}
138
139/// 镜头控制 Trait (允许并发操作,不阻塞 Sensor)
140pub trait LensControl: Send + Sync {
141    fn set_zoom(&self, zoom: u32) -> Result<()>;
142    fn set_focus(&self, focus: u32) -> Result<()>;
143}
144
145/// 系统/高级控制 Trait
146pub trait SystemControl: Send + Sync {
147    /// 【硬核特性】USB 端口级复位
148    /// 注意:这是一个 unsafe 操作,可能会导致其他 USB 设备短暂断连
149    /// # Safety
150    unsafe fn force_reset(&self) -> Result<()>;
151
152    /// 设置硬件触发模式
153    fn set_trigger(&self, config: TriggerConfig) -> Result<()>;
154
155    /// 导出当前配置快照 (用于持久化)
156    /// 返回值使用 serde_json::Value 以兼容不同后端的配置结构
157    #[cfg(feature = "serialize")]
158    fn export_state(&self) -> Result<serde_json::Value>;
159}
160
161// 【新增】为 Box<T> 实现 Stream,这样 Box<dyn Stream> 也能被当做 Stream 使用
162#[async_trait]
163impl<S: Stream + ?Sized + Send> Stream for Box<S> {
164    async fn start(&mut self) -> Result<()> {
165        (**self).start().await
166    }
167
168    async fn stop(&mut self) -> Result<()> {
169        (**self).stop().await
170    }
171
172    async fn next_frame(&mut self) -> Result<Frame<'_>> {
173        (**self).next_frame().await
174    }
175
176    #[cfg(feature = "simulation")]
177    async fn inject_frame(&mut self, frame: Frame<'_>) -> Result<()> {
178        (**self).inject_frame(frame).await
179    }
180}