use crate::actors::camera_list::CreationKit;
use crate::actors::watcher_udev::Device;
use crate::pipelines;
use crate::util::flock::Locked;
use crate::util::media;
use std::error::Error;
use std::io;
use std::sync::Arc;
use super::{CameraInfo, Config};
use v4l;
use v4l::video::Capture;
fn apply_config(config: &Config, mut format: v4l::Format) -> v4l::Format {
format.fourcc = config.fourcc;
format.width = config.width;
format.height = config.height;
format
}
struct CameraDevice {
device: media::Device,
}
impl super::UnacquiredCameraImpl for CameraDevice {
fn acquire(self: Box<Self>) -> Result<Arc<dyn super::CameraImpl>, Box<dyn Error>> {
if let Ok(device) = self.device.try_lock() {
let video_capture_device = v4l::Device::with_path(device.get_video_capture_path()?)?;
Ok(Arc::new(Camera {device, video_capture_device}))
} else {
Err(Box::new(super::AcquireError::AlreadyAcquired))
}
}
}
struct Camera {
device: Locked<media::Device>,
video_capture_device: v4l::Device,
}
impl super::CameraImpl for Camera {
fn configure(&self, config: Config) -> Result<(), io::Error> {
let format = self.video_capture_device.format()?;
let format = apply_config(&config, format);
self.video_capture_device.set_format(&format)?;
Ok(())
}
fn video_capture_device(&self) -> &v4l::Device {
&self.video_capture_device
}
}
pub struct Checker {
}
impl Checker {
pub fn check_match(device: &Device)
-> Option<CreationKit>
{
device.device_node.as_ref()
.and_then(|p| {
media::Device::new(p).unwrap()
.get_device_info().ok()
})
.and_then(|d| {
if d.get_driver() == "uvcvideo" {
Some(CreationKit {
info: CameraInfo {
device: device.clone(),
id: format!("uvc:{}:{:0x}", d.get_device(), device.stable_id()),
},
builder: build as super::Builder,
})
} else {
None
}
})
}
}
pub fn build(camera: CameraInfo)
-> Result<pipelines::UnacquiredCamera, Box<dyn Error>>
{
let device = media::Device::new(
camera.device
.device_node.as_ref()
.unwrap() )?;
Ok(pipelines::UnacquiredCamera {
device: Box::new(CameraDevice {
device,
}),
id: camera.id,
})
}