1use cfg_if::cfg_if;
2use media_core::{
3 video::{ColorRange, VideoFormat},
4 Result,
5};
6
7use crate::{DeviceEvent, DeviceManager};
8
9cfg_if! {
10 if #[cfg(target_os = "windows")] {
11 pub use crate::backend::media_foundation::MediaFoundationDeviceManager as DefaultCameraManager;
12 } else if #[cfg(any(target_os = "macos", target_os = "ios"))] {
13 pub use crate::backend::av_foundation::AVFoundationCaptureDeviceManager as DefaultCameraManager;
14 } else {
15 compile_error!("unsupported target");
16 }
17}
18
19#[derive(Clone, Debug)]
20pub(crate) struct CameraFormat {
21 pub format: VideoFormat,
22 pub color_range: ColorRange,
23 pub width: u32,
24 pub height: u32,
25 pub frame_rates: Vec<f32>,
26}
27
28pub struct CameraManager<T: DeviceManager> {
29 backend: T,
30}
31
32impl<T: DeviceManager> CameraManager<T> {
33 pub fn new() -> Result<Self> {
34 let mut backend = T::init()?;
35 backend.refresh()?;
36 Ok(Self {
37 backend,
38 })
39 }
40
41 pub fn list(&self) -> Vec<&T::DeviceType> {
42 self.backend.list()
43 }
44
45 pub fn index(&self, index: usize) -> Option<&T::DeviceType> {
46 self.backend.index(index)
47 }
48
49 pub fn index_mut(&mut self, index: usize) -> Option<&mut T::DeviceType> {
50 self.backend.index_mut(index)
51 }
52
53 pub fn lookup(&self, id: &str) -> Option<&T::DeviceType> {
54 self.backend.lookup(id)
55 }
56
57 pub fn lookup_mut(&mut self, id: &str) -> Option<&mut T::DeviceType> {
58 self.backend.lookup_mut(id)
59 }
60
61 pub fn refresh(&mut self) -> Result<()> {
62 self.backend.refresh()
63 }
64
65 pub fn set_change_handler<F>(&mut self, handler: F) -> Result<()>
66 where
67 F: Fn(&DeviceEvent) + Send + Sync + 'static,
68 {
69 self.backend.set_change_handler(handler)
70 }
71}
72
73impl<T: DeviceManager> Drop for CameraManager<T> {
74 fn drop(&mut self) {
75 self.backend.deinit();
76 }
77}
78
79impl CameraManager<DefaultCameraManager> {
80 pub fn new_default() -> Result<Self> {
81 Self::new()
82 }
83}