Blindly Copying Avisynth Considered Harmful

Some Avisynth filters are really, really popular and show up many scripts. Some of them like RemoveGrain and TemporalSoften have even been ported because they’re useful and used in so many scripts.

…But what is TemporalSoften really used for?

TemporalSoften is the definition of cargo cult programming, its code and concept gets copied over and over again and nobody knows exactly why. Let’s start with a few facts:

  • TemporalSoften is a horribly bad temporal smoother even compared to its competition over 10 years ago
  • TemporalSoften has never been used to unironically denoise anything the past 10 years

With these facts in mind you have to wonder why anyone’d ever put it in a script from the past decade. The answer is simple, if you set the denoising thresholds to their max values you get a filter that averages an odd number of frames. If you’re creative you can blend several frames with different weights. That’s actually kinda useful sometimes. So useful someone already wrote an Avisynth plugin for it. It’s a shame that it was fairly quickly forgotten. Unfortunately nobody who ported TemporalSoften to VapourSynth stopped to think about what it was actually used for and instead a very optimized version of TemporalSoften was created. And rewritten. And optimized a bit more. Because why not?

To try to counter this madness I’ve made a collection of small useful and experimental functions available. The first version can be found in this thread. Go try it and stop blending frames with TemporalSoften.

Stop Using RemoveGrain

RemoveGrain is kind of an abomination as a filter. Mostly because it has over 20 different modes that effectively are different filters. These are probably just numbered in the order the author came up with them and this can be very confusing. Having that many modes also leads to the big question of what these modes actually do and which ones are actually used. A quick check showed that modes 2, 4, 11, 12, 19 and 20 are the most common (most other modes are useless and/or pointless in case you’re wondering).

Mode 2: 3×3 clipping operation with no nice name

Mode 4: 3×3 median

Mode 11&12: 3×3 convolution using [1 2 1, 2 4 2, 1 2 1]

Mode 19: 3×3 convolution using [1 1 1, 1 0 1, 1 1 1]

Mode 20: 3×3 convolution using [1 1 1, 1 1 1, 1 1 1]

If you’re paying attention you can easily see that all except mode 2 are easily replaceable by easier to read functions that support more input formats. Go do that!

R33 – A Somewhat Experimental Release

What’s to experimental in this release you ask? Basically all the code got modified. Everywhere. To re-factor and optimize things. The most important improvements are:

  • 8-bit and 16-bit integer and float support in all core functions where it makes sense
  • Many commonly used core functions were optimized (Median, Minimum, Maximum, Inflate, Deflate, Convolution)
  • The internal resizers can now have the active region set to achieve things like subpixel shifts
  • VSFS was removed and replaced by AVFS, this AVFS version works with both VapourSynth and Avisynth and has all the latest changes
  • The Python installation to use can now be selected in the installer
  • Release builds are now mostly compiled with clang-cl for improved speed

There are also a few important compatibility related changes from previous versions:

  • AVFS works very differently from VSFS (command line vs shell integration) but can still accomplish more or less the same thing
  • PlaneStats function had the MinMax property split into separate Min and Max
  • GenericFilters is no longer included because the core functions plus the TCanny plugin can now replace 99% of its uses
  • AssVapour was renamed to SubText and uses the sub namespace now

R32 – Interlaced Resizing is Evil

But we added it anyway. Seriously people, just say no to interlaced material. Or de-interlace it properly. And you should all update since a bug that caused caches to not always be automatically inserted where they should be was fixed.

Breaking changes:

Progressive material that’s encoded as interlaced (far too common) may now by default have interlaced resizing applied to it. Use core.std.SetFieldBased(clip, 0) to easily flag it as progressive before resizing.

PlaneAverage has now been removed. Use PlaneStats instead.

VSPipe outputs planar RGB in the GBR plane order now to match what other programs expect as input.

2016-03-26 12.09.00

Unsuspecting flowers having nothing to do with this post

R31 – Boring Maintenance

All code is bug free until someone else tries to run it. It’s a scientific fact!

This release fixes all known resizer issues that have been discovered so far. Fortunately none of them led to image corruption, just incorrect rejection of certain conversions.

And it can’t be a release without warning about something that’s slightly changed in some way. So here comes the warning. The installer now writes the registry keys related to the 64bit version into HKLM64 which makes more sense. All the old entries will also be kept until everyone has switched to the new ones. This is in preparation of the day the 32bit VapourSynth windows version stops existing, which unfortunately won’t be anytime soon despite it being over 12 years since we got x64.

R30 – Recommended by 9 out of 10 Installer Haters

Other possible titles:

  • DEATH TO… Installers?
  • More Avisynth than Avisynth
  • Improvements to Reduce Seeking in Source Filters

Welcome to the glorious even numbered release of R30! A release with so many new things a single topic cannot do it justice.

The first point proves that sometimes less is more. There’s now a version for windows that doesn’t need to be installed. It’s used together with embeddable Python and allows vspipe to be used for output. It’s also possible to use the VapourSynth Editor with it by putting it in the same directory.

For those of you who still can’t live without certain Avisynth filters there are great news. Avisynth 2.6 plugins are now supported in both 32 and 64 bit builds. Note that 64 bit builds can’t use 2.5 plugins. Which isn’t a real problem since almost none exist anyway.

And finally the performance related change. This continues the work in R29 of making the time it takes to produce a single frame more consistent. Plugins can now signal that they prefer to have frames requested in sequential order, if possible, and a reasonable effort will be made to make it that way. This fixes most of the remaining possible slowdowns to in scripts because the source filter has to search too much. Note that new source filter builds are needed which will be out soon. FFMS2, d2vsource and L-SMASH works will be released with support for this in a few days… or weeks.

Of course there are some other small fixes too but they aren’t really interesting enough to list here.

Possibly breaking changes:

The resize functions have their default behavior changed to make the colorimetry arguments override the frame properties by default. Previously the frame properties would always take precedence when present. To restore the old behavior set prefer_props.

PlaneDifference is completely removed and PlaneAverage will be completely removed in R32. They’re both replaced by PlaneStats which can calculate multiple metrics at once with no speed penalty.