mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-09-21 23:13:21 +08:00
chore: vendor trimmed v4l2r capture crate
This commit is contained in:
130
libs/v4l2r/src/ioctl/g_selection.rs
Normal file
130
libs/v4l2r/src/ioctl/g_selection.rs
Normal file
@@ -0,0 +1,130 @@
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
use bitflags::bitflags;
|
||||
use enumn::N;
|
||||
use nix::errno::Errno;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::bindings;
|
||||
use crate::bindings::v4l2_rect;
|
||||
use crate::bindings::v4l2_selection;
|
||||
|
||||
#[derive(Debug, N, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
pub enum SelectionType {
|
||||
Capture = bindings::v4l2_buf_type_V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
Output = bindings::v4l2_buf_type_V4L2_BUF_TYPE_VIDEO_OUTPUT,
|
||||
}
|
||||
|
||||
#[derive(Debug, N, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
pub enum SelectionTarget {
|
||||
Crop = bindings::V4L2_SEL_TGT_CROP,
|
||||
CropDefault = bindings::V4L2_SEL_TGT_CROP_DEFAULT,
|
||||
CropBounds = bindings::V4L2_SEL_TGT_CROP_BOUNDS,
|
||||
NativeSize = bindings::V4L2_SEL_TGT_NATIVE_SIZE,
|
||||
Compose = bindings::V4L2_SEL_TGT_COMPOSE,
|
||||
ComposeDefault = bindings::V4L2_SEL_TGT_COMPOSE_DEFAULT,
|
||||
ComposeBounds = bindings::V4L2_SEL_TGT_COMPOSE_BOUNDS,
|
||||
ComposePadded = bindings::V4L2_SEL_TGT_COMPOSE_PADDED,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct SelectionFlags: u32 {
|
||||
const GE = bindings::V4L2_SEL_FLAG_GE;
|
||||
const LE = bindings::V4L2_SEL_FLAG_LE;
|
||||
const KEEP_CONFIG = bindings::V4L2_SEL_FLAG_KEEP_CONFIG;
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
mod ioctl {
|
||||
use crate::bindings::v4l2_selection;
|
||||
nix::ioctl_readwrite!(vidioc_g_selection, b'V', 94, v4l2_selection);
|
||||
nix::ioctl_readwrite!(vidioc_s_selection, b'V', 95, v4l2_selection);
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GSelectionError {
|
||||
#[error("invalid type or target requested")]
|
||||
Invalid,
|
||||
#[error("ioctl error: {0}")]
|
||||
IoctlError(Errno),
|
||||
}
|
||||
|
||||
impl From<GSelectionError> for Errno {
|
||||
fn from(err: GSelectionError) -> Self {
|
||||
match err {
|
||||
GSelectionError::Invalid => Errno::EINVAL,
|
||||
GSelectionError::IoctlError(e) => e,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Safe wrapper around the `VIDIOC_G_SELECTION` ioctl.
|
||||
pub fn g_selection<R: From<v4l2_rect>>(
|
||||
fd: &impl AsRawFd,
|
||||
selection: SelectionType,
|
||||
target: SelectionTarget,
|
||||
) -> Result<R, GSelectionError> {
|
||||
let mut sel = v4l2_selection {
|
||||
type_: selection as u32,
|
||||
target: target as u32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
match unsafe { ioctl::vidioc_g_selection(fd.as_raw_fd(), &mut sel) } {
|
||||
Ok(_) => Ok(R::from(sel.r)),
|
||||
Err(Errno::EINVAL) => Err(GSelectionError::Invalid),
|
||||
Err(e) => Err(GSelectionError::IoctlError(e)),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SSelectionError {
|
||||
#[error("invalid type or target requested")]
|
||||
Invalid,
|
||||
#[error("invalid range requested")]
|
||||
InvalidRange,
|
||||
#[error("cannot change selection rectangle currently")]
|
||||
Busy,
|
||||
#[error("ioctl error: {0}")]
|
||||
IoctlError(nix::Error),
|
||||
}
|
||||
|
||||
impl From<SSelectionError> for Errno {
|
||||
fn from(err: SSelectionError) -> Self {
|
||||
match err {
|
||||
SSelectionError::Invalid => Errno::EINVAL,
|
||||
SSelectionError::InvalidRange => Errno::ERANGE,
|
||||
SSelectionError::Busy => Errno::EBUSY,
|
||||
SSelectionError::IoctlError(e) => e,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Safe wrapper around the `VIDIOC_S_SELECTION` ioctl.
|
||||
pub fn s_selection<RI: Into<v4l2_rect>, RO: From<v4l2_rect>>(
|
||||
fd: &impl AsRawFd,
|
||||
selection: SelectionType,
|
||||
target: SelectionTarget,
|
||||
rect: RI,
|
||||
flags: SelectionFlags,
|
||||
) -> Result<RO, SSelectionError> {
|
||||
let mut sel = v4l2_selection {
|
||||
type_: selection as u32,
|
||||
target: target as u32,
|
||||
flags: flags.bits(),
|
||||
r: rect.into(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
match unsafe { ioctl::vidioc_s_selection(fd.as_raw_fd(), &mut sel) } {
|
||||
Ok(_) => Ok(RO::from(sel.r)),
|
||||
Err(Errno::EINVAL) => Err(SSelectionError::Invalid),
|
||||
Err(Errno::ERANGE) => Err(SSelectionError::InvalidRange),
|
||||
Err(Errno::EBUSY) => Err(SSelectionError::Busy),
|
||||
Err(e) => Err(SSelectionError::IoctlError(e)),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user