use std::fmt::Debug;
use std::ops::Deref;
use vapoursynth_sys as ffi;
use crate::format::Format;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct Resolution {
pub width: usize,
pub height: usize,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct Framerate {
pub numerator: u64,
pub denominator: u64,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Property<T: Debug + Clone + Copy + Eq + PartialEq> {
Variable,
Constant(T),
}
#[derive(Debug, Copy, Clone)]
pub struct VideoInfo<'core> {
pub format: Format<'core>,
pub framerate: Property<Framerate>,
pub resolution: Property<Resolution>,
pub num_frames: usize,
}
impl<'core> VideoInfo<'core> {
pub(crate) unsafe fn from_ptr(ptr: *const ffi::VSVideoInfo) -> Self {
let info = unsafe { &*ptr };
debug_assert!(info.fpsNum >= 0);
debug_assert!(info.fpsDen >= 0);
debug_assert!(info.width >= 0);
debug_assert!(info.height >= 0);
debug_assert!(info.numFrames >= 0);
let format = unsafe { Format::from_ptr(&info.format) };
let framerate = if info.fpsNum == 0 {
debug_assert!(info.fpsDen == 0);
Property::Variable
} else {
debug_assert!(info.fpsDen != 0);
Property::Constant(Framerate {
numerator: info.fpsNum as _,
denominator: info.fpsDen as _,
})
};
let resolution = if info.width == 0 {
debug_assert!(info.height == 0);
Property::Variable
} else {
debug_assert!(info.height != 0);
Property::Constant(Resolution {
width: info.width as _,
height: info.height as _,
})
};
let num_frames = {
debug_assert!(info.numFrames != 0);
info.numFrames as _
};
Self {
format,
framerate,
resolution,
num_frames,
}
}
pub(crate) fn ffi_type(self) -> ffi::VSVideoInfo {
let format = self.format.deref();
let (fps_num, fps_den) = match self.framerate {
Property::Variable => (0, 0),
Property::Constant(Framerate {
numerator,
denominator,
}) => (numerator as i64, denominator as i64),
};
let (width, height) = match self.resolution {
Property::Variable => (0, 0),
Property::Constant(Resolution { width, height }) => (width as i32, height as i32),
};
let num_frames = self.num_frames as i32;
ffi::VSVideoInfo {
format: *format,
fpsNum: fps_num,
fpsDen: fps_den,
width,
height,
numFrames: num_frames,
}
}
}
impl<T> From<T> for Property<T>
where
T: Debug + Clone + Copy + Eq + PartialEq,
{
#[inline]
fn from(x: T) -> Self {
Property::Constant(x)
}
}