Log in

View Full Version : bugs in tdecimate mode 2


Katie Boundary
24th April 2018, 12:34
While screwing around with Tdecimate, trying to get Transformers: Beast Machines back down to 25.00 frames per second without any duplications or incorrect deletions, I noticed some odd errors from tdecimate:

1) Using mode 2 doesn't always generate a clip with the actual specified frame rate; or at least, AVIsynth doesn't recognize the resulting clip as having the specified frame rate. I often had to follow tdecimate(mode=2,rate=25) with assumefps(25) in order to splice clips together.

2) A lot of maxndl values in mode 2 will throw sync error messages without explanation or consistency, depending on what else is in the script, the alignment of the planets, what you had for breakfast, etc.

3) If you try to get around the above problem by chaining multiple tdecimates together, using Mode 0 to get most of the way down to your desired frame rate and then Mode 2 to finish the job, Mode 2 will sometimes generate an "unable to achieve desired decimation ratio" error. So, for example, tdecimate(cycler=5,cycle=32).tdecimate(mode=2,rate=25) works, but tdecimate(cycler=5,cycle=31).tdecimate(mode=2,rate=25) does not.

Problems 2 and 3 are really only problematic because maxndl exists to tweak mode 2 to handle radically different kinds of content, which should really be handled by entirely different algorithms.

TheFluff
24th April 2018, 13:46
If you want really arbitrary decimation patterns you probably also want variable frame rate. Just sayin'.

That being said: I don't think any of these are really bugs. #1 just sounds like the frame rate reported by tdecimate being close to - but not exactly - the desired one. This is not surprising to me. Normally when you use decimation, you keep a fixed fraction of frames, usually 4 out of 5 (drop 1-in-5, for NTSC->23.976fps). The resulting frame rate is thus the original fps multiplied by 4/5. With TDecimate mode 2, you remove an arbitrary number of frames, not necessarily a very even fraction - instead of dropping 2000 out of 10000 frames for a nice 4/5 ratio, you might drop 1982 out of 10000, which "simplifies" to the inconvenient fraction 991/5000, and your framerate would consequently be multiplied by 991/5000.

#2: maxndl specifies how many frames in a row TDecimate can keep without decimating. If it keeps a long string of frames, it's going to have to find a long string of drops to achieve the desired frame rate, and if it doesn't find them close enough to the keeps, the audio is going to go out of sync. It can't detect this in advance because it's not using a two-pass algorithm. Don't use a large maxndl unless you're sure there are plenty of dups to be found.

#3: Just do the maths, okay? Assuming the original frame rate is 30fps, 5-in-31 decimation results in a framerate of 25.161290322580648. We want 25, so we want to multiply the 25.161 by a fraction close to 25/25.161 = 0.9935. Now, wolframalpha tells us that 155/156 is a good rational approximation for this, but it doesn't matter, because TDecimate mode 2 doesn't even attempt to find approximations for numbers that small (https://github.com/pinterf/TIVTC/blob/master/src/TIVTC/TDecimateMode2.cpp#L403), and simply rejects decimation ratios smaller than 1/100 or greater than 99/100.


All of this being said, don't use mode 2, it probably doesn't do what you want.

manolito
24th April 2018, 14:06
I usually get better results using mode 7 with TDecimate...
Also I am a fan of the good old FDecimate plugin by Donald Graft (The older version 1.0.2 works better for me than version 1.1.0). You can find it here:
http://rationalqm.us/fdecimate/fdecimate.html

Cheers
manolito

Katie Boundary
24th April 2018, 18:55
If you want really arbitrary decimation patterns you probably also want variable frame rate. Just sayin'.

No, I want a constant frame rate of 25.00000000 frames per second, as I said in the OP, because that is what the content was originally rendered at (special thanks to ChiDragon for learning about the 1001-field-long pulldown pattern).

With TDecimate mode 2, you remove an arbitrary number of frames, not necessarily a very even fraction - instead of dropping 2000 out of 10000 frames for a nice 4/5 ratio, you might drop 1982 out of 10000, which "simplifies" to the inconvenient fraction 991/5000, and your framerate would consequently be multiplied by 991/5000.

Mode 2 is explicitly stated, in the documentation, to NOT give a damn about arbitrary numbers or ratios (unless using parameters that call for such things). It only cares about the final frame rate and about maintaining A/V sync.

And if you want to throw numbers around, the goal is to drop 199 out of every 1200 frames. 1001/1200 = 25/(30,000/1001)

maxndl specifies how many frames in a row TDecimate can keep without decimating. If it keeps a long string of frames, it's going to have to find a long string of drops to achieve the desired frame rate, and if it doesn't find them close enough to the keeps, the audio is going to go out of sync. It can't detect this in advance because it's not using a two-pass algorithm. Don't use a large maxndl

