Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Why you shouldn't use Triticals TDecimate...

Share the word

I need to clarify when I refer to TDecimate I'm referring to both TDecimate and VDecimate (which is a port of it to VapourSynth)

Time and time again I see people using this function to decimate for inverse-telecine purposes but I implore you to continue reading this and use an alternative decimation method.

Why? (tl;dr)

Simply put, it's far too inaccurate and it is ruining a lot of encodes.

How so?

To give you some examples, let's pretend we have an NTSC DVD MPEG-2 footage, which has a common need to be decimated.

Let's say every single frame in the file is an NTSC frame (2 fields == 1 frame, interlaced). Now let's say after deinterlacing that footage has a duplicate frame every 5th frame (which would be hardcoded Pulldown 2:3 in this specific scenario).

If we use TDecimate with a cycle of 5 this will seem to work when you play it back, it actually won't be. Most people tend to just check a couple of seconds of the footage to see if it decimated correctly if they bother to check at all. If you test it by using dryrun=True argument, you will see now and then there will be an incorrect frame decimated, like a frame with new data instead of a duplicate, or it will delete a duplicate that is less compressed and keep the frame with more compression because metrically the compression caused it to be seen as a frame with new data.

Not only that but very often you will get an incorrect amount of frames returned to you. If you look at the dryrun=True test footage against its VDecimateDrop prop you will see it will often not decimate a frame in that cycle instantly breaking the actual frame rate and frame count.

Even if you check for both of these problems and believe this hasn't happened I guarantee you that you have not checked the entire file and realized it does happen later on, and even if you have checked and can confirm it hasn't happened, you surely have wasted a lot of time at this point.

This is why I don't recommend using it, it's way too inaccurate and way too linked to guesswork to be accurate. If you aim for a good encode, do not aim for quantity over quality, do not be lazy, take the time out of your day and use a manual decimation alternative.

What else can I use?

I recommend using VapourSynth's core.std.SelectEvery or AviSynth's range of Select functions. These allow you to remove specific frames by index/number rather than guesswork. Since you know what it's doing and you know it is removing what you told it to remove there's no room for mistake unless you made a mistake when using it.

An example, with VapourSynth, would be to do a core.std.SelectEvery on a clip and set the cycle to 5 and offsets to [0, 1, 3, 4] which would delete the 3rd frame every 5 frames which is what seems common for NTSC (30000/1001 frame-rate) footage that used Pulldown 2:3. Since we know it's definitely deleting a frame every cycle we know it will return the correct frame-rate and frame count, and since we know that this specific footage duplicated every 2nd frame, we know that deleting every 3rd frame is correct.

The only problem however with this method is that you need to make sure that the cycle and offsets combination your using is actually accurate and stays true throughout the entire footage, it's quite common for footage to change offsets throughout general footage/scene changes e.t.c. It's also common for footage to be this frame-rate for the intro and that frame-rate for the rest for example so look out for that as you may not want (or need) to decimate at all.

Important: The values shown here like cycle and offsets are in no way what YOUR specific footage might need to use! Take it as an example, do not copy-paste-forget!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment