Log in

View Full Version : SlowMo: Simple slow motion, using interpolation


Pages : [1] 2

spoRv
6th December 2016, 11:41
###########################################################################################
### SlowMo 1.01: Simple slow motion, using interpolation ###
### ###
### Usage: SlowMo(clip,multiplier) ###
### ###
### Example: want to make clip to play at half rate ###
### ###
### SlowMo(clip,2) - or just SlowMo(clip) as 2 is the default value ###
### ###
### AviSynth script made by spoRv (http://blog.sporv.com) - Created: 2016-12-05 ###
### ###
### Creative Commons 4,0 - Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) ###
### Link to the licence page: https://creativecommons.org/licenses/by-sa/4.0/ ###
###########################################################################################

function slowmo(clip clip, int "mul") {
num=clip.FrameRateNumerator
den=clip.FrameRateDenominator
mul=default(mul,2)
clip.assumefps(num,den)
backward_vec = clip.MVAnalyse(blksize=16, isb = true, chroma=false, pel=1, searchparam=1, idx=1)
forward_vec = clip.MVAnalyse(blksize=16, isb = false, chroma=false, pel=1, searchparam=1, idx=1)
last.MVFlowFps(backward_vec, forward_vec, num=num*mul, den=den, mask=0, idx=1)
assumefps(num,den)
}


Needed to slow a shot in a clip, I searched for a proper script, but haven't found it; I thought to use InterFrame, and assumefps at half the final rate, but was too "heavy" for my old PC... I just needed something better than ConvertFPS...

Found a code here: http://www.avsforum.com/forum/26-home-theater-computers/1025800-avisynth-script-doubling-video-frame-rates.html - take it, slightly modified - with my limited knowledge - and corrected the most important thing, that nobody seems to take in account: when a film (23.976fps = 24000/1001) must be converted to double frame (for interframe purpose or, like in this case, for a slow motion) it should be 48000/1002 and NOT 48000/1001... with this error, an entire movie will have many frames less, and audio will be audibly out of sync after few minutes. I was wrong, 48000/1001 is the right number; corrected the code to reflect this.

My little contribution; hope this code is right (if not, feel free to correct/improve it) and could be useful for someone.

FranceBB
6th December 2016, 13:35
It's always good to have a filter to do this kind of things in avisynth.
I'm gonna try it tomorrow, as I'm at work right now ;)

jmartinr
6th December 2016, 13:50
it should be 48000/1002 and NOT 48000/1001.
That can't be right. Please explain.

ChaosKing
6th December 2016, 14:12
(48000/1002) / 2 ~= 23,952
(48000/1001) / 2 ~= 23,976 ;)

Groucho2004
6th December 2016, 16:20
You guys realize that this "script" is an example from the MVTools2 manual with a simple AssumeFPS() at the end, right? There are also a shitload of variations of this all over this forum.

The "made by" and "creative license" are ridiculous.

johnmeyer
6th December 2016, 17:14
I agree that this doesn't really advance the state of the art much and, since it is a function, it really should have a little more packed into it that the average user might not think of doing if he or she was just going to use the cookbook code in the documentation.

But there is a MUCH bigger issue that even Groucho2004 didn't pick up on: this function uses the obsolete MVTools plugin!!! That plugin is ancient history, almost a decade old, and it has completely and totally been superseded by MVTools2.

I have over a dozen slow-mo scripts that I've written (or stolen), and I just scanned through them. Here are some things the OP might want to consider adding:

1. Use MVTools2 NOT the old MVTools!!!!
2. Normally the block size is large for doing slow motion, so having a fixed block size of 16 is probably OK. However, you can get different results by using the overlap parameter. That needs to be used.
3. There are variations on the slo-mo script which use MRecalculate (something introduced in MVTools2 as it was updated). The OP needs to try this out and see if it produces better and/or faster results.
4. Use prefiltering for the vector clip. Removegrain is often used, although I've seen fft3D and other filters used as well.
5. Once you update to use the much better (and multi-threaded) MVTools2, there are all sorts of other parameters you should play with, such as pel=2, search=3, etc.

I too am confused by the denominator of 1002. I don't think that is right, and would love to understand the thinking behind it. The 1000/1001 multiplier is required to accommodate the NTSC color convention. That same ratio is used for both 24 and 30 fps material, yielding 23.976 and 29.97 respectively (rounded). I sort of understand the thinking that may have lead to using 1000/1002 for 48 fps, but I don't think it is correct.

Finally, I would suggest making a generalized version of the function which can also handle interlaced video.

So, while I applaud the effort, I think it needs some serious rework before it can be useful for slow motion in the year 2016.

johnmeyer
6th December 2016, 17:22
P.S. Here is some code to get the OP started re-writing the function to use MVTools2. This is nothing special, and is only slightly more advanced than what is in the documentation:


