mod audio;
mod video;
pub use audio::*;
pub use video::*;
use super::config;
use crate::common::Rational32;
#[derive(Debug, Clone)]
pub struct FilterPluginTable {
pub name: String,
pub label: Option<String>,
pub information: String,
pub flags: FilterPluginFlags,
pub config_items: Vec<config::FilterConfigItem>,
}
define_bitflag! {
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct FilterPluginFlags: i32 {
video: aviutl2_sys::filter2::FILTER_PLUGIN_TABLE::FLAG_VIDEO,
audio: aviutl2_sys::filter2::FILTER_PLUGIN_TABLE::FLAG_AUDIO,
input: aviutl2_sys::filter2::FILTER_PLUGIN_TABLE::FLAG_INPUT,
filter: aviutl2_sys::filter2::FILTER_PLUGIN_TABLE::FLAG_FILTER,
}
}
pub trait FilterUserdata: Send + Sync + Sized + 'static {
fn new(effect_id: i64) -> Self;
}
impl FilterUserdata for () {
fn new(_effect_id: i64) -> Self {}
}
#[derive(Debug)]
pub struct FilterUserdataHandle<T: FilterUserdata> {
pub(crate) inner: std::sync::Arc<parking_lot::RwLock<T>>,
}
impl<T: FilterUserdata> FilterUserdataHandle<T> {
pub(crate) fn new(inner: std::sync::Arc<parking_lot::RwLock<T>>) -> Self {
Self { inner }
}
pub fn read(&self) -> FilterUserdataReadGuard<'_, T> {
FilterUserdataReadGuard {
inner: self.inner.read(),
}
}
pub fn try_read(&self) -> Option<FilterUserdataReadGuard<'_, T>> {
self.inner
.try_read()
.map(|inner| FilterUserdataReadGuard { inner })
}
pub fn write(&self) -> FilterUserdataWriteGuard<'_, T> {
FilterUserdataWriteGuard {
inner: self.inner.write(),
}
}
pub fn try_write(&self) -> Option<FilterUserdataWriteGuard<'_, T>> {
self.inner
.try_write()
.map(|inner| FilterUserdataWriteGuard { inner })
}
}
pub struct FilterUserdataReadGuard<'handle, T: FilterUserdata> {
inner: parking_lot::RwLockReadGuard<'handle, T>,
}
impl<T: FilterUserdata> std::ops::Deref for FilterUserdataReadGuard<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
pub struct FilterUserdataWriteGuard<'handle, T: FilterUserdata> {
inner: parking_lot::RwLockWriteGuard<'handle, T>,
}
impl<T: FilterUserdata> std::ops::Deref for FilterUserdataWriteGuard<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T: FilterUserdata> std::ops::DerefMut for FilterUserdataWriteGuard<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
pub trait FilterPlugin: Send + Sync + Sized {
type Userdata: FilterUserdata;
fn new(info: crate::common::AviUtl2Info) -> crate::common::AnyResult<Self>;
fn plugin_info(&self) -> crate::filter::FilterPluginTable;
fn proc_video(
&self,
_config: &[crate::filter::FilterConfigItem],
_video: &mut crate::filter::FilterProcVideo<Self::Userdata>,
) -> crate::common::AnyResult<()> {
anyhow::bail!("proc_video is not implemented");
}
fn proc_audio(
&self,
_config: &[crate::filter::FilterConfigItem],
_audio: &mut crate::filter::FilterProcAudio<Self::Userdata>,
) -> crate::common::AnyResult<()> {
anyhow::bail!("proc_audio is not implemented");
}
fn with_instance<R>(f: impl FnOnce(&Self) -> R) -> R
where
Self: crate::filter::__bridge::FilterSingleton,
{
<Self as crate::filter::__bridge::FilterSingleton>::with_instance(f)
}
fn with_instance_mut<R>(f: impl FnOnce(&mut Self) -> R) -> R
where
Self: crate::filter::__bridge::FilterSingleton,
{
<Self as crate::filter::__bridge::FilterSingleton>::with_instance_mut(f)
}
}
#[derive(Debug, Clone, Copy)]
pub struct SceneInfo {
pub width: u32,
pub height: u32,
pub frame_rate: Rational32,
pub sample_rate: u32,
}
#[derive(Debug, Clone, Copy)]
pub struct ObjectInfo {
pub id: i64,
pub effect_id: i64,
pub layer: u32,
pub frame: u32,
pub frame_total: u32,
pub time: f64,
pub time_total: f64,
pub is_filter_object: bool,
pub frame_s: u32,
pub frame_e: u32,
}
impl ObjectInfo {
pub fn frame_range(&self) -> std::ops::RangeInclusive<u32> {
self.frame_s..=self.frame_e
}
}
#[derive(Debug, thiserror::Error)]
pub enum FilterProcError {
#[error("api call failed")]
ApiCallFailed,
#[error("input string contains null byte")]
InputCwstrContainsNull(#[from] crate::common::NullByteError),
#[error("value is out of range")]
ValueOutOfRange,
#[error("filter config data is locked")]
FilterConfigDataLocked,
#[error("filter config data is not bound to the current filter process")]
FilterConfigDataNotBound,
}
pub type FilterProcResult<T> = Result<T, FilterProcError>;