R76 – Respecting Cache Limits

R76 completely reworks how the cache limits work and actually much more strictly adheres to them if it all possible. This means that scripts that previously were running just fine may slow down due to memory constraints. For example even with the default limit of 4GB scripts like mc_degrain could actually use 16GB+ of memory when processing 4k material. That doesn’t sound so bad until the Linux out of memory killer strikes and many scripts can’t complete at all.

This version improves things by limiting the number of concurrent threads running at the same time when memory is constrained. For example in the case of MVTools (super-analyze-degrain3) with 4k 10bit material an additional thread can mean approximately 500MB more memory is required. Previously all limiting would fail when there were no more frames stored in the caches and only the working set of the running filters remained. When this state is reached the number of running threads is reduced. Note that if you have a 16 core CPU that can run 32 hardware threads at once decreasing the number down to 8-16 actually running threads usually has very little real effect since consumer CPUs will dual channel ram most of the time will be memory bandwidth limited anyway.

However if you see it go down to 1-4 threads from 32 you should REALLY increase the maximum cache size.

Two serious bugs were also fixed, one caused corrupt output from the “generic filters” (maxium, minimum, 3×3 convolution and so on) in some compiles in the avx2 code path. The other bug is much more specific and could cause memory leaks if an API4 filter requested frames from a node not properly declared as a dependency. If that sounds very specific it’s just what MVTools v25&v26 did.

R75 – Sanding off the R74 Edges and Plugin Manifests

R74 had some bugs and issues related to the new packaging and now the worst is fixed. But that’s not really all that interesting. Instead let’s talk about what manifests and plugin loading changes in R75 can do for you. R74 already introduced recursive loading of all plugins in a directory. This meant that a multi-file plugin like znedi3 could have both its DLL and its data file as a neat group in a separate directory since they belong together.

R75 added manifests, these files are useful if your plugin consist of several support libraries (DLLs) because then VapourSynth can skip wasting time loading the unrelated DLLs. When a manifest file is encountered in a subdirectory only the filenames listed will be loaded and and everything else skipped.

[VapourSynth Manifest V1]
bestsource

The platform specific library ending (.dll/.so/.dylib) is appended to the listed filenames. Multiple filenames with one on each line is allowed. It’s also possible to use relative paths as long as they point to subdirectories. The file must be named manifest.vs.

The other new feature is that a plugin now can have multiple versions compiled for different CPU instruction set levels and automatically load the optimal one for the current system. This is automatically done on autoloading when manifests are present or when explicitly calling LoadPlugin on the base name (such as base.dll) of a plugin. Only the base version has to exist and if any level is missing it will try the other ones in order.

The levels chosen are:

LevelGCC/ClangMSVCFilename
Plain x64 (x86_64_v1)base.dll
AVX2 level (Intel Haswell, x86_64_v3)-march=haswell/arch:AVX2base.avx2.dll
Zen4 level without AMD only instructions-march=znver4 -mno-sse4aNo equivalentbase.zn4.dll

If you’re familiar with the defined x86_64 “levels” you may wonder where v2 and v4 went. The short answer is that v2 is mostly pointless (SSE4.2-ish) due to AVX2 (v3) CPUs being so widely available. Intel’s Haswell CPUs were released in 2013.

For v4 the answer is a lot more convoluted because Intel had no plan and no idea about what they were doing. Basically it’s the instruction set of an Intel Skylake CPU with AVX512 enabled. The first consumer CPU with AVX512. And also almost last. Many of the following CPUs from Intel had AVX512 disabled and only enabled for sever parts which nobody actually has at home. This combined with crippling downclocking issues when AVX512 instructions were used means that ironically when you tell most modern compilers to make code for Skylake CPUs (-march=skylake or -march=x86_64_v4) they won’t actually use the wider registers and only use the same register width as AVX2 code. That’s how bad early AVX512 was on consumer CPUs.

Over time more and more AVX512 instructions have also been added that are quite useful. However Intel CPUs would add one new group of instructions and remove another. Meaning that there’s no clear path forward and code compiled for these more modern Intel CPUs wouldn’t necessarily work with later ones. A complete mess. It wasn’t until AMD introduced reasonably priced AVX512 support for consumers with Zen4 things started to fall into place for normal people. At this point, 7 years after the original Skylake, many additional AVX512 instructions had been added. Not only that, Zen5 is a proper superset so it’s fully compatible with Zen4. And so will Zen6 also be. Meaning that from now there’s a consistent target with full width AVX512 used that NORMAL PEOPLE CAN ACTUALLY BUY! This also fits very well with Intel’s coming CPUs with AVX10.2 support that adds very few new instructions of value.

New Packaging and Install Methods in R74

Everything has changed! Your old installations will break! Encodings will fail!

But in the end you’ll be able to install VapourSynth EVERYWHERE by typing pip install vapoursynth followed by vapoursynth config.