prefiltered = RemoveGrain(source,2)
super = MSuper(source,hpad=16, vpad=16, levels=1) # one level is enough for MRecalculate
superfilt = MSuper(prefiltered, hpad=16, vpad=16) # all levels for MAnalyse
backward = MAnalyse(superfilt, isb = true, blksize=16,overlap=8,search=3,dct=0)
forward = MAnalyse(superfilt, isb = false, blksize=16,overlap=8,search=3,dct=0)
forward_re = MRecalculate(super, forward, blksize=8, thSAD=100)
backward_re = MRecalculate(super, backward, blksize=8, thSAD=100)
MFlowFps(source,super, backward_re, forward_re, num=30000, den=1001,ml=200,mask=2)

If I were to write a function, I'd look at every single parameter for each individual function in the MVTools2 slow motion chain, and play around with it in order to see its impact on slow motion. The key to writing this function is to produce something which produces the minimum number of artifacts. The place where these artifacts are most prominent are:

1. Strong vertical lines. A horizontal pan of a picket fence is a real torture test.

2. Object reveal. When a background object emerges from behind a foreground object, you often get all sorts of strange morphing.

I'd also look at adding some sort of masking to the function.

Groucho2004
6th December 2016, 17:24
5. Once you update to use the much better (and multi-threaded) MVTools2
Even though there is a version of MVTools2 (out of way too many floating around) that can make use of avstp.dll, all newer versions by Fizick and pinterf are not multi-threaded.

And yes John, I missed that the script is for MVTools(1). :p

spoRv
6th December 2016, 17:33
@Groucho2004:
Thanks for the input; "made by" because I simply copy&paste some code, and added some variation... not that difficult, I must admit, but I've done it, so, that's it. Creative Commons is a nice addition, albeit unuseful, I suspect! :D

@johnmeyer:
Constructive feedbacks are always welcome! As I'm not an avisynth programmer, this is a simple function I added to my library, concious that a very better version could be done; but, in comparison to the basic ConvertFPS, it's better, and it is sufficent for my purposes. So, I would be more than happy if you would like to make a complete rework using better/more efficient filters,

48000/1002 is the right calculation for the slow motion, half speed, of film rate, and NOT for the 48fps, that should be 48000/1001 - even if I don't know if there is any standard that supports it. For NTSC half speed, is 60000/1002, while for PAL a simple 50/1 - or 50000/1000 :D
THIS IS NOT TRUE, my fault, going to correct the script right now; please, do NOT use avisynth during renal colis, it could happen your mind is not that lucid...

Groucho2004
6th December 2016, 17:34
There was a lot of discussion about this going on in the MVTools threads:
http://forum.doom9.org/showthread.php?p=1783504#post1783504
http://forum.doom9.org/showthread.php?p=1785795#post1785795

captaiŋadamo
6th December 2016, 17:40
48000/1002 is the right calculation for the slow motion, half speed, of film rate, and NOT for the 48fps, that should be 48000/1001 - even if I don't know if there is any standard that supports it. For NTSC half speed, is 60000/1002, while for PAL a simple 50/1 - or 50000/1000 :D

Where do you get the 1002 from? If you want to half the speed you need only double the numerator. The NTSC offset doesn't change.

spoRv
6th December 2016, 17:53
My fault! You are all right, and I'm a completely stupid... :(
Going to correct the script right now!

It was something like 48000/2002 which is equal to 24000/1001 - what I was thinking...

captaiŋadamo
6th December 2016, 17:57
48000/1001/2 != 24000/1001

You're joking, right? Basic algebra proves you wrong.

ETA: Seems you've spotted your mistake. :)

BetA13
6th December 2016, 18:54
can i use this for realtime rendering with my videos?
lets say id use mpchc with ffdshow - avisynth.

where or how should i get started to use this with my videp player?

thanks for any help :)

