Skip to main content

vapoursynth4_sys/
vs.rs

1/*
2 This Source Code Form is subject to the terms of the Mozilla Public
3 License, v. 2.0. If a copy of the MPL was not distributed with this
4 file, You can obtain one at http://mozilla.org/MPL/2.0/.
5*/
6
7// VapourSynth4.h
8//! This is `VapourSynth`'s main header file.
9//! Plugins and applications that use the library must include it.
10//!
11//! `VapourSynth`'s public API is all C.
12
13use std::ffi::{c_char, c_double, c_float, c_int, c_void};
14
15use super::{opaque_struct, vs_make_version};
16
17/// Major API version.
18pub const VAPOURSYNTH_API_MAJOR: u16 = 4;
19/// Minor API version. It is bumped when new functions are added to [`VSAPI`]
20/// or core behavior is noticeably changed.
21pub const VAPOURSYNTH_API_MINOR: u16 = if cfg!(feature = "vs-42") {
22    2
23} else if cfg!(feature = "vs-41") {
24    1
25} else {
26    0
27};
28/// API version. The high 16 bits are [`VAPOURSYNTH_API_MAJOR`], the low 16 bits are
29/// [`VAPOURSYNTH_API_MINOR`].
30pub const VAPOURSYNTH_API_VERSION: i32 =
31    vs_make_version(VAPOURSYNTH_API_MAJOR, VAPOURSYNTH_API_MINOR);
32
33/// The number of audio samples in an audio frame. It is a static number to
34/// make it possible to calculate which audio frames are needed to retrieve specific samples.
35pub const VS_AUDIO_FRAME_SAMPLES: i32 = 3072;
36
37opaque_struct!(
38    /// A frame that can hold audio or video data.
39    ///
40    /// Each row of pixels in a frame is guaranteed to have an alignment of at least 32 bytes.
41    /// Two frames with the same width and bytes per sample are guaranteed to have the same stride.
42    ///
43    /// Audio data is also guaranteed to be at least 32 byte aligned.
44    ///
45    /// Any data can be attached to a frame, using a `VSMap`.
46    VSFrame,
47    /// A reference to a node in the constructed filter graph. Its primary use is as an argument
48    /// to other filter or to request frames from.
49    VSNode,
50    /// The core represents one instance of `VapourSynth`.
51    /// Every core individually loads plugins and keeps track of memory.
52    VSCore,
53    /// A `VapourSynth` plugin. There are a few of these built into the core,
54    /// and therefore available at all times: the basic filters (identifier `com.vapoursynth.std`,
55    /// namespace `std`), the resizers (identifier `com.vapoursynth.resize`, namespace `resize`),
56    /// and the Avisynth compatibility module, if running in Windows
57    /// (identifier `com.vapoursynth.avisynth`, namespace `avs`).
58    ///
59    /// The Function Reference describes how to load `VapourSynth` and Avisynth plugins.
60    ///
61    /// A [`VSPlugin`] instance is constructed by the core when loading a plugin
62    /// (.so / .dylib / .dll), and the pointer is passed to the plugin's
63    /// `VapourSynthPluginInit2()` function.
64    ///
65    /// A `VapourSynth` plugin can export any number of filters.
66    ///
67    /// Plugins have a few attributes:
68    ///
69    /// - An identifier, which must be unique among all `VapourSynth` plugins in existence,
70    ///   because this is what the core uses to make sure a plugin only gets loaded once.
71    /// - A namespace, also unique. The filters exported by a plugin end up
72    ///     in the plugin's namespace.
73    /// - A full name, which is used by the core in a few error messages.
74    /// - The version of the plugin.
75    /// - The `VapourSynth` API version the plugin requires.
76    /// - A file name.
77    ///
78    /// Things you can do with a [`VSPlugin`]:
79    ///
80    /// - Enumerate all the filters it exports, using
81    ///   [`getNextPluginFunction()`](VSAPI::getNextPluginFunction).
82    /// - Invoke one of its filters, using [`invoke()`](VSAPI::invoke).
83    /// - Get its location in the file system, using [`getPluginPath()`](VSAPI::getPluginPath).
84    ///
85    /// All loaded plugins (including built-in) can be enumerated with
86    /// [`getNextPlugin()`](VSAPI::getNextPlugin).
87    ///
88    /// Once loaded, a plugin only gets unloaded when the `VapourSynth` core is freed.
89    VSPlugin,
90    /// A function belonging to a Vapoursynth plugin. This object primarily exists
91    /// so a plugin's name, argument list and return type can be queried by editors.
92    ///
93    /// One peculiarity is that plugin functions cannot be invoked using a
94    /// [`VSPluginFunction`] pointer but is instead done using [`invoke()`](VSAPI::invoke)
95    /// which takes a [`VSPlugin`] and the function name as a string.
96    VSPluginFunction,
97    /// Holds a reference to a function that may be called.
98    /// This type primarily exists so functions can be shared between
99    /// the scripting layer and plugins in the core.
100    VSFunction,
101    /// [`VSMap`] is a container that stores (key, value) pairs.
102    /// The keys are strings and the values can be (arrays of) integers,
103    /// floating point numbers, arrays of bytes, [`VSNode`], [`VSFrame`], or [`VSFunction`].
104    ///
105    /// The pairs in a [`VSMap`] are sorted by key.
106    ///
107    /// **In `VapourSynth`, [`VSMap`]s have several uses:**
108    /// - storing filters' arguments and return values
109    /// - storing user-defined functions' arguments and return values
110    /// - storing the properties attached to frames
111    ///
112    /// Only alphanumeric characters and the underscore may be used in keys.
113    ///
114    /// Creating and destroying a map can be done with [`createMap()`](VSAPI::createMap) and
115    /// [`freeMap()`](VSAPI::freeMap), respectively.
116    ///
117    /// A map's contents can be retrieved and modified using a number of functions,
118    /// all prefixed with "map".
119    ///
120    /// A map's contents can be erased with [`clearMap()`](VSAPI::clearMap).
121    VSMap,
122    /// Opaque type representing a registered logger.
123    VSLogHandle,
124    /// Opaque type representing the current frame request in a filter.
125    VSFrameContext
126);
127
128#[repr(C)]
129#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
130pub enum VSColorFamily {
131    Undefined = 0,
132    Gray = 1,
133    RGB = 2,
134    YUV = 3,
135}
136
137#[repr(C)]
138#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
139pub enum VSSampleType {
140    Integer = 0,
141    Float = 1,
142}
143
144const fn vs_make_video_id(
145    color_family: VSColorFamily,
146    sample_type: VSSampleType,
147    bits_per_sample: isize,
148    sub_sampling_w: isize,
149    sub_sampling_h: isize,
150) -> isize {
151    ((color_family as isize) << 28)
152        | ((sample_type as isize) << 24)
153        | (bits_per_sample << 16)
154        | (sub_sampling_w << 8)
155        | sub_sampling_h
156}
157
158use VSColorFamily::{Gray, RGB, YUV};
159use VSSampleType::{Float, Integer};
160
161/// The presets suffixed with H and S have floating point sample type.
162/// The H and S suffixes stand for half precision and single precision, respectively.
163/// All formats are planar.
164#[repr(C)]
165#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
166pub enum VSPresetVideoFormat {
167    None = 0,
168
169    Gray8 = vs_make_video_id(Gray, Integer, 8, 0, 0),
170    Gray9 = vs_make_video_id(Gray, Integer, 9, 0, 0),
171    Gray10 = vs_make_video_id(Gray, Integer, 10, 0, 0),
172    Gray12 = vs_make_video_id(Gray, Integer, 12, 0, 0),
173    Gray14 = vs_make_video_id(Gray, Integer, 14, 0, 0),
174    Gray16 = vs_make_video_id(Gray, Integer, 16, 0, 0),
175    Gray32 = vs_make_video_id(Gray, Integer, 32, 0, 0),
176
177    GrayH = vs_make_video_id(Gray, Float, 16, 0, 0),
178    GrayS = vs_make_video_id(Gray, Float, 32, 0, 0),
179
180    YUV410P8 = vs_make_video_id(YUV, Integer, 8, 2, 2),
181    YUV411P8 = vs_make_video_id(YUV, Integer, 8, 2, 0),
182    YUV440P8 = vs_make_video_id(YUV, Integer, 8, 0, 1),
183
184    YUV420P8 = vs_make_video_id(YUV, Integer, 8, 1, 1),
185    YUV422P8 = vs_make_video_id(YUV, Integer, 8, 1, 0),
186    YUV444P8 = vs_make_video_id(YUV, Integer, 8, 0, 0),
187
188    YUV420P9 = vs_make_video_id(YUV, Integer, 9, 1, 1),
189    YUV422P9 = vs_make_video_id(YUV, Integer, 9, 1, 0),
190    YUV444P9 = vs_make_video_id(YUV, Integer, 9, 0, 0),
191
192    YUV420P10 = vs_make_video_id(YUV, Integer, 10, 1, 1),
193    YUV422P10 = vs_make_video_id(YUV, Integer, 10, 1, 0),
194    YUV444P10 = vs_make_video_id(YUV, Integer, 10, 0, 0),
195
196    YUV420P12 = vs_make_video_id(YUV, Integer, 12, 1, 1),
197    YUV422P12 = vs_make_video_id(YUV, Integer, 12, 1, 0),
198    YUV444P12 = vs_make_video_id(YUV, Integer, 12, 0, 0),
199
200    YUV420P14 = vs_make_video_id(YUV, Integer, 14, 1, 1),
201    YUV422P14 = vs_make_video_id(YUV, Integer, 14, 1, 0),
202    YUV444P14 = vs_make_video_id(YUV, Integer, 14, 0, 0),
203
204    YUV410P16 = vs_make_video_id(YUV, Integer, 16, 2, 2),
205    YUV411P16 = vs_make_video_id(YUV, Integer, 16, 2, 0),
206    YUV440P16 = vs_make_video_id(YUV, Integer, 16, 0, 1),
207
208    YUV420P16 = vs_make_video_id(YUV, Integer, 16, 1, 1),
209    YUV422P16 = vs_make_video_id(YUV, Integer, 16, 1, 0),
210    YUV444P16 = vs_make_video_id(YUV, Integer, 16, 0, 0),
211
212    YUV410PH = vs_make_video_id(YUV, Float, 16, 2, 2),
213    YUV410PS = vs_make_video_id(YUV, Float, 32, 2, 2),
214    YUV411PH = vs_make_video_id(YUV, Float, 16, 2, 0),
215    YUV411PS = vs_make_video_id(YUV, Float, 32, 2, 0),
216    YUV440PH = vs_make_video_id(YUV, Float, 16, 0, 1),
217    YUV440PS = vs_make_video_id(YUV, Float, 32, 0, 1),
218
219    YUV420PH = vs_make_video_id(YUV, Float, 16, 1, 1),
220    YUV420PS = vs_make_video_id(YUV, Float, 32, 1, 1),
221    YUV422PH = vs_make_video_id(YUV, Float, 16, 1, 0),
222    YUV422PS = vs_make_video_id(YUV, Float, 32, 1, 0),
223    YUV444PH = vs_make_video_id(YUV, Float, 16, 0, 0),
224    YUV444PS = vs_make_video_id(YUV, Float, 32, 0, 0),
225
226    RGB24 = vs_make_video_id(RGB, Integer, 8, 0, 0),
227    RGB27 = vs_make_video_id(RGB, Integer, 9, 0, 0),
228    RGB30 = vs_make_video_id(RGB, Integer, 10, 0, 0),
229    RGB36 = vs_make_video_id(RGB, Integer, 12, 0, 0),
230    RGB42 = vs_make_video_id(RGB, Integer, 14, 0, 0),
231    RGB48 = vs_make_video_id(RGB, Integer, 16, 0, 0),
232
233    RGBH = vs_make_video_id(RGB, Float, 16, 0, 0),
234    RGBS = vs_make_video_id(RGB, Float, 32, 0, 0),
235}
236
237/// Controls how a filter will be multithreaded, if at all.
238#[repr(C)]
239#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
240pub enum VSFilterMode {
241    /// Completely parallel execution. Multiple threads will call a filter's "getFrame" function,
242    /// to fetch several frames in parallel.
243    Parallel = 0,
244    /// For filters that are serial in nature but can request in advance one or more frames
245    /// they need. A filter's "getFrame" function will be called from multiple threads at a time
246    /// with activation reason [`VSActivationReason::Initial`],
247    /// but only one thread will call it with activation reason
248    /// [`VSActivationReason::AllFramesReady`] at a time.
249    ParallelRequests = 1,
250    /// Only one thread can call the filter's "getFrame" function at a time.
251    /// Useful for filters that modify or examine their internal state to
252    /// determine which frames to request.
253    ///
254    /// While the "getFrame" function will only run in one thread at a time,
255    /// the calls can happen in any order. For example, it can be called with reason
256    /// [`VSActivationReason::Initial`] for frame 0, then again with reason
257    /// [`VSActivationReason::Initial`] for frame 1,
258    /// then with reason [`VSActivationReason::AllFramesReady`]  for frame 0.
259    Unordered = 2,
260    /// For compatibility with other filtering architectures.
261    /// *DO NOT USE IN NEW FILTERS*. The filter's "getFrame" function only ever gets called from
262    /// one thread at a time. Unlike [`Unordered`](VSFilterMode::Unordered),
263    /// only one frame is processed at a time.
264    FrameState = 3,
265}
266
267/// Used to indicate the type of a [`VSFrame`] or [`VSNode`] object.
268#[repr(C)]
269#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
270pub enum VSMediaType {
271    Video = 1,
272    Audio = 2,
273}
274
275/// Describes the format of a clip.
276///
277/// Use [`queryVideoFormat()`](VSAPI::queryVideoFormat) to fill it in with proper error checking.
278/// Manually filling out the struct is allowed but discouraged
279/// since illegal combinations of values will cause undefined behavior.
280#[repr(C)]
281#[derive(Clone, Eq, PartialEq, Hash, Debug)]
282pub struct VSVideoFormat {
283    /// See [`VSColorFamily`].
284    pub color_family: VSColorFamily,
285    /// See [`VSSampleType`].
286    pub sample_type: VSSampleType,
287    /// Number of significant bits.
288    pub bits_per_sample: c_int,
289    /// Number of bytes needed for a sample. This is always a power of 2 and the smallest possible
290    /// that can fit the number of bits used per sample.
291    pub bytes_per_sample: c_int,
292
293    /// log2 subsampling factor, applied to second and third plane
294    pub sub_sampling_w: c_int,
295    /// log2 subsampling factor, applied to second and third plane.
296    ///
297    /// Convenient numbers that can be used like so:
298    /// ```py
299    /// uv_width = y_width >> subSamplingW;
300    /// ```
301    pub sub_sampling_h: c_int,
302
303    /// Number of planes, implicit from colorFamily
304    pub num_planes: c_int,
305}
306
307/// Audio channel positions as an enum. Mirrors the `FFmpeg` audio channel constants
308/// in older api versions.
309#[repr(C)]
310#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
311pub enum VSAudioChannels {
312    FrontLeft = 0,
313    FrontRight = 1,
314    FrontCenter = 2,
315    LowFrequency = 3,
316    BackLeft = 4,
317    BackRight = 5,
318    FrontLeftOFCenter = 6,
319    FrontRightOFCenter = 7,
320    BackCenter = 8,
321    SideLeft = 9,
322    SideRight = 10,
323    TopCenter = 11,
324    TopFrontLeft = 12,
325    TopFrontCenter = 13,
326    TopFrontRight = 14,
327    TopBackLeft = 15,
328    TopBackCenter = 16,
329    TopBackRight = 17,
330    StereoLeft = 29,
331    StereoRight = 30,
332    WideLeft = 31,
333    WideRight = 32,
334    SurroundDirectLeft = 33,
335    SurroundDirectRight = 34,
336    LowFrequency2 = 35,
337}
338
339/// Describes the format of a clip.
340///
341/// Use [`queryAudioFormat()`](VSAPI::queryAudioFormat) to fill it in with proper error checking.
342/// Manually filling out the struct is allowed but discouraged
343/// since illegal combinations of values will cause undefined behavior.
344#[repr(C)]
345#[derive(Clone, Eq, PartialEq, Hash, Debug)]
346pub struct VSAudioFormat {
347    /// See [`VSSampleType`].
348    pub sample_type: VSSampleType,
349    /// Number of significant bits.
350    pub bits_per_sample: c_int,
351    /// Number of bytes needed for a sample. This is always a power of 2 and the smallest possible
352    /// that can fit the number of bits used per sample, implicit from
353    /// [`VSAudioFormat::channel_layout`].
354    pub bytes_per_sample: c_int,
355    /// Number of audio channels, implicit from [`VSAudioFormat::bits_per_sample`]
356    pub num_channels: c_int,
357    /// A bitmask representing the channels present using the constants in 1 left shifted
358    /// by the constants in [`VSAudioChannels`].
359    pub channel_layout: u64,
360}
361
362/// Types of properties that can be stored in a [`VSMap`].
363#[repr(C)]
364#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
365pub enum VSPropertyType {
366    Unset = 0,
367    Int = 1,
368    Float = 2,
369    Data = 3,
370    Function = 4,
371    VideoNode = 5,
372    AudioNode = 6,
373    VideoFrame = 7,
374    AudioFrame = 8,
375}
376
377/// When a `mapGet*` function fails, it returns one of these in the err parameter.
378///
379/// All errors are non-zero.
380#[repr(C)]
381#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
382pub enum VSMapPropertyError {
383    Success = 0,
384    /// The requested key was not found in the map.
385    Unset = 1,
386    /// The wrong function was used to retrieve the property.
387    /// E.g. [`mapGetInt()`](VSAPI::mapGetInt) was used on a property of type
388    /// [`VSPropertyType::Float`].
389    Type = 2,
390    /// The requested index was out of bounds.
391    Index = 4,
392    /// The map has the error state set.
393    Error = 3,
394}
395
396/// Controls the behaviour of [`mapSetInt()`](VSAPI::mapSetInt) and friends.
397#[repr(C)]
398#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
399pub enum VSMapAppendMode {
400    /// All existing values associated with the key will be replaced with the new value.
401    Replace = 0,
402    /// The new value will be appended to the list of existing values associated with the key.
403    Append = 1,
404}
405
406/// Contains information about a [`VSCore`] instance.
407#[repr(C)]
408#[derive(Eq, PartialEq, Hash, Debug)]
409pub struct VSCoreInfo {
410    /// Printable string containing the name of the library, copyright notice,
411    /// core and API versions.
412    pub version_string: *const c_char,
413    /// Version of the core.
414    pub core: c_int,
415    /// Version of the API.
416    pub api: c_int,
417    /// Number of worker threads.
418    pub num_threads: c_int,
419    /// The framebuffer cache will be allowed to grow up to this size (bytes)
420    /// before memory is aggressively reclaimed.
421    pub max_framebuffer_size: i64,
422    /// Current size of the framebuffer cache, in bytes.
423    pub used_framebuffer_size: i64,
424}
425
426/// Contains information about a [`VSCore`] instance.
427///
428/// Same as [`VSCoreInfo`], plus the flags the core was created with. Added in API 4.2.
429#[cfg(feature = "vs-42")]
430#[repr(C)]
431#[derive(Clone, Eq, PartialEq, Hash, Debug)]
432pub struct VSCoreInfo2 {
433    /// Printable string containing the name of the library, copyright notice,
434    /// core and API versions.
435    pub version_string: *const c_char,
436    /// Version of the core.
437    pub core: c_int,
438    /// Version of the API.
439    pub api: c_int,
440    /// The [`VSCoreCreationFlags`] the core was created with.
441    pub creation_flags: c_int,
442    /// Number of worker threads.
443    pub num_threads: c_int,
444    /// The framebuffer cache will be allowed to grow up to this size (bytes)
445    /// before memory is aggressively reclaimed.
446    pub max_framebuffer_size: i64,
447    /// Current size of the framebuffer cache, in bytes.
448    pub used_framebuffer_size: i64,
449}
450
451/// Contains information about a clip.
452#[repr(C)]
453#[derive(Clone, Eq, PartialEq, Hash, Debug)]
454pub struct VSVideoInfo {
455    /// Format of the clip. Will have [`VSVideoFormat::color_family`] set to
456    /// [`VSColorFamily::Undefined`] if the format can vary.
457    pub format: VSVideoFormat,
458    /// Numerator part of the clip's frame rate. It will be 0 if the frame rate can vary.
459    /// Should always be a reduced fraction.
460    pub fps_num: i64,
461    /// Denominator part of the clip's frame rate. It will be 0 if the frame rate can vary.
462    /// Should always be a reduced fraction.
463    pub fps_den: i64,
464    /// Width of the clip. Both width and height will be 0 if the clip's dimensions can vary.
465    pub width: c_int,
466    /// Height of the clip. Both width and height will be 0 if the clip's dimensions can vary.
467    pub height: c_int,
468    /// Length of the clip.
469    pub num_frames: c_int,
470}
471
472/// Contains information about a clip.
473#[repr(C)]
474#[derive(Clone, Eq, PartialEq, Hash, Debug)]
475pub struct VSAudioInfo {
476    /// Format of the clip. Unlike video the audio format can never change.
477    pub format: VSAudioFormat,
478    /// Sample rate.
479    pub sample_rate: c_int,
480    /// Length of the clip in audio samples.
481    pub num_samples: i64,
482    /// Length of the clip in audio frames.
483    ///
484    /// The total number of audio frames needed to hold [`Self::num_samples`],
485    /// implicit from [`Self::num_samples`] when calling
486    /// [`createAudioFilter()`](VSAPI::createAudioFilter)
487    pub num_frames: c_int,
488}
489
490/// See [`VSFilterGetFrame`].
491#[repr(C)]
492#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
493pub enum VSActivationReason {
494    Initial = 0,
495    AllFramesReady = 1,
496    Error = -1,
497}
498
499/// See [`addLogHandler()`](VSAPI::addLogHandler).
500#[repr(C)]
501#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
502pub enum VSMessageType {
503    Debug = 0,
504    Information = 1,
505    Warning = 2,
506    Critical = 3,
507    /// also terminates the process, should generally not be used by normal filters
508    Fatal = 4,
509}
510
511/// Options when creating a core.
512#[repr(C)]
513#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
514pub enum VSCoreCreationFlags {
515    /// Required to use the graph inspection api functions.
516    /// Increases memory usage due to the extra information stored.
517    EnableGraphInspection = 1,
518    /// Don't autoload any user plugins. Core plugins are always loaded.
519    DisableAutoLoading = 2,
520    /// Don't unload plugin libraries when the core is destroyed.
521    /// Due to a small amount of memory leaking every load and unload
522    /// (windows feature, not my fault) of a library,
523    /// this may help in applications with extreme amount of script reloading.
524    DisableLibraryUnloading = 4,
525    /// Outputs a list of all allocated frames as a log message
526    /// after every external frame request has been completed.
527    EnableFrameRefDebug = 8,
528}
529
530impl std::ops::BitOr for VSCoreCreationFlags {
531    type Output = c_int;
532
533    fn bitor(self, rhs: Self) -> Self::Output {
534        self as c_int | rhs as c_int
535    }
536}
537
538/// Options when loading a plugin.
539#[repr(C)]
540#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
541pub enum VSPluginConfigFlags {
542    /// Allow functions to be added to the plugin object after the plugin loading phase.
543    /// Mostly useful for Avisynth compatibility and other foreign plugin loaders.
544    Modifiable = 1,
545}
546
547impl std::ops::BitOr for VSPluginConfigFlags {
548    type Output = c_int;
549
550    fn bitor(self, rhs: Self) -> Self::Output {
551        self as c_int | rhs as c_int
552    }
553}
554
555/// Since the data type can contain both pure binary data and printable strings,
556/// the type also contains a hint for whether or not it is human readable.
557/// Generally the unknown type should be very rare and is almost only created
558/// as an artifact of API3 compatibility.
559#[repr(C)]
560#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
561pub enum VSDataTypeHint {
562    Unknown = -1,
563    Binary = 0,
564    Utf8 = 1,
565}
566
567/// Describes the upstream frame request pattern of a filter.
568#[repr(C)]
569#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
570pub enum VSRequestPattern {
571    /// Anything goes. Note that filters that may be requesting beyond the end of a
572    /// [`VSNode`] length in frames (repeating the last frame) should use
573    /// [`VSRequestPattern::General`]) and not any of the other modes.
574    General = 0,
575    /// Will only request an input frame at most once if all output frames are requested
576    /// exactly one time. This includes filters such as Trim, Reverse, `SelectEvery`.
577    NoFrameReuse = 1,
578    /// Only requests frame N to output frame N. The main difference to
579    /// [`VSRequestPattern::NoFrameReuse`] is that the requested frame
580    /// is always fixed and known ahead of time. Filter examples
581    /// Lut, Expr (conditionally, see [`VSRequestPattern::General`] note)
582    /// and similar.
583    StrictSpatial = 2,
584    /// Basically identical to [`VSRequestPattern::NoFrameReuse`] except that it hints
585    /// the last frame may be requested multiple times. Added in API 4.1.
586    #[cfg(feature = "vs-41")]
587    FrameReuseLastOnly = 3,
588}
589
590/// Describes how the output of a node is cached.
591#[repr(C)]
592#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
593pub enum VSCacheMode {
594    /// Cache is enabled or disabled based on the reported request patterns
595    /// and number of consumers.
596    Auto = -1,
597    /// Never cache anything.
598    ForceDisable = 0,
599    /// Always use the cache.
600    ForceEnable = 1,
601}
602
603/// Core entry point
604pub type VSGetVapourSynthAPI = unsafe extern "system-unwind" fn(version: c_int) -> *const VSAPI;
605
606// SECTION - Plugin, function and filter related
607/// User-defined function called by the core to create an instance of the filter.
608/// This function is often named `fooCreate`.
609///
610/// In this function, the filter's input parameters should be retrieved and validated,
611/// the filter's private instance data should be initialised, and
612/// [`createAudioFilter()`](VSAPI::createAudioFilter) or
613/// [`createVideoFilter()`](VSAPI::createVideoFilter) should be called.
614/// This is where the filter should perform any other initialisation it requires.
615///
616/// If for some reason you cannot create the filter, you have to free any created node references
617/// using [`freeNode()`](VSAPI::freeNode), call [`mapSetError()`](VSAPI::mapSetError) on `out`,
618/// and return.
619///
620/// # Arguments
621///
622/// * `in` - Input parameter list.
623///
624///     Use [`mapGetInt()`](VSAPI::mapGetInt) and friends to retrieve a parameter value.
625///
626///   The map is guaranteed to exist only until the filter's "init" function returns.
627///   In other words, pointers returned by [`mapGetData()`](VSAPI::mapGetData)
628///   will not be usable in the filter's "getFrame" and "free" functions.
629///
630/// * `out` - Output parameter list. [`createAudioFilter()`](VSAPI::createAudioFilter) or
631///   [`createVideoFilter()`](VSAPI::createVideoFilter) will add the output node(s)
632///   with the key named "clip", or an error, if something went wrong.
633///
634/// * `userData` - Pointer that was passed to [`registerFunction()`](VSAPI::registerFunction).
635pub type VSPublicFunction = unsafe extern "system-unwind" fn(
636    in_: *const VSMap,
637    out: *mut VSMap,
638    user_data: *mut c_void,
639    core: *mut VSCore,
640    vsapi: *const VSAPI,
641);
642/// A plugin's entry point. It must be called `VapourSynthPluginInit2`.
643/// This function is called after the core loads the shared library.
644/// Its purpose is to configure the plugin and to register the filters the plugin wants to export.
645///
646/// # Arguments
647///
648/// * `plugin` - A pointer to the plugin object to be initialized.
649/// * `vspapi` - A pointer to a [`VSPLUGINAPI`] struct with a subset of the `VapourSynth` API
650///   used for initializing plugins. The proper way to do things is to call
651///   [`configPlugin`](VSPLUGINAPI::configPlugin) and then
652///   [`registerFunction`](VSPLUGINAPI::registerFunction) for each function to export.
653pub type VSInitPlugin =
654    unsafe extern "system-unwind" fn(plugin: *mut VSPlugin, vspapi: *const VSPLUGINAPI);
655/// Free function type
656pub type VSFreeFunctionData = Option<unsafe extern "system-unwind" fn(user_data: *mut c_void)>;
657/// A filter's "getFrame" function. It is called by the core when it needs the filter
658/// to generate a frame.
659///
660/// It is possible to allocate local data, persistent during the multiple calls
661/// requesting the output frame.
662///
663/// In case of error, call [`setFilterError()`](VSAPI::setFilterError),
664/// free `*frameData` if required, and return `NULL`.
665///
666/// Depending on the [`VSFilterMode`] set for the filter, multiple output frames
667/// could be requested concurrently.
668///
669/// It is never called concurrently for the same frame number.
670///
671/// # Arguments
672///
673/// * `n` - Requested frame number.
674/// * `activationReason` - One of [`VSActivationReason`].
675///
676///   ## Note
677///
678///   This function is first called with [`VSActivationReason::Initial`].
679///   At this point the function should request the input frames it needs and return `NULL`.
680///   When one or all of the requested frames are ready, this function is called again with
681///   [`VSActivationReason::AllFramesReady`].
682///   The function should only return a frame when called with
683///   [`VSActivationReason::AllFramesReady`].
684///
685///   If a the function is called with [`VSActivationReason::Error`] all processing has
686///   to be aborted and any.
687///
688///   * `instanceData` - The filter's private instance data.
689///   * `frameData` - Optional private data associated with output frame number `n`.
690///     It must be deallocated before the last call for the given frame
691///     ([`VSActivationReason::AllFramesReady`] or error).
692///
693///   It points to a `void *[4]` array of memory that may be used freely.
694///   See filters like Splice and Trim for examples.
695///
696/// Return a reference to the output frame number n when it is ready, or `NULL`.
697/// The ownership of the frame is transferred to the caller.
698pub type VSFilterGetFrame = unsafe extern "system-unwind" fn(
699    n: c_int,
700    activation_reason: VSActivationReason,
701    instance_data: *mut c_void,
702    frame_data: *mut *mut c_void,
703    frame_ctx: *mut VSFrameContext,
704    core: *mut VSCore,
705    vsapi: *const VSAPI,
706) -> *const VSFrame;
707/// A filter's "free" function.
708///
709/// This is where the filter should free everything it allocated, including its instance data.
710//
711/// # Arguments
712///
713/// * `instanceData` - The filter's private instance data.
714pub type VSFilterFree = Option<
715    unsafe extern "system-unwind" fn(
716        instance_data: *mut c_void,
717        core: *mut VSCore,
718        vsapi: *const VSAPI,
719    ),
720>;
721// !SECTION
722
723// SECTION - Other
724/// Function of the client application called by the core when a requested frame is ready,
725/// after a call to [`getFrameAsync()`](VSAPI::getFrameAsync).
726///
727/// If multiple frames were requested, they can be returned in any order.
728/// Client applications must take care of reordering them.
729///
730/// This function is only ever called from one thread at a time.
731///
732/// [`getFrameAsync()`](VSAPI::getFrameAsync) may be called from this function to
733/// request more frames.
734///
735/// # Arguments
736///
737/// * `userData` - Pointer to private data from the client application,
738///   as passed previously to [`getFrameAsync()`](VSAPI::getFrameAsync).
739///
740/// * `f` - Contains a reference to the generated frame, or `NULL` in case of failure.
741///   The ownership of the frame is transferred to the caller.
742///
743/// * `n` - The frame number.
744///
745/// * `node` - Node the frame belongs to.
746///
747/// * `errorMsg` - String that usually contains an error message if the frame generation failed.
748///   `NULL` if there is no error.
749pub type VSFrameDoneCallback = unsafe extern "system-unwind" fn(
750    user_data: *mut c_void,
751    f: *const VSFrame,
752    n: c_int,
753    node: *mut VSNode,
754    error_msg: *const c_char,
755);
756/// # Arguments
757///
758/// * `msgType` - The type of message. One of [`VSMessageType`].
759///
760///   If `msgType` is [`VSMessageType::Fatal`]),
761///   `VapourSynth` will call `abort()` after the message handler returns.
762///
763/// * `msg` - The message.
764pub type VSLogHandler = Option<
765    unsafe extern "system-unwind" fn(msg_type: c_int, msg: *const c_char, user_data: *mut c_void),
766>;
767pub type VSLogHandlerFree = Option<unsafe extern "system-unwind" fn(user_data: *mut c_void)>;
768// !SECTION
769
770/// This struct is used to access `VapourSynth`'s API when a plugin is initially loaded.
771#[allow(non_snake_case)]
772#[repr(C)]
773pub struct VSPLUGINAPI {
774    /// See [`getAPIVersion()`](VSAPI::getAPIVersion) in the struct [`VSAPI`].
775    /// Returns [`VAPOURSYNTH_API_VERSION`] of the library
776    pub getAPIVersion: unsafe extern "system-unwind" fn() -> c_int,
777    /// Used to provide information about a plugin when loaded. Must be called exactly once from
778    /// the `VapourSynthPluginInit2()` entry point. It is recommended to use the
779    /// [`vs_make_version]` macro when providing the `pluginVersion`.
780    /// If you don't know the specific `apiVersion` you actually require simply pass
781    /// [`VAPOURSYNTH_API_VERSION`] to match the header version
782    /// you're compiling against. The flags consist of values from
783    /// [`VSPluginConfigFlags`] `ORed` together but should for most plugins typically be 0.
784    ///
785    /// Returns non-zero on success.
786    pub configPlugin: unsafe extern "system-unwind" fn(
787        identifier: *const c_char,
788        plugin_namespace: *const c_char,
789        name: *const c_char,
790        plugin_version: c_int,
791        api_version: c_int,
792        flags: c_int,
793        plugin: *mut VSPlugin,
794    ) -> c_int,
795    /// See [`registerFunction()`](VSAPI::registerFunction) in the struct [`VSAPI`],
796    ///
797    /// Returns non-zero on success.
798    pub registerFunction: unsafe extern "system-unwind" fn(
799        name: *const c_char,
800        args: *const c_char,
801        returnType: *const c_char,
802        argsFunc: VSPublicFunction,
803        functionData: *mut c_void,
804        plugin: *mut VSPlugin,
805    ) -> c_int,
806}
807
808/// Specifies the dependency of a filter on other nodes.
809#[repr(C)]
810#[derive(Eq, PartialEq, Hash, Debug)]
811pub struct VSFilterDependency {
812    /// The node frames are requested from.
813    pub source: *mut VSNode,
814    /// A value from [`VSRequestPattern`].
815    pub request_pattern: VSRequestPattern,
816}
817
818// MARK: VSAPI
819
820/// This giant struct is the way to access `VapourSynth`'s public API.
821#[allow(non_snake_case)]
822#[repr(C)]
823pub struct VSAPI {
824    // SECTION - Audio and video filter related including nodes
825    /// Creates a new video filter node.
826    ///
827    /// # Arguments
828    ///
829    /// * `out` - Output map for the filter node.
830    ///
831    /// * `name` - Instance name. Please make it the same as
832    ///   the filter's name for easy identification.
833    ///
834    /// * `vi` - The output format of the filter.
835    ///
836    /// * `getFrame` - The filter's "getFrame" function. Must not be `NULL`.
837    ///
838    /// * `free` - The filter's "free" function. Can be `NULL`.
839    ///
840    /// * `filterMode` - One of [`VSFilterMode`].
841    ///   Indicates the level of parallelism supported by the filter.
842    ///
843    /// * `dependencies` - An array of nodes the filter requests frames from
844    ///   and the access pattern. Used to more efficiently configure caches.
845    ///
846    /// * `numDeps` - Length of the dependencies array.
847    ///
848    /// * `instanceData` - A pointer to the private filter data. This pointer will be passed to
849    ///   the `getFrame` and `free` functions. It should be freed by the free function.
850    ///
851    /// After this function returns, `out` will contain the new node appended to
852    /// the "clip" property, or an error, if something went wrong.
853    pub createVideoFilter: unsafe extern "system-unwind" fn(
854        out: *mut VSMap,
855        name: *const c_char,
856        vi: *const VSVideoInfo,
857        getFrame: VSFilterGetFrame,
858        free: VSFilterFree,
859        filterMode: VSFilterMode,
860        dependencies: *const VSFilterDependency,
861        numDeps: c_int,
862        instanceData: *mut c_void,
863        core: *mut VSCore,
864    ),
865    /// Identical to [`createVideoFilter()`](Self::createVideoFilter) except that
866    /// the new node is returned instead of appended to the out map.
867    ///
868    /// Returns `NULL` on error.
869    pub createVideoFilter2: unsafe extern "system-unwind" fn(
870        name: *const c_char,
871        vi: *const VSVideoInfo,
872        getFrame: VSFilterGetFrame,
873        free: VSFilterFree,
874        filterMode: VSFilterMode,
875        dependencies: *const VSFilterDependency,
876        numDeps: c_int,
877        instanceData: *mut c_void,
878        core: *mut VSCore,
879    ) -> *mut VSNode,
880    /// Creates a new video filter node.
881    ///
882    /// # Arguments
883    ///
884    /// * `out` - Output map for the filter node.
885    ///
886    /// * `name` - Instance name. Please make it the same as
887    ///   the filter's name for easy identification.
888    ///
889    /// * `ai` - The output format of the filter.
890    ///
891    /// * `getFrame` - The filter's "getFrame" function. Must not be `NULL`.
892    ///
893    /// * `free` - The filter's "free" function. Can be `NULL`.
894    ///
895    /// * `filterMode` - One of [`VSFilterMode`].
896    ///   Indicates the level of parallelism supported by the filter.
897    ///
898    /// * `dependencies` - An array of nodes the filter requests frames from
899    ///   and the access pattern. Used to more efficiently configure caches.
900    ///
901    /// * `numDeps` - Length of the dependencies array.
902    ///
903    /// * `instanceData` - A pointer to the private filter data. This pointer will be passed to
904    ///   the `getFrame` and `free` functions. It should be freed by the free function.
905    ///
906    /// After this function returns, out will contain the new node appended to
907    /// the "clip" property, or an error, if something went wrong.
908    pub createAudioFilter: unsafe extern "system-unwind" fn(
909        out: *mut VSMap,
910        name: *const c_char,
911        ai: *const VSAudioInfo,
912        getFrame: VSFilterGetFrame,
913        free: VSFilterFree,
914        filterMode: VSFilterMode,
915        dependencies: *const VSFilterDependency,
916        numDeps: c_int,
917        instanceData: *mut c_void,
918        core: *mut VSCore,
919    ),
920    /// Identical to [`createAudioFilter()`](Self::createAudioFilter) except that
921    /// the new node is returned instead of appended to the out map.
922    ///
923    /// Returns `NULL` on error.
924    pub createAudioFilter2: unsafe extern "system-unwind" fn(
925        name: *const c_char,
926        ai: *const VSAudioInfo,
927        getFrame: VSFilterGetFrame,
928        free: VSFilterFree,
929        filterMode: VSFilterMode,
930        dependencies: *const VSFilterDependency,
931        numDeps: c_int,
932        instanceData: *mut c_void,
933        core: *mut VSCore,
934    ) -> *mut VSNode,
935    /// Must be called immediately after audio or video filter creation.
936    ///
937    /// Returns the upper bound of how many additional frames it is reasonable to pass to
938    /// [`cacheFrame()`](Self::cacheFrame) when trying to make a request more linear.
939    pub setLinearFilter: unsafe extern "system-unwind" fn(node: *mut VSNode) -> c_int,
940    /// Determines the strategy for frame caching. Pass a [`VSCacheMode`] constant.
941    /// Mostly useful for cache debugging since the auto mode should
942    /// work well in just about all cases. Calls to this function may also be silently ignored.
943    ///
944    /// Resets the cache to default options when called, discarding
945    /// [`setCacheOptions`](Self::setCacheOptions) changes.
946    pub setCacheMode: unsafe extern "system-unwind" fn(node: *mut VSNode, mode: VSCacheMode),
947    /// Call after setCacheMode or the changes will be discarded.
948    /// Sets internal details of a node's associated cache.
949    /// Calls to this function may also be silently ignored.
950    ///
951    /// # Arguments
952    ///
953    /// * `fixedSize` - Set to non-zero to make the cache always hold `maxSize` frames.
954    ///
955    /// * `maxSize` - The maximum number of frames to cache.
956    ///   Note that this value is automatically adjusted using
957    ///   an internal algorithm unless fixedSize is set.
958    ///
959    /// * `maxHistorySize` - How many frames that have been recently evicted from the cache to
960    ///   keep track off. Used to determine if growing or shrinking the cache is beneficial.
961    ///   Has no effect when `fixedSize` is set.
962    pub setCacheOptions: unsafe extern "system-unwind" fn(
963        node: *mut VSNode,
964        fixedSize: c_int,
965        maxSize: c_int,
966        maxHistorySize: c_int,
967    ),
968
969    /// Decreases the reference count of a node and destroys it once it reaches 0.
970    ///
971    /// It is safe to pass `NULL`.
972    pub freeNode: unsafe extern "system-unwind" fn(node: *mut VSNode),
973    /// Increment the reference count of a node. Returns the same node for convenience.
974    pub addNodeRef: unsafe extern "system-unwind" fn(node: *mut VSNode) -> *mut VSNode,
975    /// Returns [`VSMediaType`]. Used to determine if a node is of audio or video type.
976    pub getNodeType: unsafe extern "system-unwind" fn(node: *mut VSNode) -> VSMediaType,
977    /// Returns a pointer to the video info associated with a node.
978    /// The pointer is valid as long as the node lives.
979    /// It is undefined behavior to pass a non-video node.
980    pub getVideoInfo: unsafe extern "system-unwind" fn(node: *mut VSNode) -> *const VSVideoInfo,
981    /// Returns a pointer to the audio info associated with a node.
982    /// The pointer is valid as long as the node lives.
983    /// It is undefined behavior to pass a non-audio node.
984    pub getAudioInfo: unsafe extern "system-unwind" fn(node: *mut VSNode) -> *const VSAudioInfo,
985    // !SECTION
986
987    // SECTION - Frame related functions
988    /// Creates a new video frame, optionally copying the properties attached to another frame.
989    /// It is a fatal error to pass invalid arguments to this function.
990    ///
991    /// The new frame contains uninitialised memory.
992    ///
993    /// # Arguments
994    ///
995    /// * `format` - The desired colorspace format. Must not be `NULL`.
996    ///
997    /// * `width` -
998    /// * `height` - The desired dimensions of the frame, in pixels.
999    ///   Must be greater than 0 and have a suitable multiple for the subsampling in format.
1000    ///
1001    /// * `propSrc` - A frame from which properties will be copied. Can be `NULL`.
1002    ///
1003    /// Returns a pointer to the created frame.
1004    /// Ownership of the new frame is transferred to the caller.
1005    ///
1006    /// See also [`newVideoFrame2()`](Self::newVideoFrame2).
1007    pub newVideoFrame: unsafe extern "system-unwind" fn(
1008        format: *const VSVideoFormat,
1009        width: c_int,
1010        height: c_int,
1011        propSrc: *const VSFrame,
1012        core: *mut VSCore,
1013    ) -> *mut VSFrame,
1014    /// Creates a new video frame, optionally copying the properties attached to another frame.
1015    /// It is a fatal error to pass invalid arguments to this function.
1016    ///
1017    /// The new frame contains uninitialised memory.
1018    ///
1019    /// # Arguments
1020    ///
1021    /// * `format` - The desired colorspace format. Must not be `NULL`.
1022    ///
1023    /// * `width` -
1024    /// * `height` - The desired dimensions of the frame, in pixels.
1025    ///   Must be greater than 0 and have a suitable multiple for the subsampling in format.
1026    ///
1027    /// * `planeSrc` - Array of frames from which planes will be copied.
1028    ///   If any elements of the array are `NULL`, the corresponding planes in the new frame
1029    ///   will contain uninitialised memory.
1030    ///
1031    /// * `planes` - Array of plane numbers indicating which plane to copy from
1032    ///   the corresponding source frame.
1033    ///
1034    /// * `propSrc` - A frame from which properties will be copied. Can be `NULL`.
1035    ///
1036    /// Returns a pointer to the created frame.
1037    /// Ownership of the new frame is transferred to the caller.
1038    ///
1039    /// # Example
1040    ///
1041    /// (assume frameA, frameB, frameC are existing frames):
1042    ///
1043    /// ```c
1044    /// const VSFrame * frames[3] = { frameA, frameB, frameC };
1045    /// const int planes[3] = { 1, 0, 2 };
1046    /// VSFrame *newFrame = vsapi->newVideoFrame2(f, w, h, frames, planes, frameB, core);
1047    /// ```
1048    ///
1049    /// The newFrame's first plane is now a copy of frameA's second plane,
1050    /// the second plane is a copy of frameB's first plane,
1051    /// the third plane is a copy of frameC's third plane
1052    /// and the properties have been copied from frameB.
1053    pub newVideoFrame2: unsafe extern "system-unwind" fn(
1054        format: *const VSVideoFormat,
1055        width: c_int,
1056        height: c_int,
1057        planeSrc: *const *const VSFrame,
1058        planes: *const c_int,
1059        propSrc: *const VSFrame,
1060        core: *mut VSCore,
1061    ) -> *mut VSFrame,
1062    /// Creates a new audio frame, optionally copying the properties attached to another frame.
1063    /// It is a fatal error to pass invalid arguments to this function.
1064    ///
1065    /// The new frame contains uninitialised memory.
1066    ///
1067    /// # Arguments
1068    ///
1069    /// * `format` - The desired audio format. Must not be `NULL`.
1070    ///
1071    /// * `numSamples` - The number of samples in the frame. All audio frames apart from
1072    ///   the last one returned by a filter must have [`VS_AUDIO_FRAME_SAMPLES`].
1073    ///
1074    /// * `propSrc` - A frame from which properties will be copied. Can be `NULL`.
1075    ///
1076    /// Returns a pointer to the created frame.
1077    /// Ownership of the new frame is transferred to the caller.
1078    ///
1079    /// See also [`newAudioFrame2()`](Self::newAudioFrame2).
1080    pub newAudioFrame: unsafe extern "system-unwind" fn(
1081        format: *const VSAudioFormat,
1082        numSamples: c_int,
1083        propSrc: *const VSFrame,
1084        core: *mut VSCore,
1085    ) -> *mut VSFrame,
1086    /// Creates a new audio frame, optionally copying the properties attached to another frame.
1087    /// It is a fatal error to pass invalid arguments to this function.
1088    ///
1089    /// The new frame contains uninitialised memory.
1090    ///
1091    /// # Arguments
1092    ///
1093    /// * `format` - The desired audio format. Must not be `NULL`.
1094    ///
1095    /// * `numSamples` - The number of samples in the frame. All audio frames apart from
1096    ///   the last one returned by a filter must have [`VS_AUDIO_FRAME_SAMPLES`].
1097    ///
1098    /// * `propSrc` - A frame from which properties will be copied. Can be `NULL`.
1099    ///
1100    /// * `channelSrc` - Array of frames from which channels will be copied.
1101    ///   If any elements of the array are `NULL`, the corresponding planes in
1102    ///   the new frame will contain uninitialised memory.
1103    ///
1104    /// * `channels` - Array of channel numbers indicating which channel to copy from
1105    ///   the corresponding source frame.
1106    ///   Note that the number refers to the nth channel and not a channel name constant.
1107    ///
1108    /// Returns a pointer to the created frame.
1109    /// Ownership of the new frame is transferred to the caller.
1110    pub newAudioFrame2: unsafe extern "system-unwind" fn(
1111        format: *const VSAudioFormat,
1112        numSamples: c_int,
1113        channelSrc: *const *const VSFrame,
1114        channels: *const c_int,
1115        propSrc: *const VSFrame,
1116        core: *mut VSCore,
1117    ) -> *mut VSFrame,
1118    /// Decrements the reference count of a frame and deletes it when it reaches 0.
1119    ///
1120    /// It is safe to pass `NULL`.
1121    pub freeFrame: unsafe extern "system-unwind" fn(f: *const VSFrame),
1122    /// Increments the reference count of a frame. Returns f as a convenience.
1123    pub addFrameRef: unsafe extern "system-unwind" fn(f: *const VSFrame) -> *mut VSFrame,
1124    /// Duplicates the frame (not just the reference). As the frame buffer is shared in
1125    /// a copy-on-write fashion, the frame content is not really duplicated until
1126    /// a write operation occurs. This is transparent for the user.
1127    ///
1128    /// Returns a pointer to the new frame. Ownership is transferred to the caller.
1129    pub copyFrame:
1130        unsafe extern "system-unwind" fn(f: *const VSFrame, core: *mut VSCore) -> *mut VSFrame,
1131    /// Returns a read-only pointer to a frame's properties.
1132    /// The pointer is valid as long as the frame lives.
1133    pub getFramePropertiesRO: unsafe extern "system-unwind" fn(f: *const VSFrame) -> *const VSMap,
1134    /// Returns a read/write pointer to a frame's properties.
1135    /// The pointer is valid as long as the frame lives.
1136    pub getFramePropertiesRW: unsafe extern "system-unwind" fn(f: *mut VSFrame) -> *mut VSMap,
1137
1138    /// Returns the distance in bytes between two consecutive lines of a plane of a video frame.
1139    /// The stride is always positive.
1140    ///
1141    /// Returns 0 if the requested plane doesn't exist or if it isn't a video frame.
1142    pub getStride: unsafe extern "system-unwind" fn(f: *const VSFrame, plane: c_int) -> isize,
1143    /// Returns a read-only pointer to a plane or channel of a frame.
1144    /// Returns `NULL` if an invalid plane or channel number is passed.
1145    ///
1146    /// # Note
1147    ///
1148    /// Don't assume all three planes of a frame are allocated
1149    /// in one contiguous chunk (they're not).
1150    pub getReadPtr: unsafe extern "system-unwind" fn(f: *const VSFrame, plane: c_int) -> *const u8,
1151    /// Returns a read-write pointer to a plane or channel of a frame.
1152    /// Returns `NULL` if an invalid plane or channel number is passed.
1153    ///
1154    /// # Note
1155    ///
1156    /// Don't assume all three planes of a frame are allocated
1157    /// in one contiguous chunk (they're not).
1158    pub getWritePtr: unsafe extern "system-unwind" fn(f: *mut VSFrame, plane: c_int) -> *mut u8,
1159
1160    /// Retrieves the format of a video frame.
1161    pub getVideoFrameFormat:
1162        unsafe extern "system-unwind" fn(f: *const VSFrame) -> *const VSVideoFormat,
1163    /// Retrieves the format of an audio frame.
1164    pub getAudioFrameFormat:
1165        unsafe extern "system-unwind" fn(f: *const VSFrame) -> *const VSAudioFormat,
1166    /// Returns a value from [`VSMediaType`] to distinguish audio and video frames.
1167    pub getFrameType: unsafe extern "system-unwind" fn(f: *const VSFrame) -> VSMediaType,
1168    /// Returns the width of a plane of a given video frame, in pixels.
1169    /// The width depends on the plane number because of the possible chroma subsampling.
1170    ///
1171    /// Returns 0 for audio frames.
1172    pub getFrameWidth: unsafe extern "system-unwind" fn(f: *const VSFrame, plane: c_int) -> c_int,
1173    /// Returns the height of a plane of a given video frame, in pixels.
1174    /// The height depends on the plane number because of the possible chroma subsampling.
1175    ///
1176    /// Returns 0 for audio frames.
1177    pub getFrameHeight: unsafe extern "system-unwind" fn(f: *const VSFrame, plane: c_int) -> c_int,
1178    /// Returns the number of audio samples in a frame. Always returns 1 for video frames.
1179    pub getFrameLength: unsafe extern "system-unwind" fn(f: *const VSFrame) -> c_int,
1180    // !SECTION
1181
1182    // SECTION - General format functions
1183    /// Tries to output a fairly human-readable name of a video format.
1184    ///
1185    /// # Arguments
1186    ///
1187    /// * `format` - The input video format.
1188    /// * `buffer` - Destination buffer. At most 32 bytes including
1189    ///   terminating `NUL` will be written.
1190    ///
1191    /// Returns non-zero on success.
1192    pub getVideoFormatName: unsafe extern "system-unwind" fn(
1193        format: *const VSVideoFormat,
1194        buffer: *mut c_char,
1195    ) -> c_int,
1196    /// Tries to output a fairly human-readable name of an audio format.
1197    ///
1198    /// # Arguments
1199    ///
1200    /// * `format` - The input audio format.
1201    /// * `buffer` - Destination buffer. At most 32 bytes including
1202    ///   terminating `NUL` will be written.
1203    ///
1204    /// Returns non-zero on success.
1205    pub getAudioFormatName: unsafe extern "system-unwind" fn(
1206        format: *const VSAudioFormat,
1207        buffer: *mut c_char,
1208    ) -> c_int,
1209    /// Fills out a \[_sic_\] [`VSVideoInfo`] struct based on the provided arguments.
1210    /// Validates the arguments before filling out format.
1211    ///
1212    /// # Arguments
1213    ///
1214    /// * `format` - The struct to fill out.
1215    /// * `colorFamily` - One of [`VSColorFamily`].
1216    /// * `sampleType` - One of [`VSSampleType`].
1217    /// * `bitsPerSample` - Number of meaningful bits for a single component.
1218    ///   The valid range is 8-32.
1219    ///
1220    ///     For floating point formats only 16 or 32 bits are allowed.
1221    /// * `subSamplingW` - log2 of the horizontal chroma subsampling.
1222    ///   0 == no subsampling. The valid range is 0-4.
1223    /// * `subSamplingH` - log2 of the vertical chroma subsampling.
1224    ///   0 == no subsampling. The valid range is 0-4.
1225    ///
1226    ///     ## Note
1227    ///
1228    ///     RGB formats are not allowed to be subsampled in `VapourSynth`.
1229    ///
1230    /// Returns non-zero on success.
1231    pub queryVideoFormat: unsafe extern "system-unwind" fn(
1232        format: *mut VSVideoFormat,
1233        colorFamily: VSColorFamily,
1234        sampleType: VSSampleType,
1235        bitsPerSample: c_int,
1236        subSamplingW: c_int,
1237        subSamplingH: c_int,
1238        core: *mut VSCore,
1239    ) -> c_int,
1240    /// Fills out a [`VSAudioFormat`] struct based on the provided arguments.
1241    /// Validates the arguments before filling out format.
1242    ///
1243    /// # Arguments
1244    ///
1245    /// * `format` - The struct to fill out.
1246    ///
1247    /// * `sampleType` - One of [`VSSampleType`].
1248    ///
1249    /// * `bitsPerSample` - Number of meaningful bits for a single component.
1250    ///   The valid range is 8-32.
1251    ///
1252    ///     For floating point formats only 32 bits are allowed.
1253    ///
1254    /// * `channelLayout` - A bitmask constructed from bitshifted constants in
1255    ///   [`VSAudioChannels`]. For example stereo is expressed as
1256    ///   `(1 << acFrontLeft) | (1 << acFrontRight)`.
1257    ///
1258    /// Returns non-zero on success.
1259    pub queryAudioFormat: unsafe extern "system-unwind" fn(
1260        format: *mut VSAudioFormat,
1261        sampleType: VSSampleType,
1262        bitsPerSample: c_int,
1263        channelLayout: u64,
1264        core: *mut VSCore,
1265    ) -> c_int,
1266    /// Get the id associated with a video format. Similar to
1267    /// [`queryVideoFormat()`](Self::queryVideoFormat) except that it returns a format id
1268    /// instead of filling out a [`VSVideoInfo`] struct.
1269    ///
1270    /// # Arguments
1271    ///
1272    /// * `colorFamily` - One of [`VSColorFamily`].
1273    ///
1274    /// * `sampleType` - One of [`VSSampleType`].
1275    ///
1276    /// * `bitsPerSample` - Number of meaningful bits for a single component.
1277    ///   The valid range is 8-32.
1278    ///
1279    ///     For floating point formats only 16 or 32 bits are allowed.
1280    ///
1281    /// * `subSamplingW` - log2 of the horizontal chroma subsampling.
1282    ///   0 == no subsampling. The valid range is 0-4.
1283    ///
1284    /// * `subSamplingH` - log2 of the vertical chroma subsampling.
1285    ///   0 == no subsampling. The valid range is 0-4.
1286    ///
1287    ///     ## Note
1288    ///
1289    ///     RGB formats are not allowed to be subsampled in `VapourSynth`.
1290    ///
1291    /// Returns a valid format id if the provided arguments are valid, on error 0 is returned.
1292    pub queryVideoFormatID: unsafe extern "system-unwind" fn(
1293        colorFamily: VSColorFamily,
1294        sampleType: VSSampleType,
1295        bitsPerSample: c_int,
1296        subSamplingW: c_int,
1297        subSamplingH: c_int,
1298        core: *mut VSCore,
1299    ) -> u32,
1300    /// Fills out the `VSVideoFormat` struct passed to format based
1301    ///
1302    /// # Arguments
1303    ///
1304    /// * `format` - The struct to fill out.
1305    ///
1306    /// * `id` - The format identifier: one of [`VSPresetVideoFormat`]
1307    ///   or a value gotten from [`queryVideoFormatID()`](Self::queryVideoFormatID).
1308    ///
1309    /// Returns 0 on failure and non-zero on success.
1310    pub getVideoFormatByID: unsafe extern "system-unwind" fn(
1311        format: *mut VSVideoFormat,
1312        id: u32,
1313        core: *mut VSCore,
1314    ) -> c_int,
1315    // !SECTION
1316
1317    // SECTION - Frame request and filter getFrame functions
1318    /// Fetches a frame synchronously. The frame is available when the function returns.
1319    ///
1320    /// This function is meant for external applications using the core as a library,
1321    /// or if frame requests are necessary during a filter's initialization.
1322    ///
1323    /// Thread-safe.
1324    ///
1325    /// # Arguments
1326    ///
1327    /// * `n` - The frame number. Negative values will cause an error.
1328    ///
1329    /// * `node` - The node from which the frame is requested.
1330    ///
1331    /// * `errorMsg` - Pointer to a buffer of `bufSize` bytes to store a possible error message.
1332    ///   Can be `NULL` if no error message is wanted.
1333    ///
1334    /// * `bufSize` - Maximum length for the error message, in bytes (including the trailing '0').
1335    ///   Can be 0 if no error message is wanted.
1336    ///
1337    /// Returns a reference to the generated frame, or `NULL` in case of failure.
1338    /// The ownership of the frame is transferred to the caller.
1339    ///
1340    /// # Warning
1341    ///
1342    /// Never use inside a filter's "getFrame" function.
1343    pub getFrame: unsafe extern "system-unwind" fn(
1344        n: c_int,
1345        node: *mut VSNode,
1346        errorMsg: *mut c_char,
1347        bufSize: c_int,
1348    ) -> *const VSFrame,
1349    /// Requests the generation of a frame. When the frame is ready,
1350    /// a user-provided function is called.
1351    /// Note that the completion callback will only be called from a single thread at a time.
1352    ///
1353    /// This function is meant for applications using `VapourSynth` as a library.
1354    ///
1355    /// Thread-safe.
1356    ///
1357    /// # Arguments
1358    ///
1359    /// * `n` - Frame number. Negative values will cause an error.
1360    ///
1361    /// * `node` - The node from which the frame is requested.
1362    ///
1363    /// * `callback` - See [`VSFrameDoneCallback`].
1364    ///
1365    /// * `userData` - Pointer passed to the callback.
1366    ///
1367    /// # Warning
1368    ///
1369    /// Never use inside a filter's "getFrame" function.
1370    pub getFrameAsync: unsafe extern "system-unwind" fn(
1371        n: c_int,
1372        node: *mut VSNode,
1373        callback: VSFrameDoneCallback,
1374        userData: *mut c_void,
1375    ),
1376    /// Retrieves a frame that was previously requested with
1377    /// [`requestFrameFilter()`](Self::requestFrameFilter).
1378    ///
1379    /// Only use inside a filter's "getFrame" function.
1380    ///
1381    /// A filter usually calls this function when its activation reason is
1382    /// [`VSActivationReason::AllFramesReady`].
1383    /// See [`VSActivationReason`].
1384    ///
1385    /// It is safe to retrieve a frame more than once, but each reference needs to be freed.
1386    ///
1387    /// # Arguments
1388    ///
1389    /// * `n` - The frame number.
1390    ///
1391    /// * `node` - The node from which the frame is retrieved.
1392    ///
1393    /// * `frameCtx` - The context passed to the filter's "getFrame" function.
1394    ///
1395    /// Returns a pointer to the requested frame, or `NULL` if the requested frame is
1396    /// not available for any reason. The ownership of the frame is transferred to the caller.
1397    pub getFrameFilter: unsafe extern "system-unwind" fn(
1398        n: c_int,
1399        node: *mut VSNode,
1400        frameCtx: *mut VSFrameContext,
1401    ) -> *const VSFrame,
1402    /// Requests a frame from a node and returns immediately.
1403    ///
1404    /// Only use inside a filter's "getFrame" function.
1405    ///
1406    /// A filter usually calls this function when its activation reason is arInitial.
1407    /// The requested frame can then be retrieved using
1408    /// [`getFrameFilter()`](Self::getFrameFilter), when the filter's activation reason is
1409    /// [`VSActivationReason::AllFramesReady`].
1410    ///
1411    /// It is best to request frames in ascending order, i.e. n, n+1, n+2, etc.
1412    ///
1413    /// # Arguments
1414    ///
1415    /// * `n` - The frame number. Negative values will cause an error.
1416    ///
1417    /// * `node` - The node from which the frame is requested.
1418    ///
1419    /// * `frameCtx` - The context passed to the filter's "getFrame" function.
1420    pub requestFrameFilter: unsafe extern "system-unwind" fn(
1421        n: c_int,
1422        node: *mut VSNode,
1423        frameCtx: *mut VSFrameContext,
1424    ),
1425    /// By default all requested frames are referenced until a filter's frame request is done.
1426    /// In extreme cases where a filter needs to reduce 20+ frames into a single output frame
1427    /// it may be beneficial to request these in batches
1428    /// and incrementally process the data instead.
1429    ///
1430    /// Should rarely be needed.
1431    ///
1432    /// Only use inside a filter's "getFrame" function.
1433    ///
1434    /// # Arguments
1435    ///
1436    /// * `n` - The frame number. Negative values will cause an error.
1437    ///
1438    /// * `node` - The node from which the frame is requested.
1439    ///
1440    /// * `frameCtx` - The context passed to the filter's "getFrame" function.
1441    pub releaseFrameEarly: unsafe extern "system-unwind" fn(
1442        node: *mut VSNode,
1443        n: c_int,
1444        frameCtx: *mut VSFrameContext,
1445    ),
1446    /// Pushes a not requested frame into the cache. This is useful for (source) filters
1447    /// that greatly benefit from completely linear access
1448    /// and producing all output in linear order.
1449    ///
1450    /// This function may only be used in filters that were created with
1451    /// [`setLinearFilter`](Self::setLinearFilter).
1452    ///
1453    /// Only use inside a filter's "getFrame" function.
1454    pub cacheFrame: unsafe extern "system-unwind" fn(
1455        frame: *const VSFrame,
1456        n: c_int,
1457        frameCtx: *mut VSFrameContext,
1458    ),
1459    /// Adds an error message to a frame context, replacing the existing message, if any.
1460    ///
1461    /// This is the way to report errors in a filter's "getFrame" function.
1462    /// Such errors are not necessarily fatal, i.e. the caller can try to
1463    /// request the same frame again.
1464    pub setFilterError: unsafe extern "system-unwind" fn(
1465        errorMessage: *const c_char,
1466        frameCtx: *mut VSFrameContext,
1467    ),
1468    // !SECTION
1469
1470    // SECTION - External functions
1471    /// # Arguments
1472    ///
1473    /// * `func` - User-defined function that may be called in any context.
1474    ///
1475    /// * `userData` - Pointer passed to `func`.
1476    ///
1477    /// * `free` - Callback tasked with freeing userData. Can be `NULL`.
1478    pub createFunction: unsafe extern "system-unwind" fn(
1479        func: VSPublicFunction,
1480        userData: *mut c_void,
1481        free: VSFreeFunctionData,
1482        core: *mut VSCore,
1483    ) -> *mut VSFunction,
1484    /// Decrements the reference count of a function and deletes it when it reaches 0.
1485    ///
1486    /// It is safe to pass `NULL`.
1487    pub freeFunction: unsafe extern "system-unwind" fn(f: *mut VSFunction),
1488    /// Increments the reference count of a function. Returns f as a convenience.
1489    pub addFunctionRef: unsafe extern "system-unwind" fn(f: *mut VSFunction) -> *mut VSFunction,
1490    /// Calls a function. If the call fails out will have an error set.
1491    ///
1492    /// # Arguments
1493    ///
1494    /// * `func` - Function to be called.
1495    ///
1496    /// * `in_` - Arguments passed to `func`.
1497    ///
1498    /// * `out` - Returned values from `func`.
1499    pub callFunction:
1500        unsafe extern "system-unwind" fn(func: *mut VSFunction, in_: *const VSMap, out: *mut VSMap),
1501    // !SECTION
1502
1503    // SECTION - Map and property access functions
1504    /// Creates a new property map. It must be deallocated later with [`freeMap()`](Self::freeMap).
1505    pub createMap: unsafe extern "system-unwind" fn() -> *mut VSMap,
1506    /// Frees a map and all the objects it contains.
1507    pub freeMap: unsafe extern "system-unwind" fn(map: *mut VSMap),
1508    /// Deletes all the keys and their associated values from the map, leaving it empty.
1509    pub clearMap: unsafe extern "system-unwind" fn(map: *mut VSMap),
1510    /// copies all values in src to dst, if a key already exists in dst it's replaced
1511    pub copyMap: unsafe extern "system-unwind" fn(src: *const VSMap, dst: *mut VSMap),
1512
1513    /// Adds an error message to a map. The map is cleared first.
1514    /// The error message is copied. In this state the map may only be freed,
1515    /// cleared or queried for the error message.
1516    ///
1517    /// For errors encountered in a filter's "getFrame" function, use
1518    /// [`setFilterError()`](Self::setFilterError).
1519    pub mapSetError: unsafe extern "system-unwind" fn(map: *mut VSMap, errorMessage: *const c_char),
1520    /// Returns a pointer to the error message contained in the map,
1521    /// or `NULL` if there is no error set. The pointer is valid until
1522    /// the next modifying operation on the map.
1523    pub mapGetError: unsafe extern "system-unwind" fn(map: *const VSMap) -> *const c_char,
1524
1525    /// Returns the number of keys contained in a property map.
1526    pub mapNumKeys: unsafe extern "system-unwind" fn(map: *const VSMap) -> c_int,
1527    /// Returns the nth key from a property map.
1528    ///
1529    /// Passing an invalid index will cause a fatal error.
1530    ///
1531    /// The pointer is valid as long as the key exists in the map.
1532    pub mapGetKey:
1533        unsafe extern "system-unwind" fn(map: *const VSMap, index: c_int) -> *const c_char,
1534    /// Removes the property with the given key. All values associated with the key are lost.
1535    ///
1536    /// Returns 0 if the key isn't in the map. Otherwise it returns 1.
1537    pub mapDeleteKey:
1538        unsafe extern "system-unwind" fn(map: *mut VSMap, key: *const c_char) -> c_int,
1539    /// Returns the number of elements associated with a key in a property map.
1540    ///
1541    /// Returns -1 if there is no such key in the map.
1542    pub mapNumElements:
1543        unsafe extern "system-unwind" fn(map: *const VSMap, key: *const c_char) -> c_int,
1544    /// Returns a value from [`VSPropertyType`] representing type of elements in the given key.
1545    /// If there is no such key in the map, the returned value is
1546    /// [`VSPropertyType::Unset`]).
1547    /// Note that also empty arrays created with mapSetEmpty are typed.
1548    pub mapGetType:
1549        unsafe extern "system-unwind" fn(map: *const VSMap, key: *const c_char) -> VSPropertyType,
1550    /// Creates an empty array of type in key.
1551    ///
1552    /// Returns non-zero value on failure due to key already existing or having an invalid name.
1553    pub mapSetEmpty: unsafe extern "system-unwind" fn(
1554        map: *mut VSMap,
1555        key: *const c_char,
1556        type_: VSPropertyType,
1557    ) -> c_int,
1558
1559    /// Retrieves an integer from a specified key in a map.
1560    ///
1561    /// Returns the number on success, or 0 in case of error.
1562    ///
1563    /// If the map has an error set (i.e. if [`mapGetError()`](VSAPI::mapGetError)
1564    /// returns non-`NULL`), `VapourSynth` will die with a fatal error.
1565    ///
1566    /// # Arguments
1567    ///
1568    /// * `index` - Zero-based index of the element.
1569    ///
1570    ///     Use [`mapNumElements()`](Self::mapNumElements) to know the total number of elements
1571    ///   associated with a key.
1572    ///
1573    /// * `error` - One of [`VSMapPropertyError`], [`VSMapPropertyError::Success`]
1574    ///   on success.
1575    ///
1576    ///     You may pass `NULL` here, but then any problems encountered while retrieving
1577    ///   the property will cause `VapourSynth` to die with a fatal error.
1578    pub mapGetInt: unsafe extern "system-unwind" fn(
1579        map: *const VSMap,
1580        key: *const c_char,
1581        index: c_int,
1582        error: *mut VSMapPropertyError,
1583    ) -> i64,
1584    /// Works just like [`mapGetInt()`](Self::mapGetInt) except that the value returned is
1585    /// also converted to an integer using saturation.
1586    pub mapGetIntSaturated: unsafe extern "system-unwind" fn(
1587        map: *const VSMap,
1588        key: *const c_char,
1589        index: c_int,
1590        error: *mut VSMapPropertyError,
1591    ) -> c_int,
1592    /// Retrieves an array of integers from a map. Use this function if there are a lot of numbers
1593    /// associated with a key, because it is faster than calling
1594    /// [`mapGetInt()`](Self::mapGetInt) in a loop.
1595    ///
1596    /// Returns a pointer to the first element of the array on success,
1597    /// or `NULL` in case of error. Use [`mapNumElements()`](Self::mapNumElements) to
1598    /// know the total number of elements associated with a key.
1599    ///
1600    /// See [`mapGetInt()`](Self::mapGetInt) for a complete description of
1601    /// the arguments and general behavior.
1602    pub mapGetIntArray: unsafe extern "system-unwind" fn(
1603        map: *const VSMap,
1604        key: *const c_char,
1605        error: *mut VSMapPropertyError,
1606    ) -> *const i64,
1607    /// Sets an integer to the specified key in a map.
1608    ///
1609    /// Multiple values can be associated with one key, but they must all be the same type.
1610    ///
1611    /// # Arguments
1612    ///
1613    /// * `key` - Name of the property. Alphanumeric characters and underscore may be used.
1614    ///
1615    /// * `i` - Value to store.
1616    ///
1617    /// * `append` - One of [`VSMapAppendMode`].
1618    ///
1619    /// Returns 0 on success, or 1 if trying to append to
1620    /// a property with the wrong type to an existing key.
1621    pub mapSetInt: unsafe extern "system-unwind" fn(
1622        map: *mut VSMap,
1623        key: *const c_char,
1624        i: i64,
1625        append: VSMapAppendMode,
1626    ) -> c_int,
1627    /// Adds an array of integers to a map. Use this function if there are a lot of numbers
1628    /// to add because it is faster than calling [`mapSetInt()`](Self::mapSetInt) in a loop.
1629    ///
1630    /// If map already contains a property with this key, that property will be overwritten and
1631    /// all old values will be lost.
1632    ///
1633    /// # Arguments
1634    ///
1635    /// * `key` - Name of the property. Alphanumeric characters and underscore may be used.
1636    ///
1637    /// * `i` - Pointer to the first element of the array to store.
1638    ///
1639    /// * `size` - Number of integers to read from the array. It can be 0, in which case
1640    ///   no integers are read from the array, and the property will be created empty.
1641    ///
1642    /// Returns 0 on success, or 1 if size is negative.
1643    pub mapSetIntArray: unsafe extern "system-unwind" fn(
1644        map: *mut VSMap,
1645        key: *const c_char,
1646        i: *const i64,
1647        size: c_int,
1648    ) -> c_int,
1649
1650    /// Retrieves a floating point number from a map.
1651    ///
1652    /// Returns the number on success, or 0 in case of error.
1653    ///
1654    /// See [`mapGetInt()`](Self::mapGetInt) for a complete description of
1655    /// the arguments and general behavior.
1656    pub mapGetFloat: unsafe extern "system-unwind" fn(
1657        map: *const VSMap,
1658        key: *const c_char,
1659        index: c_int,
1660        error: *mut VSMapPropertyError,
1661    ) -> c_double,
1662    /// Works just like [`mapGetFloat()`](Self::mapGetFloat) except that the value returned
1663    /// is also converted to a float.
1664    pub mapGetFloatSaturated: unsafe extern "system-unwind" fn(
1665        map: *const VSMap,
1666        key: *const c_char,
1667        index: c_int,
1668        error: *mut VSMapPropertyError,
1669    ) -> c_float,
1670    /// Retrieves an array of floating point numbers from a map. Use this function if there are
1671    /// a lot of numbers associated with a key, because it is faster than calling
1672    /// [`mapGetFloat()`](Self::mapGetFloat) in a loop.
1673    ///
1674    /// Returns a pointer to the first element of the array on success,
1675    /// or `NULL` in case of error. Use [`mapNumElements()`](Self::mapNumElements) to
1676    /// know the total number of elements associated with a key.
1677    ///
1678    /// See [`mapGetInt()`](Self::mapGetInt) for a complete description of
1679    /// the arguments and general behavior.
1680    pub mapGetFloatArray: unsafe extern "system-unwind" fn(
1681        map: *const VSMap,
1682        key: *const c_char,
1683        error: *mut VSMapPropertyError,
1684    ) -> *const c_double,
1685    /// Sets a float to the specified key in a map.
1686    ///
1687    /// See [`mapSetInt()`](Self::mapSetInt) for a complete description of
1688    /// the arguments and general behavior.
1689    pub mapSetFloat: unsafe extern "system-unwind" fn(
1690        map: *mut VSMap,
1691        key: *const c_char,
1692        d: c_double,
1693        append: VSMapAppendMode,
1694    ) -> c_int,
1695    /// Adds an array of floating point numbers to a map. Use this function if there are
1696    /// a lot of numbers to add, because it is faster than calling
1697    /// [`mapSetFloat()`](Self::mapSetFloat) in a loop.
1698    ///
1699    /// If map already contains a property with this key, that property will be overwritten and
1700    /// all old values will be lost.
1701    ///
1702    /// # Arguments
1703    ///
1704    /// * `key` - Name of the property. Alphanumeric characters and underscore may be used.
1705    ///
1706    /// * `d` - Pointer to the first element of the array to store.
1707    ///
1708    /// * `size` - Number of floating point numbers to read from the array. It can be 0,
1709    ///   in which case no numbers are read from the array,
1710    ///   and the property will be created empty.
1711    ///
1712    /// Returns 0 on success, or 1 if size is negative.
1713    pub mapSetFloatArray: unsafe extern "system-unwind" fn(
1714        map: *mut VSMap,
1715        key: *const c_char,
1716        d: *const c_double,
1717        size: c_int,
1718    ) -> c_int,
1719
1720    /// Retrieves arbitrary binary data from a map. Checking
1721    /// [`mapGetDataTypeHint()`](Self::mapGetDataTypeHint) may provide a hint about
1722    /// whether or not the data is human readable.
1723    ///
1724    /// Returns a pointer to the data on success, or `NULL` in case of error.
1725    ///
1726    /// The array returned is guaranteed to be `NULL`-terminated.
1727    /// The `NULL` byte is not considered to be part of the array
1728    /// ([`mapGetDataSize`](Self::mapGetDataSize) doesn't count it).
1729    ///
1730    /// The pointer is valid until the map is destroyed, or until the corresponding key
1731    /// is removed from the map or altered.
1732    ///
1733    /// See [`mapGetInt()`](Self::mapGetInt) for a complete description of
1734    /// the arguments and general behavior.
1735    pub mapGetData: unsafe extern "system-unwind" fn(
1736        map: *const VSMap,
1737        key: *const c_char,
1738        index: c_int,
1739        error: *mut VSMapPropertyError,
1740    ) -> *const c_char,
1741    /// Returns the size in bytes of a property of type ptData (see [`VSPropertyType`]),
1742    /// or 0 in case of error. The terminating `NULL` byte added by
1743    /// [`mapSetData()`](Self::mapSetData) is not counted.
1744    ///
1745    /// See [`mapGetInt()`](Self::mapGetInt) for a complete description of
1746    /// the arguments and general behavior.
1747    pub mapGetDataSize: unsafe extern "system-unwind" fn(
1748        map: *const VSMap,
1749        key: *const c_char,
1750        index: c_int,
1751        error: *mut VSMapPropertyError,
1752    ) -> c_int,
1753    /// Returns the size in bytes of a property of type ptData (see [`VSPropertyType`]),
1754    /// or 0 in case of error. The terminating `NULL` byte added by
1755    /// [`mapSetData()`](Self::mapSetData) is not counted.
1756    ///
1757    /// See [`mapGetInt()`](Self::mapGetInt) for a complete description of
1758    /// the arguments and general behavior.
1759    pub mapGetDataTypeHint: unsafe extern "system-unwind" fn(
1760        map: *const VSMap,
1761        key: *const c_char,
1762        index: c_int,
1763        error: *mut VSMapPropertyError,
1764    ) -> VSDataTypeHint,
1765    /// Sets binary data to the specified key in a map.
1766    ///
1767    /// Multiple values can be associated with one key, but they must all be the same type.
1768    ///
1769    /// # Arguments
1770    ///
1771    /// * `key` - Name of the property. Alphanumeric characters and the underscore may be used.
1772    ///
1773    /// * `data` - Value to store.
1774    ///
1775    ///     This function copies the data, so the pointer should be freed when no longer needed.
1776    ///   A terminating `NULL` is always added to the copied data but not included in
1777    ///   the total size to make string handling easier.
1778    ///
1779    /// * `size` - The number of bytes to copy. If this is negative,
1780    ///   everything up to the first `NULL` byte will be copied.
1781    ///
1782    /// * `type` - One of [`VSDataTypeHint`] to hint whether or not it is human readable data.
1783    ///
1784    /// * `append` - One of [`VSMapAppendMode`].
1785    ///
1786    /// Returns 0 on success, or 1 if trying to append to a property with the wrong type.
1787    pub mapSetData: unsafe extern "system-unwind" fn(
1788        map: *mut VSMap,
1789        key: *const c_char,
1790        data: *const c_char,
1791        size: c_int,
1792        type_: VSDataTypeHint,
1793        append: VSMapAppendMode,
1794    ) -> c_int,
1795
1796    /// Retrieves a node from a map.
1797    ///
1798    /// Returns a pointer to the node on success, or `NULL` in case of error.
1799    ///
1800    /// This function increases the node's reference count, so [`freeNode()`](Self::freeNode)
1801    /// must be used when the node is no longer needed.
1802    ///
1803    /// See [`mapGetInt()`](Self::mapGetInt) for a complete description of
1804    /// the arguments and general behavior.
1805    pub mapGetNode: unsafe extern "system-unwind" fn(
1806        map: *const VSMap,
1807        key: *const c_char,
1808        index: c_int,
1809        error: *mut VSMapPropertyError,
1810    ) -> *mut VSNode,
1811    /// Sets a node to the specified key in a map.
1812    ///
1813    /// See [`mapSetInt()`](Self::mapSetInt) for a complete description of
1814    /// the arguments and general behavior.
1815    pub mapSetNode: unsafe extern "system-unwind" fn(
1816        map: *mut VSMap,
1817        key: *const c_char,
1818        node: *mut VSNode,
1819        append: VSMapAppendMode,
1820    ) -> c_int,
1821    /// Sets a node to the specified key in a map and decreases the reference count.
1822    ///
1823    /// See [`mapSetInt()`](Self::mapSetInt) for a complete description of
1824    /// the arguments and general behavior.
1825    ///
1826    /// Note: always consumes the reference, even on error
1827    pub mapConsumeNode: unsafe extern "system-unwind" fn(
1828        map: *mut VSMap,
1829        key: *const c_char,
1830        node: *mut VSNode,
1831        append: VSMapAppendMode,
1832    ) -> c_int,
1833
1834    /// Retrieves a frame from a map.
1835    ///
1836    /// Returns a pointer to the frame on success, or `NULL` in case of error.
1837    ///
1838    /// This function increases the frame's reference count, so
1839    /// [`freeFrame()`](Self::freeFrame) must be used when the frame is no longer needed.
1840    ///
1841    /// See [`mapGetInt()`](Self::mapGetInt) for a complete description of
1842    /// the arguments and general behavior.
1843    pub mapGetFrame: unsafe extern "system-unwind" fn(
1844        map: *const VSMap,
1845        key: *const c_char,
1846        index: c_int,
1847        error: *mut VSMapPropertyError,
1848    ) -> *const VSFrame,
1849    /// Sets a frame to the specified key in a map.
1850    ///
1851    /// See [`mapSetInt()`](Self::mapSetInt) for a complete description of
1852    /// the arguments and general behavior.
1853    pub mapSetFrame: unsafe extern "system-unwind" fn(
1854        map: *mut VSMap,
1855        key: *const c_char,
1856        f: *const VSFrame,
1857        append: VSMapAppendMode,
1858    ) -> c_int,
1859    /// Sets a frame to the specified key in a map and decreases the reference count.
1860    ///
1861    /// See [`mapSetInt()`](Self::mapSetInt) for a complete description of
1862    /// the arguments and general behavior.
1863    pub mapConsumeFrame: unsafe extern "system-unwind" fn(
1864        map: *mut VSMap,
1865        key: *const c_char,
1866        f: *const VSFrame,
1867        append: VSMapAppendMode,
1868    ) -> c_int,
1869
1870    /// Retrieves a function from a map.
1871    ///
1872    /// Returns a pointer to the function on success, or `NULL` in case of error.
1873    ///
1874    /// This function increases the function's reference count, so
1875    /// [`freeFunction()`](Self::freeFunction) must be used when the function is no longer needed.
1876    ///
1877    /// See [`mapGetInt()`](Self::mapGetInt) for a complete description of
1878    /// the arguments and general behavior.
1879    pub mapGetFunction: unsafe extern "system-unwind" fn(
1880        map: *const VSMap,
1881        key: *const c_char,
1882        index: c_int,
1883        error: *mut VSMapPropertyError,
1884    ) -> *mut VSFunction,
1885    /// Sets a function object to the specified key in a map.
1886    ///
1887    /// See [`mapSetInt()`](Self::mapSetInt) for a complete description of
1888    /// the arguments and general behavior.
1889    pub mapSetFunction: unsafe extern "system-unwind" fn(
1890        map: *mut VSMap,
1891        key: *const c_char,
1892        func: *mut VSFunction,
1893        append: VSMapAppendMode,
1894    ) -> c_int,
1895    /// Sets a function object to the specified key in a map and decreases the reference count.
1896    ///
1897    /// See [`mapSetInt()`](Self::mapSetInt) for a complete description of
1898    /// the arguments and general behavior.
1899    pub mapConsumeFunction: unsafe extern "system-unwind" fn(
1900        map: *mut VSMap,
1901        key: *const c_char,
1902        func: *mut VSFunction,
1903        append: VSMapAppendMode,
1904    ) -> c_int,
1905    // !SECTION
1906
1907    // SECTION - Plugin and plugin function related
1908    /// Function that registers a filter exported by the plugin.
1909    /// A plugin can export any number of filters. This function may only be called during
1910    /// the plugin loading phase unless the [`VSPluginConfigFlags::Modifiable`] flag was
1911    /// set by [`configPlugin`](VSPLUGINAPI::configPlugin).
1912    ///
1913    /// # Arguments
1914    ///
1915    /// * `name` - Filter name. The characters allowed are letters, numbers, and the underscore.
1916    ///   The first character must be a letter. In other words: ^[a-zA-Z][a-zA-Z0-9_]*$
1917    ///
1918    ///     Filter names _should be_ `PascalCase`.
1919    ///
1920    /// * `args` - String containing the filter's list of arguments.
1921    ///
1922    ///     Arguments are separated by a semicolon. Each argument is made of several fields
1923    ///   separated by a colon. Don't insert additional whitespace characters,
1924    ///   or `VapourSynth` will die.
1925    ///
1926    ///     ## Fields:
1927    ///
1928    ///     * The argument name.
1929    ///
1930    ///         The same characters are allowed as for the filter's name.
1931    ///       Argument names should be all lowercase and use only letters and the underscore.
1932    ///
1933    ///     * The type.
1934    ///
1935    ///         * "int": `int64_t`
1936    ///         * "float": double
1937    ///         * "data": const char*
1938    ///         * "anode": const [`VSNode`]* (audio type)
1939    ///         * "vnode": const [`VSNode`]* (video type)
1940    ///         * "aframe": const [`VSFrame`]* (audio type)
1941    ///         * "vframe": const [`VSFrame`]* (video type)
1942    ///         * "func": const [`VSFunction`]*
1943    ///
1944    ///         It is possible to declare an array by appending "[]" to the type.
1945    ///
1946    ///     * "opt"
1947    ///
1948    ///         If the parameter is optional.
1949    ///
1950    ///     * "empty"
1951    ///
1952    ///         For arrays that are allowed to be empty.
1953    ///
1954    ///     * "any"
1955    ///
1956    ///         Can only be placed last without a semicolon after.
1957    ///       Indicates that all remaining arguments that don't match
1958    ///       should also be passed through.
1959    ///
1960    ///     ## Example
1961    ///
1962    ///     The following example declares the arguments "blah", "moo", and "asdf":
1963    ///
1964    ///     ```txt
1965    ///     blah:vnode;moo:int[]:opt;asdf:float:opt;
1966    ///     ```
1967    ///
1968    ///     The following example declares the arguments "blah" and accepts all other arguments
1969    ///   no matter the type:
1970    ///
1971    ///     ```txt
1972    ///     blah:vnode;any
1973    ///     ```
1974    ///
1975    /// * `returnType` - Specifies works similarly to `args` but instead specifies which keys
1976    ///   and what type will be returned. Typically this will be:
1977    ///
1978    ///     ```txt
1979    ///     clip:vnode;
1980    ///     ```
1981    ///
1982    ///     for video filters. It is important to not simply specify "any" for all filters
1983    ///   since this information is used for better auto-completion in many editors.
1984    ///
1985    /// * `argsFunc` -  See [`VSPublicFunction`].
1986    ///
1987    /// * `functionData` - Pointer to user data that gets passed to `argsFunc`
1988    ///   when creating a filter. Useful to register multiple filters using
1989    ///   a single `argsFunc` function.
1990    ///
1991    /// * `plugin` - Pointer to the plugin object in the core, as passed to
1992    ///   `VapourSynthPluginInit2()`.
1993    pub registerFunction: unsafe extern "system-unwind" fn(
1994        name: *const c_char,
1995        args: *const c_char,
1996        returnType: *const c_char,
1997        argsFunc: VSPublicFunction,
1998        functionData: *mut c_void,
1999        plugin: *mut VSPlugin,
2000    ) -> c_int,
2001    /// Returns a pointer to the plugin with the given identifier, or NULL if not found.
2002    ///
2003    /// # Arguments
2004    ///
2005    /// * `identifier` - Reverse URL that uniquely identifies the plugin.
2006    pub getPluginByID: unsafe extern "system-unwind" fn(
2007        identifier: *const c_char,
2008        core: *mut VSCore,
2009    ) -> *mut VSPlugin,
2010    /// Returns a pointer to the plugin with the given namespace, or `NULL` if not found.
2011    ///
2012    /// [`getPluginByID`](Self::getPluginByID) is generally a better option.
2013    ///
2014    /// # Arguments
2015    ///
2016    /// * `ns` - Namespace.
2017    pub getPluginByNamespace:
2018        unsafe extern "system-unwind" fn(ns: *const c_char, core: *mut VSCore) -> *mut VSPlugin,
2019    /// Used to enumerate over all currently loaded plugins.
2020    /// The order is fixed but provides no other guarantees.
2021    ///
2022    /// # Arguments
2023    ///
2024    /// * `plugin` - Current plugin. Pass `NULL` to get the first plugin.
2025    ///
2026    /// Returns a pointer to the next plugin in order or
2027    /// `NULL` if the final plugin has been reached.
2028    pub getNextPlugin:
2029        unsafe extern "system-unwind" fn(plugin: *mut VSPlugin, core: *mut VSCore) -> *mut VSPlugin,
2030    /// Returns the name of the plugin that was passed to
2031    /// [`configPlugin`](VSPLUGINAPI::configPlugin).
2032    pub getPluginName: unsafe extern "system-unwind" fn(plugin: *mut VSPlugin) -> *const c_char,
2033    /// Returns the identifier of the plugin that was passed to
2034    /// [`configPlugin`](VSPLUGINAPI::configPlugin).
2035    pub getPluginID: unsafe extern "system-unwind" fn(plugin: *mut VSPlugin) -> *const c_char,
2036    /// Returns the namespace the plugin currently is loaded in.
2037    pub getPluginNamespace:
2038        unsafe extern "system-unwind" fn(plugin: *mut VSPlugin) -> *const c_char,
2039    /// Used to enumerate over all functions in a plugin.
2040    /// The order is fixed but provides no other guarantees.
2041    ///
2042    /// # Arguments
2043    ///
2044    /// * `func` - Current function. Pass `NULL` to get the first function.
2045    ///
2046    /// * `plugin` - The plugin to enumerate functions in.
2047    ///
2048    /// Returns a pointer to the next function in order or
2049    /// `NULL` if the final function has been reached.
2050    pub getNextPluginFunction: unsafe extern "system-unwind" fn(
2051        func: *mut VSPluginFunction,
2052        plugin: *mut VSPlugin,
2053    ) -> *mut VSPluginFunction,
2054    /// Get a function belonging to a plugin by its name.
2055    pub getPluginFunctionByName: unsafe extern "system-unwind" fn(
2056        name: *const c_char,
2057        plugin: *mut VSPlugin,
2058    ) -> *mut VSPluginFunction,
2059    /// Returns the name of the function that was passed to
2060    /// [`registerFunction()`](Self::registerFunction).
2061    pub getPluginFunctionName:
2062        unsafe extern "system-unwind" fn(func: *mut VSPluginFunction) -> *const c_char,
2063    /// Returns the argument string of the function that was passed to
2064    /// [`registerFunction()`](Self::registerFunction).
2065    pub getPluginFunctionArguments:
2066        unsafe extern "system-unwind" fn(func: *mut VSPluginFunction) -> *const c_char,
2067    /// Returns the return type string of the function that was passed to
2068    /// [`registerFunction()`](Self::registerFunction).
2069    pub getPluginFunctionReturnType:
2070        unsafe extern "system-unwind" fn(func: *mut VSPluginFunction) -> *const c_char,
2071    /// Returns the absolute path to the plugin, including the plugin's file name.
2072    /// This is the real location of the plugin, i.e. there are no symbolic links in the path.
2073    ///
2074    /// Path elements are always delimited with forward slashes.
2075    ///
2076    /// `VapourSynth` retains ownership of the returned pointer.
2077    pub getPluginPath: unsafe extern "system-unwind" fn(plugin: *const VSPlugin) -> *const c_char,
2078    /// Returns the version of the plugin.
2079    /// This is the same as the version number passed to
2080    /// [`configPlugin()`](VSPLUGINAPI::configPlugin).
2081    pub getPluginVersion: unsafe extern "system-unwind" fn(plugin: *const VSPlugin) -> c_int,
2082    /// Invokes a filter.
2083    ///
2084    /// [`invoke()`](Self::invoke) checks that the args passed to the filter are consistent
2085    /// with the argument list registered by the plugin that contains the filter,
2086    /// calls the filter's "create" function, and checks that
2087    /// the filter returns the declared types.
2088    /// If everything goes smoothly, the filter will be ready to generate frames after
2089    /// [`invoke()`](Self::invoke) returns.
2090    ///
2091    /// # Arguments
2092    ///
2093    /// * `plugin` - A pointer to the plugin where the filter is located. Must not be `NULL`.
2094    ///
2095    ///     See [`getPluginByID()`](Self::getPluginByID).
2096    ///
2097    /// * `name` - Name of the filter to invoke.
2098    ///
2099    /// * `args` - Arguments for the filter.
2100    ///
2101    /// Returns a map containing the filter's return value(s).
2102    /// The caller takes ownership of the map.
2103    /// Use [`mapGetError()`](Self::mapGetError) to check if the filter was invoked successfully.
2104    ///
2105    /// Most filters will either set an error, or one or more clips with the key "clip".
2106    /// The exception to this are functions, for example `LoadPlugin`,
2107    /// which doesn't return any clips for obvious reasons.
2108    pub invoke: unsafe extern "system-unwind" fn(
2109        plugin: *mut VSPlugin,
2110        name: *const c_char,
2111        args: *const VSMap,
2112    ) -> *mut VSMap,
2113    // !SECTION
2114
2115    // SECTION - Core and information
2116    /// Creates the `VapourSynth` processing core and returns a pointer to it.
2117    /// It is possible to create multiple cores but in most cases it shouldn't be needed.
2118    ///
2119    /// # Arguments
2120    ///
2121    /// * `flags` - [`VSCoreCreationFlags`] `ORed` together if desired.
2122    ///   Pass 0 for sane defaults that should suit most uses.
2123    ///
2124    pub createCore: unsafe extern "system-unwind" fn(flags: c_int) -> *mut VSCore,
2125
2126    /// Frees a core. Should only be done after all frame requests have completed
2127    /// and all objects belonging to the core have been released.
2128    pub freeCore: unsafe extern "system-unwind" fn(core: *mut VSCore),
2129
2130    /// Sets the maximum size of the framebuffer cache.
2131    ///
2132    /// Note: the total cache size at which vapoursynth more aggressively tries to reclaim memory,
2133    /// it is not a hard limit
2134    ///
2135    /// # Return:
2136    ///
2137    /// the new maximum size.
2138    pub setMaxCacheSize: unsafe extern "system-unwind" fn(bytes: i64, core: *mut VSCore) -> i64,
2139
2140    /// Sets the number of threads used for processing. Pass 0 to automatically detect.
2141    /// Returns the number of threads that will be used for processing.
2142    pub setThreadCount:
2143        unsafe extern "system-unwind" fn(threads: c_int, core: *mut VSCore) -> c_int,
2144
2145    /// Returns information about the `VapourSynth` core.
2146    pub getCoreInfo: unsafe extern "system-unwind" fn(core: *mut VSCore, info: *mut VSCoreInfo),
2147
2148    /// Returns the highest [`VAPOURSYNTH_API_VERSION`]
2149    /// the library support.
2150    pub getAPIVersion: unsafe extern "system-unwind" fn() -> c_int,
2151    // !SECTION
2152
2153    // SECTION - Message handler
2154    /// Send a message through `VapourSynth`'s logging framework.
2155    /// See [`addLogHandler`](Self::addLogHandler).
2156    ///
2157    /// # Arguments
2158    /// * `msgType` - The type of message. One of [`VSMessageType`].
2159    ///
2160    ///     If `msgType` is [`VSMessageType::Fatal`],
2161    ///   `VapourSynth` will call `abort()` after delivering the message.
2162    ///
2163    /// * `msg` - The message.
2164    pub logMessage: unsafe extern "system-unwind" fn(
2165        msgType: VSMessageType,
2166        msg: *const c_char,
2167        core: *mut VSCore,
2168    ),
2169    /// Installs a custom handler for the various error messages `VapourSynth` emits.
2170    /// The message handler is per [`VSCore`] instance. Returns a unique handle.
2171    ///
2172    /// If no log handler is installed up to a few hundred messages are cached and
2173    /// will be delivered as soon as a log handler is attached. This behavior exists mostly
2174    /// so that warnings when auto-loading plugins (default behavior) won't disappear-
2175    ///
2176    /// # Arguments
2177    ///
2178    /// * `handler` -  Custom message handler. If this is `NULL`,
2179    ///   the default message handler will be restored.
2180    ///
2181    /// * `free` - Called when a handler is removed.
2182    ///
2183    /// * `userData` - Pointer that gets passed to the message handler.
2184    pub addLogHandler: unsafe extern "system-unwind" fn(
2185        handler: VSLogHandler,
2186        free: VSLogHandlerFree,
2187        userData: *mut c_void,
2188        core: *mut VSCore,
2189    ) -> *mut VSLogHandle,
2190    /// Removes a custom handler. Return non-zero on success and zero if the handle is invalid.
2191    ///
2192    /// # Arguments
2193    ///
2194    /// * `handle` - Handle obtained from [`addLogHandler()`](Self::addLogHandler).
2195    pub removeLogHandler:
2196        unsafe extern "system-unwind" fn(handle: *mut VSLogHandle, core: *mut VSCore) -> c_int,
2197
2198    // !SECTION
2199
2200    // MARK: API 4.1
2201    // mostly graph and node inspection, PLEASE DON'T USE INSIDE FILTERS
2202
2203    /* Additional cache management to free memory */
2204    /// clears the cache of the specified node
2205    #[cfg(feature = "vs-41")]
2206    pub clearNodeCache: unsafe extern "system-unwind" fn(node: *mut VSNode),
2207    /// clears all caches belonging to the specified core
2208    #[cfg(feature = "vs-41")]
2209    pub clearCoreCaches: unsafe extern "system-unwind" fn(core: *mut VSCore),
2210
2211    /* Basic node information */
2212    /// the name passed to `create*Filter*`
2213    #[cfg(feature = "vs-41")]
2214    pub getNodeName: unsafe extern "system-unwind" fn(node: *mut VSNode) -> *const c_char,
2215    #[cfg(feature = "vs-41")]
2216    /// returns [`VSFilterMode`]
2217    pub getNodeFilterMode: unsafe extern "system-unwind" fn(node: *mut VSNode) -> VSFilterMode,
2218    #[cfg(feature = "vs-41")]
2219    pub getNumNodeDependencies: unsafe extern "system-unwind" fn(node: *mut VSNode) -> c_int,
2220    #[cfg(feature = "vs-41")]
2221    pub getNodeDependency: unsafe extern "system-unwind" fn(
2222        node: *mut VSNode,
2223        index: c_int,
2224    ) -> *const VSFilterDependency,
2225
2226    /* Node timing functions */
2227    /// non-zero when filter timing is enabled
2228    #[cfg(feature = "vs-41")]
2229    pub getCoreNodeTiming: unsafe extern "system-unwind" fn(core: *mut VSCore) -> c_int,
2230    /// non-zero enables filter timing, note that disabling simply stops the counters from incrementing
2231    #[cfg(feature = "vs-41")]
2232    pub setCoreNodeTiming: unsafe extern "system-unwind" fn(core: *mut VSCore, enable: c_int),
2233    /// time spent processing frames in nanoseconds, reset sets the counter to 0 again
2234    #[cfg(feature = "vs-41")]
2235    pub getNodeProcessingTime:
2236        unsafe extern "system-unwind" fn(node: *mut VSNode, reset: c_int) -> i64,
2237    /// time spent processing frames in nanoseconds in all destroyed nodes, reset sets the counter to 0 again
2238    #[cfg(feature = "vs-41")]
2239    pub getFreedNodeProcessingTime:
2240        unsafe extern "system-unwind" fn(core: *mut VSCore, reset: c_int) -> i64,
2241
2242    // MARK: API 4.2
2243    /// Same as [`getCoreInfo()`](Self::getCoreInfo), but also reports the
2244    /// [`VSCoreCreationFlags`] the core was created with.
2245    #[cfg(feature = "vs-42")]
2246    pub getCoreInfo2: unsafe extern "system-unwind" fn(core: *mut VSCore, info: *mut VSCoreInfo2),
2247
2248    // MARK: Graph information
2249    /*
2250     * !!! Experimental/expensive graph information
2251     * These functions only exist to retrieve internal details for debug purposes and
2252     * graph visualization They will only only work properly when used on a core created
2253     * with `ccfEnableGraphInspection` and are not safe to use concurrently with frame requests
2254     * or other API functions. Because of this they are unsuitable for use in plugins and filters.
2255     */
2256    /// level=0 returns the name of the function that created the filter,
2257    /// specifying a higher level will retrieve the function above that
2258    /// invoked it or `NULL` if a non-existent level is requested
2259    #[cfg(feature = "vs-graph")]
2260    pub getNodeCreationFunctionName:
2261        unsafe extern "system-unwind" fn(node: *mut VSNode, level: c_int) -> *const c_char,
2262    /// level=0 returns the id of the plugin that created the filter,
2263    /// specifying a higher level will retrieve the plugin above that
2264    /// invoked it or `NULL` if a non-existent level is requested
2265    #[cfg(feature = "vs-graph")]
2266    pub getNodeCreationPluginID:
2267        unsafe extern "system-unwind" fn(node: *mut VSNode, level: c_int) -> *const c_char,
2268    /// level=0 returns the namespace of the plugin that created the filter,
2269    /// specifying a higher level will retrieve the plugin above that
2270    /// invoked it or `NULL` if a non-existent level is requested
2271    #[cfg(feature = "vs-graph")]
2272    pub getNodeCreationPluginNS:
2273        unsafe extern "system-unwind" fn(node: *mut VSNode, level: c_int) -> *const c_char,
2274    /// level=0 returns a copy of the arguments passed to the function that created the filter,
2275    /// returns `NULL` if a non-existent level is requested
2276    #[cfg(feature = "vs-graph")]
2277    pub getNodeCreationFunctionArguments:
2278        unsafe extern "system-unwind" fn(node: *mut VSNode, level: c_int) -> *const VSMap,
2279}
2280
2281// Since R74 no `VapourSynth` distribution ships an import library, so Windows
2282// binds the DLL directly by name instead of going through one.
2283#[cfg(feature = "link-vs")]
2284#[cfg_attr(windows, link(name = "libvapoursynth", kind = "raw-dylib"))]
2285#[cfg_attr(not(windows), link(name = "vapoursynth"))]
2286unsafe extern "system-unwind" {
2287    /// Returns a pointer to the global [`VSAPI`] instance.
2288    ///
2289    /// Returns `NULL` if the requested API version is not supported or
2290    /// if the system does not meet the minimum requirements to run `VapourSynth`.
2291    /// It is recommended to pass [`VAPOURSYNTH_API_VERSION`]
2292    pub fn getVapourSynthAPI(version: c_int) -> *const VSAPI;
2293}
2294
2295#[cfg(test)]
2296mod tests {
2297    use super::*;
2298
2299    #[test]
2300    fn layout() {
2301        assert_eq!(
2302            std::mem::size_of::<VSPresetVideoFormat>(),
2303            std::mem::size_of::<c_int>(),
2304            "VSPresetFormat"
2305        );
2306        assert_eq!(
2307            std::mem::size_of::<VSDataTypeHint>(),
2308            std::mem::size_of::<c_int>(),
2309            "VSDataTypeHint"
2310        );
2311        assert_eq!(
2312            std::mem::size_of::<VSCoreCreationFlags>(),
2313            std::mem::size_of::<c_int>(),
2314            "VSCoreCreationFlags"
2315        );
2316        assert_eq!(
2317            std::mem::size_of::<VSFilterMode>(),
2318            std::mem::size_of::<c_int>(),
2319            "VSFilterMode"
2320        );
2321        assert_eq!(
2322            std::mem::size_of::<VSColorFamily>(),
2323            std::mem::size_of::<c_int>(),
2324            "VSColorFamily"
2325        );
2326        assert_eq!(
2327            std::mem::size_of::<VSSampleType>(),
2328            std::mem::size_of::<c_int>(),
2329            "VSSampleType"
2330        );
2331        assert_eq!(
2332            std::mem::size_of::<VSMapAppendMode>(),
2333            std::mem::size_of::<c_int>(),
2334            "VSMapAppendMode"
2335        );
2336        assert_eq!(
2337            std::mem::size_of::<VSMessageType>(),
2338            std::mem::size_of::<c_int>(),
2339            "VSMessageType"
2340        );
2341        assert_eq!(
2342            std::mem::size_of::<VSCacheMode>(),
2343            std::mem::size_of::<c_int>(),
2344            "VSCacheMode"
2345        );
2346    }
2347
2348    /// [`VSAPI`] is a plain array of function pointers, and the library always
2349    /// exposes the full struct regardless of the API version a client compiles
2350    /// against. A client is therefore only ever allowed to declare a *prefix* of
2351    /// it, so a miscounted or mis-gated member silently shifts everything after
2352    /// it. Counts come from `vs_internal_vsapi` in upstream `src/core/vsapi.cpp`.
2353    #[test]
2354    fn vsapi_member_count() {
2355        const BASE: usize = 106;
2356        const API_41: usize = 10;
2357        const API_42: usize = 1;
2358        const GRAPH: usize = 4;
2359
2360        let expected = BASE
2361            + if cfg!(feature = "vs-41") { API_41 } else { 0 }
2362            + if cfg!(feature = "vs-42") { API_42 } else { 0 }
2363            + if cfg!(feature = "vs-graph") { GRAPH } else { 0 };
2364
2365        assert_eq!(
2366            std::mem::size_of::<VSAPI>(),
2367            expected * std::mem::size_of::<*const ()>(),
2368            "VSAPI should have {expected} members for the enabled features"
2369        );
2370    }
2371
2372    /// The struct layout above is only valid if the library is at least as new as
2373    /// the API we compiled against, so fail loudly rather than reading past its end.
2374    #[cfg(feature = "link-vs")]
2375    #[test]
2376    fn library_is_new_enough() {
2377        let api = unsafe { getVapourSynthAPI(VAPOURSYNTH_API_VERSION) };
2378        assert!(
2379            !api.is_null(),
2380            "the linked library does not support API {VAPOURSYNTH_API_MAJOR}.{VAPOURSYNTH_API_MINOR}"
2381        );
2382        let reported = unsafe { ((*api).getAPIVersion)() };
2383        assert!(
2384            reported >= VAPOURSYNTH_API_VERSION,
2385            "linked library reports API {reported:#x}, compiled against {VAPOURSYNTH_API_VERSION:#x}"
2386        );
2387    }
2388}