After that there are a few more optional commands you can find detailed in the updated installation instructions.

No more installers needed. Things will be neatly separated in every Python virtual environment. Everything will just work. Apart from migrating from your old installation. Plugins are now stored in a a subdirectory of the VapourSynth Python package. To get the new location run vapoursynth.get_plugin_dir() in Python. This will in the future allow all plugins and scripts to be installed through pip instead of VSRepo which over time will be phased out. NO PLUGINS WILL BE LOADED FROM THE PREVIOUS LOCATIONS!

Other Important Things

If you want to use VSRepo you now have to install it separately using pip (yes, pip install vsrepo is now possible). Likewise AVFS has been split off into its own repository and is now a separate download.

There still is a normal windows installer and the portable version install script if you prefer to still use them. Do however note that simply “upgrading” from R73 or earlier probably will break a lot of things due to the changes.

Why this didn’t happen earlier

This change has been requested for many years. Almost from the start ever since the Python module was packaged into a proper wheel. Due to a lot of factors this wasn’t even technically possible until recently. Or at least not without an insane testing workload.

The main improvement to Python that made this possible was the limited API which allows binary wheels to work on multiple Python versions without needing to compile a separate version for every release. This reduces the number of packages from over a gazillion to about 5. The limited API did however not have enough features until around Python 3.11-3.12 to accomplish this since VapourSynth uses memory views and such in its bindings.

And even if the pre-requisites are there you still have to figure out how to do it. VapourSynth is split into two main components, the core library written in C++ and VSScript, a library that embeds Python and abstracts script evaluation which is very hard to get right. If you’re paying attention you’ve now realized that VapourSynth is a library used by a Python module that is used by another library (VSScript) that embeds Python and is then in turn loaded by vspipe.

This is an almost circular dependency. Probably nothing else in existence does this. There are no Python tutorials covering this. Embedding Python is in and of itself something that feels more like an afterthought than something intended and creates many problems. Or to put it simply: it took this long to figure it out after Python 3.12 was released.

R73 – The Last Windows 7 Release

The time has finally come. I’ve been busy the past few months so all you get are a few bug fixes in another maintenance release. Also Visual Studio 2026 was released and its toolchain only support Windows 10 and newer. Likewise Cython is planning to soon drop support for Python 3.8 which is the last Python version to support Windows 7. Or to put it simply: Windows 7 is now getting much harder to support. The number of Windows 7 users is also much smaller now and just like the removal of 32 bit x86 builds this streamlines the build process quite a bit.

If anyone decides to produce legacy compiles tell me and I’ll link them but I suspect the market for those are very limited. I think that’s it. The upside is that clang-cl probably can be used to compile the next release and make it a bit faster.

Website Migration and Changes

I was forced to move the domain and change hosting provider for the first time in 13 years due to the previous providers having been bought by Newfold Digital, a company that turns everything it buys into overpriced shit. As a result of this I’ve also implemented a few changes:

  • Comments have been disabled here and all old comments have been wiped
  • I’ve enabled discussions on Github where comments and discussions can be posted instead

You can also check the Help and Chat page for IRC, Discord and forum links.

R72 – Named Pipes and Python 3.12+ Support on Windows

Many poorly coded but popular Python modules like to write lots of junk directly to stdout. This is a big problem when piping from vspipe to another application and will break everything. On “not Windows” it was possible to use named pipes to get around this however on Windows you were stuck until now. To create a named pipe for output simply do vspipe script.vpy "\\.\pipe\<your pipe name>" and use the same “filename” as input for FFmpeg or recent x265 builds. A patch has also been submitted to x264 but hasn’t been accepted yet.

As mentioned in the previous posts every Python version starting with 3.12 is now supported in the Windows installer. This of course also includes Python 3.13 and 3.14 and will help people using poorly coded but popular Python modules that are slow to get support for for new Python versions.

Supporting All Recent Python Versions!

There’s now an experimental version of VapourSynth that support Python 3.12 and later. This means 3.13 and the 3.14 pre-release as well. Windows binaries can be found here. It’s safe to use and is apart from the better Python support identical to the R71 release.

If no major issues are found this will become the standard distribution method for the windows installer in future releases starting with R72.

R69 & R70 – Maintaining Things While Busy with Life

Bug fixes again. Surprise! And some additional format constants. The most notable fixes are for a potential crash when splicing more than 2 audio clip and when resizing video by 0.5x using avx512.

In terms of user facing changes a few more format constants got added by popular demand and the VSScript API finally got a function to enumerate which output indices are actually set.

YATTA 8-134 – Binaries now available

Every now and then I make a minimal effort to keep YATTA working. A few years ago I made the adjustments needed for for x64 and Avisynth+ support to keep it marginally relevant. Today I finally stopped being too lazy to actually publish compiled binaries which can be found on Github.