API changes R3->R4 Header files: All header files have had 4 appended to their name. The R4 files are called: VapourSynth4.h VSHelper4.h VSScript4.h VSConstants4.h Where the constants one is new and has all the constants used for frame properties but aren't needed to use the basic api. Constant names: A lot of the enums have changed prefixed. For example cm => cf, pa => ma and so on. Video format: Video formats are no longer pointers that can be compared for equivalence. Instead the full struct is passed around. Format ids have also been converted to a uin32_t that stores all the same information. Note that you still have to use the api to unpack it since otherwise v3 format ids won't be correctly interpreted. Core creation: createCore() now takes a set of flags instead of a thread number since it can be set directly after construction with setThreadCount() anyway. The flags control the few options that have to be set at creation time and can't be changed later. Plugin and function registration: There's a completely new entry point called VapourSynthPluginInit2 with a different definition. The relevant functions are now passed as function pointers in a struct like the main api. Things mostly work the same but configPlugin() now takes an additional argument for the plugin version number. It's recommended to use the VS_MAKE_VERSION macro for this. The "read only" field has now been turned into a flags field where 0 is the new default value to make a plugin read only. The flag pcModifiable has been introduced to get the R3 api behavior of passing 0. Function registrations now take an additional argument for the return type that follows the same format as the input arguments. If a function has an unknown or simple unpredictable return type it can be set to "any". Note that R3 functions will have the "any" return type. Since the audio types anode and a frame were introduced the video counterparts were renamed to vnode and vframe instead of clip and frame. VSMap/property manipulation: All functions starting with prop* have been renamed to map*. Likewise get/setError has been renamed to mapGet/SetError for greater consistency. The paTouch mode has been removed and mapSetEmpty should be used instead in the rare cases where it's needed. Audio node and audio frame types were added and the types are now declared as normal enum constants and not obscure characters. The best way to think about audio and video nodes are that they're two separate types that happen to share functions to manipulate them. As a result of this reasoning a single key in a VSMap can only hold audio or video nodes but not a mix of both. The same applies to frames (but they're rarely used as arguments). The data type now has a hint for whether the data should be treated as utf8 or binary which can be useful for filters that print values. Data set by R3 filters will always be reported as unknown. Two new convenience functions were added. mapGetSaturatedInt and mapGetSaturatedFloat which are equivalent to int64ToIntS(propGetInt) and the same operation for float. Filter changes: createFilter has been replaced by createVideoFilter. The init callback has been deprecated and instead VSVideoInfo is passed directly to createVideoFilter. Flags have been reworked and nfNoCache has been replaced by the dependency listing. This is simply an array of the nodes used as input and whether or not requests from them are strictly spatial. Note that if you take two different length clips as input you may request the final frame of the shorter clip very many times and violate the strictly spatial flag. The nfMakeLinear flag has been replaced by the two api functions setLinearFilter and cacheFrame which allows filters to push not requested frames into the cache. See FFMS2 and AVISource for examples of this. The getFrame callback has also been changed in two important ways, the void **instanceData pointer has been changed to void * to remove the pointless additional indirection. The void **frameData pointer now points to a scratch space of size void *[4] instead of only being a single pointer. This can be used to not have to allocate and free memory on every frame processed. See the Splice filter for an example of this. The arFrameReady event has been completely removed since nobody used it. Likewise YCoCg has been removed as a separate color family and is now simply considered to be YUV matrix. Audio filter support: Audio filters are created with createAudioFilter and work very similarly to video filters. Note that all audio frames have a fixed size (VS_AUDIO_FRAME_SAMPLES) except for the last one in a clip that may be shorter if necessary. This needs to be kept in mind when writing filters that append two clips. Message handlers: Message handlers are now registered per core and not globally to improve core and environment isolation. Note that there's no longer a default handler that prints messages to stderr if no handler is installed so direct users of the core/vsscript need to install one to still get messages printed. There's also a new mtInformation level that's self-explanatory. VSHelper: The header now has all functions placed in the vsh namespace (C++) or prefixes them with vsh (C) in order to not clutter things up as much. Several functions were also renamed for clarity. Renamed functions: all functions with a vs_ prefix had it removed (see C/C++ mode differences above) isSameFormat => isSameVideoInfo (IMPORTANT! do not confuse with the new function called isSameVideoFormat) isConstantFormat => isConstantVideoFormat vs_aligned_malloc => vsh_aligned_malloc vs_aligned_free => vsh_aligned_free VS_ALIGNED_MALLOC => VSH_ALIGNED_MALLOC VS_ALIGNED_FREE => VSH_ALIGNED_FREE vs_normalizeRational => reduceRational VSScript: The api is mostly the same with the exception that createScript() has to be manually called in all cases and the API now uses a struct of function pointers. It's also possible to pass a pre-created core to createScript() in order to set options such as logging output before script evaluation. VSScript also no longer changes the working directory by default when evaluating scripts. This option has been removed due to it involving global state. Python changes: Multiple constants such as YCOCG have been dropped since they no longer exist in the C API. Many deprecated functions like get_core() have been removed. Note that these functions have been deprecated since at least R51 and usually much longer ago and therefore shouldn't cause problems. Frame data access has been reworked and the broken get_read_array and get_write_array functions have been dropped. They're replaced by frame[plane/channel] which will return a python array to access the underlying data directly without a risk of access violations.