Expand description
This crate provides safe bindings for the Video4Linux (v4l) stack.
The stack consists of three libraries written in C:
- libv4l1 (v4l1 API, deprecated)
- libv4l2 (v4l2 API, the primary target of this crate)
- libv4lconvert (emulates common formats such as RGB3 in userspace)
Additional documentation can currently also be found in the README.md file which is most easily viewed on github.
Overview
Video devices on Linux can be accessed by path or by index (which then corresponds to a path), e.g. “/dev/video0” for the device which first became known to the system.
There are three methods of dealing with (capture) device memory:
MMAP
(memory region in device memory or kernel space, mapped into userspace)User
pointer (memory region allocated in host memory, written into by the kernel)DMA
(direct memory access for memory transfer without involving the CPU)
The following schematic shows the mmap
and userptr
mechanisms:
mmap
device --[MAP]--> kernel --[MAP]--> user
device --[DMA]--> kernel --[MAP]--> user
userptr
device --[DMA]--> user
It is important to note that user pointer is for device-to-user memory transfer whereas DMA is for device-to-device transfer, e.g. directly uploading a captured frame into GPU memory.
As you can see, user pointer and DMA are potential candidates for zero-copy applications where buffers should be writable. If a read-only buffer is good enough, MMAP buffers are fine and do not incur any copy overhead either. Most (if not all) devices reporting streaming I/O capabilities support MMAP buffer sharing, but not all support user pointer access.
The regular user of this crate will mainly be interested in frame capturing. Here is a very brief example of streaming I/O with memory mapped buffers:
use v4l::buffer::Type;
use v4l::io::traits::CaptureStream;
use v4l::prelude::*;
let mut dev = Device::new(0).expect("Failed to open device");
let mut stream =
MmapStream::with_buffers(&mut dev, Type::VideoCapture, 4).expect("Failed to create buffer stream");
loop {
let (buf, meta) = stream.next().unwrap();
println!(
"Buffer size: {}, seq: {}, timestamp: {}",
buf.len(),
meta.sequence,
meta.timestamp
);
}
Have a look at the examples to learn more about device and buffer management.
Re-exports
pub use v4l2_sys as v4l_sys;
pub use capability::Capabilities;
pub use control::Control;
pub use device::Device;
pub use format::Format;
pub use format::FourCC;
pub use fraction::Fraction;
pub use frameinterval::FrameInterval;
pub use framesize::FrameSize;
pub use memory::Memory;
pub use timestamp::Timestamp;