Opens a camera device and negotiates the video format based on configuration This is the main entry point for opening a camera. The function: 1. Initializes Media Foundation if not already initialized 2. Creates a hardware MediaSource for the specified device 3. Probes supported formats directly from the MediaSource 4. Selects the best matching format based on configuration requirements 5. Create
(id: &str, config: CameraConfig)
| 208 | /// - `Box<dyn Stream>` - The initialized camera stream for frame capture |
| 209 | /// - `DeviceControls` - Control interface for device-specific operations (exposure, focus, etc.) |
| 210 | pub fn open(id: &str, config: CameraConfig) -> Result<(Box<dyn Stream>, DeviceControls)> { |
| 211 | initialize_mf()?; |
| 212 | |
| 213 | // 1. Find and create hardware MediaSource |
| 214 | let media_source = unsafe { create_media_source(id)? }; |
| 215 | |
| 216 | // 2. Directly probe supported formats from MediaSource without creating Reader yet |
| 217 | let negotiated_fmt = negotiate_format(&media_source, &config)?; |
| 218 | |
| 219 | tracing::info!( |
| 220 | "Camera opened: {}x{} @ {}fps ({:?})", |
| 221 | negotiated_fmt.width, |
| 222 | negotiated_fmt.height, |
| 223 | negotiated_fmt.fps, |
| 224 | negotiated_fmt.format |
| 225 | ); |
| 226 | |
| 227 | // 3. Create MsmfStream |
| 228 | // Async Reader creation and callback binding are now fully encapsulated inside MsmfStream |
| 229 | let stream = MsmfStream::new(&media_source, negotiated_fmt) |
| 230 | .map_err(|e| CameraError::Io(std::io::Error::other(e.to_string())))?; |
| 231 | |
| 232 | let controls = create_controls(stream.get_reader()); |
| 233 | |
| 234 | Ok((Box::new(stream), controls)) |
| 235 | } |
| 236 | |
| 237 | /// Creates a MediaSource for a specific camera device |
| 238 | /// |
no test coverage detected