/// Wraps non-thread-safe capture device like a v4l webcam use linuxvideo:: { format:: { PixFormat, PixelFormat, }, Device, stream::ReadStream, }; pub struct Capture { size_image: usize, stream: ReadStream, } impl Capture { pub fn new () -> Result { let x = Device::open ("/dev/video0")?; dbg! (x.formats (linuxvideo::BufType::VIDEO_CAPTURE).collect::> ()); let x = x.video_capture (PixFormat::new (u32::MAX, u32::MAX, PixelFormat::MJPG))?; dbg! (x.format ()); let size_image = usize::try_from (x.format ().size_image ()).unwrap (); let stream = x.into_stream ()?; Ok (Self { size_image, stream, }) } pub fn size_image (&self) -> usize { self.size_image } /// Blocks until the capture device gets us a frame pub fn wait_for_frame (&mut self, output: &mut [u8]) -> Result { if output.len () < self.size_image () { return Err (Error::OutputBufferTooSmall); } Ok (self.stream.dequeue (|view| { let bytesused = usize::try_from (view.bytesused ()).unwrap (); let input = &view [0..bytesused]; &mut output [0..bytesused].copy_from_slice (&input); Ok (input.len ()) })?) } } #[derive (Debug, thiserror::Error)] pub enum Error { #[error ("I/O")] Io (#[from] std::io::Error), #[error ("output buffer too small")] OutputBufferTooSmall, }