mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-06-19 10:21:51 +08:00
chore: vendor trimmed v4l2r capture crate
This commit is contained in:
91
libs/v4l2r/src/memory/dmabuf.rs
Normal file
91
libs/v4l2r/src/memory/dmabuf.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
58
libs/v4l2r/src/memory/mmap.rs
Normal file
58
libs/v4l2r/src/memory/mmap.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
77
libs/v4l2r/src/memory/userptr.rs
Normal file
77
libs/v4l2r/src/memory/userptr.rs
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user