/// Core camera interface trait for dependency inversion /// This trait provides a clean abstraction that isolates production code from capture-source concerns use anyhow::Result; use async_trait::async_trait; use chrono::{DateTime, Utc}; use std::sync::Arc; use crate::memory::frame_data::{FrameData, FrameFormat}; use std::path::PathBuf; /// Core camera interface that both hardware and video file cameras implement pub trait CameraInterface: Send + Sync { /// Initialize the camera hardware or video source fn initialize( &mut self, ) -> std::pin::Pin> + Send + '_>>; /// Capture a single frame from the camera fn capture_frame( &mut self, ) -> std::pin::Pin> + Send + '_>>; /// Get camera metadata and capabilities fn get_metadata(&self) -> CameraMetadata; /// Check if the camera is currently active and ready fn is_running(&self) -> bool; /// Get current frame count fn frame_count(&self) -> u64; /// Gracefully shutdown the camera fn shutdown( &mut self, ) -> std::pin::Pin> + Send + '_>>; } /// Represents a captured frame with metadata #[derive(Clone)] pub struct CapturedFrame { /// Frame data (shared for zero-copy) pub data: Arc, /// Sequential frame number pub frame_number: u64, /// When the frame was captured pub capture_timestamp: DateTime, /// Camera-specific metadata pub metadata: FrameMetadata, } /// Camera metadata describing capabilities and configuration #[derive(Debug, Clone)] pub struct CameraMetadata { /// Camera identifier pub camera_id: String, /// Camera type (e.g. hardware backend or video file) pub camera_type: String, /// Supported frame formats pub supported_formats: Vec, /// Maximum resolution pub max_resolution: (u32, u32), /// Current resolution pub current_resolution: (u32, u32), /// Target frames per second pub target_fps: f64, /// Whether the camera supports real-time capture pub is_real_time: bool, /// Total frames available (None for continuous streams) pub total_frames: Option, } /// Per-frame metadata #[derive(Debug, Clone)] pub struct FrameMetadata { /// Exposure settings (if applicable) pub exposure_ms: Option, /// Gain settings (if applicable) pub gain: Option, /// Temperature readings (if available) pub temperature_celsius: Option, /// Any camera-specific properties pub properties: std::collections::HashMap, } /// Camera configuration that works for both hardware and video sources #[derive(Debug, Clone)] pub struct CameraConfig { /// Type of camera to create pub camera_type: CameraType, /// Target resolution pub resolution: (u32, u32), /// Target frame rate pub fps: f64, /// Additional camera-specific settings pub settings: std::collections::HashMap, } /// Enum defining camera types (device or video file) #[derive(Debug, Clone)] pub enum CameraType { /// Production hardware camera Production { /// Device index or identifier device_id: String, /// Hardware-specific backend backend: String, }, /// Video file camera configuration VideoFile { /// Absolute video file path path: PathBuf, /// Whether to loop playback when reaching the end loop_playback: bool, /// Playback speed multiplier (1.0 = realtime) playback_speed: f64, }, } impl Default for CameraConfig { fn default() -> Self { Self { camera_type: CameraType::Production { device_id: "0".to_string(), backend: "default".to_string(), }, resolution: (1280, 720), fps: 30.0, settings: std::collections::HashMap::new(), } } } impl CapturedFrame { /// Create a new captured frame pub fn new( data: Arc, frame_number: u64, capture_timestamp: DateTime, metadata: FrameMetadata, ) -> Self { Self { data, frame_number, capture_timestamp, metadata, } } /// Get frame dimensions pub fn dimensions(&self) -> (u32, u32) { (self.data.width, self.data.height) } /// Get frame data size in bytes pub fn data_size(&self) -> usize { self.data.data.len() } } impl Default for FrameMetadata { fn default() -> Self { Self { exposure_ms: None, gain: None, temperature_celsius: None, properties: std::collections::HashMap::new(), } } } impl CameraMetadata { /// Create minimal camera metadata pub fn new(camera_id: String, camera_type: String) -> Self { Self { camera_id, camera_type, supported_formats: vec![FrameFormat::JPEG], max_resolution: (1920, 1080), current_resolution: (1280, 720), target_fps: 30.0, is_real_time: true, total_frames: None, } } }