johnmeyer
6th December 2016, 19:49
For real time rendering you might want to look into SVPFlow (http://forum.doom9.org/showthread.php?t=164554). That is what is was built for (i.e., real-time interpolation).

Groucho2004, thanks for those links. The second one, linking to StainlessS' code, is especially interesting.

BetA13
6th December 2016, 21:18
For real time rendering you might want to look into SVPFlow (http://forum.doom9.org/showthread.php?t=164554). That is what is was built for (i.e., real-time interpolation).

Groucho2004, thanks for those links. The second one, linking to StainlessS' code, is especially interesting.


yes, i do use svp, BUT, i do want slow motion..so, how do i do it..

Groucho2004
6th December 2016, 22:06
Here (https://www.dropbox.com/s/s63qy9spnfohnrw/str.mkv?dl=0) is a clip I have been using to test the slo-mo functions. Watch the motion estimation go nuts on the striped patterns. :D

johnmeyer
6th December 2016, 22:46
Here (https://www.dropbox.com/s/s63qy9spnfohnrw/str.mkv?dl=0) is a clip I have been using to test the slo-mo functions. Watch the motion estimation go nuts on the striped patterns. :DInteresting test case. I played around with it and, while certainly not perfect, I could live with the results of this script:


prefiltered = RemoveGrain(source,22)
super = MSuper(source,hpad=16, vpad=16, levels=1) # one level is enough for MRecalculate
superfilt = MSuper(prefiltered, hpad=16, vpad=16) # all levels for MAnalyse
backward = MAnalyse(superfilt, isb = true, blksize=16,overlap=4,search=3,dct=0)
forward = MAnalyse(superfilt, isb = false, blksize=16,overlap=4,search=3,dct=0)
forward_re = MRecalculate(super, forward, blksize=8, overlap=2, thSAD=100)
backward_re = MRecalculate(super, backward, blksize=8, overlap=2, thSAD=100)
output=MFlowFps(source,super, backward_re, forward_re, num=48000, den=1001,ml=200,mask=2)
output=output.selectodd()
interleave(source,output)


As you can see, I made sure that every other frame is an original, so you can easily see the merging and breaking of the stripes.

At the end of the clip, where she lowers her leg, the script does produce ghosting, although when played, this artifact will not look too bad, at least compared to the "morphological" artifacts that you get when the stripes break.

Groucho2004
6th December 2016, 23:12
Interesting test case. I played around with it and, while certainly not perfect, I could live with the results of this script
That's better than all my attempts. Very nice.

johnmeyer
7th December 2016, 00:02
That's better than all my attempts. Very nice.Thanks! Unfortunately, as you well know, this code will fail on some other clip. It's just the nature of the current state of the art, I guess.

StainlessS
7th December 2016, 00:36
Perhaps of use in testing.


Function ChangeFrameRate(clip c,Bool "Blend",Bool "Flow",Int "Num",Int "Den",
\ Bool "Prefilter",Bool "Chroma",Bool "Chroma1",Bool "Chroma2",
\ Int "BlkSize",Int "Recalc",
\ Int "OverLap",Int "OverLap1",Int "OverLap2",
\ Int "thSAD1",Int "thSAD2"
\ ) {
# Req MvTools2 v2.7.1.22+ for FINAL Overlap>0
Blend = Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow = Default(Flow,False) # If True, Use MFlowFps instead of MBlockFps
n=Default(num,0) d=default(den,0) valid=(n>0 && d>0) n=(!valid)?c.FramerateNumerator*2:n d=(!valid)?c.FramerateDenominator:d # Default=doublerate
Prefilter=Default(Prefilter,True)
Chroma = Default(Chroma ,True)
Chroma1 = Default(Chroma1,True)
Chroma2 = Default(Chroma2,True)
BlkSize = Default(BlkSize,16)
Recalc = Default(Recalc,2) # 0 -> 2.
Overlap = Default(Overlap ,4)
Overlap1= Default(Overlap1,2)
Overlap2= Default(Overlap2,0)
thSAD1 = Default(thSAD1,100) # MRecalculate default is 200
thSAD2 = Default(thSAD2,100)
Assert(0 <= Recalc <=2,"ChangeFrameRate: 0 <= ReCalc <= 2")
super = c.MSuper(pel=2, hpad=BlkSize, vpad=BlkSize,rfilter=4,Levels=(0<Recalc)?1:0) # MRecalculate needs only 1 Level, MAnalyse needs all Levels
MAnal = (Prefilter) ? c.RemoveGrain(22).MSuper(hpad=BlkSize, vpad=BlkSize) : Super
bv = MAnal.MAnalyse(isb=true, chroma=Chroma, blksize=BlkSize, OverLap=OverLap , searchparam=3, search=3, badrange=(-24), plevel=0)
fv = MAnal.MAnalyse(isb=false, chroma=Chroma, blksize=BlkSize, OverLap=OverLap , searchparam=3, search=3, badrange=(-24), plevel=0)
bv = (0<ReCalc)?MRecalculate(super, chroma=Chroma1, bv, blksize=BlkSize/2, Overlap=OverLap1, searchparam=1, search=3, thSAD=thSAD1):bv
fv = (0<ReCalc)?MRecalculate(super, chroma=Chroma1, fv, blksize=BlkSize/2, Overlap=OverLap1, searchparam=1, search=3, thSAD=thSAD1):fv
bv = (1<ReCalc)?MRecalculate(super, chroma=Chroma2, bv, blksize=BlkSize/4, Overlap=OverLap2, searchparam=0, search=3, thSAD=thSAD2):bv
fv = (1<ReCalc)?MRecalculate(super, chroma=Chroma2, fv, blksize=BlkSize/4, Overlap=OverLap2, searchparam=0, search=3, thSAD=thSAD2):fv
Return (!Flow)
\ ? c.MBlockFps(super, bv, fv, num=n, den=d, Blend=Blend, mode=0)
\ : c.MFlowFps(super, bv, fv, num=n, den=d, Blend=Blend)
}


Function DoubleRate(clip c,Bool "Blend",Bool "Flow") {Return c.ChangeFrameRate(Blend,Flow,c.FramerateNumerator*2,c.FramerateDenominator)}

spoRv
7th December 2016, 01:47
Thanks a lot StainlessS; the blend variable is the perfect touch!

So, using your function, mine would be:

function slowmo(clip clip, int "mul") {
num=clip.FrameRateNumerator
den=clip.FrameRateDenominator
mul=default(mul,2)
clip.assumefps(num,den)
ChangeFrameRate(num=num*mul,den=den)
assumefps(num,den)
}

Right?

StainlessS
7th December 2016, 02:23
Something like this would do

Function slowmo(clip clip, int "mul") {
clip
mul=default(mul,2)
ChangeFrameRate(num=FrameRateNumerator*mul,den=FrameRateDenominator)
assumefps(clip.FrameRateNumerator,clip.FrameRateDenominator)
}

EDIT:
You can add other args to ChangeFrameRate() as deemed fit.

EDIT: I've changed post #21 numbering of Chroma, OverLap and thSAD args to be more sensible.

manolito
7th December 2016, 04:54
Just out of curiosity I converted Groucho's test clip to half speed using the old MotionProtectedFPS routine which uses the Motion.dll plugin by clouded.
Download the result here:
http://www87.zippyshare.com/v/bHByFhAB/file.html

Background:
Some time ago I worked with MrC (author of AVStoDV) on the implementation of a motion protected fps conversion routine. After many tests I always came back to the above method because it always produced less and mainly less annoying artifacts than the MVFlowFPS based routines.

Of course there are more elaborate FPS converting routines like the one by Stainless, but at this time the point was to keep it as simple and fast as possible.

I find the result of MotionProtectedFPS very pleasing to watch, but then again I can only watch it on a mediocre laptop display and on a CRT TV. How does my conversion compare to the other scripts posted so far?


Cheers
manolito

pinterf
7th December 2016, 08:44
Even though there is a version of MVTools2 (out of way too many floating around) that can make use of avstp.dll, all newer versions by Fizick and pinterf are not multi-threaded
I'm not using avstp but since my mod is partly originated from 2.6.0.5, avstp would work with it, at least I haven't removed this feature.

Groucho2004
7th December 2016, 10:12
I'm not using avstp but since my mod is partly originated from 2.6.0.5, avstp would work with it, at least I haven't removed this feature.
Hm, I did not even try that. Anyway, multi-threading by using avstp is unfortunately not very efficient so it's better to use AVS+ or SEt's AVSMT for that.

StainlessS
7th December 2016, 18:56
but at this time the point was to keep it as simple and fast as possible.

You could set defaults Prefilter=False, Recalc=0, and perhaps Overlap=0 Chroma=false, for speed (Flow =true/false depending upon preference).
I dont know best settings for Chroma, Overlap and thSAD args, someone needs to do tests and make suggestions for better defaults for specific purpose,
ie speed or quality.
Purpose of function was to make testing easier without having to have a dozen or more different functions.
There is little unnecessary overhead in the function, perhaps a little in the pre frame serving stage only (during filter graph construction,
maybe a few milliseconds).

manolito
8th December 2016, 14:31
Many hours later I have some interesting test results...

The test results can be downloaded here:
https://we.tl/0JWNRaj3nj

I used two source files. The first one comes from Groucho, the other one is a very demanding anime clip. I converted both sources to SD resolution so my slow computer could play them.

For the conversion I used three scripts:
1. The original MotionProtectedFPS script
2. The script by StainlessS from the top of this page
3. The script by JohnMeyer from post #18 in this thread

For the StainlessS script I had to install the older MVTools2 v2.5.11.22 because the current pinterf mods do not like my non-SSE2 CPU. I did not get any errors using the default values so I think everything was OK.

For the JohnMeyer script I removed the little dirty trick to interleave the result with the source.


For all three scripts I also tried to convert the source to twice the source fps, but this was not helpful. The resulting clips were not smoother, and the motion artifacts were even more prominent.

Speed was very similar for the scripts. MotionProtectedFPS clocked in at 1.7fps, StainlessS was 1.5fps, and JohnMeyer came in at 1.4fps. Not too significant.


Now for the quality:
Motion artifacts cannot be avoided for these methods, the question is how unpleasant these artifacts are.

MotionProtectedFPS:
Lot of ghosting on the girl's leg for Groucho's clip. The anime clip is very critical at 1min 55sec. The vertical edges of the grill do have considerable warping artifacts.

StainlessS:
No difference for Groucho's clip. The anime clip does look slightly better.

JohnMeyer:
By far the least motion artifacts. BUT...
For both clips during the first 10 seconds there is some horrible motion judder. I have no idea if this can be fixed by different params for the backward motion vectors. The judder disappears completely after the first 10 seconds, so there should be a way to treat the beginning of a clip differently from the rest. Don't know...


Cheers
manolito

johnmeyer
8th December 2016, 18:49
JohnMeyer:
By far the least motion artifacts. BUT...
For both clips during the first 10 seconds there is some horrible motion judder. I have no idea if this can be fixed by different params for the backward motion vectors. The judder disappears completely after the first 10 seconds, so there should be a way to treat the beginning of a clip differently from the rest. Don't know...
oConverting the video to SD pretty much invalidates everything else you did because it changes how the tools work (see my post a few years ago about bugs in some versions of MVTools2 when used with certain resolutions). It also may have introduced other issues.

Before I submitted my script code earlier in this thread, I tuned it using the original HD clip. I can assure you that there was absolutely zero judder. Groucho2004 also tried the code and had some nice things to say, and didn't report any judder.

So, I suspect that whatever you used to change the resolution ended up screwing up the video.

johnmeyer
8th December 2016, 19:13
I created some video from the "torture test" clip. I used exactly the script I already posted, but addedassumefps(24.0 * 1000.0 / 1001.0)to the end so that the result was slow motion. I used Cineform for the codec.

Here's the link to resulting the 67 MB clip:

50% Slo-Mo test using "torture clip" (https://www.mediafire.com/?aj871mrbrf8m1qe)

Groucho2004
8th December 2016, 19:51
JohnMeyer:
By far the least motion artifacts. BUT...
For both clips during the first 10 seconds there is some horrible motion judder.
I suspect that you have a mistake in the script, I can't reproduce the "judder" from your sample clips. Wrapping John's code into a slo-mo function would look like this:
AVISource("str.avi")
SloMo(multi = 2)

function SloMo(clip source, int "multi")
{
org_num = FramerateNumerator(source)
org_den = FramerateDenominator(source)
multi = default(multi, 2)

prefiltered = RemoveGrain(source, 22)
super = MSuper(source, hpad = 16, vpad = 16, levels = 1) # one level is enough for MRecalculate
superfilt = MSuper(prefiltered, hpad = 16, vpad = 16) # all levels for MAnalyse
backward = MAnalyse(superfilt, isb = true, blksize = 16, overlap = 4, search = 3, dct = 0)
forward = MAnalyse(superfilt, isb = false, blksize = 16, overlap = 4, search = 3, dct=0)
forward_re = MRecalculate(super, forward, blksize = 8, overlap = 2, thSAD = 100)
backward_re = MRecalculate(super, backward, blksize = 8, overlap = 2, thSAD = 100)
multiclip = MFlowFps(source, super, backward_re, forward_re, num = org_num * multi, den = org_den, ml = 200, mask = 2)
out = AssumeFPS(multiclip, org_num, org_den)

return out
}

Groucho2004
8th December 2016, 19:58
I used Cineform for the codec.[/URL]I can't find a standalone codec/decoder for this.

johnmeyer
8th December 2016, 20:01
I can't find a standalone codec/decoder for this.It used to be easy to get, but since GoPro bought Cineform, they bundled the codec into their "Cineform Studio" free editor.

I can encode and then upload using a different codec. Which one would you suggest?

Groucho2004
8th December 2016, 22:20
I can encode and then upload using a different codec. Which one would you suggest?
UTVideo or, if that results in a too large file, x264 (MKV) with a low CRF like 12-14.

StainlessS
8th December 2016, 22:23
Thank you Mani,
No surprise that JohnMeyer is the king, pin, I suspected it all the long :)
I tried my best to amalgamate what was considered 'bestish', I think pretty much all tests talked about could be included in the test function that I provided,
We are waiting for Mani's test :) *You still got a lovely smile Mani, I suspect that it is not really yours).

Mani, test alternative switches in the StainleSSS, thing, what you like best ?

(The StainlessS thing is just all of the others, mixed together)

johnmeyer
9th December 2016, 01:34
I must be having a senior moment because I'm not sure where to get the MKV codec so I can encode from within VirtualDub. Is this the right place?

http://www.mkvcodec.com/

Groucho2004
9th December 2016, 03:18
I must be having a senior moment because I'm not sure where to get the MKV codec so I can encode from within VirtualDub. Is this the right place?

http://www.mkvcodec.com/
MKV is just a container. With x264 you can directly encode the script and wrap the elementary stream in a MKV. Just specify the extension .mkv for the output file.
As for VDub - The only encoding I do with VDub is to UTVideo, I prefer using the command line. However, there is an option to use external command line encoders like x264 but I have never used it. I hope someone more knowledgable than me can provide better guidance.

manolito
9th December 2016, 09:36
I suspect that you have a mistake in the script, I can't reproduce the "judder" from your sample clips. Wrapping John's code into a slo-mo function would look like this:

You may call me "AviSynth challenged", but I have been around long enough to be able to wrap a script into a function, thank you very much... :D:D

After a lot of more tests I finally found the stupid culprit. It was DirectShowSource (which I used just for laziness - I am integrating the routine into a universal speed conversion tool which I made for some musician friends, and everyone has DirectShowSource).

Anyway, johnmeyer's script seems to do a lot more seeking than the other scripts. Now I use DSS2Mod with a preroll value of 15, and the judder is completely gone...


@ StainlessS
Sorry so far I did not find any time to play with the params in your script. I don't even know if I will do it at all, because johnmeyer's script just works beautifully with all the clips I tried so far.


@ johnmeyer
Converting the video to SD pretty much invalidates everything else you did because it changes how the tools work (see my post a few years ago about bugs in some versions of MVTools2 when used with certain resolutions). It also may have introduced other issues.

Before I submitted my script code earlier in this thread, I tuned it using the original HD clip. I can assure you that there was absolutely zero judder. Groucho2004 also tried the code and had some nice things to say, and didn't report any judder.

So, I suspect that whatever you used to change the resolution ended up screwing up the video.

No, it didn't. I used Spline36Resize which is very neutral and encoded with HCenc at a bitrate of 8500 and the highest quality settings. I use Fizick's latest MVTools version.

Well, the issue is solved... :o
I do have a different philosophy on these things. I do not care this much about HD and UHD resolutions, for my aging eyes DVD resolution is all I need. And the inherent problems for motion protected FPS conversions are the same for HD and SD.

And then I certainly have no use for an FPS converter which needs to be fine tuned for every source. An FPS converter is not a creative or artistic tool like a lot of other filters. It just has to get the job done without introducing any (or at least as few as possible) artifacts. And its settings should work well for all sources.

For me your script does just that, it works way better than the other scripts I tested. Thanks a lot for sharing it.

BTW I just saw that you are from California. I hope that the rainy season hasn't started yet. I get a little homesick for Santa Cruz, I haven't been there in a couple of years... ;)


Cheers
manolito

amayra
9th December 2016, 12:07
so this script is like FrameTools (https://github.com/gdiaz384/frameTools) ?

manolito
9th December 2016, 15:34
No, I cannot see any similarities...

Cheers

manolito
9th December 2016, 15:39
Here is the little Speed Changing tool I was talking about. Download here:
https://files.videohelp.com/u/172211/ChangeSpeed.zip

I made it a while ago for a musician friend who needed this to slow down music clips while preserving the pitch so he could learn the songs more easily.

It is rough and ugly, but it does what it was intended for. Right now I integrated johnmeyer's FPS conversion script plus I updated all the tools.

Have fun...

Cheers
manolito

johnmeyer
9th December 2016, 17:59
Anyway, johnmeyer's script seems to do a lot more seeking than the other scripts. Now I use DSS2Mod with a preroll value of 15, and the judder is completely gone...

... And the inherent problems for motion protected FPS conversions are the same for HD and SD.
I'd be interested to know what you meant by "seeking." I'd love to make it run faster.

As for your second statement, it it generally correct, but it also is misleading for two reasons. The first I already mention: there is a bug in some version of MVTools2 which only shows up at certain resolutions. The second reason is that the block sizes you choose are going to depend on the resolution. To illustrate, if you had a video that was only 16x16 pixels, a block size of 16 would not do much for you. Put another way, the block size needs to be chosen with some thought to the size of the "structures" you are attempting to track. As you increase the number of pixels used to represent the same scene, the block size (and overlap) probably have to be increased.

Groucho2004
9th December 2016, 18:05
I'd be interested to know what you meant by "seeking." I'd love to make it run faster.
It means that MVTools requests frames in a non-linear fashion in this script. The source filter has to provide past and future frames relative to the current frame. DirectShowSource is notorious for choking on non-linear frame requests and should be avoided if possible.

johnmeyer
9th December 2016, 18:28
Thanks for the clarification, Groucho2004. Is there any way to control this? I guess I've heard of this before because there is a "Requestlinear" statement that is available with some AVISynth filters.

manolito
9th December 2016, 20:25
The second reason is that the block sizes you choose are going to depend on the resolution. To illustrate, if you had a video that was only 16x16 pixels, a block size of 16 would not do much for you. Put another way, the block size needs to be chosen with some thought to the size of the "structures" you are attempting to track. As you increase the number of pixels used to represent the same scene, the block size (and overlap) probably have to be increased.

Yes, I see your point. But the values for block size and overlap you used in your script do work very well for all the SD clips I tested so far. Looks like you hit the sweet spot...

But even if there is a linear relation between the source resolution and the optimum block size and overlap, shouldn't it be possible to automatically pick the optimal values? AviSynth knows the source frame size.

My main use for motion protected fps conversion is not slo-mo, it is standard conversion between NTSC and PAL. The usual methods all have their flaws. PAL folks often have not much tolerance for repeated or dropped fields. Right now I am running a torture NTSC -> PAL conversion where the source is truly interlaced (Prince - The Hits). The usual method introduces some judder (bob deinterlace, changeFPS, resize and reinterlace). What I am trying now is same rate deinterlace, resize and convert framerate to progressive 25 fps using your script.

I already tried this a while ago using MotionProtectedFPS, the result was not bad at all, but still too many artifacts. I am very curious how this conversion using your script will come out.


Cheers
manolito

Groucho2004
9th December 2016, 21:42
Thanks for the clarification, Groucho2004. Is there any way to control this? I guess I've heard of this before because there is a "Requestlinear" statement that is available with some AVISynth filters.
If you're using a decent source filter with frame accurate seeking you should usually not need helper functions like RequestLinear. I never needed it, even with multi-threaded QTGMC().

manolito
10th December 2016, 14:43
Right now I am running a torture NTSC -> PAL conversion where the source is truly interlaced (Prince - The Hits Collection - US release). The usual method introduces some judder (bob deinterlace, changeFPS, resize and reinterlace). What I am trying now is same rate deinterlace, resize and convert framerate to progressive 25 fps using your script.

I already tried this a while ago using MotionProtectedFPS, the result was not bad at all, but still too many artifacts. I am very curious how this conversion using your script will come out.

This conversion took a long time on my ancient desktop machine at 1.5 fps, but it was worth it. The source is very demanding, and my older MotionProtectedFPS conversion displayed a lot of artifacts. Not too annoying, but still. Especially the end credits with vertically moving letters looked bad.

And now this conversion using johnmeyer's script does not have any of these artifacts. Near perfect, even the end credits. I think that for motion protected fps conversions this script is all you can ask for. It will certainly replace the MotionProtectedFPS routine for me.


Thanks and cheers
manolito

StainlessS
10th December 2016, 17:56
Ok, here mod of previous test function + a bit more.
Modded to be (I think) by default, same as JohnMeyer's offering, with exception of SearchParam in MRecalculate which is dropped down from 3 in MAnalyse (default 2),
down to 1. Flow default changed to True. Recalc to 1.
Also added Flow_ml and Block_Mode args.
Maybe someone like to test for modified SearchParam.

Also, Added John's Interleave original frames jiggery pokery [implemented in MulRate()] and works also with frames multiplier greater than 2.


Function ChangeFrameRate(clip c,Bool "Blend",Bool "Flow",Int "Num",Int "Den",
\ Bool "Prefilter",Bool "Chroma",Bool "Chroma1",Bool "Chroma2",
\ Int "BlkSize",Int "Recalc",
\ Int "OverLap",Int "OverLap1",Int "OverLap2",
\ Int "thSAD1",Int "thSAD2",
\ Float "Flow_ml",
\ Int "Block_Mode"
\ ) {
# Req MvTools2 v2.7.1.22+ for FINAL Overlap>0
Blend = Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow = Default(Flow,True) # If True, Use MFlowFps instead of MBlockFps
n=Default(num,0) d=default(den,0) valid=(n>0 && d>0) n=(!valid)?c.FramerateNumerator*2:n d=(!valid)?c.FramerateDenominator:d # Default=doublerate
Prefilter=Default(Prefilter,True)
Chroma = Default(Chroma ,True)
Chroma1 = Default(Chroma1,True)
Chroma2 = Default(Chroma2,True)
BlkSize = Default(BlkSize,16)
Recalc = Default(Recalc,1) # 0 -> 2.
Overlap = Default(Overlap ,4)
Overlap1= Default(Overlap1,2)
Overlap2= Default(Overlap2,0)
thSAD1 = Default(thSAD1,100) # MRecalculate default is 200
thSAD2 = Default(thSAD2,100)
Flow_ml = Float(Default(Flow_ml,200.0))
Block_Mode=Default(Block_Mode,0) # 0 (Fastest, default) -> 5(debug)
Assert(0 <= Recalc <=2,"ChangeFrameRate: 0 <= ReCalc <= 2")
super = c.MSuper(pel=2, hpad=BlkSize, vpad=BlkSize,rfilter=4,Levels=(0<Recalc)?1:0) # MRecalculate needs only 1 Level, MAnalyse needs all Levels
MAnal = (Prefilter) ? c.RemoveGrain(22).MSuper(hpad=BlkSize, vpad=BlkSize) : Super
bv = MAnal.MAnalyse(isb=true, chroma=Chroma, blksize=BlkSize, OverLap=OverLap , search=3, searchparam=3, badrange=(-24), plevel=0)
fv = MAnal.MAnalyse(isb=false, chroma=Chroma, blksize=BlkSize, OverLap=OverLap , search=3, searchparam=3, badrange=(-24), plevel=0)
bv = (0<ReCalc)?MRecalculate(super, chroma=Chroma1, bv, blksize=BlkSize/2, Overlap=OverLap1, search=3, searchparam=1, thSAD=thSAD1):bv
fv = (0<ReCalc)?MRecalculate(super, chroma=Chroma1, fv, blksize=BlkSize/2, Overlap=OverLap1, search=3, searchparam=1, thSAD=thSAD1):fv
bv = (1<ReCalc)?MRecalculate(super, chroma=Chroma2, bv, blksize=BlkSize/4, Overlap=OverLap2, search=3, searchparam=0, thSAD=thSAD2):bv
fv = (1<ReCalc)?MRecalculate(super, chroma=Chroma2, fv, blksize=BlkSize/4, Overlap=OverLap2, search=3, searchparam=0, thSAD=thSAD2):fv
Return (!Flow)
\ ? c.MBlockFps(super, bv, fv, num=n, den=d, Blend=Blend, mode=Block_Mode)
\ : c.MFlowFps(super, bv, fv, num=n, den=d, Blend=Blend, ml =Flow_ml)
}

Function MulRate(clip c,Bool "Blend",Bool "Flow",int "mul",Bool "ILeave") {
Function MulRate_EvS(String s,int n,int mul) {
s=(s!="")?","+s:s
s="SelectEvery("+String(mul)+","+String(n)+")"+s
# RT_DebugF("s='%s'",s,name="MulRate: ")
return (n>1)?MulRate_EvS(s,n-1,mul):s
}
c
mul=default(mul,2)
Ileave=Default(Ileave,True)
ChangeFrameRate(Blend,Flow,c.FramerateNumerator*mul,c.FramerateDenominator)
(ILeave&&mul>=2) ? Eval("Interleave(c,"+MulRate_EvS("",mul-1,mul)+")") : NOP
Return Last
}

Function DoubleRate(clip c,Bool "Blend",Bool "Flow",Bool "ILeave") { return c.MulRate(Blend,Flow,2,ILeave) }

Function SlowMo(clip c,Bool "Blend",Bool "Flow", int "mul",Bool "ILeave") {
c
MulRate(Blend,Flow,mul,ILeave)
Return Last.assumefps(c.FrameRateNumerator,c.FrameRateDenominator)
}



client

AVISource("D:\SlowMoTester.mkv.AVI")

SlowMo(mul=2,iLeave=True) # Double framecount, Interleave (EDIT: replace with) original frames every even frame.


EDIT: Blend=False, unlike John's default true, I refuse to use blend mode (change yourself if you prefer not being able to detect scene changes).

EDIT: On-site edit broke script, fixed.

Creates some weird warping if you set mul to 10.

manolito
11th December 2016, 10:06
Thanks StainlessS for the new script. Very nifty scripting. especially the MulRate function for the ILeave thing, you are a real AviSynth wiz... :cool:

I did a few tests already, the source was the most critical section of my Anime clip.

Results:
johnmeyer's script still gets my top rating.

Yours is very close, probably no visual difference with natural film. But still the artifacts on this vertical grill are a little more prominent. The Blend and ILeave variables made no difference at all to my eyes.

And MotionProtectedFPS is just not competetive any longer... :devil:

Download the resulting clips here:
http://www47.zippyshare.com/v/lJmnElOu/file.html


Cheers
manolito

johnmeyer
11th December 2016, 17:00
Just a note to anyone who does their own comparisons: you have to tune the script to get good results. I am flattered that "my script" produces good results, but that is mostly due to the fact that I spent ten minutes trying dozens of different settings (block size, overlap, threshholds, etc.) until I got a good result. I then posted the script with those settings. I suspect that you might get equal -- or perhaps better -- results with some of the other scripts if you did similar tuning yourself.

More to the point: don't think that my script is some sort of slow-motion panacea. It too will produce worse results than will some other scripts when fed a different test case.