chore: vendor trimmed v4l2r capture crate

This commit is contained in:
mofeng-git
2026-05-23 02:36:40 +00:00
parent 032f47a891
commit 6a1616c32a
34 changed files with 4851 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
//! Operations specific to DMABuf-type buffers.
use log::warn;
use super::*;
use crate::{bindings, ioctl};
use std::os::fd::RawFd;
use std::os::unix::io::{AsFd, AsRawFd};
pub struct DmaBuf;
pub type DmaBufferHandles<T> = Vec<DmaBufHandle<T>>;
impl Memory for DmaBuf {
const MEMORY_TYPE: MemoryType = MemoryType::DmaBuf;
type RawBacking = RawFd;
unsafe fn get_plane_buffer_backing(
m: &bindings::v4l2_plane__bindgen_ty_1,
) -> &Self::RawBacking {
&m.fd
}
unsafe fn get_single_planar_buffer_backing(
m: &bindings::v4l2_buffer__bindgen_ty_1,
) -> &Self::RawBacking {
&m.fd
}
unsafe fn get_plane_buffer_backing_mut(
m: &mut bindings::v4l2_plane__bindgen_ty_1,
) -> &mut Self::RawBacking {
&mut m.fd
}
unsafe fn get_single_planar_buffer_backing_mut(
m: &mut bindings::v4l2_buffer__bindgen_ty_1,
) -> &mut Self::RawBacking {
&mut m.fd
}
}
impl Imported for DmaBuf {}
pub trait DmaBufSource: AsRawFd + AsFd + Debug + Send {
fn len(&self) -> u64;
/// Make Clippy happy.
fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl DmaBufSource for std::fs::File {
fn len(&self) -> u64 {
match self.metadata() {
Err(_) => {
warn!("Failed to compute File size for use as DMABuf, using 0...");
0
}
Ok(m) => m.len(),
}
}
}
/// Handle for a DMABUF plane. Any type that can provide a file descriptor is
/// valid.
#[derive(Debug)]
pub struct DmaBufHandle<T: DmaBufSource>(pub T);
impl<T: DmaBufSource> From<T> for DmaBufHandle<T> {
fn from(dmabuf: T) -> Self {
DmaBufHandle(dmabuf)
}
}
impl<T: DmaBufSource + 'static> PlaneHandle for DmaBufHandle<T> {
type Memory = DmaBuf;
fn fill_v4l2_plane(&self, plane: &mut bindings::v4l2_plane) {
plane.m.fd = self.0.as_raw_fd();
plane.length = self.0.len() as u32;
}
}
impl<T: DmaBufSource> DmaBufHandle<T> {
pub fn map(&self) -> Result<PlaneMapping, ioctl::MmapError> {
let len = self.0.len();
ioctl::mmap(&self.0, 0, len as u32)
}
}

View File

@@ -0,0 +1,58 @@
//! Operations specific to MMAP-type buffers.
use super::*;
use crate::{bindings, ioctl};
use std::fmt::Debug;
use std::os::fd::AsFd;
#[derive(Default)]
pub struct Mmap;
impl Memory for Mmap {
const MEMORY_TYPE: MemoryType = MemoryType::Mmap;
type RawBacking = u32;
unsafe fn get_plane_buffer_backing(
m: &bindings::v4l2_plane__bindgen_ty_1,
) -> &Self::RawBacking {
&m.mem_offset
}
unsafe fn get_single_planar_buffer_backing(
m: &bindings::v4l2_buffer__bindgen_ty_1,
) -> &Self::RawBacking {
&m.offset
}
unsafe fn get_plane_buffer_backing_mut(
m: &mut bindings::v4l2_plane__bindgen_ty_1,
) -> &mut Self::RawBacking {
&mut m.mem_offset
}
unsafe fn get_single_planar_buffer_backing_mut(
m: &mut bindings::v4l2_buffer__bindgen_ty_1,
) -> &mut Self::RawBacking {
&mut m.offset
}
}
impl SelfBacked for Mmap {}
/// Dummy handle for a MMAP plane, to use with APIs that require handles. MMAP
/// buffers are backed by the device, and thus we don't need to attach any extra
/// information to them.
#[derive(Default, Debug, Clone)]
pub struct MmapHandle;
// There is no information to fill with MMAP buffers ; the index is enough.
impl PlaneHandle for MmapHandle {
type Memory = Mmap;
fn fill_v4l2_plane(&self, _plane: &mut bindings::v4l2_plane) {}
}
impl Mappable for MmapHandle {
fn map<D: AsFd>(device: &D, plane_info: &QueryBufPlane) -> Option<PlaneMapping> {
ioctl::mmap(device, plane_info.mem_offset, plane_info.length).ok()
}
}

View File

@@ -0,0 +1,77 @@
//! Operations specific to UserPtr-type buffers.
use super::*;
use crate::bindings;
pub struct UserPtr;
impl Memory for UserPtr {
const MEMORY_TYPE: MemoryType = MemoryType::UserPtr;
type RawBacking = core::ffi::c_ulong;
unsafe fn get_plane_buffer_backing(
m: &bindings::v4l2_plane__bindgen_ty_1,
) -> &Self::RawBacking {
&m.userptr
}
unsafe fn get_single_planar_buffer_backing(
m: &bindings::v4l2_buffer__bindgen_ty_1,
) -> &Self::RawBacking {
&m.userptr
}
unsafe fn get_plane_buffer_backing_mut(
m: &mut bindings::v4l2_plane__bindgen_ty_1,
) -> &mut Self::RawBacking {
&mut m.userptr
}
unsafe fn get_single_planar_buffer_backing_mut(
m: &mut bindings::v4l2_buffer__bindgen_ty_1,
) -> &mut Self::RawBacking {
&mut m.userptr
}
}
impl Imported for UserPtr {}
/// Handle for a USERPTR plane. These buffers are backed by userspace-allocated
/// memory, which translates well into Rust's slice of `u8`s. Since slices also
/// carry size information, we know that we are not passing unallocated areas
/// of the address-space to the kernel.
///
/// USERPTR buffers have the particularity that the `length` field of `struct
/// v4l2_buffer` must be set before doing a `QBUF` ioctl. This handle struct
/// also takes care of that.
#[derive(Debug)]
pub struct UserPtrHandle<T: AsRef<[u8]> + Debug + Send + 'static>(pub T);
impl<T: AsRef<[u8]> + Debug + Send + Clone> Clone for UserPtrHandle<T> {
fn clone(&self) -> Self {
UserPtrHandle(self.0.clone())
}
}
impl<T: AsRef<[u8]> + Debug + Send + 'static> AsRef<[u8]> for UserPtrHandle<T> {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl<T: AsRef<[u8]> + Debug + Send> From<T> for UserPtrHandle<T> {
fn from(buffer: T) -> Self {
UserPtrHandle(buffer)
}
}
impl<T: AsRef<[u8]> + Debug + Send + 'static> PlaneHandle for UserPtrHandle<T> {
type Memory = UserPtr;
fn fill_v4l2_plane(&self, plane: &mut bindings::v4l2_plane) {
let slice = AsRef::<[u8]>::as_ref(&self.0);
plane.m.userptr = slice.as_ptr() as std::os::raw::c_ulong;
plane.length = slice.len() as u32;
}
}