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