adaptivegrain/vapoursynth/src/vsscript/mod.rs
2019-05-30 11:06:53 +00:00

70 lines
2.4 KiB
Rust

//! VapourSynth script-related things.
#[cfg(not(feature = "gte-vsscript-api-32"))]
use std::sync::Mutex;
use std::sync::{Once, ONCE_INIT};
use vapoursynth_sys as ffi;
#[cfg(not(feature = "gte-vsscript-api-32"))]
lazy_static! {
static ref FFI_CALL_MUTEX: Mutex<()> = Mutex::new(());
}
// Some `vsscript_*` function calls have threading issues. Protect them with a mutex.
// https://github.com/vapoursynth/vapoursynth/issues/367
macro_rules! call_vsscript {
($call:expr) => {{
// Fixed in VSScript API 3.2.
// TODO: also not needed when we're running API 3.2 even without a feature.
#[cfg(not(feature = "gte-vsscript-api-32"))]
let _lock = FFI_CALL_MUTEX.lock();
$call
}};
}
/// Ensures `vsscript_init()` has been called at least once.
// TODO: `vsscript_init()` is already thread-safe with `std::call_once()`, maybe this can be done
// differently to remove the thread protection on Rust's side? An idea is to have a special type
// which calls `vsscript_init()` in `new()` and `vsscript_finalize()` in `drop()` and have the rest
// of the API accessible through that type, however that could become somewhat unergonomic with
// having to store its lifetime everywhere and potentially pass it around the threads.
#[inline]
pub(crate) fn maybe_initialize() {
static ONCE: Once = ONCE_INIT;
ONCE.call_once(|| unsafe {
ffi::vsscript_init();
// Verify the VSScript API version.
#[cfg(feature = "gte-vsscript-api-31")]
{
fn split_version(version: i32) -> (i32, i32) {
(version >> 16, version & 0xFFFF)
}
let vsscript_version = ffi::vsscript_getApiVersion();
let (major, minor) = split_version(vsscript_version);
let (my_major, my_minor) = split_version(ffi::VSSCRIPT_API_VERSION);
if my_major != major {
panic!(
"Invalid VSScript major API version (expected: {}, got: {})",
my_major, major
);
} else if my_minor > minor {
panic!(
"Invalid VSScript minor API version (expected: >= {}, got: {})",
my_minor, minor
);
}
}
});
}
mod errors;
pub use self::errors::{Error, VSScriptError};
mod environment;
pub use self::environment::{Environment, EvalFlags};