vapoursynth/
lib.rs

1//!  A safe wrapper for [VapourSynth](https://github.com/vapoursynth/vapoursynth), written in Rust.
2//!
3//! The primary goal is safety (that is, safe Rust code should not trigger undefined behavior), and
4//! secondary goals include performance and ease of use.
5//!
6//! ## Functionality
7//!
8//! Most of the VapourSynth API is covered. It's possible to evaluate `.vpy` scripts, access their
9//! properties and output, retrieve frames; enumerate loaded plugins and invoke their functions as
10//! well as create VapourSynth filters.
11//!
12//! For an example usage see
13//! [examples/vspipe.rs](https://github.com/rust-av/vapoursynth-rs/blob/master/vapoursynth/examples/vspipe.rs),
14//! a complete reimplementation of VapourSynth's
15//! [vspipe](https://github.com/vapoursynth/vapoursynth/blob/master/src/vspipe/vspipe.cpp) in safe
16//! Rust utilizing this crate.
17//!
18//! For a VapourSynth plugin example see
19//! [sample-plugin](https://github.com/rust-av/vapoursynth-rs/blob/master/sample-plugin) which
20//! implements some simple filters.
21//!
22//! ## Short example
23//!
24//! ```no_run
25//! # extern crate vapoursynth;
26//! # use anyhow::Error;
27//! #
28//! # fn foo() -> Result<(), Error> {
29//! use vapoursynth::prelude::*;
30//!
31//! let env = Environment::from_file("test.vpy", EvalFlags::SetWorkingDir)?;
32//! let node = env.get_output(0)?.0; // Without `.0` for VSScript API 3.0
33//! let frame = node.get_frame(0)?;
34//!
35//! println!("Resolution: {}×{}", frame.width(0), frame.height(0));
36//! # Ok(())
37//! # }
38//! # fn main() {
39//! # }
40//! ```
41//!
42//! ## Plugins
43//!
44//! To make a VapourSynth plugin, start by creating a new Rust library with
45//! `crate-type = ["cdylib"]`. Then add filters by implementing the `plugins::Filter` trait. Bind
46//! them to functions by implementing `plugins::FilterFunction`, which is much more easily done via
47//! the `make_filter_function!` macro. Finally, put `export_vapoursynth_plugin!` at the top level
48//! of `src/lib.rs` to export the functionality.
49//!
50//! **Important note:** due to what seems to be a
51//! [bug](https://github.com/rust-lang/rust/issues/50176) in rustc, it's impossible to make plugins
52//! on the `i686-pc-windows-gnu` target (all other variations of `x86_64` and `i686` do work).
53//! Please use `i686-pc-windows-msvc` for an i686 Windows plugin.
54//!
55//! ## Short plugin example
56//!
57//! ```no_run
58//! #[macro_use]
59//! extern crate vapoursynth;
60//!
61//! use anyhow::{anyhow, Error};
62//! use vapoursynth::prelude::*;
63//! use vapoursynth::core::CoreRef;
64//! use vapoursynth::plugins::{Filter, FilterArgument, FrameContext, Metadata};
65//! use vapoursynth::video_info::VideoInfo;
66//!
67//! // A simple filter that passes the frames through unchanged.
68//! struct Passthrough<'core> {
69//!     source: Node<'core>,
70//! }
71//!
72//! impl<'core> Filter<'core> for Passthrough<'core> {
73//!     fn video_info(&self, _api: API, _core: CoreRef<'core>) -> Vec<VideoInfo<'core>> {
74//!         vec![self.source.info()]
75//!     }
76//!
77//!     fn get_frame_initial(
78//!         &self,
79//!         _api: API,
80//!         _core: CoreRef<'core>,
81//!         context: FrameContext,
82//!         n: usize,
83//!     ) -> Result<Option<FrameRef<'core>>, Error> {
84//!         self.source.request_frame_filter(context, n);
85//!         Ok(None)
86//!     }
87//!
88//!     fn get_frame(
89//!         &self,
90//!         _api: API,
91//!         _core: CoreRef<'core>,
92//!         context: FrameContext,
93//!         n: usize,
94//!     ) -> Result<FrameRef<'core>, Error> {
95//!         self.source
96//!             .get_frame_filter(context, n)
97//!             .ok_or(anyhow!("Couldn't get the source frame"))
98//!     }
99//! }
100//!
101//! make_filter_function! {
102//!     PassthroughFunction, "Passthrough"
103//!
104//!     fn create_passthrough<'core>(
105//!         _api: API,
106//!         _core: CoreRef<'core>,
107//!         clip: Node<'core>,
108//!     ) -> Result<Option<Box<dyn Filter<'core> + 'core>>, Error> {
109//!         Ok(Some(Box::new(Passthrough { source: clip })))
110//!     }
111//! }
112//!
113//! export_vapoursynth_plugin! {
114//!     Metadata {
115//!         identifier: "com.example.passthrough",
116//!         namespace: "passthrough",
117//!         name: "Example Plugin",
118//!         read_only: true,
119//!     },
120//!     [PassthroughFunction::new()]
121//! }
122//! # fn main() {
123//! # }
124//! ```
125//!
126//! Check [sample-plugin](https://github.com/rust-av/vapoursynth-rs/blob/master/sample-plugin) for
127//! an example plugin which exports some simple filters.
128//!
129//! ## Supported Versions
130//!
131//! All VapourSynth and VSScript API versions starting with 4.0 are supported.
132//!
133//! ## Building
134//!
135//! Make sure you have the corresponding libraries available if you enable the linking features.
136//! You can use the `VAPOURSYNTH_LIB_DIR` environment variable to specify a custom directory with
137//! the library files.
138//!
139//! On Windows the easiest way is to use the VapourSynth installer (make sure the VapourSynth SDK
140//! is checked). The crate should pick up the library directory automatically. If it doesn't or if
141//! you're cross-compiling, set `VAPOURSYNTH_LIB_DIR` to
142//! `<path to the VapourSynth installation>\sdk\lib64` or `<...>\lib32`, depending on the target
143//! bitness.
144
145#![allow(unsafe_op_in_unsafe_fn)]
146
147#[cfg(test)]
148pub extern crate vapoursynth_sys;
149
150// Re-export vapoursynth_sys as ffi for use in macros
151#[doc(hidden)]
152pub use vapoursynth_sys as ffi;
153
154pub mod api;
155pub mod component;
156pub mod core;
157pub mod format;
158pub mod frame;
159pub mod function;
160pub mod map;
161pub mod node;
162pub mod plugin;
163pub mod plugins;
164pub mod video_info;
165pub mod vsscript;
166
167pub mod prelude {
168    //! The VapourSynth prelude.
169    //!
170    //! Contains the types you most likely want to import anyway.
171    pub use super::api::{API, MessageType};
172    pub use super::component::Component;
173    pub use super::format::{ColorFamily, PresetFormat, SampleType};
174    pub use super::frame::{Frame, FrameRef, FrameRefMut};
175    pub use super::map::{Map, OwnedMap, ValueType};
176    pub use super::node::{GetFrameError, Node};
177    pub use super::plugin::Plugin;
178    pub use super::video_info::Property;
179    pub use super::vsscript::{self, Environment, EvalFlags};
180}
181
182pub use anyhow;
183
184mod tests;