It has nothing to do with using a "large" maxndl. I was running into situations where, for example, a maxndl of 5 or 6 would work, 7 or 8 would not, 9 and 10 would, 11 would not, etc... but only on Line 5. On line 3, a maxndl of 7 or 8 would work just fine.

5-in-31 decimation results in a framerate of 25.161290322580648. We want 25, so we want to multiply the 25.161 by a fraction close to 25/25.161 = 0.9935. Now, wolframalpha tells us that 155/156 is a good rational approximation for this, but it doesn't matter, because TDecimate mode 2 doesn't even attempt to find approximations for numbers that small (https://github.com/pinterf/TIVTC/blob/master/src/TIVTC/TDecimateMode2.cpp#L403), and simply rejects decimation ratios smaller than 1/100 or greater than 99/100.

Now THAT is useful information. Thanks.

All of this being said, don't use mode 2, it probably doesn't do what you want.

I tried Mode 7 but it doesn't work with the maxndl parameter, making it difficult to fine-tune.

I usually get better results using mode 7 with TDecimate...
Also I am a fan of the good old FDecimate plugin by Donald Graft (The older version 1.0.2 works better for me than version 1.1.0). You can find it here:
http://rationalqm.us/fdecimate/fdecimate.html

I'll give that a try. Thanks!

StainlessS
24th April 2018, 19:02
Also I am a fan of the good old FDecimate plugin by Donald Graft (The older version 1.0.2 works better for me than version 1.1.0). You can find it here:
http://rationalqm.us/fdecimate/fdecimate.html


Be aware that the author (EDIT: DonaldGraft, Neuron2, Guest, VideoH) related disappointment with the FDecimate plug, (think may have said 'brain dead' or similar).
From memory, it discards the first frame that comes in under some threshold, rather than the best to remove frame.
Also the metrics used, chroma block differences are added with the wrong luma block difference sum, so is also bugged.
However despite problems, does not seem to be that bad, and also can add frames to achieve required framerate, as well as remove them.
[EDIT: Just guessin', but think that the problems probably play little or no part when increasing framerate.]

EDIT: Dont know which version I used / fixed for use with MDec2() plug. [EDIT: Was v1.1.0]

EDIT: "brain dead":- https://forum.doom9.org/showthread.php?p=1644669#post1644669

manolito
24th April 2018, 19:21
Yes, I remember Mr. Graft saying this...
Maybe it was partly because he felt a little guilty for never fixing it.

The reason I prefer version 1.0.2:
https://forum.doom9.org/showthread.php?p=1159858#post1159858

I use it mainly as a replacement for ChangeFPS when I know that the source has dupes. Results in way way better decimation.


Cheers
manolito

StainlessS
24th April 2018, 19:33
I actually quite liked FDecimate myself, and considering that it did have problems, it still worked well despite them, dont know why ???
If you just wanted to change the framerate, and did not care too much about whether it was upwards or downwards, then FDecimate was just the job,
I had no idea that it was bugged until I purloined the source for use in Mdec2.

Logan9778
24th April 2018, 19:49
What do you guys think about changefps()? I was using that in my code in another thread here, and it seems to work pretty well. It's being used on a cartoon though, so hard to tell if it's "exact" in its sync with the audio.

On a side note, could I ask you guru's to take a look at my code in this thread and get your opinions on it?

https://forum.doom9.org/showthread.php?t=175404

I'm still quite a noob at this.

manolito
24th April 2018, 20:14
If you just wanted to change the framerate, and did not care too much about whether it was upwards or downwards, then FDecimate was just the job,
I had no idea that it was bugged until I purloined the source for use in Mdec2.

Always learning new stuff... :p
I had never thought that FDecimate can also increase the frame rate. The term "decimate" certainly does not imply it, and the manual also just talks about reducing the frame rate.

But whatever, I just used it to bring a 25fps clip up to 29.97fps, and the result looks every bit as good as using ChangeFPS. Very nice, and it is perfect for my attitude to ignore the dozens of threshold and other parameters. A simple "FDecimate(rate)" is all I need.

Like Frank Zappa said: One Size Fits All :D


Cheers
manolito

Katie Boundary
25th April 2018, 00:49
It's okay, guys; I found a workaround! LOL

mpeg2source("101.d2v").tfm(mode=0,pp=0,slow=2,micmatching=0)

A=trim(0,479).tdecimate(mode=2,rate=25,maxndl=7).assumefps(25)
B=trim(480,510).tdecimate(mode=1,cycler=2,cycle=13).assumefps(25)
C=trim(511,1033).deleteframe(3,9,15,21,27,33,39,45,51,57,63,69,75,81,87,93,99,105,111,118,124,130,136,142,148,154,160,166,172,178,184,190,196,202,208,214,220,226,232,238,244,250,256,262,268,274,280,286,292,298,304,310,317,323,329,335,341,347,353,359,365,371,377,383,389,395,401,407,413,419,425,431,437,443,449,455,461,467,473,479,485,491,497,503,509,515,522).assumefps(25)
D=trim(1034,0).tdecimate(cycler=199,cycle=1200,sdlim=5).assumefps(25)

A+B+C+D

My favorite thing is when I try to skip to a specific part of the video and my machine spends 15-20 seconds trying to compute a 1,200-frame-long decimation cycle.

StainlessS
25th April 2018, 18:51
Mani,

OK, I've read the reason you like v1.02 FDecimate, I used the metrics from v1.10 for MDec2, but they are identical to the earlier version, so no
similar problems to the linked thread (still was bugged though as prev posted). (I probably used to use v1.02 and at some point found v1.10 but dont
really use FDecimate now and probably never noticed any problems in 110).
I guess its the change in below logic that created your preference to v1.02, ie


if (metrics == true)
{
// Don't decimate and show metrics for every frame.
metric = CalculateMetrics(inframe - 1, inframe, env);
GETFRAME(inframe, src);
}


102

else
{
// Decimate to achieve configured frame rate.
// Avoiding delivering a duplicate if possible.
if (last < 0 || inframe == last || CalculateMetrics(last, dec_data[inframe], env) > threshold)
use = dec_data[inframe];
else
use = dec_data[inframe] + 1;
GETFRAME(use, src);
last = use;
}



110

else
{
// Decimate to achieve configured frame rate.
// Avoiding delivering a duplicate if possible.
blind = dec_data[inframe];
if (last < 0)
choose = blind;
else if (CalculateMetrics(last, blind, env) > threshold)
choose = blind;
else if (CalculateMetrics(last, blind + 1, env) > threshold)
choose = blind + 1;
else if (CalculateMetrics(last, blind + 2, env) > threshold)
choose = blind + 2;
else
choose = blind;
use = choose;
if (protect && CalculateMetrics(use, use + 1, env) <= threshold)
use = use + 1;
GETFRAME(use, src);
last = use;
}


Could you provide a (short) clip that exhibits drawbacks in v1.10 (PM me if you like).
Also, I note that Protect arg was inserted before older existing args in v1.10, making possible script breaking changes.
I've discovered a bug in MDec2, I removed a separate pitch variable (from the modified FDecimate metrics) for the previous frame, and so must assume that I did that mod before I was aware that pitch can change frame by frame in a clip, due to perhaps interleaving
cropped clips. I'll do a mod of Mdec2 with 2.5, 2.6+ and 2.6 x64 dll's and if you provide a suitable clip,
I'll try to fix the problem in FDecimate, if I can, also fix the bugged metrics, and provide similar dll's and additional planar + RGB colorspaces.

EDIT: If I cannot fix the problem introduced in v1.10, I will fix v1.02 and do additional colrospace + dlls. (in which case what would you suggest as version number)

manolito
26th April 2018, 12:00
Could you provide a (short) clip that exhibits drawbacks in v1.10 (PM me if you like).

Sorry I can't...

I discovered FDecimate about 10 years ago, I mainly liked it for its simplicity, and unlike many other decimators it would always produce the desired target bitrate no matter what. And this was much more important to me than always removing the correct dupes in each and every case.

I switched back to the older v. 1.0.2 after reading DoctorM's post, I did a few tests (without really analyzing and comparing the results thoroughly). I thought that it did look better in some cases, but it could also have been wishful thinking.

Right now I use it all the time for my DVB-T2 broadcasts. The format is 1080p 50fps, HEVC video and E-AC3 or AAC-LATM audio, video is always progressive also for stuff shot on Video.

For film material they just bring it to 25fps and then duplicate every frame, for soaps and series material they deinterlace it and broadcast 50 unique frames per second. Since I always downconvert my recordings to AVC in SD resolution @ 25fps (see how retro I am...), I need a decimator which works each and every time without fiddling with the settings. ChangeFPS and SelectEven do cause artifacts at edit points. FDecimate and TDecimate mode 7 both look good, maybe TDecimate has a very slight edge sometimes, but when watching the clip I cannot detect the difference.


Cheers
manolito

StainlessS
26th April 2018, 15:32
OK, I'll do mod of 1.02, maybe versioned as 1.03 and perhaps someone else can mod that if they wish for 1.10 stuff.
(should be easily done if compare of source for 1.02 and 1.10 using eg KDiff [which I really like]).

EDIT: Actually KDiff3:- http://kdiff3.sourceforge.net/

manolito
26th April 2018, 16:06
OK, I'll do mod of 1.02, maybe versioned as 1.03

Sounds good to me...