pub mod codec;
pub mod user;
use paste::paste;
use std::marker::PhantomData;
use crate::bindings;
use crate::bindings::v4l2_ctrl_av1_film_grain;
use crate::bindings::v4l2_ctrl_av1_frame;
use crate::bindings::v4l2_ctrl_av1_sequence;
use crate::bindings::v4l2_ctrl_av1_tile_group_entry;
use crate::bindings::v4l2_ctrl_fwht_params;
use crate::bindings::v4l2_ctrl_h264_decode_params;
use crate::bindings::v4l2_ctrl_h264_pps;
use crate::bindings::v4l2_ctrl_h264_pred_weights;
use crate::bindings::v4l2_ctrl_h264_scaling_matrix;
use crate::bindings::v4l2_ctrl_h264_slice_params;
use crate::bindings::v4l2_ctrl_h264_sps;
use crate::bindings::v4l2_ctrl_hevc_decode_params;
use crate::bindings::v4l2_ctrl_hevc_pps;
use crate::bindings::v4l2_ctrl_hevc_scaling_matrix;
use crate::bindings::v4l2_ctrl_hevc_slice_params;
use crate::bindings::v4l2_ctrl_hevc_sps;
use crate::bindings::v4l2_ctrl_vp8_frame;
use crate::bindings::v4l2_ctrl_vp9_frame;
use crate::bindings::v4l2_ext_control;
use crate::bindings::v4l2_ext_control__bindgen_ty_1;
use crate::controls::codec::FwhtFlags;
pub trait AsV4l2ControlSlice {
fn as_v4l2_control_slice(&mut self) -> &mut [v4l2_ext_control];
}
impl AsV4l2ControlSlice for &mut [v4l2_ext_control] {
fn as_v4l2_control_slice(&mut self) -> &mut [v4l2_ext_control] {
self
}
}
pub trait ExtControlTrait {
const ID: u32;
type PAYLOAD;
}
#[repr(transparent)]
pub struct SafeExtControl<T: ExtControlTrait>(v4l2_ext_control, PhantomData<T>);
impl<T: ExtControlTrait> SafeExtControl<T> {
pub fn id(&self) -> u32 {
self.0.id
}
}
impl<T: ExtControlTrait> AsV4l2ControlSlice for &mut SafeExtControl<T> {
fn as_v4l2_control_slice(&mut self) -> &mut [v4l2_ext_control] {
unsafe { std::slice::from_raw_parts_mut(&mut self.0, 1) }
}
}
impl<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = i32>,
{
pub fn from_value(value: i32) -> Self {
Self(
v4l2_ext_control {
id: T::ID,
__bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 { value },
..Default::default()
},
PhantomData,
)
}
pub fn value(&self) -> i32 {
unsafe { self.0.__bindgen_anon_1.value }
}
pub fn set_value(&mut self, value: i32) {
self.0.__bindgen_anon_1.value = value;
}
}
impl<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = i64>,
{
pub fn from_value64(value64: i64) -> Self {
Self(
v4l2_ext_control {
id: T::ID,
__bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 { value64 },
..Default::default()
},
PhantomData,
)
}
pub fn value64(&self) -> i64 {
unsafe { self.0.__bindgen_anon_1.value64 }
}
pub fn set_value64(&mut self, value: i64) {
self.0.__bindgen_anon_1.value64 = value;
}
}
impl<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_fwht_params>,
{
pub fn flags(&self) -> Option<FwhtFlags> {
FwhtFlags::from_bits(self.fwht_params().flags)
}
}
macro_rules! wrap_single_control {
($ctrl:expr) => {
paste! {
impl<T> From<[<v4l2_ctrl_ $ctrl>]> for SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = [<v4l2_ctrl_ $ctrl>]>,
{
fn from(params: [<v4l2_ctrl_ $ctrl>]) -> Self {
let payload = Box::new(params);
Self(
v4l2_ext_control {
id: T::ID,
size: std::mem::size_of::<T::PAYLOAD>() as u32,
__bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 {
[<p_ $ctrl>]: Box::into_raw(payload),
},
..Default::default()
},
PhantomData,
)
}
}
impl<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = [<v4l2_ctrl_ $ctrl>]>,
{
pub fn $ctrl(&self) -> &[<v4l2_ctrl_ $ctrl>] {
unsafe { self.0.__bindgen_anon_1.[<p_ $ctrl>].as_ref().unwrap() }
}
pub fn [<$ctrl _mut>](&mut self) -> &mut [<v4l2_ctrl_ $ctrl>] {
unsafe { self.0.__bindgen_anon_1.[<p_ $ctrl>].as_mut().unwrap() }
}
}
}
};
}
macro_rules! wrap_controls {
($($ctrl:expr),*) => {
$(
wrap_single_control!($ctrl);
)*
};
}
macro_rules! wrap_drop {
($($ctrl:expr),*) => {
paste! {
impl<T: ExtControlTrait> Drop for SafeExtControl<T> {
fn drop(&mut self) {
if self.0.size > 0 {
unsafe {
match self.0.id {
$(
bindings::[<V4L2_CID_STATELESS_ $ctrl:upper>] => {
let _ = Box::from_raw(self.0.__bindgen_anon_1.[<p_ $ctrl>]);
}
)*
_ => (),
}
}
}
}
}
}
};
}
macro_rules! wrap_both {
($($ctrl:tt)*) => {
wrap_controls!($($ctrl)*);
wrap_drop!($($ctrl)*);
};
}
wrap_both!(
av1_film_grain,
av1_frame,
av1_sequence,
av1_tile_group_entry,
fwht_params,
h264_decode_params,
h264_pred_weights,
h264_pps,
h264_scaling_matrix,
h264_slice_params,
h264_sps,
hevc_decode_params,
hevc_pps,
hevc_scaling_matrix,
hevc_slice_params,
hevc_sps,
vp8_frame,
vp9_frame
);