View Full Version : MVTools, Depan, DepanEstimate for VapourSynth
jackoneill
21st September 2014, 21:36
So I thought, "Why not port MVTools?"
https://github.com/dubhater/vapoursynth-mvtools/releases
readme.rst (https://github.com/dubhater/vapoursynth-mvtools/blob/master/readme.rst)
Now includes ports of Depan and DepanEstimate.
Crashes or corrupted output may happen, as I haven't done very extensive testing.
Reel.Deel
21st September 2014, 21:49
Awesome! :)
Thanks for your efforts.
Mystery Keeper
22nd September 2014, 00:22
Myrsloik was against it, but since we've got no better alternative, THANK YOU! With native motion compensation VapourSynth can finally have all the best filters without the need to use AviSynth plugins!
feisty2
22nd September 2014, 03:33
dope work, thx for ur support to vapoursynth, I'm tryna have a taste of new vapoursynth lately
Myrsloik
22nd September 2014, 13:32
Myrsloik was against it, but since we've got no better alternative, THANK YOU! With native motion compensation VapourSynth can finally have all the best filters without the need to use AviSynth plugins!
I was mostly against touching that code myself and trying to clean it up. It's obvious that jackoneill can tolerate worse code than me.
Now it's time for some VapourSynth world domination!
jackoneill
22nd September 2014, 19:41
v1.1 fixes a crash and brings back the "dct" parameter to Analyse and Recalculate. Now you can make your scripts really slow.
lansing
23rd September 2014, 03:18
great news, have been waiting for this who knows how long.
I did some benchmarks with the sample script for mdegrain2 in the documentation,
AVISource("c:\test.avi") # or MPEG2Source, DirectShowSource, some previous filter, etc
super = MSuper(pel=2, sharp=1)
backward_vec2 = MAnalyse(super, isb = true, delta = 2, overlap=4)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, overlap=4)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, overlap=4)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, overlap=4)
MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400)
super = core.mv.Super(src)
mvbw2 = core.mv.Analyse(super, isb=True, delta=2, overlap=4)
mvbw = core.mv.Analyse(super, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(super, isb=False, delta=1, overlap=4)
mvfw2 = core.mv.Analyse(super, isb=False, delta=2, overlap=4)
out = core.mv.Degrain2(clip=src, super=super, mvbw=mvbw, mvfw=mvfw, mvbw2=mvbw2, mvfw2=mvfw2, thsad=400)
cpu can be loaded 100%, 64 bit version is about 20% faster than 32 bit version. With a 720x480 source, 64 bit gave me 60fps while 32 bit gave me 50fps.
Keiyakusha
23rd September 2014, 07:54
On i7 8 threads, the same script as above looks something like this for me:
Vapoursynth x86, d2vsource, vapoursynth-mvtools:
threads=4 -> 27fps, 50% CPU
threads=8 -> 40fps, 100% CPU
AVS+ x86 MT, mpeg2source, mvtools SVP:
Prefetch(4) -> 42fps, 50% CPU
Prefetch(8) -> 57fps, 100% CPU
Edit:
AVS 2.6 x86 MT, mpeg2source, mvtools SVP:
4 threads -> 40fps, 42% CPU
8 threads -> 55fps, 93% CPU
Edit2:
Vapoursynth x86, d2vsource, mvtools SVP (avs plugin):
threads=4 -> 41fps, 50% CPU
threads=8 -> 42fps, 60% CPU (wow, this one sucks >__<)
Anyway, to sum this up, for me vapoursynth-mvtools port is way slower than any other solutions.
Are_
23rd September 2014, 11:54
This is on an AMD cpu 8 cores.
MPEG2Source was used on avisynth, and d2vsource for vapoursynth, source was a VOB file from a DVD and used the sample code from lansing:
# AVISYNTH 2.6 MT - MVTOOLS SVP
Frames processed: 2501 (0 - 2500)
FPS (min | max | average): 34.21 | 82.74 | 51.78
CPU usage (average): 94%
Thread count: 10
Physical Memory usage (peak): 585 MB
Virtual Memory usage (peak): 733 MB
Time (elapsed): 000:00:48.304
# VAPOURSYNTH WIN32
Output 2500 frames in 67.32 seconds (37.13 fps)
# VAPOURSYNTH LINUX x86_64 (-march=native -O2)
Output 2500 frames in 55.85 seconds (44.76 fps)
# VAPOURSYNTH LINUX x86_64 (-march=native -Ofast -lto)
Output 2500 frames in 54.89 seconds (45.55 fps)
# VAPOURSYNTH LINUX x86_64 (retarded compiler flags optimizations)
Output 2500 frames in 53.39 seconds (46.83 fps)
All vapoursynth tests were topping the cpu at 100%.
I don't know why avisynth scored so poorly for me compared to Keiyakusha. :/
DarkSpace
23rd September 2014, 12:15
I guess that the difference comes from the fact that Keiyakusha used the SVP MVTools, while the Dither MVTools are probably (does anyone know for certain?) based on the original MVTools2 rather than the modified SVP MVTools.
Keiyakusha
23rd September 2014, 12:16
I don't know why avisynth scored so poorly for me compared to Keiyakusha. :/
Looks like you incorrectly used MT in Avisynth. It reports threadcount 8 and cpu load 33% but this threadcount is a total value from all the processes involved, means mvtools processing probably was using way less threads.
Edit: well anyway, maybe avsmeter author can explain what this value really shows, but in my case the number of threads was like twice than the ones you have even in case avisynth was configured to 4 threads.
Also in any multithreaded environment, mvtools svp should be noticeably faster than the one from dither package (assuming latter one runs without avstp). However in singlethreaded environment SVP is slower than alternatives.
Edit: in case of AVS+ with the script above, my threadcount reads 20 for Prefetch4 and 24 for Prefetch8. Have no time to install AVS2.6 again but I expect it to be similar.
Are_
23rd September 2014, 12:40
Ok my bad, I didn't know setting mtmode half script does not work.
Updated results in the original post.
TurboPascal7
23rd September 2014, 12:51
Edit: in case of AVS+ with the script above, my threadcount reads 20 for Prefetch4 and 24 for Prefetch8. Have no time to install AVS2.6 again but I expect it to be similar.
More info on this here (http://forum.doom9.org/showpost.php?p=1668266&postcount=629). It has nothing to do with avsmeter, just avs+ being buggy.
Keiyakusha
23rd September 2014, 13:02
More info on this here (http://forum.doom9.org/showpost.php?p=1668266&postcount=629). It has nothing to do with avsmeter, just avs+ being buggy.
Even with avs 2.6 MT avsmeter displays more threads than the number we set in "setmtmode". For whatever reason.
But yeah, I wondered why I have the whole 20+ threads. This explains it!
jackoneill
23rd September 2014, 13:41
Anyone want to compare this version's speed when using a single thread and the original Avisynth plugin (2.5.11.3) running in a non-MT Avisynth?
Myrsloik
23rd September 2014, 13:48
Anyone want to compare this version's speed when using a single thread and the original Avisynth plugin (2.5.11.3) running in a non-MT Avisynth?
Original meaning the dither tools version of mvtools. right?
jackoneill
23rd September 2014, 14:20
Original meaning the dither tools version of mvtools. right?
No, original is this: http://avisynth.org.ru/mvtools/mvtools-v2.5.11.3.zip. 8 bit and no internal multithreading.
The one from Dither is a fork of an earlier version of this original.
foxyshadis
23rd September 2014, 19:51
Single threaded performance on my Haswell laptop, 720x480 video, mvdegrain2 script above:
mvtools 2.5: 9.7fps
mvtools 2.6: 20.6fps
vsmvtools 32: 21.0fps
vsmvtools 64: 23.9fps
8-threaded performance:
vsmvtools 32: 36.6
vsmvtools 64: 41.2
Will edit in with avisynth threaded performance when I get hold of it again.
lansing
23rd September 2014, 22:44
720x480 source,
non-mt avisynth mvtools2 original: 12.89fps
single thread vapoursynth:
32 bit: 11.77fps
64 bit: 15fps
Keiyakusha
24th September 2014, 08:58
720x480 source. All used plugins are the latest versions.
AVS 2.6 Alpha5, mpeg2source:
vanilla-mvtools: CPU ~15%; 10 fps
svp-mvtools: CPU ~15%; 12.3 fps
dither-mvtools: CPU ~15%; 9.3 fps (without avstp)
Vapoursynth x86, d2vsource:
vapour-mvtools: CPU ~15%; 8.75 fps (threads=1)
Edit: also it might be useful to note that without any processing, d2vsource is 2 times faster than mpeg2source (1000+ fps) so it can't cause any fps drop.
Reel.Deel
24th September 2014, 14:58
A while back I did some speed test with different versions of MVTools. Results were similar to Keiyakusha's; MVTools from SVP (http://svp-team.com/wiki/Plugins:_MVTools2) is faster than the rest. On their website they claim MAnalyze to be faster. Maybe jackoneill can include this difference?
MAnalyse
Can be faster than original version (with chroma=true) by 20-40%, look at PlaneOfBlocks.h for changes.
Bloax
24th September 2014, 15:55
Mmm, sounds like I'll have to replace Avisynth soon.
Great news!
Are_
24th September 2014, 21:58
Some more test, mvdegrain2 script above:
### 1 thread ###
## 720x480p ##
# AVISYNTH 2.6 Beta 5 - vanilla mvtools :: 7.21 fps
# VAPOURSYNTH WINDOWS 32bit :: 6.46 fps
# VAPOURSYNTH WINDOWS 64bit :: 7.99 fps
# VAPOURSYNTH LINUX 64bit :: 7.92 fps
## 1920x1080p ##
# AVISYNTH 2.6 Beta 5 - vanilla mvtools :: 1.09 fps
# VAPOURSYNTH WINDOWS 32bit :: 0.93 fps
# VAPOURSYNTH WINDOWS 64bit :: 1.09 fps
# VAPOURSYNTH LINUX 64bit :: 1.18 fps
### 8 threads ###
## 720x480p ##
# AVISYNTH 2.6 MT - vanilla mvtools :: 40.38 fps
# VAPOURSYNTH WINDOWS 32bit :: 37.24 fps
# VAPOURSYNTH WINDOWS 64bit :: 45.66 fps
# VAPOURSYNTH LINUX 64bit :: 47.06 fps
## 1920x1080p ##
# AVISYNTH 2.6 Beta 5 - vanilla mvtools :: 6.08 fps
# VAPOURSYNTH WINDOWS 32bit :: 4.95 fps
# VAPOURSYNTH WINDOWS 64bit :: 5.78 fps
# VAPOURSYNTH LINUX 64bit :: 6.53 fps
Groucho2004
25th September 2014, 08:51
Even with avs 2.6 MT avsmeter displays more threads than the number we set in "setmtmode". For whatever reason.
But yeah, I wondered why I have the whole 20+ threads. This explains it!
AVSMeter displays the the number of threads spawned by avisynth and all loaded modules (DLLs). If a module spawns multiple threads itself (in combination with AVSTP, for example), they will of course be added to the thread count.
Mystery Keeper
25th September 2014, 11:05
Concerning the speed: building it with MSVC would probably help.
jackoneill
28th September 2014, 12:31
v2.0 is out (https://github.com/dubhater/vapoursynth-mvtools/releases).
The last two filters used by QTGMC are now available. I'm curious how these two perform compared to the original Avisynth plugin, because I replaced some inline asm with C code.
If you're feeling grateful for this and other VapourSynth ports, maybe buy me an ebook (https://gist.github.com/dubhater/12a6af383dd006999ba3).
Mystery Keeper
28th September 2014, 13:39
What a glorious day! Thank you very much for your hard work!
Reel.Deel
28th September 2014, 15:48
Good day indeed :). Is there an accurate way to measure speed/performance in VS?
Keiyakusha
28th September 2014, 16:01
Good day indeed :). Is there an accurate way to measure speed/performance in VS?
vspipe?
---
BTW, with the script posted on the 1st page, speed is about the same for 2.0 build. But I it doesn't uses "last two filters". Still QTGMC overall was slower with vapour-mvtools so with these filters speed will probably be same as before at best. This means we're still somehow dependent on avisynth plugin in case of x86 architecture.
Are_
28th September 2014, 22:37
Here we go.
Source was 720x480p. MPEG2Source for avisynth, d2vsource for vapoursynth.
super = core.mv.Super(src)
mvbw = core.mv.Analyse(super, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(super, isb=False, delta=1, overlap=4)
out = core.mv.FlowBlur(clip=src, super=super, mvbw=mvbw, mvfw=mvfw, blur=100)
1 thread
# AVISYNTH 2.6 Beta 5 - vanilla mvtools
11.60 fps
# VAPOURSYNTH WINDOWS 32bit
9.92 fps
# VAPOURSYNTH WINDOWS 64bit
11.80 fps
# VAPOURSYNTH LINUX 64bit
12.00 fps
8 threads
# AVISYNTH 2.6 MT - vanilla mvtools
57.76 fps
# VAPOURSYNTH WINDOWS 32bit
55.96 fps
# VAPOURSYNTH WINDOWS 64bit
65.95 fps
# VAPOURSYNTH LINUX 64bit
69.11 fps
super = core.mv.Super(src)
vectors = core.mv.Analyse(super, isb=False, delta=1, overlap=4)
out = core.mv.Mask(src, vectors)
1 thread
# AVISYNTH 2.6 Beta 5 - vanilla mvtools
27.81 fps
# VAPOURSYNTH WINDOWS 32bit
24.22
# VAPOURSYNTH WINDOWS 64bit
28.46 fps
# VAPOURSYNTH LINUX 64bit
31.01 fps
8 threads
# AVISYNTH 2.6 MT - vanilla mvtools
108.77 fps
# VAPOURSYNTH WINDOWS 32bit
130.80 fps
# VAPOURSYNTH WINDOWS 64bit
151.90 fps
# VAPOURSYNTH LINUX 64bit
168.53 fps
Revgen
28th September 2014, 23:20
Thank you jackoneill!
jackoneill
1st October 2014, 16:53
:goodpost:
May I request that MFlowInter be ported as well, which is used by Firesledge's ivtc_txt60mc (http://forum.doom9.org/showthread.php?p=1466105#post1466105) function. :thanks:
ivtc_txt60mc is a useful function.
jackoneill
3rd October 2014, 15:11
v3 is out (https://github.com/dubhater/vapoursynth-mvtools/releases). It includes FlowInter and fixes for two problems.
I realised that a single version number is sufficient.
feisty2
3rd October 2014, 16:47
add mdegrainN and multivectors functions maybe?
large time radius could be kinda useful along with dct=1 to those "shivering" kinda clips
jackoneill
3rd October 2014, 17:48
add mdegrainN and multivectors functions maybe?
large time radius could be kinda useful along with dct=1 to those "shivering" kinda clips
Maybe. What are these multivector functions?
feisty2
3rd October 2014, 18:08
they are from the modified version in ditherpackage
with "multi=true" in manalyse, a common vector clip will turn into multivectors clips
and the special multivectors clips can be passed to special functions like mdegrainN or mcompensate via "tr" parameter
feisty2
3rd October 2014, 18:17
vmulti=super.manalyse (delta=6,multi=true) is simply identical to
bv6=super.manalyse (delta=6,isb=true)
bv5
bv4
...
fv4
fv5
fv6
Mystery Keeper
3rd October 2014, 18:22
feisty2, here (https://bitbucket.org/mystery_keeper/templinearapproximate-vapoursynth/src/5bbf9c72d57508dd1aef7ec3cc1efb1420444418/MCDenoise.py?at=master#cl-87) is how I do it.
feisty2
3rd October 2014, 18:30
wow, cool, thank you, Mystery Keeper :)
feisty2
3rd October 2014, 18:58
little pickle here, Mystery Keeper, what should I do if I want mdegrainn (tr=6) instead of mcompensate :(
spawnbsd
3rd October 2014, 20:50
Great plugin, but any idea when we'll see 16bit support ?
jackoneill
3rd October 2014, 21:06
Great plugin, but any idea when we'll see 16bit support ?
Dunno. This year, if I'm not too lazy.
On that topic, how does everyone feel about adding support for 16 bit input to Analyse by simply shifting it to 8 bit? Filters like the Degrains and Compensate will work with 16 bit input directly, of course.
Mystery Keeper
3rd October 2014, 21:44
little pickle here, Mystery Keeper, what should I do if I want mdegrainn (tr=6) instead of mcompensate :(Then, of course, you would need to write the function that takes array of clips. But I think that's better than generating special multivector clips.
Mystery Keeper
3rd October 2014, 21:45
On that topic, how does everyone feel about adding support for 16 bit input to Analyse by simply shifting it to 8 bit? Filters like the Degrains and Compensate will work with 16 bit input directly, of course. Should be alright. At least that would be a start. Personally, I'm looking forward to DCT.
Are_
3rd October 2014, 21:50
On that topic, how does everyone feel about adding support for 16 bit input to Analyse by simply shifting it to 8 bit? Filters like the Degrains and Compensate will work with 16 bit input directly, of course.
I don't see anything wrong with that.
foxyshadis
3rd October 2014, 22:09
On that topic, how does everyone feel about adding support for 16 bit input to Analyse by simply shifting it to 8 bit? Filters like the Degrains and Compensate will work with 16 bit input directly, of course.
Heck, you could probably get away with 4-bit for the most part. Obviously, dithering down would just introduce unwanted noise, but truncating should work fine. I look forward to it, someday!
feisty2
4th October 2014, 05:26
Mystery Keeper, I mean, the reason that large time radius mcompensate could be done this way is mcompensate only takes one vector clip once, if you have n vector clips, there would be n mcompensates, but mdegrain takes a lot of vector clips once basing on the time radius, so, I donno how to do the same thing to mdegrain like mcompensate
cretindesalpes
4th October 2014, 15:05
how does everyone feel about adding support for 16 bit input to Analyse by simply shifting it to 8 bit? Filters like the Degrains and Compensate will work with 16 bit input directly, of course.
Don’t waste your time at this, moreover it would be misleading. We can explicitly convert the high-bitdepth clips to 8 bits for analysis. Anyway, I think there is a definite benefit to run the analysis on 10–12 bits. I often remap the luma channel to increase the contrast is some specific ranges (generally the dark parts), and keeping 8 bits crunches other ranges, reducing the accuracy of the analysis on fine textures.
jackoneill
4th October 2014, 21:14
Don’t waste your time at this, moreover it would be misleading. We can explicitly convert the high-bitdepth clips to 8 bits for analysis. Anyway, I think there is a definite benefit to run the analysis on 10–12 bits. I often remap the luma channel to increase the contrast is some specific ranges (generally the dark parts), and keeping 8 bits crunches other ranges, reducing the accuracy of the analysis on fine textures.
Damn. No easy way out of it, huh.
chainik_svp
5th October 2014, 22:22
jackoneill
I really don't want to suggest anything but the code in SVPflow is really cleaned comparing to original MVTools ;)
Just compare a few numbers - as you already know all the magic is in "PlaneOfBlocks" cpp/h, and they're ~80 KB of code(*) in MVTools (and in your build too) BUT only 42 KB in SVPflow.
(*) huge commented blocks are also included
Also original MVTools loosing >= 20% of performance just for nothing...
Mystery Keeper
5th October 2014, 22:51
jackoneill
I really don't want to suggest anything but the code in SVPflow is really cleaned comparing to original MVTools ;)
Just compare a few numbers - as you already know all the magic is in "PlaneOfBlocks" cpp/h, and they're ~80 KB of code(*) in MVTools (and in your build too) BUT only 42 KB in SVPflow.
(*) huge commented blocks are also included
Also original MVTools loosing >= 20% of performance just for nothing...So would you kindly port it to VapourSynth?
chainik_svp
5th October 2014, 23:03
So would you kindly port it to VapourSynth?
Since we (SVP) need ffdshow support I'm thinking only of AVS+ 64bit right now.
But if "porting" is just a few interface functions then why not...
===
In fact it's not great to have so many branches of MVTools:
- original version
- the one with MT built-in
- SVP's build of original version plus (external) GPU rendering
- completely refactored SVPflow
- this VS version
and all the version but SVPflow share the very same code for MV search algorithm
Mystery Keeper
5th October 2014, 23:18
chainik_svp, put algorithm into static library and link it to the different projects?
chainik_svp
5th October 2014, 23:26
chainik_svp, put algorithm into static library and link it to the different projects?
this's how SVPflow is working :)
rendering part with GPU support (and some more features) is "hidden"
"MAnalyse" part is in a separate GPL library
since SVPflow is the only branch changing something in the MVTools' math I really think it should be the base for any other versions
Mystery Keeper
5th October 2014, 23:35
chainik_svp, keep in mind that VapourSynth is multithreaded (GPU use becomes complicated), cross-platform and both 32 and 64-bit versions are used. Though 32-bit version is only needed when script uses AviSynth plugins.
jackoneill
9th October 2014, 12:58
v4 is out (https://github.com/dubhater/vapoursynth-mvtools/releases), with more barely tested changes.
* Fix the use of an uninitialised variable in Recalculate (kind of important).
* Add some more SAD functions. Block sizes of 8x4, 16x2, 32x16, and 32x32 should now be just as fast as in the original Avisynth plugin.
* Allow YUV422P8 input. The filters only needed to accept such clips, because the required code was already there.
Are_
10th October 2014, 16:56
Wow, I'm having about ~20% speed improvement on my linux box, or I'm doing something wrong or you did a really good job there.
jackoneill
10th October 2014, 18:51
Wow, I'm having about ~20% speed improvement on my linux box, or I'm doing something wrong or you did a really good job there.
If you compiled the latest from git it's probably that change the SVP folks made. I finally copied it. v5 will have it.
Aurelio
7th November 2014, 14:38
Great work!
Any plans to port also MFlowFps and MBlockFps?
jackoneill
7th November 2014, 21:29
Great work!
Any plans to port also MFlowFps and MBlockFps?
Yes, there are plans.
Mystery Keeper
10th December 2014, 11:04
An unofficial build of MVTools test version with "dct" parameter back and working. (https://www.mediafire.com/?7vxaaf01dnqspqx)
Reel.Deel
23rd December 2014, 22:21
Since Mystery Keeper's build is already a few commits behind any plans to release a current binary?
Mystery Keeper
24th December 2014, 00:45
I just thought I shouldn't build on every commit and waited to be notified about release. Can build anytime.
jackoneill
24th December 2014, 11:09
Since Mystery Keeper's build is already a few commits behind any plans to release a current binary?
I don't think the newer commits change much for the user.
MonoS
24th December 2014, 14:53
Any information about 16bit??
jackoneill
24th December 2014, 16:47
Any information about 16bit??
It will happen in a few years.
jackoneill
2nd January 2015, 14:03
Here is v5 (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v5).
* Import speedup from the SVP fork. Affects every filter except Super.
* Add "search_coarse" parameter to Analyse, also from SVP.
* Add FlowFPS and BlockFPS.
* Bring back the "dct" parameter to Analyse and Recalculate (thanks to Mystery Keeper). I hope it sticks this time.
* Fix bug with infinite clips and isb=False in Analyse and Recalculate.
I'm told that FlowFPS is too slow for realtime frame rate conversion (24 to 60 fps). BlockFPS is probably fast enough, but its output is even uglier. :)
mark0077
5th January 2015, 20:33
I currently use SVP dlls with a customised InterFrame script in our HTPC. Is v5 above with the speedups and some of the params from SVP close to being everything that has changed from mvtools to SVP, or are there any plans for the full SVP code to be workable with vapoursynth.
Is it worth taking at this early stage for a live system over avisynth 2.6 MT with SVP dlls in terms of quality and speed?
jackoneill
6th January 2015, 11:35
I currently use SVP dlls with a customised InterFrame script in our HTPC. Is v5 above with the speedups and some of the params from SVP close to being everything that has changed from mvtools to SVP, or are there any plans for the full SVP code to be workable with vapoursynth.
Is it worth taking at this early stage for a live system over avisynth 2.6 MT with SVP dlls in terms of quality and speed?
I believe the speedup and the "search_coarse" parameter were the only changes between 2.5.11.3 and the SVP fork's 2.5.11.9. The SVP's additional filters are not open source, as far as I know.
I have heard that Avisynth MT is unstable and not very efficient in the way it does multithreading. :) The quality is the same. For the speed, see the comparisons posted earlier in this thread.
Pat357
25th January 2015, 19:00
I can't get Degrain (from libmvtools.dll v5) to work. Sometimes it works when I limit the threads to 1 and use only Degrain1.
With Avisynth MVTools version, I have no problems at all and can use threads=8 and MDegrain3.
What happens is that vspipe.exe always crashes when (trying) to produce an output clip. I get no error code or whatever.
When I use VSEDIT-32b, and do "check script" it gives all OK and provides me the correct properties from the output clip, but when I try to preview, the editor crashes the same way as vspipe.exe
Also using the VSFS plugin, it always creates a large .avi file, but as soon as I try to read it using a player, the file disappears and the player gives a black screen.
Faulting application name: vspipe.exe, version: 0.0.0.0, time stamp: 0x547394ac
Faulting module name: libmvtools.dll, version: 0.0.0.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x0023126e
Faulting process id: 0x112c
Faulting application start time: 0x01d038ba87e6c605
Faulting application path: c:\Program Files (x86)\VapourSynth\core32\vspipe.exe
Faulting module path: c:\Program Files (x86)\VapourSynth\filters\vapoursynth-mvtools-v5-win32\libmvtools.dll
Report Id: c5d8c719-a4ad-11e4-b6fb-005056c00008
Same for VSedit-32 :
Faulting application name: vsedit-32bit.exe, version: 3.0.0.0, time stamp: 0x548596cb
Faulting module name: libmvtools.dll, version: 0.0.0.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x0023126e
Faulting process id: 0x9c0
Faulting application start time: 0x01d038d06ee303c6
Faulting application path: K:\programs\VapourSynthEditor-32bit\vsedit-32bit.exe
Faulting module path: c:\Program Files (x86)\VapourSynth\filters\vapoursynth-mvtools-v5-win32\libmvtools.dll
Report Id: f88ead17-a4c3-11e4-b6fb-005056c00008
Fault bucket 813441851, type 17
Event Name: APPCRASH
Response: Not available
Cab Id: 0
Problem signature:
P1: vsedit-32bit.exe
P2: 3.0.0.0
P3: 548596cb
P4: libmvtools.dll
P5: 0.0.0.0
P6: 00000000
P7: c0000005
P8: 0023126e
P9:
P10:
Attached files:
F:\TEMP\WERD819.tmp.WERInternalMetadata.xml
These files may be available here:
C:\Users\patrick\AppData\Local\Microsoft\Windows\WER\ReportArchive\AppCrash_vsedit-32bit.exe_86177ff6bffc9c9619a498727ee95caed3faf8e0_172cf356
Analysis symbol:
Rechecking for solution: 0
Report Id: f88ead17-a4c3-11e4-b6fb-005056c00008
Report Status: 0
Here is my "problem" script :
import vapoursynth as vs
core = vs.get_core(threads=4, accept_lowercase = True)
core.std.LoadPlugin(path=r"c:\Program Files (x86)\VapourSynth\filters\vapoursynth-mvtools-v5-win32\libmvtools.dll")
core.avs.loadplugin(path=r"k:\programs\Neuron\dgmpgdec158\DGDecode.dll")
ret=core.avs.MPEG2Source(r"k:\film\Ghost Rider - Spirit of Vengeance (2012) HDTVRip\good files demuxed\ghost - 1 - MPEG2, 576p25.d2v")
ret=core.std.Trim(ret, 2000 , 5000)
ret = core.resize.Lanczos(clip=ret, width=720, height=480, format=vs.YUV420P8)
src=ret
c = core.mv.Super(src,pel=2, sharp=1)
bv3 = core.mv.Analyse(c, isb = 1, delta = 3, overlap=4)
bv2 = core.mv.Analyse(c, isb = 1, delta = 2, overlap=4)
bv1 = core.mv.Analyse(c, isb = 1, delta = 1, overlap=4)
fv1 = core.mv.Analyse(c, isb = 0, delta = 1, overlap=4)
fv2 = core.mv.Analyse(c, isb = 0, delta = 2, overlap=4)
fv3 = core.mv.Analyse(c, isb = 0, delta = 3, overlap=4)
# ret = core.mv.Degrain1(clip=src, super=c, mvbw=bv1, mvfw=fv1)
ret = core.mv.Degrain3(clip=src, super=c, mvbw=bv1, mvfw=fv1, mvbw2=bv2, mvfw2=fv2 ,mvbw3=bv3, mvfw3=fv3)
ret.set_output()
Any idea why vspipe and vsedit-32 both crash without any error ?
Also if I do "vspipe --info script.vpy - " , it does not crash and gives me the correct properties from output video, no crashes.
i7-970 3.2Ghz processor (6+6 cores), 24 GB RAM, WIN7pro-x64 , full up to date.
Vapoursynth r25 and r26rc2 both tested (32-bit versions), libmvtools.dll is latest v5, Python v3.4.2 (32-bit)
System is not over-clocked.
Other .vpy files that do not use the libmvtools.dll plugin the run great, so the installation is not the problem, I think.
Also, to exclude other factors as much as possible, this script based on "original MVTools" runs just fine :
import vapoursynth as vs
# import sys
core = vs.get_core(threads=8, accept_lowercase = True)
# core.std.LoadPlugin(path=r"k:\programs\ffms2-r936c59-avs_vsp\ffms2.dll")
# core.std.LoadPlugin(path=r"c:\Program Files (x86)\VapourSynth\filters\vapoursynth-mvtools-v5-win32\libmvtools.dll")
core.avs.loadplugin(path=r"k:\programs\Neuron\dgmpgdec158\DGDecode.dll")
core.avs.LoadPlugin(path=r"k:\programs\AviSynth 2.5\special filters\mvtools-v2.5.11.3\mvtools2.dll")
# core.std.LoadPlugin(path=r"k:\programs\AviSynth 2.5\special filters\Vapoursynth avisynth filters\vsrawsource.dll")
core.avs.LoadPlugin(path=r"k:\programs\AviSynth 2.5\special filters\masktools-v2.0a48\mt_masktools-26.dll")
core.avs.LoadPlugin(path=r"k:\programs\AviSynth 2.5\special filters\MaskTools-v1.5.8\MaskTools.dll")
# ret=core.ffms2.Source(r"k:\film\Battlefield_3_Fault_Line_Full_Trailer_mov_remux.mkv", threads=1)
ret=core.avs.MPEG2Source(r"k:\film\Ghost Rider - Spirit of Vengeance (2012) HDTVRip\good files demuxed\ghost - 1 - MPEG2, 576p25.d2v")
ret=core.std.Trim(ret, 2000 , 7000)
ret = core.resize.Lanczos(clip=ret, width=720, height=408, format=vs.YUV420P8)
src=ret
c = core.avs.MSuper(src,pel=2, sharp=1)
bv3 = core.avs.MAnalyse(c, isb = 1, delta = 3, overlap=4)
bv2 = core.avs.MAnalyse(c, isb = 1, delta = 2, overlap=4)
bv1 = core.avs.MAnalyse(c, isb = 1, delta = 1, overlap=4)
fv1 = core.avs.MAnalyse(c, isb = 0, delta = 1, overlap=4)
fv2 = core.avs.MAnalyse(c, isb = 0, delta = 2, overlap=4)
fv3 = core.avs.MAnalyse(c, isb = 0, delta = 3, overlap=4)
ret = core.avs.MDegrain3(src,c,bv1,fv1,bv2,fv2,bv3,fv3,thSAD=400)
# ret = core.avs.Degrain3(clip=src, super=c, mvbw=bv1, mvfw=fv1, mvbw2=bv2, mvfw2=fv2 ,mvbw3=bv3, mvfw3=fv3 , thsad=400)
# ret = core.avs.MDegrain3(c1=src,c2=c,c3=bv1,c4=fv1,c5=bv2,c6=fv2,thSAD=400)
# diff = core.avs.mt_makediff(src,ret1)
# ret2 = core.avs.mt_adddiff(src,diff)
# ret = core.resize.Lanczos(clip=ret, width=1440, height=720, format=vs.YUV420P8)
# last=ret
# ret = core.std.Trim(ret , 1 , 5001 )
# ret.output(sys.stdout, y4m=True)
# print(core.raws.FormatList())
# print(core.list_functions())
ret.set_output()
I spend already 2 full days to try to find the issue, and honestly I'm still clueless ;
- Testing other files and various formats and containers
- Testing with other plugins to read the files : AVISourse, FFMS v2.20, DGdecNV 2048, DG MPEG2Source 1.58, ...
- Memory consumption was never more then 400 MB.
How can I further debug this ? What tools can I use for this ?
Are_
25th January 2015, 20:18
This is strange, maybe related to de 32bit version on Windows.
Did you test 64bit version?
I managed a ~5h long encode making use of d2v+qtgmc+mvtools with no problems (also your snippet does not give me any error).
Mystery Keeper
25th January 2015, 21:05
24GB RAM? Why in the world are you using 32-bit versions? Use 64-bit. Crash with no error might very well be memory allocation error.
jackoneill
25th January 2015, 23:17
What if you pass "isse=False" to all the MVTools filters?
Also you can replace DGDecode with d2vsource (https://github.com/dwbuiten/d2vsource/releases).
foxyshadis
25th January 2015, 23:39
Hmm, an access violation doesn't sound like an out of memory, but a stray pointer somewhere. jackoneill, have you tried running the Clang Static Analyzer to check for issues? It's in Fedora with yum install llvm-clang-analyzer
jackoneill
26th January 2015, 13:03
I wouldn't know what to do with the static analyzer.
Does this happen to work better? http://ulozto.net/xZ99sXrQ/vapoursynth-mvtools-1ec0868f3bd9-win32-7z
If the DLL above still crashes, retest Degrain1 and Degrain2. In this new DLL either they all crash or they all work.
Pat357
26th January 2015, 13:16
What if you pass "isse=False" to all the MVTools filters?
Also you can replace DGDecode with d2vsource (https://github.com/dwbuiten/d2vsource/releases).
Thanks , but the "isse=False" didn't help.
Script below gave once the expected output, but then every time had crashed vspipe.exe
Adapted script :
import vapoursynth as vs
# import sys
core = vs.get_core(threads=2, accept_lowercase = True)
core.std.LoadPlugin(path=r"c:\Program Files (x86)\VapourSynth\filters\vapoursynth-mvtools-v5-win32\libmvtools.dll")
core.std.LoadPlugin(path=r"c:\Program Files (x86)\VapourSynth\filters\d2vsource_beta7\32bit\d2vsource.dll")
ret=core.d2v.Source(input=r"k:\film\Ghost Rider - Spirit of Vengeance (2012) HDTVRip\good files demuxed\ghost - 1 - MPEG2, 576p25.d2v")
# ret=core.std.Trim(ret, 2000 , 5000)
ret = core.resize.Lanczos(clip=ret, width=720, height=480, format=vs.YUV420P8)
src=ret
super = core.mv.Super(src ,pel=2, sharp=1 , isse=False)
# bv3 = core.mv.Analyse(super , blksize=8, isb=True, delta=3, overlap=4)
bv2 = core.mv.Analyse(super , blksize=8, isb=True, delta=2, overlap=4)
bv1 = core.mv.Analyse(super , blksize=8, isb=True, delta=1, overlap=4)
fv1 = core.mv.Analyse(super , blksize=8, isb= False, delta=1, overlap=4)
fv2 = core.mv.Analyse(super , blksize=8, isb=False, delta=2 , overlap=4)
# fv3 = core.mv.Analyse(super , blksize=8, isb=False, delta=3, overlap=4)
# ret = core.mv.Degrain1(clip=src, super=super, mvbw=bv1, mvfw=fv1 , thsad=400)
ret = core.mv.Degrain2(clip=src, super=super, mvbw=bv1, mvfw=fv1, mvbw2=bv2, mvfw2=fv2 , thsad=400 )
# ret = core.mv.Degrain3(clip=src, super=super, mvbw=bv1, mvfw=fv1, mvbw2=bv2, mvfw2=fv2 , mvbw3=bv3, mvfw3=fv3 , thsad=400)
ret.set_output()
Pat357
26th January 2015, 13:51
I wouldn't know what to do with the static analyzer.
Does this happen to work better? http://ulozto.net/xZ99sXrQ/vapoursynth-mvtools-1ec0868f3bd9-win32-7z
If the DLL above still crashes, retest Degrain1 and Degrain2. In this new DLL either they all crash or they all work.
File has been deleted. Please re-upload it.
Thanks !
Pat357
26th January 2015, 14:10
I wouldn't know what to do with the static analyzer.
Does this happen to work better? http://ulozto.net/xZ99sXrQ/vapoursynth-mvtools-1ec0868f3bd9-win32-7z
If the DLL above still crashes, retest Degrain1 and Degrain2. In this new DLL either they all crash or they all work.
Got the file. Thanks for that.
Now Degrain2 sometimes works with "threads=1/2"', Degrain3 only with threads=1. Still not stable though : 4 out of 5 attempts still crash vspipe.exe.
I really doubt that memory is an issue here : using the original MVTools, I can use MDegrain3 with 8 threads on the same input video....
Do you need more crash reports ?
jackoneill
26th January 2015, 14:16
I was able to get it to crash in a 32 bit Windows XP, but passing isse=False to Degrain2 and Degrain3 makes them work. Are you sure this doesn't help you?
Pat357
26th January 2015, 14:32
I was able to get it to crash in a 32 bit Windows XP, but passing isse=False to Degrain2 and Degrain3 makes them work. Are you sure this doesn't help you?
Thank you very much !
The first time you mentioned isse=False, I've added it only to Super().
Now I've added it to Degrain2 and Degrain3 and with success !
I'm now running Degrain3 with "threads=4" and still no crashes.
BTW I'm running Win7Pro-64 bit to be able to access my 24GB RAM. Non-Pro Win7-64 can only address 16 GB RAM IIRC.
Does this "isse=False" does what I think it does ? Not using SSE instructions ?
Would this make the script slower ?
jackoneill
26th January 2015, 14:45
isse=False makes Degrain3 use C++ functions instead of some SSE2 functions. It probably makes things slower (you can compare Degrain1 with and without isse).
Pat357
26th January 2015, 14:56
isse=False makes Degrain3 use C++ functions instead of some SSE2 functions. It probably makes things slower (you can compare Degrain1 with and without isse).
Do you have an idea why this fixes Degrain2 and Degrain3 ?
My system is i7-970 3.2 MHz , which should support SSE2 and a lot more.
Do you think switching to vapoursynth 64-bit would give the same problems ?
Is it somewhere intrinsic to VS 32 bit versions ?
jackoneill
26th January 2015, 17:01
Do you have an idea why this fixes Degrain2 and Degrain3 ?
My system is i7-970 3.2 MHz , which should support SSE2 and a lot more.
Do you think switching to vapoursynth 64-bit would give the same problems ?
Is it somewhere intrinsic to VS 32 bit versions ?
Found the problem. My compiler needed an additional parameter. Nothing to do with your computer or VapourSynth. This one should just work: http://ulozto.net/xKFH4DUb/vapoursynth-mvtools-v5-realigned-stack-win32-7z
Pat357
26th January 2015, 19:00
Found the problem. My compiler needed an additional parameter. Nothing to do with your computer or VapourSynth. This one should just work: http://ulozto.net/xKFH4DUb/vapoursynth-mvtools-v5-realigned-stack-win32-7z
Thanks !
This one works without the "isse=False" option ! .:thanks:
I still wonder why I was apparently the first to stumble on this problem.
Also on another system (Hasswell 4770, 16 GB, Win7Pro x64) had the very same problem. I will test this version again on that system.
Myrsloik
26th January 2015, 19:05
Thanks !
This one works without the "isse=False" option ! .:thanks:
I still wonder why I was apparently the first to stumble on this problem.
Also on another system (Hasswell 4770, 16 GB, Win7Pro x64) had the very same problem. I will test this version again on that system.
Most likely because everyone else is using the 64bit version which doesn't have the problem and is faster. And you probably should do the same unless you really need certain avisynth filter.
jackoneill
30th January 2015, 21:29
v6 is here (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v6), and it didn't even take as many years as advertised!
* Add support for grayscale, 4:4:0, and 4:4:4 video.
* Add support for up to 16 bits per sample.
* Add SCDetection filter.
* Reject overlap greater than half the block size.
* Fix crash in BlockFPS when the input clip's frame rate is unknown (introduced in v5).
* Fix colourful bottom border in Degrain3 when overlap is greater than 0 (introduced in v5).
* Fix possible bug with infinite clips in Compensate.
* Fix frequent crash in Degrain2 and Degrain3 due to stack misalignment, specific to the win32 builds. Probably all previous versions are affected.
Obviously everything is slower with 16 bit input, and more memory is used.
DarkSpace
30th January 2015, 21:46
v6 is here (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v6), and it didn't even take as many years as advertised!
Nice!
* Add support for grayscale, 4:4:0, and 4:4:4 video.
What is 4:4:0 supposed to be? Grey-and-Red video? Do you have any examples? I'm rather confused right now...
jackoneill
30th January 2015, 22:26
Nice!
What is 4:4:0 supposed to be? Grey-and-Red video? Do you have any examples? I'm rather confused right now...
In 4:4:0 the chroma has the same width as the luma, and half the height.
DarkSpace
30th January 2015, 22:39
In 4:4:0 the chroma has the same width as the luma, and half the height.
Ah, okay, thanks. I just noticed (once again) that I assign the wrong meaning to these numbers. :mad:
Now that you explain it, I even remember at least reading once that rotated 4:2:2 is 4:4:0 ... :stupid:
buchanan
2nd February 2015, 23:31
Hi,
I get a crash when feeding QTGMC with a 1920x1080 16bit per sample clip : vspipe crashes telling me the faulty module is libmvtools.dll
When I open the scrip using VDub, i get a "division by zero" error in libmvtools, here is the crash report :
VirtualDub crash report -- build 35491 (release-AMD64)
--------------------------------------
Disassembly:
6ef94c00: 784a js 16ef94c4c
6ef94c02: 8914c7 mov [rdi+rax*8], edx
6ef94c05: 42890c80 mov [rax+r8*4], ecx
6ef94c09: 488b8424c00000 mov rax, [rsp+c0]
00
6ef94c11: 49634b10 movsxd rcx, [r11+10h]
6ef94c15: 4c630c28 movsxd r9, [rax+rbp]
6ef94c19: 31c0 xor eax, eax
6ef94c1b: 4c39c9 cmp ecx, ecx
6ef94c1e: 7d22 jge 16ef94c42
6ef94c20: 4a8d0409 lea rax, [rcx+r9]
6ef94c24: 4c89ca mov edx, r9
6ef94c27: 4829ca sub edx, ecx
6ef94c2a: 480fafc2 imul eax, edx
6ef94c2e: 4d0fafc9 imul ecx, ecx
6ef94c32: 480fafc9 imul ecx, ecx
6ef94c36: 48c1e008 shl rax, 08h
6ef94c3a: 4899 cdq
6ef94c3c: 4c01c9 add ecx, ecx
6ef94c3f: 48f7f9 idiv eax, ecx
6ef94c42: 4983f801 cmp rax, 01h
6ef94c46: 43890487 mov [r15+r8*4], eax
6ef94c4a: 0f859b010000 jnz 16ef94deb
6ef94c50: 8b8c24f4010000 mov ecx, [rsp+1f4]
6ef94c57: 8b8424f0010000 mov eax, [rsp+1f0]
6ef94c5e: 41b900010000 mov ecx, 00000100
6ef94c64: 4c8bb424a00000 mov r14, [rsp+a0]
00
6ef94c6c: 4c897c2438 mov [rsp+38h], r15
6ef94c71: 4883c614 add rsi, 14h
6ef94c75: 48897c2420 mov [rsp+20h], rdi
6ef94c7a: 448d8408010100 lea r8d, [rax+rcx+101]
00
6ef94c82: c1e008 shl eax, 08h
6ef94c85: 99 cdq
6ef94c86: 41f7f8 idiv eax, eax <-- FAULT
6ef94c89: 4129c1 sub ecx, eax
6ef94c8c: 898424f0010000 mov [rsp+1f0], eax
6ef94c93: 89c8 mov eax, ecx
6ef94c95: c1e008 shl eax, 08h
6ef94c98: 488b8c24880000 mov rcx, [rsp+88]
00
6ef94ca0: 99 cdq
6ef94ca1: 41f7f8 idiv eax, eax
6ef94ca4: 8b942408010000 mov edx, [rsp+108]
6ef94cab: 4129c1 sub ecx, eax
6ef94cae: 898424f4010000 mov [rsp+1f4], eax
6ef94cb5: 488b442478 mov rax, [rsp+78h]
6ef94cba: 44894c2430 mov [rsp+30h], r9d
6ef94cbf: 448b8c24d80000 mov r9d, [rsp+d8]
00
6ef94cc7: 4889442428 mov [rsp+28h], rax
6ef94ccc: 488b8424c80000 mov rax, [rsp+c8]
00
6ef94cd4: 4e8d0410 lea r8, [rax+r10]
6ef94cd8: 41ff16 call dword ptr [r14]
6ef94cdb: 4c8ba424b80000 mov r12, [rsp+b8]
00
6ef94ce3: 8d0c1b lea ecx, [rbx+rbx]
6ef94ce6: 488b9424f80000 mov rdx, [rsp+f8]
00
6ef94cee: 4c8b8c24f00000 mov r9, [rsp+f0]
00
6ef94cf6: 4c8b8424880000 mov r8, [rsp+88]
00
6ef94cfe: 4863 db 63h
Built on Althena on Sun Oct 27 16:00:02 2013 using compiler version 1400
Windows 6.1 (Windows 7 x64 build 7601) [Service Pack 1]
Memory status: virtual free 8386984M/8388608M, commit limit 49032M, physical total 24517M
RAX = fffffd00
RBX = 3a0
RCX = ffffff02
RDX = ffffffff
RSI = 6dfc4
RDI = 1540f9d0
RBP = 0
R8 = 0
R9 = 100
R10 = 3a0
R11 = 1873eb88
R12 = 9319ee0
R13 = 0
R14 = 118f7148
R15 = 1540f960
RSP = 1540f770
RIP = 6ef94c86
EFLAGS = 00010287
Crash reason: Integer Divide-by-Zero
Crash context:
An integer division by zero occurred in module 'libmvtools'.
Pointer dumps:
RDI 1540f9d0: 286bdce0 00000000 30b5e610 00000000 28fec020 00000000 293e2020 00000000
RSP 1540f770: 00000002 00000000 00000007 000007fe 30868020 00000000 00000f20 00000000
1540f790: 1540f9d0 00000000 00000010 00000000 00000106 00000000 1540f960 00000000
1540f7b0: 00000000 00000000 00000002 00000000 00000002 00000000 00000010 00000000
1540f7d0: 1540fad0 00000000 1540f940 00000000 1540f9a0 00000000 1540f950 00000000
R11 1873eb88: 000001d0 000002f0 00000000 0000002a ffbc1e25 000001d8 000002f0 00000000
R12 09319ee0: 30868020 00000000 3372270c 88000050 08cc6d30 00000000 3372270d 8800ff50
R14 118f7148: 6f1d0690 00000000 6f1d2190 00000000 6f1d2190 00000000 6ef91df0 00000000
R15 1540f960: fffffffd ffffff02 038f4700 00000000 00000f00 00000780 00000780 00000000
Thread call stack:
6ef94c86: libmvtools!VapourSynthPluginInit [6ef80000+1b80+13106]
7fedb122bee: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+1792e]
7fedb120424: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+15164]
7fedb183c48: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+78988]
7fedb1aca30: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+a1770]
7fedb110439: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+5179]
7fedb184477: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+791b7]
7fedb1846c1: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+79401]
7fedb11f19b: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+13edb]
7fedb11bd93: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+10ad3]
7fedb11d4c5: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+12205]
7fedb192739: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+87479]
7fedb183e15: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+78b55]
7fedb157afb: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+4c83b]
7fedb11fae8: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+14828]
7fedb15b530: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+50270]
7fedb1890f6: VapourSynth!getVapourSynthAPI [7fedb0e0000+2b2c0+7de36]
776959ed: kernel32!BaseThreadInitThunk [77680000+159e0+d]
778cc541: ntdll!RtlUserThreadStart [778a0000+2c520+21]
-- End of report
Do you need any other info I could provide ?
jackoneill
2nd February 2015, 23:50
It's already fixed in git. Until v7, you can avoid the crash by passing "isse=False" to Analyse when feeding it 16 bit video. Only 16 bit video is affected. 15 and lower is fine.
buchanan
2nd February 2015, 23:58
Ok thanks ! :)
Are_
3rd February 2015, 14:39
Welp, more test then:
CPU is a AMD FX-8150, 3600 MHz, Turbo CORE/Cool n' Quiet/C6 dissabled. Windows 7 Ultimate 64bit / Gentoo Linux 64bit.
Input is 720×480 YUV420P8, mpeg2, 2000 frames, decoded with lsmash-works.
VapourSynth command used with an additional "--requests 1" for the 1 thread tests:
vspipe test.py /dev/null --start 9501 --end 11500
AviSynth command used:
AVSMeter.exe "tests.avs" -range=9501,11500
Software versions:
VapourSynth version = r26 (https://github.com/vapoursynth/vapoursynth/releases/tag/R26)
vapoursynth-mvtools version = v6 (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v6)
avisynth vanilla mvtools version = v2.5.11.3 (http://avisynth.org.ru/mvtools/mvtools2.html#download)
avisynth svp mvtools version = 2.5.11.9-svp (http://www.svp-team.com/wiki/Download)
avisynth firesledge mvtools version = 2.6.0.5 (http://forum.doom9.org/showthread.php?p=1386559#post1386559)
lsmash-works version = r775 (https://www.dropbox.com/sh/3i81ttxf028m1eh/AAABkQn4Y5w1k-toVhYLasmwa?dl=0)
AviSynth version = 2.6.0 RC1 (http://forum.doom9.org/showthread.php?t=171668)
AVSMeter version = v1.9.4 (http://forum.doom9.org/showthread.php?t=165528)
Only the 64bit version of VapourSynth was tested, as 32bit is gonna be deprecated and noone should be using it anyway.
No MT version of AviSynth was tested because it has proven unstable and somewhat useless nowdays, 4gb_ram / number_of_threads is not enough for HD content.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Results for Degrain test:
8 threads:
VapourSynth Windows = 32.35 fps (100% cpu)
VapourSynth Linux = 37.50 fps (100% cpu)
AviSynth firesledge = 8.32 fps (35% cpu)
1 thread:
VapourSynth Windows = 5.32 fps (12% cpu)
VapourSynth Linux = 5.50 fps (12% cpu)
AviSynth Vanilla = 4.42 fps (12% cpu)
AviSynth SVP = 6.05 fps (12% cpu)
VapourSynth script:
import vapoursynth as vs
core = vs.get_core() # threads=1
v = core.lsmas.LWLibavSource(r'720x480 YUV420P8 mpeg2.mkv')
super = core.mv.Super(src)
mvbw3 = core.mv.Analyse(super, isb=True, delta=3, overlap=4)
mvbw2 = core.mv.Analyse(super, isb=True, delta=2, overlap=4)
mvbw = core.mv.Analyse(super, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(super, isb=False, delta=1, overlap=4)
mvfw2 = core.mv.Analyse(super, isb=False, delta=2, overlap=4)
mvfw3 = core.mv.Analyse(super, isb=False, delta=3, overlap=4)
v = core.mv.Degrain3(clip=src, super=super, mvbw=mvbw, mvfw=mvfw, mvbw2=mvbw2, mvfw2=mvfw2, mvbw3=mvbw3, mvfw3=mvfw3)
v.set_output()
AviSynth script:
LWLibavVideoSource("720x480 YUV420P8 mpeg2.mkv")
super = MSuper(last)
mvbw3 = MAnalyse(super, isb=True, delta=3, overlap=4)
mvbw2 = MAnalyse(super, isb=True, delta=2, overlap=4)
mvbw = MAnalyse(super, isb=True, delta=1, overlap=4)
mvfw = MAnalyse(super, isb=False, delta=1, overlap=4)
mvfw2 = MAnalyse(super, isb=False, delta=2, overlap=4)
mvfw3 = MAnalyse(super, isb=False, delta=3, overlap=4)
MDeGrain3(last, super, mvbw, mvfw, mvbw2, mvfw2, mvbw3, mvfw3)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Results for BlockFPS test (change frame rate: 23.97->25):
8 threads:
VapourSynth Windows = 289.26 fps (99% cpu)
VapourSynth Linux = 312.38 fps (99% cpu)
AviSynth firesledge = 51.66 fps (30% cpu)
1 thread:
VapourSynth Windows = 55.98 fps (12% cpu)
VapourSynth Linux = 83.92 fps (12% cpu)
AviSynth Vanilla = 45.41 fps (12% cpu)
AviSynth SVP = 60.09 fps (12% cpu)
VapourSynth script:
import vapoursynth as vs
core = vs.get_core() # threads=1
v = core.lsmas.LWLibavSource(r'720x480 YUV420P8 mpeg2.mkv')
super = core.mv.Super(v)
mvbw = core.mv.Analyse(super, isb=True, delta=1, overlap=0)
mvfw = core.mv.Analyse(super, isb=False, delta=1, overlap=0)
v = core.mv.BlockFPS(clip=v, super=super, mvbw=mvbw, mvfw=mvfw)
AviSynth script:
LWLibavVideoSource("720x480 YUV420P8 mpeg2.mkv")
super = MSuper()
mvbw = MAnalyse(super, isb=True, delta=1, overlap=0)
mvfw = MAnalyse(super, isb=False, delta=1, overlap=0)
MBlockFps(super, mvbw, mvfw)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Results for FlowFPS test (change frame rate: 23.97->25):
8 threads:
VapourSynth Windows = 29.83 fps (26% cpu)
VapourSynth Linux = 39.08 fps (26% cpu)
AviSynth firesledge = 19.38 fps (29% cpu)
1 thread:
VapourSynth Windows = 11.76 fps (12% cpu)
VapourSynth Linux = 13.81 fps (12% cpu)
AviSynth Vanilla = 11.75 fps (12% cpu)
AviSynth SVP = 15.73 fps (12% cpu)
VapourSynth script:
import vapoursynth as vs
core = vs.get_core() # threads=1
v = core.lsmas.LWLibavSource(r'720x480 YUV420P8 mpeg2.mkv')
super = core.mv.Super(v)
mvbw = core.mv.Analyse(super, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(super, isb=False, delta=1, overlap=4)
v = core.mv.FlowFPS(clip=v, super=super, mvbw=mvbw, mvfw=mvfw)
v.set_output()
AviSynth script:
LWLibavVideoSource("720x480 YUV420P8 mpeg2.mkv")
super = MSuper()
mvbw = MAnalyse(super, isb=True, delta=1, overlap=4)
mvfw = MAnalyse(super, isb=False, delta=1, overlap=4)
MFlowFps(super, mvbw, mvfw)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FlowFPS results were strange, not only it was not able to beat avisynth version, but it was not able to top the cores when multithreading was used (only one thread is maxed out).
jackoneill
3rd February 2015, 15:20
Thanks for the comparison!
FlowFPS is the only filter that still runs on a single thread. It's due to the way it's written. The input frames it needs can be generated in parallel, which is why you see some speed-up with 8 threads.
feisty2
3rd February 2015, 15:31
is core.mv.degrain3 equal to Expr ([core.mv.degrain1 (clip, super, mvbw1, mvfw1).std.Lut ("x / 3"), core.mv.degrain1 (clip, super, mvbw2, mvfw2).std.Lut ("x / 3"), core.mv.degrain1 (clip, super, mvbw3, mvfw3).std.Lut ("x / 3")], ["x y + z +"]) ?
if so, I think I can extend the time radius to any int by script
edit: typo
Are_
3rd February 2015, 15:52
Thanks for the comparison!
FlowFPS is the only filter that still runs on a single thread. It's due to the way it's written. The input frames it needs can be generated in parallel, which is why you see some speed-up with 8 threads.
Thanks to you jackoneill. I see, now it makes sense.
Btw, I updated it with linux results, for some obscure reason, linux is still faster than windows, the power of -march=native?
jackoneill
4th February 2015, 09:54
Oh, I forgot: comparing to 2.5.11.3 isn't exactly fair anymore. I imported a change from the SVP fork which makes it a bit faster, so that's what should be used in comparisons.
Groucho2004
4th February 2015, 10:59
avisynth mvtools version = v2.5.11.3 (http://avisynth.org.ru/mvtools/mvtools2.html#download)
You should try cretindesalpes's 2.6.0.5 that is internally multithreaded. See here (http://forum.doom9.org/showthread.php?p=1386559#post1386559).
Are_
4th February 2015, 13:49
Ok, updated the post with ST results for svp fork and MT results for firesledge fork.
zerowalker
4th February 2015, 22:10
Ok, updated the post with ST results for svp fork and MT results for firesledge fork.
Oh nice.
Something seems off though, was sure it used more CPU.
But then again in my fast tests the FPS difference is like yours.
It's very impressive, only downside is that i am so used to Avisynth that it's hard to get things going, luckily though it's still script which makes it fairly easy to understand:)
jackoneill
15th February 2015, 11:40
v7 is here (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v7), mostly with fixes to bugs introduced in v6.
* Use SATD functions optimised for SSE4.1, AVX, XOP, and AVX2, copied from x264. Affects Analyse and Recalculate used with dct=5..10.
* Add sanity check for thscd1 parameter. It will no longer accept values larger than 8*8*255. That was always the maximum value, it just wasn't checked.
* Fix bug in Analyse with isse=True and 16 bits per sample input (introduced in v6).
* Fix Recalculate (completely broken in v6).
* Fix pink tint in Degrain and Compensate when overlap is used and isse=True (introduced in v6).
* Store the ml parameter in Mask as float, as it's supposed to be, instead of integer. Fix by HolyWu. (introduced who knows when, possibly right at the beginning).
buchanan
15th February 2015, 15:53
Thank you.
Encoding with 16bit fed into QTGMC stops after ~3000 frames / 1 min. Same script with 8 bit into TGMC runs fine until the end
jackoneill
15th February 2015, 17:12
Thank you.
Encoding with 16bit fed into QTGMC stops after ~3000 frames / 1 min. Same script with 8 bit into TGMC runs fine until the end
32 or 64 bit? Does v6 work better?
Run it in VirtualDub to get a somewhat useful crash report.
zerowalker
16th February 2015, 02:12
Here is two shots from Avisynth and Vapoursynth.
http://imgur.com/fvlPQ7q,SITTfOS#0
The image difference is minimal but it's there (you will have to download and switch between them to see it).
feisty2
16th February 2015, 10:24
what's "mv.Finest"?
it's new, no avs mvtools got this
and... I couldn't find a readme for it
jackoneill
16th February 2015, 11:32
Here is two shots from Avisynth and Vapoursynth.
http://imgur.com/fvlPQ7q,SITTfOS#0
The image difference is minimal but it's there (you will have to download and switch between them to see it).
Is that with overlap and v6? Because at least some of the differences there could be caused by a bug in v6 (the slight brightening of the dark object with the Logitech logo on it). It's fixed in v7. Other than that, the differences in degraining must be due to the small differences in the output of Super. They're so insignificant, I don't feel like doing anything about it.
what's "mv.Finest"?
it's new, no avs mvtools got this
and... I couldn't find a readme for it
Finest is a helper used by some of the Flow* filters. It does a thing to the super clip. It's not new. In the Avisynth plugins it's not public, that's all.
Are_
16th February 2015, 12:27
Here is two shots from Avisynth and Vapoursynth.
http://imgur.com/fvlPQ7q,SITTfOS#0
The image difference is minimal but it's there (you will have to download and switch between them to see it).
Second image looks like it has some kind of dithering mesh applied to it, how did you produce it? Because I'm not having that with vapoursynth.
Reel.Deel
16th February 2015, 14:05
Finest is a helper used by some of the Flow* filters. It does a thing to the super clip. It's not new. In the Avisynth plugins it's not public, that's all.
MVTools from SVP (http://www.svp-team.com/wiki/Plugins:_MVTools2#The_interface) made it available.
This function is commented out in latest MVTools 2.5 versions and it's obviously a mistake cause it can helps a lot with caching the big frame for hpel (pel=2) and qpel (pel=4) modes.
So MVFinest is only used on the Flow* filters, and can help caching on large frames when pel=2 or 4 is used?
I tried the following but I get this error in VDub x64: An out-of-bounds memory access (access violation) occurred in module 'libmvtools'......reading address 000000000E2F76C4.
If I comment out the mv.Finest call it works fine. I might be doind something wrong but if I'm not then here's the crash report: http://privatepaste.com/9bf3b6e1f9
import vapoursynth as vs
core = vs.get_core()
src = core.lsmas.LWLibavSource(r'M:\1080p BD test.mkv')
super = core.mv.Super(src)
super = core.mv.Finest(super)
mvbw = core.mv.Analyse(super, isb=True)
mvfw = core.mv.Analyse(super)
out = core.mv.FlowFPS(clip=src, super=super, mvbw=mvbw, mvfw=mvfw, num=50, den=1)
out.set_output()
jackoneill
16th February 2015, 18:05
MVTools from SVP (http://www.svp-team.com/wiki/Plugins:_MVTools2#The_interface) made it available.
So MVFinest is only used on the Flow* filters, and can help caching on large frames when pel=2 or 4 is used?
I tried the following but I get this error in VDub x64: An out-of-bounds memory access (access violation) occurred in module 'libmvtools'......reading address 000000000E2F76C4.
If I comment out the mv.Finest call it works fine. I might be doind something wrong but if I'm not then here's the crash report: http://privatepaste.com/9bf3b6e1f9
import vapoursynth as vs
core = vs.get_core()
src = core.lsmas.LWLibavSource(r'M:\1080p BD test.mkv')
super = core.mv.Super(src)
super = core.mv.Finest(super)
mvbw = core.mv.Analyse(super, isb=True)
mvfw = core.mv.Analyse(super)
out = core.mv.FlowFPS(clip=src, super=super, mvbw=mvbw, mvfw=mvfw, num=50, den=1)
out.set_output()
Ah, so it's public in the SVP fork.
The Flow* filters invoke it internally when they need it, so you don't have to do anything. I don't know what additional use the SVP folks have for it (maybe in their secret filters?), but here it's already used as much as it can be. I made it public because why not.
It crashes because Analyse doesn't expect to receive the output of Finest.
Reel.Deel
16th February 2015, 18:16
@HolyWu and jackoneill
Thanks for explaining, I understand now. http://www.cheesebuerger.de/images/midi/boese/d074.gif
MonoS
17th February 2015, 14:28
The plugin crash using QTGMC
Here the crash info
VirtualDub crash report -- build 35491 (release-AMD64)
--------------------------------------
Disassembly:
6efb07e0: 008b81100100 add [rbx+11081], cl
6efb07e6: 00448b81 add [rbx+rcx*4-7fh], al
6efb07ea: 1c01 sbb al, 01h
6efb07ec: 0000 add [rax], al
6efb07ee: 39d0 cmp eax, edx
6efb07f0: 0f8efa010000 jle 16efb09f0
6efb07f6: 4139c0 cmp eax, eax
6efb07f9: 0f8e61020000 jle 16efb0a60
6efb07ff: 8981f8000000 mov [rcx+f8], eax
6efb0805: 8b8108010000 mov eax, [rcx+108]
6efb080b: 398114010000 cmp [rcx+114], eax
6efb0811: 8b9120010000 mov edx, [rcx+120]
6efb0817: 0f4d8114010000 cmovge eax, [rcx+114]
6efb081e: 39d0 cmp eax, edx
6efb0820: 0f4cc2 cmovl eax, edx
6efb0823: 8981fc000000 mov [rcx+fc], eax
6efb0829: 80b98800000000 cmp byte ptr [rcx+88], 00h
6efb0830: 741a jz 16efb084c
6efb0832: 488b81f4000000 mov rax, [rcx+f4]
6efb0839: 488981e8000000 mov [rcx+e8], rax
6efb0840: 8b81fc000000 mov eax, [rcx+fc]
6efb0846: 8981f0000000 mov [rcx+f0], eax
6efb084c: 448b8928020000 mov r9d, [rcx+228]
6efb0853: 8b8124020000 mov eax, [rcx+224]
6efb0859: 448b81f0000000 mov r8d, [rcx+f0]
6efb0860: 410fafc1 imul eax, ecx
6efb0864: 41d1f8 sar eax, 1
6efb0867: 4501c8 add eax, ecx
6efb086a: 99 cdq
6efb086b: 41f7f8 idiv eax, eax <-- FAULT
6efb086e: 410fafc1 imul eax, ecx
6efb0872: 99 cdq
6efb0873: 41f7f8 idiv eax, eax
6efb0876: 898124020000 mov [rcx+224], eax
6efb087c: 5b pop ebx
6efb087d: 5e pop esi
6efb087e: 5f pop edi
6efb087f: 5d pop ebp
6efb0880: 415c pop esp
6efb0882: c3 ret
6efb0883: 8ba9f0010000 mov ebp, [rcx+1f0]
6efb0889: 448d4dff lea r9d, [rbp-01h]
6efb088d: 39fd cmp ebp, edi
6efb088f: 440f4fcf cmovg ecx, edi
6efb0893: e964feffff jmp 16efb06fc
6efb0898: 0f db 0fh
6efb0899: 1f db 1fh
6efb089a: 8400 test [rax], al
6efb089c: 0000 add [rax], al
6efb089e: 0000 add [rax], al
6efb08a0: 448b89ec010000 mov r9d, [rcx+1ec]
6efb08a7: 418d59ff lea ebx, [r9-01h]
6efb08ab: 4139e9 cmp ecx, ebp
6efb08ae: 4189c1 mov ecx, eax
6efb08b1: 0f4fdd cmovg ebx, ebp
6efb08b4: 39c7 cmp edi, eax
6efb08b6: 0f8c40feffff jl 16efb06fc
6efb08bc: ebc5 jmp 16efb0883
6efb08be: 6690 nop
6efb08c0: 8bb1f0010000 mov esi, [rcx+1f0]
6efb08c6: 448d56ff lea r10d, [rsi-01h]
6efb08ca: 4439ce cmp esi, ecx
6efb08cd: 450f4fd1 cmovg edx, ecx
6efb08d1: e9c3fdffff jmp 16efb0699
6efb08d6: 662e db 2eh
6efb08d8: 0f db 0fh
6efb08d9: 1f db 1fh
6efb08da: 8400 test [rax], al
6efb08dc: 0000 add [rax], al
6efb08de: 0000 add [rax], al
Built on Althena on Sun Oct 27 16:00:02 2013 using compiler version 1400
Windows 6.1 (Windows 7 x64 build 7601) [Service Pack 1]
Memory status: virtual free 8387123M/8388608M, commit limit 8056M, physical total 4029M
RAX = 2737100
RBX = 310
RCX = 68ae1a0
RDX = 0
RSI = 7b9ebf0
RDI = 47
RBP = 440
R8 = 0
R9 = 64640
R10 = 440
R11 = 3
R12 = 44bd7e
R13 = 64640
R14 = 14
R15 = fff37380
RSP = 75bf660
RIP = 6efb086b
EFLAGS = 00010247
Crash reason: Integer Divide-by-Zero
Crash context:
An integer division by zero occurred in module 'libmvtools'.
Pointer dumps:
RAX 02737100: 6170b690 00000000 6170b6b0 00000000 6170b6d0 00000000 54143f73 88000035
RCX 068ae1a0: 00000059 00000047 00000010 00000010 000018af 00000002 00000001 00000001
RSI 07b9ebf0: 00000008 00000000 0061a6aa 00000000 00000000 0061e57e 00000000 00000000
RSP 075bf660: 068ae1a0 00000000 00000030 00000000 00000000 00000000 20368b0c 00000000
075bf680: 00000019 00000000 6efb810b 00000000 00000010 00000000 003d0000 00000000
075bf6a0: 00000008 00000000 00000008 00000000 003d0288 00000000 77253448 00000000
075bf6c0: 075bf700 00000000 00000008 00000004 075bf6e0 00000000 000bf017 000befe5
R12 0044bd7a: 0000004b 00000000 b221ffff 0002982b 03fe0000 bdc00001 00000044 00010000
Thread call stack:
6efb086b: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+2eb8b]
6efb810b: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+3642b]
77253448: ntdll!RtlAllocateHeap [77200000+53360+e8]
77253448: ntdll!RtlAllocateHeap [77200000+53360+e8]
6efb8e9d: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+371bd]
6ef82a21: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+d41]
6efa77b4: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+25ad4]
6ef87c84: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+5fa4]
7fed8ff0349: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+5009]
7fed90644d7: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+79197]
7fed8fff19b: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+13e5b]
7fed8ffbd83: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+10a43]
7fed8ffd4bc: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+1217c]
7fed9072769: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+87429]
7fed9063e75: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+78b35]
7fed9037aeb: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+4c7ab]
7fed8fffae8: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+147a8]
7fed903b5c0: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+50280]
7fed9069156: VapourSynth!getVapourSynthAPI [7fed8fc0000+2b340+7de16]
770f59ed: kernel32!BaseThreadInitThunk [770e0000+159e0+d]
7722c541: ntdll!RtlUserThreadStart [77200000+2c520+21]
-- End of report
This is the script
import vapoursynth as vs
import havsfunc as has
core = vs.get_core()
src = core.d2v.Source("D:/JDownloader/Film/VTS_01_1.d2v", nocrop=True).fmtc.bitdepth(bits=16)
deint = has.QTGMC(src, Preset="Very Slow", SourceMatch=3, MatchPreset2="Slow", Lossless=2, NoisePreset="Slow", TFF=False, EZDenoise=1.5).fmtc.nativetostack16()
deint.set_output()
[As a note, the dvd i'm trying to convert is a dvd the author itself sent me, hy neuron2 :D]
I get the same error without nativetostack16, i was forced to use it cause VD don't support 16bit input
Using v6 crash at startup, instead with v7 i can also jump between frames in the preview and can encode about 1k frames
jackoneill
17th February 2015, 18:37
The plugin crash using QTGMC
Here the crash info
Thanks, that's helpful. The thing is, the disassembly doesn't match my own copy of libmvtools.dll from vapoursynth-mvtools-v7-win64.7z (and looks totally wrong, no wonder it crashes). Can you verify the md5sum of the library, please? It should be 6231b53114e98b71f751bfa26468b7ee. It's probably the same, but let's make sure.
MonoS
17th February 2015, 19:04
Thanks, that's helpful. The thing is, the disassembly doesn't match my own copy of libmvtools.dll from vapoursynth-mvtools-v7-win64.7z (and looks totally wrong, no wonder it crashes). Can you verify the md5sum of the library, please? It should be 6231b53114e98b71f751bfa26468b7ee. It's probably the same, but let's make sure.
Yes the hash is the same, the only thing that come up in my mind is that some instruction must have rewritten some code during the execution.
Is this even possible?? Are we sore that mvtools and vs mark all the code page as not writable??
jackoneill
17th February 2015, 20:10
Yes the hash is the same, the only thing that come up in my mind is that some instruction must have rewritten some code during the execution.
Is this even possible?? Are we sore that mvtools and vs mark all the code page as not writable??
Looking more closely, it's only VirtualDub's translation of the machine code into instructions that doesn't match my own disassembly. The machine code itself (second column) is correct. VirtualDub must have a bug there.
I found the cause of the crash, though. This binary should work: http://ulozto.net/xJMBQnV5/vapoursynth-mvtools-v7-div0-win64-7z
buchanan: Perhaps you had the same problem?
MonoS
17th February 2015, 20:25
Looking more closely, it's only VirtualDub's translation of the machine code into instructions that doesn't match my own disassembly. The machine code itself (second column) is correct. VirtualDub must have a bug there.
I found the cause of the crash, though. This binary should work: http://ulozto.net/xJMBQnV5/vapoursynth-mvtools-v7-div0-win64-7z
buchanan: Perhaps you had the same problem?
A VD bug, long time no see :)
I'm trying it right now with the same clip as before [a ~30m extra], i'll let you know how it goes
Overdrive80
17th February 2015, 22:45
Actually I want port my scripts to vapoursynth but I can´t use MDegrainN from mvtools' mod by cretindesalpes. Could you consider it to implement?
Thanks.
MonoS
18th February 2015, 10:41
MVTools continue to crash even using the new dll.
The exact same crash report [yes, i made sure to use the new dll, hash A72268104CBE17049112FDF839BC0B57 ].
Only some register are different, but i think this is due to the windows address randomization
VirtualDub crash report -- build 35491 (release-AMD64)
--------------------------------------
Disassembly:
6efb07e0: 008b81100100 add [rbx+11081], cl
6efb07e6: 00448b81 add [rbx+rcx*4-7fh], al
6efb07ea: 1c01 sbb al, 01h
6efb07ec: 0000 add [rax], al
6efb07ee: 39d0 cmp eax, edx
6efb07f0: 0f8efa010000 jle 16efb09f0
6efb07f6: 4139c0 cmp eax, eax
6efb07f9: 0f8e61020000 jle 16efb0a60
6efb07ff: 8981f8000000 mov [rcx+f8], eax
6efb0805: 8b8108010000 mov eax, [rcx+108]
6efb080b: 398114010000 cmp [rcx+114], eax
6efb0811: 8b9120010000 mov edx, [rcx+120]
6efb0817: 0f4d8114010000 cmovge eax, [rcx+114]
6efb081e: 39d0 cmp eax, edx
6efb0820: 0f4cc2 cmovl eax, edx
6efb0823: 8981fc000000 mov [rcx+fc], eax
6efb0829: 80b98800000000 cmp byte ptr [rcx+88], 00h
6efb0830: 741a jz 16efb084c
6efb0832: 488b81f4000000 mov rax, [rcx+f4]
6efb0839: 488981e8000000 mov [rcx+e8], rax
6efb0840: 8b81fc000000 mov eax, [rcx+fc]
6efb0846: 8981f0000000 mov [rcx+f0], eax
6efb084c: 448b8928020000 mov r9d, [rcx+228]
6efb0853: 8b8124020000 mov eax, [rcx+224]
6efb0859: 448b81f0000000 mov r8d, [rcx+f0]
6efb0860: 410fafc1 imul eax, ecx
6efb0864: 41d1f8 sar eax, 1
6efb0867: 4501c8 add eax, ecx
6efb086a: 99 cdq
6efb086b: 41f7f8 idiv eax, eax <-- FAULT
6efb086e: 410fafc1 imul eax, ecx
6efb0872: 99 cdq
6efb0873: 41f7f8 idiv eax, eax
6efb0876: 898124020000 mov [rcx+224], eax
6efb087c: 5b pop ebx
6efb087d: 5e pop esi
6efb087e: 5f pop edi
6efb087f: 5d pop ebp
6efb0880: 415c pop esp
6efb0882: c3 ret
6efb0883: 8ba9f0010000 mov ebp, [rcx+1f0]
6efb0889: 448d4dff lea r9d, [rbp-01h]
6efb088d: 39fd cmp ebp, edi
6efb088f: 440f4fcf cmovg ecx, edi
6efb0893: e964feffff jmp 16efb06fc
6efb0898: 0f db 0fh
6efb0899: 1f db 1fh
6efb089a: 8400 test [rax], al
6efb089c: 0000 add [rax], al
6efb089e: 0000 add [rax], al
6efb08a0: 448b89ec010000 mov r9d, [rcx+1ec]
6efb08a7: 418d59ff lea ebx, [r9-01h]
6efb08ab: 4139e9 cmp ecx, ebp
6efb08ae: 4189c1 mov ecx, eax
6efb08b1: 0f4fdd cmovg ebx, ebp
6efb08b4: 39c7 cmp edi, eax
6efb08b6: 0f8c40feffff jl 16efb06fc
6efb08bc: ebc5 jmp 16efb0883
6efb08be: 6690 nop
6efb08c0: 8bb1f0010000 mov esi, [rcx+1f0]
6efb08c6: 448d56ff lea r10d, [rsi-01h]
6efb08ca: 4439ce cmp esi, ecx
6efb08cd: 450f4fd1 cmovg edx, ecx
6efb08d1: e9c3fdffff jmp 16efb0699
6efb08d6: 662e db 2eh
6efb08d8: 0f db 0fh
6efb08d9: 1f db 1fh
6efb08da: 8400 test [rax], al
6efb08dc: 0000 add [rax], al
6efb08de: 0000 add [rax], al
Built on Althena on Sun Oct 27 16:00:02 2013 using compiler version 1400
Windows 6.1 (Windows 7 x64 build 7601) [Service Pack 1]
Memory status: virtual free 8387182M/8388608M, commit limit 8056M, physical total 4029M
RAX = 2737100
RBX = 310
RCX = 787ae00
RDX = 0
RSI = 7b5b280
RDI = 47
RBP = 440
R8 = 0
R9 = 64640
R10 = 440
R11 = 3
R12 = 44bd7e
R13 = 64640
R14 = 14
R15 = fff37380
RSP = 77bf660
RIP = 6efb086b
EFLAGS = 00010247
Crash reason: Integer Divide-by-Zero
Crash context:
An integer division by zero occurred in module 'libmvtools'.
Pointer dumps:
RCX 0787ae00: 00000059 00000047 00000010 00000010 000018af 00000002 00000001 00000001
RSI 07b5b280: 00000008 00000000 0061a6aa 00000000 00000000 0061e57e 00000000 00000000
RSP 077bf660: 0787ae00 00000000 00000030 00000000 00000000 00000000 38fe8b0c 00000000
077bf680: 00000019 00000000 6efb810b 00000000 00000010 00000000 00590000 00000000
077bf6a0: 00000008 00000000 00000008 00000000 00590288 00000000 778a3448 00000000
077bf6c0: 077bf700 00000000 00000008 00000004 077bf6e0 00000000 000bf017 000befe5
Thread call stack:
6efb086b: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+2eb8b]
6efb810b: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+3642b]
778a3448: ntdll!RtlAllocateHeap [77850000+53360+e8]
778a3448: ntdll!RtlAllocateHeap [77850000+53360+e8]
6efb8ea0: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+371c0]
6ef82a21: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+d41]
6efa77b4: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+25ad4]
6ef87c84: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+5fa4]
7fedf950349: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+5009]
7fedf9c44d7: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+79197]
7fedf95f19b: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+13e5b]
7fedf95bd83: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+10a43]
7fedf95d4bc: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+1217c]
7fedf9d2769: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+87429]
7fedf9c3e75: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+78b35]
7fedf997aeb: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+4c7ab]
7fedf95fae8: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+147a8]
7fedf99b5c0: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+50280]
7fedf9c9156: VapourSynth!getVapourSynthAPI [7fedf920000+2b340+7de16]
776459ed: kernel32!BaseThreadInitThunk [77630000+159e0+d]
7787c541: ntdll!RtlUserThreadStart [77850000+2c520+21]
-- End of report
jackoneill
18th February 2015, 13:35
MVTools continue to crash even using the new dll.
The exact same crash report [yes, i made sure to use the new dll, hash A72268104CBE17049112FDF839BC0B57 ].
Only some register are different, but i think this is due to the windows address randomization
That makes no sense... What about this one? Can you show the crash report from this one? http://ulozto.net/xVhfoGVd/vapoursynth-mvtools-v7-div0-win64-7z
MonoS
18th February 2015, 14:08
Of course, here the report
VirtualDub crash report -- build 35491 (release-AMD64)
--------------------------------------
Disassembly:
6efb07e0: 008b81100100 add [rbx+11081], cl
6efb07e6: 00448b81 add [rbx+rcx*4-7fh], al
6efb07ea: 1c01 sbb al, 01h
6efb07ec: 0000 add [rax], al
6efb07ee: 39d0 cmp eax, edx
6efb07f0: 0f8efa010000 jle 16efb09f0
6efb07f6: 4139c0 cmp eax, eax
6efb07f9: 0f8e61020000 jle 16efb0a60
6efb07ff: 8981f8000000 mov [rcx+f8], eax
6efb0805: 8b8108010000 mov eax, [rcx+108]
6efb080b: 398114010000 cmp [rcx+114], eax
6efb0811: 8b9120010000 mov edx, [rcx+120]
6efb0817: 0f4d8114010000 cmovge eax, [rcx+114]
6efb081e: 39d0 cmp eax, edx
6efb0820: 0f4cc2 cmovl eax, edx
6efb0823: 8981fc000000 mov [rcx+fc], eax
6efb0829: 80b98800000000 cmp byte ptr [rcx+88], 00h
6efb0830: 741a jz 16efb084c
6efb0832: 488b81f4000000 mov rax, [rcx+f4]
6efb0839: 488981e8000000 mov [rcx+e8], rax
6efb0840: 8b81fc000000 mov eax, [rcx+fc]
6efb0846: 8981f0000000 mov [rcx+f0], eax
6efb084c: 448b8924020000 mov r9d, [rcx+224]
6efb0853: 8b8128020000 mov eax, [rcx+228]
6efb0859: 448b81f0000000 mov r8d, [rcx+f0]
6efb0860: 410fafc1 imul eax, ecx
6efb0864: 41d1f8 sar eax, 1
6efb0867: 4501c8 add eax, ecx
6efb086a: 99 cdq
6efb086b: 41f7f8 idiv eax, eax <-- FAULT
6efb086e: 410fafc1 imul eax, ecx
6efb0872: 99 cdq
6efb0873: 41f7f8 idiv eax, eax
6efb0876: 898128020000 mov [rcx+228], eax
6efb087c: 5b pop ebx
6efb087d: 5e pop esi
6efb087e: 5f pop edi
6efb087f: 5d pop ebp
6efb0880: 415c pop esp
6efb0882: c3 ret
6efb0883: 8ba9f0010000 mov ebp, [rcx+1f0]
6efb0889: 448d4dff lea r9d, [rbp-01h]
6efb088d: 39fd cmp ebp, edi
6efb088f: 440f4fcf cmovg ecx, edi
6efb0893: e964feffff jmp 16efb06fc
6efb0898: 0f db 0fh
6efb0899: 1f db 1fh
6efb089a: 8400 test [rax], al
6efb089c: 0000 add [rax], al
6efb089e: 0000 add [rax], al
6efb08a0: 448b89ec010000 mov r9d, [rcx+1ec]
6efb08a7: 418d59ff lea ebx, [r9-01h]
6efb08ab: 4139e9 cmp ecx, ebp
6efb08ae: 4189c1 mov ecx, eax
6efb08b1: 0f4fdd cmovg ebx, ebp
6efb08b4: 39c7 cmp edi, eax
6efb08b6: 0f8c40feffff jl 16efb06fc
6efb08bc: ebc5 jmp 16efb0883
6efb08be: 6690 nop
6efb08c0: 8bb1f0010000 mov esi, [rcx+1f0]
6efb08c6: 448d56ff lea r10d, [rsi-01h]
6efb08ca: 4439ce cmp esi, ecx
6efb08cd: 450f4fd1 cmovg edx, ecx
6efb08d1: e9c3fdffff jmp 16efb0699
6efb08d6: 662e db 2eh
6efb08d8: 0f db 0fh
6efb08d9: 1f db 1fh
6efb08da: 8400 test [rax], al
6efb08dc: 0000 add [rax], al
6efb08de: 0000 add [rax], al
Built on Althena on Sun Oct 27 16:00:02 2013 using compiler version 1400
Windows 6.1 (Windows 7 x64 build 7601) [Service Pack 1]
Memory status: virtual free 8387149M/8388608M, commit limit 8056M, physical total 4029M
RAX = 2737100
RBX = 310
RCX = 7de6530
RDX = 0
RSI = 5094c470
RDI = 47
RBP = 440
R8 = 0
R9 = 64640
R10 = 440
R11 = 3
R12 = 44bd7e
R13 = 64640
R14 = 14
R15 = fff37380
RSP = 75af660
RIP = 6efb086b
EFLAGS = 00010247
Crash reason: Integer Divide-by-Zero
Crash context:
An integer division by zero occurred in module 'libmvtools'.
Pointer dumps:
RAX 02737100: 0008ffff 0009ffff 0007ffff 000affff 000cffff 000affff 000cffff 000e000d
RCX 07de6530: 00000059 00000047 00000010 00000010 000018af 00000002 00000001 00000001
RSI 5094c470: 00000008 00000000 0061a6aa 00000000 00000000 0061e57e 00000000 00000000
RSP 075af660: 07de6530 00000000 00000030 00000000 00000000 00000000 2c97cb0c 00000000
075af680: 00000019 00000000 6efb810b 00000000 00000010 00000000 004b0000 00000000
075af6a0: 00000008 00000000 00000008 00000000 004b0288 00000000 778a3448 00000000
075af6c0: 075af700 00000000 00000008 00000004 075af6e0 00000000 000bf017 000befe5
R12 0044bd7a: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Thread call stack:
6efb086b: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+2eb8b]
6efb810b: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+3642b]
778a3448: ntdll!RtlAllocateHeap [77850000+53360+e8]
778a3448: ntdll!RtlAllocateHeap [77850000+53360+e8]
6efb8ea0: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+371c0]
6ef82a21: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+d41]
6efa77b4: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+25ad4]
6ef87c84: libmvtools!VapourSynthPluginInit [6ef80000+1ce0+5fa4]
7feddf90349: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+5009]
7fede0044d7: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+79197]
7feddf9f19b: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+13e5b]
7feddf9bd83: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+10a43]
7feddf9d4bc: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+1217c]
7fede012769: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+87429]
7fede003e75: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+78b35]
7feddfd7aeb: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+4c7ab]
7feddf9fae8: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+147a8]
7feddfdb5c0: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+50280]
7fede009156: VapourSynth!getVapourSynthAPI [7feddf60000+2b340+7de16]
776459ed: kernel32!BaseThreadInitThunk [77630000+159e0+d]
7787c541: ntdll!RtlUserThreadStart [77850000+2c520+21]
-- End of report
Edit: If you are on the vs/avs IRC i can come here
foxyshadis
19th February 2015, 07:46
I spent a while trying to get my head around why
nLambda = nLambda*LSAD/(LSAD + (predictor.sad>>1))*LSAD/(LSAD + (predictor.sad>>1));
is crashing, given that LSAD is 64640, and the only thing I can come up with is that predictor.sad>>1 is so huge that it overflows and negates LSAD. I think it's more likely that memory corruption or an uninitialized value is screwing up the execution, like maybe RecalculateMVs and PseudoEPZSearch didn't find anything, but I can't get it to happen at all. The annoying part of the line is that nLambda is usually 0 here anyway, so it's a meaningless calculation unless truemotion is enabled. (Virtualdub really does need to work on its 64-bit disassembly, r8d and eax aren't even close.)
MonoS, do you have a specific script and input that someone could test on?
MonoS
19th February 2015, 12:47
Ok taking a closer look to the simple x264/x265 launcher logs i noticed that with the new version with the tentative fix the plugin crash at frame 1756/1757, instead with the standard version it crashed at frame 981.
I uploaded a portion of the video i'm trying to deinterlace, i'm sorry but is a bit NSFW [i tried with a BlankClip but as i expected, no errors], i included the d2v, remember to change the directory of the m2v into it: https://www.mediafire.com/?cb8h4u3y3u8xds5
The script i used is this one:
src = core.d2v.Source("test.d2v", nocrop=True).fmtc.bitdepth(bits=16)
deint = has.QTGMC(src, Preset="Very Slow", SourceMatch=3, MatchPreset2="Slow", Lossless=2, NoisePreset="Slow", TFF=False, EZDenoise=1.5)#.fmtc.nativetostack16()
deint.set_output()
It's pretty slow [2.5fps on my toaster with an i3 3225] and i didn't tried using faster settings because i want quality [and being this setting quite extreme they should touch about all the sides of QTGMC].
For completion sake i used this settings using simple x264 launcher: VS@64bit, 8bit x264@64bit, preset veryslow, tune film, crf 17, --ref 9 --bframes 9 --b-adapt 2 --aq-mode 3 --sar 16:11 --colormatrix smpte170m --input-range tv --range tv
Trying to reproduce the crash using VSEditor but it didn't give me any problem on those frames, maybe this could help
jackoneill
19th February 2015, 13:38
Okay, really fixed this time: http://ulozto.net/xEmVsWye/vapoursynth-mvtools-v7-div0-win64-7z
There were two bugs that could have caused a division by zero at that location:
* the first one was an uninitialised variable.
* the second one, the real cause of this crash, was an overflow due to larger SADs with 16 bit input.
MonoS
19th February 2015, 13:57
It went past the troublesome frame, now i'll let the encode goes and hope that it will not crash, thanks a lot jackoneill :D
EDIT: 45000 frames later and the encode is still going, i think we can consider the bug closed
buchanan
19th February 2015, 19:13
Hi Jackoneill
I didn't have much time in the last days to do a proper bug report, but will try this latest version to see if it fixes the bug I mentioned previously ;-)
zerowalker
20th February 2015, 06:04
Here is SMDegrain with the latest MVTools v7.
http://imgur.com/5mcJoPQ,VCsV6u1,D0dGf4x,RUulFdh
MonoS
23rd February 2015, 12:03
Ok, found another bug in mvtools.
Using the 16bit codepath, function FlowInter create interesting artifact [i did not encoded this, so i don't know if they are even more interesting in motion :D] http://abload.de/img/yagi.vpy-5448viucx.png
The script used is this one
deint2 = has.QTGMC(p2,Preset="Very Slow", SourceMatch=3, MatchPreset2="Slow", Lossless=2, NoisePreset="Slow", TFF=True).std.SelectEvery(5,[0,1,3,4])
dsup = core.mv.Super(deint2)
bf = core.mv.Analyse(dsup,isb=False, delta=1, overlap=4, truemotion=True)
bb = core.mv.Analyse(dsup,isb=True, delta=1, overlap=4, truemotion=True)
fin2 = core.mv.FlowInter (deint2, dsup, bb, bf, time=50).std.SelectEvery(2,0)
fin2.set_output()
p2 are interleaced credits, i wanted to use cretindesalpes ivtc_txt60mc even if i know is totally useless in this situation [also using 16bit is useless, but who cares].
Using 8bit codepath remove the artifacts
Are_
23rd February 2015, 14:58
Now that you mention it I saw the same kind of artifacts on a 10bit clip using mv.BlockFPS and I can confirm they dissapear when you convert the video to 8bit prior to mvtools filtering.
EDIT: meh, maybe it's just working as expected, lowering blksize fixes it at 10bit for me.
MonoS
23rd February 2015, 17:12
Now that you mention it I saw the same kind of artifacts on a 10bit clip using mv.BlockFPS and I can confirm they dissapear when you convert the video to 8bit prior to mvtools filtering.
EDIT: meh, maybe it's just working as expected, lowering blksize fixes it at 10bit for me.
Did the same and seems to work, i'm encoding to see if it's fixed for sure for the whole clip
pinterf
24th February 2015, 16:01
I was trying to port a 8mm film restoring script to VS, and (among other things) got stuck at RemoveDirtMC that uses MFlow.
Any plans to port this function?
feisty2
24th February 2015, 16:38
Just take mv.compensate instead, pixel compensate (flow) ain't no good to denoising
jackoneill
24th February 2015, 16:56
I was trying to port a 8mm film restoring script to VS, and (among other things) got stuck at RemoveDirtMC that uses MFlow.
Any plans to port this function?
Maybe, later? I don't know.
chainik_svp
24th February 2015, 21:28
The result finest clip can't be used as normal super clip because they are totally different. Finest filter is automatically invoked by Flow* filters internally when pel>1. It's really not meant to be called by users.
Sadly it's not working as expected in mt environment, at least in original MVTools ;)
trust me cause I know :D
jackoneill
24th February 2015, 22:13
Sadly it's not working as expected in mt environment, at least in original MVTools ;)
trust me cause I know :D
What isn't working as expected?
chainik_svp
24th February 2015, 22:54
Internal invokation of MFinest.
AFAIR MFinest result was not actually cached...
zerowalker
25th February 2015, 10:31
Anyone looked at the images i did on the update?
As far as i can tell the "lightning" problem is still there, as both versions seems to have the same brightness?
jackoneill
25th February 2015, 11:38
Anyone looked at the images i did on the update?
As far as i can tell the "lightning" problem is still there, as both versions seems to have the same brightness?
I assume the second image is the original, unfiltered. What exactly are the other three? (For future reference, you can label images with core.text.Text() (http://www.vapoursynth.com/doc/functions/text.html)).
pinterf
25th February 2015, 16:57
Just take mv.compensate instead, pixel compensate (flow) ain't no good to denoising
Thank you, tried mv.Compensate in RemoveDirtMC, but it gave blocky artifacts like this (at the armband):
Original / Avisynth MFlow / VapourSynth mv.Compensate
http://i.imgur.com/8RR95Nlt.jpg (http://imgur.com/8RR95Nl)
RemoveDirtMC is used for removing bigger chunks of dirt. Later on mv.Degrain2 is used for noise reduction.
feisty2
25th February 2015, 18:06
Overlap=0 is nuts to block based compensate, make it half the value of blksize
zerowalker
25th February 2015, 21:20
I assume the second image is the original, unfiltered. What exactly are the other three? (For future reference, you can label images with core.text.Text() (http://www.vapoursynth.com/doc/functions/text.html)).
Oh thought the filenames would show, even confused myself now.
I think the first and fourth are Vapoursynth (first should be v7).
Second is unfiltered, and third is Avisynth.
At least that's how i the files should have been ordered:S
Thanks for telling me else i would have continued to rely on filename which doesn't even show there;P
pinterf
26th February 2015, 09:51
Overlap=0 is nuts to block based compensate, make it half the value of blksize
Yes, it's unusual. Tried both 0 and 4 for Overlap with blocksize=8 but in some cases 0 gave better results for specific scenes (fast moving string-like objects did not disappear), could not find out why.
kaefert
4th March 2015, 17:45
is there something like SVP or Interframe for Vapoursynth?
I mean some library that allows to calculate extra frames between other frames based on movement analysis?
If I understood it correctly MVTools is only the "basis" for such a tool since it provides motion analysis functions, but it does not contain a function to calculate extra frames based on those analysis, is that correct?
foxyshadis
5th March 2015, 09:51
SVPFlow is based on the same idea as MVFlow, which is an extension of MVCompensate from blocks to single pixels. It certainly is possible, it just won't be as high quality as SVP, as they've done a bang-up job of enhancing the quality as much as possible. See a rather old thread (https://forum.doom9.org/showthread.php?t=130332) for an idea of how to get MVFlowFPS working. I'm a little too tipsy to convert to VS right now.
kaefert
5th March 2015, 16:06
okey, thanks for the reply foxyshadis!
did I understand you correctly:
Is the recommendation for getting the best possible quality of Motion Interpolation to stick to using Avisynth 32bit + SVP?
foxyshadis
5th March 2015, 19:38
okey, thanks for the reply foxyshadis!
did I understand you correctly:
Is the recommendation for getting the best possible quality of Motion Interpolation to stick to using Avisynth 32bit + SVP?
Yes, SVP's gpu-accelerated quality is much nicer than either mvtools or SVP's cpu mode. They've put a lot of professional effort into it.
You can use SVP in VSynth through the avs wrapper. Right now that means limited to 8-bit, but kolak and SEt are pushing them to include stacked 16-bit as well.
kaefert
6th March 2015, 07:20
oh. okey. so does that mean that if I'm using a a Server that has a nice octacore Xeon CPU, but virtually no GPU "Matrox G200e (Server Engines)" that I have no chance to get this quality?
I guess I would need nvidia or ati to be able to use gpu-accelerated version, correct?
UPDATE: okey so I've found this compatibility list for which GPUs work:
http://www.svp-team.com/wiki/GPU_Compatibility
But I could not yet find an answer to the question if I can't simply generate the "same" quality of motion interpolated in-between frames by using SVP with the gpu=0 parameter set. (slower of course, but since I want to encode the result instead of displaying it live (like the SVP-team seems to intend) slower is annoying but not a deal breaker for me)
jackoneill
9th March 2015, 23:40
Here is v8 (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v8).
* Fix occasional division by zero in Analyse with 16 bit input
Not much new in this one.
feisty2
22nd May 2015, 15:52
uh... really don't wanna be a dick here, but gotta ask about "vmulti, mdegrainN" stuff again, those are planned to be implemented someday or like, never gonna happen?
I'm like, ditching avisynth and moving everything to vaporsynth and mvtools, it's the only major problem I got now
plz, gimme an answer, functions added by Firesledge, will they ever appear in vsmvtools?
jackoneill
22nd May 2015, 22:40
uh... really don't wanna be a dick here, but gotta ask about "vmulti, mdegrainN" stuff again, those are planned to be implemented someday or like, never gonna happen?
I'm like, ditching avisynth and moving everything to vaporsynth and mvtools, it's the only major problem I got now
plz, gimme an answer, functions added by Firesledge, will they ever appear in vsmvtools?
At the moment, I have no plans to touch MVTools except to fix bugs.
captainadamo
23rd May 2015, 00:01
Results for Degrain test:
8 threads:
VapourSynth Windows = 32.35 fps (100% cpu)
VapourSynth Linux = 37.50 fps (100% cpu)
AviSynth firesledge = 8.32 fps (35% cpu)
1 thread:
VapourSynth Windows = 5.32 fps (12% cpu)
VapourSynth Linux = 5.50 fps (12% cpu)
AviSynth Vanilla = 4.42 fps (12% cpu)
AviSynth SVP = 6.05 fps (12% cpu)
VapourSynth script:
import vapoursynth as vs
core = vs.get_core() # threads=1
v = core.lsmas.LWLibavSource(r'720x480 YUV420P8 mpeg2.mkv')
super = core.mv.Super(src)
mvbw3 = core.mv.Analyse(super, isb=True, delta=3, overlap=4)
mvbw2 = core.mv.Analyse(super, isb=True, delta=2, overlap=4)
mvbw = core.mv.Analyse(super, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(super, isb=False, delta=1, overlap=4)
mvfw2 = core.mv.Analyse(super, isb=False, delta=2, overlap=4)
mvfw3 = core.mv.Analyse(super, isb=False, delta=3, overlap=4)
v = core.mv.Degrain3(clip=src, super=super, mvbw=mvbw, mvfw=mvfw, mvbw2=mvbw2, mvfw2=mvfw2, mvbw3=mvbw3, mvfw3=mvfw3)
v.set_output()
AviSynth script:
LWLibavVideoSource("720x480 YUV420P8 mpeg2.mkv")
super = MSuper(last)
mvbw3 = MAnalyse(super, isb=True, delta=3, overlap=4)
mvbw2 = MAnalyse(super, isb=True, delta=2, overlap=4)
mvbw = MAnalyse(super, isb=True, delta=1, overlap=4)
mvfw = MAnalyse(super, isb=False, delta=1, overlap=4)
mvfw2 = MAnalyse(super, isb=False, delta=2, overlap=4)
mvfw3 = MAnalyse(super, isb=False, delta=3, overlap=4)
MDeGrain3(last, super, mvbw, mvfw, mvbw2, mvfw2, mvbw3, mvfw3)
This was done more for fun, but with this test using v8 of MVTools and replacing only the 4x4 and 8x8 Sad_C with NEON intrinsics, I was able to get around 10.5 fps from a 720x480 raw source on an iPad Air 2 with 3 threads. Nothing blazing, but not bad for being on a tablet.
jackoneill
23rd May 2015, 08:02
This was done more for fun, but with this test using v8 of MVTools and replacing only the 4x4 and 8x8 Sad_C with NEON intrinsics, I was able to get around 10.5 fps from a 720x480 raw source on an iPad Air 2 with 3 threads. Nothing blazing, but not bad for being on a tablet.
So 10.5 fps after. How was it before?
captainadamo
23rd May 2015, 16:25
Around 6.5fps. The NEON for the 4x4 SAD only improved things consistently up to about 6.8 fps. The big gain was the 8x8 SAD in NEON which gave it the bump to 10.5 fps.
Just to note this was only when optimizing based off of profiling that single test script. And even with the NEON, those two SAD functions still basically swamp everything else in the performance counters so I don't know how much more I can squeeze out.
feisty2
24th May 2015, 10:37
mv.compensate seems like, well.. busted
import vapoursynth as vs
core = vs.get_core()
clp = core.raws.Source("Y.rgb", 736, 960, src_fmt="Y8")
clp = core.fmtc.stack16tonative(clp)
super = core.mv.Super (clp)
bv = core.mv.Analyse (super, isb=True,delta=1)
bcmp = core.mv.Compensate (clp, super, bv, thsad=400, thscd1=248, thscd2=130)
bcmp.set_output ()
bv.set_output () works okay
bcmp.set_output () = instant crash
jackoneill
24th May 2015, 15:33
mv.compensate seems like, well.. busted
import vapoursynth as vs
core = vs.get_core()
clp = core.raws.Source("Y.rgb", 736, 960, src_fmt="Y8")
clp = core.fmtc.stack16tonative(clp)
super = core.mv.Super (clp)
bv = core.mv.Analyse (super, isb=True,delta=1)
bcmp = core.mv.Compensate (clp, super, bv, thsad=400, thscd1=248, thscd2=130)
bcmp.set_output ()
bv.set_output () works okay
bcmp.set_output () = instant crash
Fixed. Thanks for the report.
Here is v9 (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v9).
* Fix crash in Compensate with Gray input
feisty2
24th May 2015, 17:02
any way to encode the vector clip to an actual vid and load it later, like whenever I need it?
tried to encode it directly and vspipe moaned about "cannot output clips with varying dimensions"
I need vectors encoded so I can do motion estimation just once and use it to motion compensate several times
MonoS
24th May 2015, 22:37
any way to encode the vector clip to an actual vid and load it later, like whenever I need it?
tried to encode it directly and vspipe moaned about "cannot output clips with varying dimensions"
I need vectors encoded so I can do motion estimation just once and use it to motion compensate several times
I'm also interested in this, and thus got interested as you asked.
Save the image data using imwri is impossible, the plugin create image as you visualize them, and due to impossibility to use vspipe to request all frames this is a manual process, also save 100 frames in png require about 30MB.
The ye olde mvtools for avs had an interesting outfile parameters, but seems lacking an infile parameter, thus making it useless, also it was removed.
Then i took a look at the code and tried to see how the analyse function saved the image.
It did so creating a frame 1xnVector and then writing/reading directly into it.
Replacing this frame for a simple array and then writing this array to a file in a binary format [and maybe applying some compression if needed].
If you don't want to modify mvtools code [for reason i can understand], creating an extra plugin [i dunno if it can be done also as a script] that read the image and binarize that into a file and vice versa, it should be a trivial task i think.
if you are not capable [iirc you said that you are not so good with c] and jackoneill don't want to make this i can spare some time.
EDIT1: I should go to splice cause almost 1AM but i got really interested in this problem.
I sketched something in my head and i think i only need how to access sequentially all the frames of a video without requesting it directly [so not something like imwri, but like lsmash] and maybe have also a progress bar of some sort [you know, you don't want to stare at a spinning circle for hours or more]
Probably something like getFrameAsync() that call a writing function with fmSerial threading mode.
EDIT1.1: Reading vspipe source i thought about modifying it to create a new output mode that do exactly that, and then create a plugin to read that binary file and recreate the vec data and i also have some idea on how to make this.
Now sleep!
feisty2
25th May 2015, 06:30
awesome! well, I failed to figure out a way to do it by scripting and, I suck at C/C++, so counting on u to save the world bro!
jackoneill
25th May 2015, 08:14
You can do this in Python:
import vapoursynth as vs
c = vs.get_core()
src = c.ffms2.Source("asdf.mp4")
superclip = c.mv.Super(src)
analysis = c.mv.Analyse(superclip, delta=1, isb=True)
f = open("/tmp/vectors.bin", "wb")
for i in range(analysis.num_frames):
if (i+1) % 100 == 0:
print(i+1, "/", analysis.num_frames)
frame = analysis.get_frame(i)
view = frame.get_read_array(0)
for y in range(len(view)):
# there is only one row (this loop runs once)
f.write(view[y])
f.close()
It's about 82 KiB/frame.
MonoS
25th May 2015, 08:43
and for reading?? if all the frames have different width there should be a frameLen in the file, also i don't see any function for creating varying dimension clip for then writing to it
jackoneill
25th May 2015, 09:35
and for reading?? if all the frames have different width there should be a frameLen in the file, also i don't see any function for creating varying dimension clip for then writing to it
I don't think the width varies in a clip. The output of Analyse has unknown dimensions simply because they are not known until a frame is returned, not because they could change from one frame to the next. Anyway, I'll leave all that as exercises for the reader.
MonoS
25th May 2015, 10:20
Then it should be a trivial task to do via scripting.
i'll try to.implemebt as soon as i return home.
@feisty2: i return home at about 15 utc, if you expect to write it yourself let me know so we don't write it twice
Myrsloik
25th May 2015, 10:41
I approve of this insanity. My idea for solving the reading (not tested but works in theory):
import vapoursynth as vs
c = vs.get_core()
src = c.ffms2.Source("rule6.avi")
superclip = c.mv.Super(src)
analysis = c.mv.Analyse(superclip, delta=1, isb=True)
vf = open("/stored/vectors.bin")
vector_width = analysis.get_frame(0).width
vector_template_clip = c.std.BlankClip(analysis, height=1, width=vector_width)
def vector_read(n, f):
vf.seek(n * f.width)
vector_data = vf.read(f.width)
fout = f.copy()
view = fout.get_write_array(0)
for x in range(fout.width):
view[0,x] = vector_data[x]
return fout
vector_clip = c.std.ModifyFrame(clip=vector_template_clip, clips=vector_template_clip, selector=vector_read)
vector_clip.set_output()
feisty2
25th May 2015, 11:00
@MonoS
gonna try to do it myself, but will let u know if I failed :)
feisty2
25th May 2015, 15:07
http://i.imgur.com/HFdBLFx.png
the writing part worked, the reading part popped out an error when I tried to preview it, soon after the error, vaporsynth crashed
Myrsloik
25th May 2015, 15:09
line 16 should be:
view = fout.get_write_array(0)
feisty2
25th May 2015, 15:18
still error, now it's
"Error getting the frame number 0:
Object is not writable."
MonoS
25th May 2015, 15:31
I humbly suggest to add an extra parameter to vector_read for selecting which file to read from.
Something like
vecFile = "/tmp/vectors.bin"
def vector_read(n, f, file):
vf= open("file", "rb")
vf.seek(n * f.width)
# etc...
return fout
vector_clip = core.std.ModifyFrame(clip=vector_template_clip, clips=vector_template_clip, selector=functools.partial(vector_read, file=vecFile)
feisty2
25th May 2015, 15:40
yeah, uh, organizing kinda stuff like this can wait I guess, right now, I can't get it to work, I got "Object is not writable" error
Myrsloik
25th May 2015, 21:57
I updated my previous post with a fixed script.
It's basically how you write a raw source filter using only python. Actually you probably could replace most of this with chikuzen's raw source...
feisty2
26th May 2015, 07:25
so I decide to take the easiest way
simply this works
vw = vec.get_frame(0).width
vecr=core.raws.Source(r"D:\test\vectors.bin", vw, 1, src_fmt="Y8")
vecr.set_output()
edit: replaced "vw" with a log file, no need to create a template anymore now
writing part
vw = vec.get_frame(0).width
log = open(r"D:\test\log.txt", "w").write (repr (vw))
reading part
w=int (open(r"D:\test\log.txt", "r").read ())
vecr=core.raws.Source(r"D:\test\vectors.bin", w, 1, src_fmt="Y8")
vecr.set_output()
MonoS
26th May 2015, 09:35
Every time i create the vector file with the same parameters and clip i get a different md5, is this to be expected??
feisty2
26th May 2015, 09:51
Every time i create the vector file with the same parameters and clip i get a different md5, is this to be expected??
guess ur source filter is the one to blame here, not mvtools, I remember Myrsloik said something like "Don't expect FFMPEG to be bit exact" or whatever similar.
Myrsloik
26th May 2015, 09:54
Every time i create the vector file with the same parameters and clip i get a different md5, is this to be expected??
The answer is mostly not but with a bit of yes. Some formats can have +-1 differences due to rounding I think. Try it with something lossless like utvideo or huffyuv as input and see if it's still different.
jackoneill
26th May 2015, 10:48
Every time i create the vector file with the same parameters and clip i get a different md5, is this to be expected??
Compare the contents.
Edit: Nevermind. I think it's just a little unused memory that never gets initialised.
feisty2
29th May 2015, 16:33
Do "thsad" and "thscd1/2" have a varying range related to bit depth like "limit" in mv.degrain or they stay in some fixed certain range (always "400" as default whatever input depth is) ?
jackoneill
29th May 2015, 17:00
Do "thsad" and "thscd1/2" have a varying range related to bit depth like "limit" in mv.degrain or they stay in some fixed certain range (always "400" as default whatever input depth is) ?
The ranges for thsad and thscdX do not vary with the bit depth. They are scaled internally as needed.
foxyshadis
30th May 2015, 00:49
The ranges for thsad and thscdX do not vary with the bit depth. They are scaled internally as needed.
I'm convinced this is the proper mode of operations for all filters, which should take fractional values instead of requiring the user to know what bit depth they're in anytime a filter is called. I'm glad havs does the heavy lifting for the filters that don't scale input. (Although it's going to have to be done all over again for anything that wants 0...1.0 in float. rean has the right idea there.)
feisty2
16th June 2015, 14:00
any plan to get mvtools to work on float point clips?
jackoneill
16th June 2015, 14:34
any plan to get mvtools to work on float point clips?
No.
feisty2
17th June 2015, 05:42
No.
okay then, how do I make all this work, like how, should I modify the cpp code to add support for float point clips? a short and simple guide like that "python removegrain19", can I ask for one plz?
I been running from C/CPP like, forever, cuz they are obscure and simply look like machine code to me, and I've always favored stuff easier like python or that "home grown avisynth language"
but that's officially over now, guess it's just, well, time to face the devil finally.
jackoneill
17th June 2015, 07:30
okay then, how do I make all this work, like how, should I modify the cpp code to add support for float point clips? a short and simple guide like that "python removegrain19", can I ask for one plz?
I been running from C/CPP like, forever, cuz they are obscure and simply look like machine code to me, and I've always favored stuff easier like python or that "home grown avisynth language"
but that's officially over now, guess it's just, well, time to face the devil finally.
Convert your float clips to integer.
feisty2
17th June 2015, 07:36
Convert your float clips to integer.
not doing that unless we got int32 or things even more delicate
and int16 is the most precise int type we got in vaporsynth for now, so, no.
Bloax
17th June 2015, 07:46
What kind of sick and twisted things are you doing that require 4294967296 states of precision over 65536 states of precision on monitors that have all of 256 states of precision?
feisty2
17th June 2015, 07:51
What kind of sick and twisted things are you doing that require 4294967296 states of precision over 65536 states of precision on monitors that have all of 256 states of precision?
color grading, int16 fails in some extreme cases, gotta take float32/int32 to prevent that
Bloax
17th June 2015, 07:58
MVTools is used for color grading? o_O
feisty2
17th June 2015, 08:01
MVTools is used for color grading? o_O
no, but once you convert your clip to a lower precision, for whatever purpose, precision will be lost FOR GOOD!
Bloax
17th June 2015, 08:08
Well then clearly do the MVTools stuff first in int16 and then convert it back to a more precise format afterwards.
This might be a bit awkward, but then again it's not like we even had more than 8 bits to fuck around with 3-4 years ago.
feisty2
17th June 2015, 08:14
Well then clearly do the MVTools stuff first in int16 and then convert it back to a more precise format afterwards.
This might be a bit awkward, but then again it's not like we even had more than 8 bits to fuck around with 3-4 years ago.
not tested but I'm actually worried about precision lost in the "float32-int16-float32" process might lead to some unexpected disasters.
Bloax
17th June 2015, 08:18
"Do it first" implies doing input->int16->mvtools->float32->etc, unless that can't be done either for arcane reasons.
feisty2
17th June 2015, 08:41
maybe not related to mvtools, but the following shows errors introduced in the "float32-int16-float32" process will actually affect the final result even if it's just 8bits
import vapoursynth as vs
core = vs.get_core()
clp = whatever
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=32, flt=True, dmode=1)
clp = core.fmtc.transfer(clp, transs="470bg", transd="linear", fulls=True, fulld=True)
clp1 = core.fmtc.bitdepth(clp, fulls=True, fulld=True, bits=16, flt=False, dmode=1).fmtc.transfer(transs="linear", transd="srgb", fulls=True, fulld=True).fmtc.bitdepth(fulls=True, fulld=True, bits=8, flt=False, dmode=3)
clp2 = core.fmtc.transfer(clp, transs="linear", transd="srgb", fulls=True, fulld=True).fmtc.bitdepth(fulls=True, fulld=True, bits=8, flt=False, dmode=3)
dif = core.std.MakeDiff(clp1,clp2).std.Expr ("x 128 - 100 * 128 +")
dif.set_output ()
Nevilne
17th June 2015, 12:08
Not sure if you understand just how much precision 16bit int has, but you can just add [diff of float32->int16 and float32->int16->mvtools] to [float32], to keep non-mvtooled float32 pixels.
feisty2
17th June 2015, 12:20
Not sure if you understand just how much precision 16bit int has, but you can just add [diff of float32->int16 and float32->int16->mvtools] to [float32], to keep non-mvtooled float32 pixels.
I'm reading CPP tutorials actually, gonna face this son of a gun sooner or later, so why not now :)
edit: new colorspaces could be defined by filters according to vs doc, so I'm thinking about double or int64 if I'm gonna write filters in cpp
Myrsloik
17th June 2015, 13:09
I'm reading CPP tutorials actually, gonna face this son of a gun sooner or later, so why not now :)
edit: new colorspaces could be defined by filters according to vs doc, so I'm thinking about double or int64 if I'm gonna write filters in cpp
Not supported because both are pointless. If floats aren't accurate enough for you then you're much more likely to be using an algorithm not suitable for the task than actually miss the few extra bits a double gives you.
feisty2
17th June 2015, 14:00
Not supported because both are pointless. If floats aren't accurate enough for you then you're much more likely to be using an algorithm not suitable for the task than actually miss the few extra bits a double gives you.
okay then, no double or long long, it's just, I was screwed over by rounding errors some time before, and got allergic to it ever since
foxyshadis
17th June 2015, 14:37
Not sure if you understand just how much precision 16bit int has, but you can just add [diff of float32->int16 and float32->int16->mvtools] to [float32], to keep non-mvtooled float32 pixels.
Tacking old LSB on top of filtered pixels is roughly equivalent to AddGrain(). Don't do that unless you just need a little randomness, in which case AddGrain will do you better.
Floating point is about working with WTW and BTB, not precision, and you'll generally want to grade it before you filter it so that you don't run into anomalies in areas you can't see, and don't accidentally filter away your important details. If 12- to 16-bit is enough for Camera Raw, 16-bit is enough for video grading.
cretindesalpes
17th June 2015, 14:39
maybe not related to mvtools, but the following shows errors introduced in the "float32-int16-float32" process will actually affect the final result even if it's just 8bits
Of course. The “errors” you see are differences between dithering patterns. Clips with extremely small differences will always exhibit these artefacts once dithered, especially with error-diffusion algorithms (*). The only way to accurately check errors is to upconvert the clip of the lowest bitdepth then subtract them and amplify the difference.
(*) For example in 1-D and 1 bit, a value of 0.500 will dither as 10101010… and a value of 0.501 will dither as 11010101… resulting in a 0+1-1+1-1+1-1+1… difference.
feisty2
17th June 2015, 15:35
upconvert? as bitdepth upconvert or resolution upconvert?
import vapoursynth as vs
core = vs.get_core()
clp = whatever
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=32, flt=True, dmode=1)
clp = core.fmtc.transfer(clp, transs="470bg", transd="linear", fulls=True, fulld=True)
clp1 = core.fmtc.bitdepth(clp, fulls=True, fulld=True, bits=16, flt=False, dmode=1).fmtc.transfer(transs="linear", transd="srgb", fulls=True, fulld=True).fmtc.bitdepth(fulls=True, fulld=True, bits=8, flt=False, dmode=3).fmtc.resample (clp.width*2,clp.height*2,fulls=True, fulld=True)
clp2 = core.fmtc.transfer(clp, transs="linear", transd="srgb", fulls=True, fulld=True).fmtc.bitdepth(fulls=True, fulld=True, bits=8, flt=False, dmode=3).fmtc.resample (clp.width*2,clp.height*2,fulls=True, fulld=True)
dif = core.std.MakeDiff(clp1,clp2).std.Expr ("x 32768 - 100 * 32768 +")
dif.set_output ()
import vapoursynth as vs
core = vs.get_core()
clp = whatever
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=32, flt=True, dmode=1)
clp = core.fmtc.transfer(clp, transs="470bg", transd="linear", fulls=True, fulld=True)
clp1 = core.fmtc.bitdepth(clp, fulls=True, fulld=True, bits=16, flt=False, dmode=1).fmtc.transfer(transs="linear", transd="srgb", fulls=True, fulld=True).fmtc.bitdepth(fulls=True, fulld=True, bits=8, flt=False, dmode=3).fmtc.bitdepth(fulls=True, fulld=True, bits=32, flt=True, dmode=1)
clp2 = core.fmtc.transfer(clp, transs="linear", transd="srgb", fulls=True, fulld=True).fmtc.bitdepth(fulls=True, fulld=True, bits=8, flt=False, dmode=3).fmtc.bitdepth(fulls=True, fulld=True, bits=32, flt=True, dmode=1)
dif = core.std.MakeDiff(clp1,clp2).std.Expr ("x 0.5 - 100 * 0.5 +")
dif.set_output ()
anyways I tried both and differences are still there
cretindesalpes
17th June 2015, 17:06
bitdepth upconvert. If you’re processing something in float, convert everything to float to compare.
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=32, flt=True)
clp = core.fmtc.transfer(clp, transs="470bg", transd="linear", fulls=True, fulld=True)
clp1 = core.fmtc.bitdepth(clp, fulls=True, fulld=True, bits=16, flt=False, dmode=1)
clp1 = core.fmtc.transfer(clp1, transs="linear", transd="srgb", fulls=True, fulld=True)
clp1 = core.fmtc.bitdepth(clp1, fulls=True, fulld=True, bits=32, flt=True)
clp2 = core.fmtc.transfer(clp, transs="linear", transd="srgb", fulls=True, fulld=True)
dif = core.std.MakeDiff(clp1,clp2).std.Expr ("x 0.5 - 100 * 0.5 +")
dif = core.fmtc.bitdepth(dif, fulls=True, fulld=True, bits=8, flt=False)
dif.set_output ()
And the difference will be even tinier if you use dmode 3 instead of dmode 1.
Reel.Deel
17th June 2015, 17:07
@feisty2
Not sure what's the obsession with 32-bit float but didn't you say your sources are usually 8-bit heavily compressed Katy Perry (or other pop) music videos? I highly doubt that processing in 32-bit float will magically make the output substantially better. I doubt the highly minute differences will be visible when playing in real-time. Also, do you have an appropriate 10-bit+ panel and workflow? If not then this discussion is moot.
I process my Canon DSLR raw photos in Lightroom (32-bit), output to 16-bit to do post processing in an external HDR software, I export to16-bit again and import into Lightroom for final grading. It would be nice to have a complete 32-bit float workflow but my current workflow is more than adequate to achieve very good results. I don't think 32-bit float will improve the results marginally.
*sorry for any grammar errors, not very efficient on my phone.
feisty2
17th June 2015, 17:56
1.Got that obsession from 3dsmax, I was playing with exposures of the objects and noticed 16bits actually produced some bandings when switching the exposure from an extreme to the opposite extreme, and float32 works fine without bandings
2.music videos, well, first, I like music videos, but more importantly, they are short so easy to test filters and demonstrate and they are lossily compressed so kinda like gets you easier to judge how filters work in extreme cases, but I do process other vids, mostly things I shot for fun
3.I got a color corrected monitor but it's not 10bpc, but like I said in 1., you don't really need 10bpc screen when you can already tell that shit happens and visible even at 8bpc screen
4.since we don't have infinite precision here to do all the intermediate steps, rounding errors will accumulate and might cause some serious shit, so gotta pick the data type closest to "infinite precision"
5.I think float32 would be better for linear light
feisty2
18th June 2015, 06:48
holy lord, I'm staring at the "mvtools" source code and it's gonna be... painful to add native float point support to it, practically gotta rewrite the whole thing, so I'm thinking of an alternative, we keep int stuff here, but pick uint32 instead of uint16, and vs got no support for Gray32, so convert uint32 to single at the final step, guess gotta remove some asm here cuz they won't work on uint32
foxyshadis
18th June 2015, 07:12
One problem is that if you tried that extreme exposure shift with an 8bit input, there would be any details to lead to banding -- it'd be one solid flat white or black with a few sprinkles of color here and there. 3dsmax starts with 64bit and downconverts (with lousy dithering IMHO) from there; it doesn't start with 8bit and work up. What you start with is far more important for your process than what you could do with it under perfect conditions.
If you're creating ultra-high-bit CGI, then you shouldn't need to apply extreme grading or filtering: That should be part of the generating process.
Like I said, float has a tangible and very valuable benefit over int -- the whole universe is its gamut, and you never have to worry about clipping, unless you routinely work with infinity. Even float16 is sufficient for conversion to int8 or int10, but since there's zero hardware or SIMD support for it, there's no point in saving a little memory for a lot of cpu time anymore. Likewise, int16 linear can uniquely represent all but maybe one or two of the bottom int10 gamma corrected values, so it is enough for any practical purpose (encoding). And if you get too hung up on roundoff errors, pretty soon you start wanting doubles or even quads.
Honestly, when it comes to filters directly associated with color control and grading, float32 support is damn handy, but I just can't see any point to it for destructive filters (like denoisers).
feisty2
18th June 2015, 07:56
I'm not grading or filtering CGI, it's just, I found 16bpc can actually be, not enough in some cases, I had used to think 16bpc should be enough for almost everything, and that 3dsmax incident refreshed my mind, so a new level of "enough for everything", float32, replaced 16bits stuff in head
and naturally, I want all 16bits stuff degraded and take float32 instead, for, first, it can get the most hardass situation handled, and it's more mathematically correct, that's a bonus
should I just be okay with 16bpc, I'm in the middle of mvtools modification
Bloax
18th June 2015, 14:41
?That 3ds Max incident where you did the equivalent of squishing a 0-255 range into 0-1 and then getting imperfections when stretching it back to 0-255 reminded you of the fact that you need more precision despite this never happening in the wild?
feisty2
18th June 2015, 15:56
that kind of thing could happen, extreme like that, maybe rare, milder version, very common actually, say, every step introduces some errors, <= 0.5/65536 at int16, literally "very small" errors, but that's just ONE step, what happens if you got a process chain, right, errors will accumulate , they will grow fatter and fatter gradually, and finally, they won't just be there as "small" errors, they will become large errors, if you just got operations like +/-, errors might stay small, now imagine, what about operations like ^, exp, log
captainadamo
18th June 2015, 16:08
Can you actually show us visual results of these "errors" you are spending huge amounts of time to get rid of? Maybe if you can actually demonstrate a need for this using a real-world sample, not something contrived in order to exaggerate, someone may be more willing to put in the work. All you've done so far is talk about theoreticals and vagaries but no actual examples.
Edited to add: It just seems that your effort would be better spent trying to mitigate these errors through other means rather than trying to hamfist in support for some other format into a codebase that is at best an opaque wall of code even for people who know C or C++ well. Let alone for someone who admits that they are basically a novice.
feisty2
18th June 2015, 16:40
I never had serious problems with int16 in regular cases so far, things are pretty extreme when int16 fails, then you might think they are "contrived in order to exaggerate", but I'm doing this like an insurance, it will surely save my ass whenever shit happens, maybe that's rare, but it won't bite in regular cases, and you even got some tiny bonus like "more mathematically correct"
Reel.Deel
18th June 2015, 16:45
I think you might be overreacting, look at QTGMC, it's all 8-bit processing and the result looks fantastic. I would be a little bit more understanding If your source was actually truly high bit depth. Anyways I think this discussion has gone off topic...
captainadamo
18th June 2015, 16:56
I never had serious problems with int16 in regular cases so far, things are pretty extreme when int16 fails, then you might think they are "contrived in order to exaggerate", but I'm doing this like an insurance, it will surely save my ass whenever shit happens, maybe that's rare, but it won't bite in regular cases, and you even got some tiny bonus like "more mathematically correct"
Then have fun with that. You do realize that all you're going to do is make all your scripts with mvtools be even slower than they already are, right? Especially if you start removing asm code like you mention above. Is likely a 2 or 3 fold increase in processing time for the mvtools part of your script really going to be worth fixing rounding errors you admit you've never actually seen make visible problems? It's your time to waste as you want...
feisty2
18th June 2015, 17:06
I changed my mind hours ago (when Myrsloik confirmed he won't add float to rgvs/core soon) actually, I'm starting with simple filters like removegrain
feisty2
23rd August 2015, 11:02
so I'm floatizing MVTools and actually not that hard like I thought it would be
https://github.com/IFeelBloated/MVTools-Float
just floatized mv.Super and working on mv.Analyze
feisty2
25th August 2015, 03:54
where did you scale SAD values calculated from clips with different bit depths to the same level (like default thsad=400 works almost the same on uint8_t and uint16_t)?
I got float SADs returned by Sad_C and how do I make it that "400" kind of stuff?
edit: never mind, just found out they are scaled inside each individual client functions, not mv.Analyze...
edit2: Do I have to store the float SAD as bytes inside VECTOR struct and restore it back to float when I read it?
feisty2
26th August 2015, 16:24
@jackoneill
2 parameters (lambda and global) in mv.analyse are actually unusable, as they are internally occupied by Python, guess you'll have to rename them
jackoneill
26th August 2015, 17:30
@jackoneill
2 parameters (lambda and global) in mv.analyse are actually unusable, as they are internally occupied by Python, guess you'll have to rename them
https://github.com/vapoursynth/vapoursynth/blob/master/doc/pythonreference.rst#python-keywords-as-filter-arguments
feisty2
27th August 2015, 03:12
ah, didn't know that before, thx for the tip
feisty2
29th August 2015, 06:07
SATD(C version) for 16 * X blocks is broken I guess
jackoneill
29th August 2015, 09:25
SATD(C version) for 16 * X blocks is broken I guess
You guess? Or do you know for sure and can point out the problem?
feisty2
29th August 2015, 09:31
You guess? Or do you know for sure and can point out the problem?
I'm sure, I can't point the problem out cuz I don't really get how that code works actually
but the result is very different from the avisynth mvtools, so it has to be broken
feisty2
29th August 2015, 09:53
@jackoneill
xxx
clp=last
sup = MSuper(clp)
bv1 = MAnalyse(sup,isb=True,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=5)
fv1 = MAnalyse(sup,isb=False,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=5)
bv2 = MAnalyse(sup,isb=True,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=5)
fv2 = MAnalyse(sup,isb=False,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=5)
bv3 = MAnalyse(sup,isb=True,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=5)
fv3 = MAnalyse(sup,isb=False,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=5)
MDegrain3(clp, sup, bv1, fv1, bv2, fv2, bv3, fv3, thsad=2000, thscd1=10000)
converttoy8 ()
http://i.imgur.com/q4J3uk0.png
import vapoursynth as vs
core = vs.get_core()
clp = xxx
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=32, flt=True)
clp2 = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=16)
sup = core.mvsf.Super(clp)
bv1 = core.mvsf.Analyze(sup,isb=True,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=5)
fv1 = core.mvsf.Analyze(sup,isb=False,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=5)
bv2 = core.mvsf.Analyze(sup,isb=True,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=5)
fv2 = core.mvsf.Analyze(sup,isb=False,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=5)
bv3 = core.mvsf.Analyze(sup,isb=True,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=5)
fv3 = core.mvsf.Analyze(sup,isb=False,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=5)
clp = core.mvsf.Degrain3(clp, sup, bv1, fv1, bv2, fv2, bv3, fv3, thsad=2000, thscd1=10000)
sup2 = core.mv.Super(clp2)
bv12 = core.mv.Analyse(sup2,isb=True,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=5)
fv12 = core.mv.Analyse(sup2,isb=False,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=5)
bv22 = core.mv.Analyse(sup2,isb=True,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=5)
fv22 = core.mv.Analyse(sup2,isb=False,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=5)
bv32 = core.mv.Analyse(sup2,isb=True,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=5)
fv32 = core.mv.Analyse(sup2,isb=False,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=5)
clp2 = core.mv.Degrain3(clp2, sup2, bv12, fv12, bv22, fv22, bv32, fv32, thsad=2000, thscd1=10000)
clp2 = core.fmtc.bitdepth(clp2, fulls=True, fulld=True, bits=32, flt=True)
fnl = core.std.StackHorizontal([clp,clp2])
fnl.set_output ()
http://i.imgur.com/zg2jNMM.png
jackoneill
29th August 2015, 10:38
I'm sure, I can't point the problem out cuz I don't really get how that code works actually
but the result is very different from the avisynth mvtools, so it has to be broken
Then how did you fix it?
feisty2
29th August 2015, 10:44
Didn't fix it, more of "rewrote it"
The 4x4 SATD works so I just extended it to 8x8 16x16 and 32x32
feisty2
30th August 2015, 06:07
@jackoneill
Did some more tests, your 16x16 SATD works at uint8_t but fails at uint16_t
feisty2
30th August 2015, 15:01
import vapoursynth as vs
core = vs.get_core()
clp = xxx
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=8)
sup = core.mv.Super(clp)
bv1 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=1,search=3,truemotion=True,dct=1)
fv1 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=1,search=3,truemotion=True,dct=1)
bv2 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=2,search=3,truemotion=True,dct=1)
fv2 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=2,search=3,truemotion=True,dct=1)
bv3 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=3,search=3,truemotion=True,dct=1)
fv3 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=3,search=3,truemotion=True,dct=1)
clp = core.mv.Degrain3(clp, sup, bv1, fv1, bv2, fv2, bv3, fv3, thsad=1200, thscd1=10000)
clp.set_output ()
http://i.imgur.com/bD7wHO9.png
import vapoursynth as vs
core = vs.get_core()
clp = core.d2v.Source ("D:/CIMW/VID.d2v")
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=16)
sup = core.mv.Super(clp)
bv1 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=1,search=3,truemotion=True,dct=1)
fv1 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=1,search=3,truemotion=True,dct=1)
bv2 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=2,search=3,truemotion=True,dct=1)
fv2 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=2,search=3,truemotion=True,dct=1)
bv3 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=3,search=3,truemotion=True,dct=1)
fv3 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=3,search=3,truemotion=True,dct=1)
clp = core.mv.Degrain3(clp, sup, bv1, fv1, bv2, fv2, bv3, fv3, thsad=1200, thscd1=10000)
clp.set_output ()
http://i.imgur.com/DHd7096.png
don't wanna be an asshole here, but...
dct=1-4 for uint16_t are broken as well...
and I pulled a request on GitHub that should have fixed dct=5-10 for uint16_t by the way
but I got no idea how to fix this... so good luck with it
jackoneill
30th August 2015, 15:20
import vapoursynth as vs
core = vs.get_core()
clp = xxx
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=8)
sup = core.mv.Super(clp)
bv1 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=1,search=3,truemotion=True,dct=1)
fv1 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=1,search=3,truemotion=True,dct=1)
bv2 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=2,search=3,truemotion=True,dct=1)
fv2 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=2,search=3,truemotion=True,dct=1)
bv3 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=3,search=3,truemotion=True,dct=1)
fv3 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=3,search=3,truemotion=True,dct=1)
clp = core.mv.Degrain3(clp, sup, bv1, fv1, bv2, fv2, bv3, fv3, thsad=1200, thscd1=10000)
clp.set_output ()
http://i.imgur.com/bD7wHO9.png
import vapoursynth as vs
core = vs.get_core()
clp = core.d2v.Source ("D:/CIMW/VID.d2v")
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=16)
sup = core.mv.Super(clp)
bv1 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=1,search=3,truemotion=True,dct=1)
fv1 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=1,search=3,truemotion=True,dct=1)
bv2 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=2,search=3,truemotion=True,dct=1)
fv2 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=2,search=3,truemotion=True,dct=1)
bv3 = core.mv.Analyse(sup,isb=True,blksize=8,overlap=4,delta=3,search=3,truemotion=True,dct=1)
fv3 = core.mv.Analyse(sup,isb=False,blksize=8,overlap=4,delta=3,search=3,truemotion=True,dct=1)
clp = core.mv.Degrain3(clp, sup, bv1, fv1, bv2, fv2, bv3, fv3, thsad=1200, thscd1=10000)
clp.set_output ()
http://i.imgur.com/DHd7096.png
don't wanna be an asshole here, but...
dct=1-4 for uint16_t are broken as well...
and I pulled a request on GitHub that should have fixed dct=5-10 for uint16_t by the way
but I got no idea how to fix this... so good luck with it
Can you also post the same frame without any filtering?
feisty2
30th August 2015, 15:34
import vapoursynth as vs
core = vs.get_core()
clp = xxx
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp.set_output ()
http://i.imgur.com/dgRukz3.png
YAFU
3rd September 2015, 00:26
Hello.
I post in this thread because I think my problem is related to mv tools (I've seen something like this script is used on page 8).
The user "brothermechanic" from blenderartists forum has published a script to reduce noise from videos made with Blender 3D renderings (Cycles engine):
http://www.blenderartists.org/forum/showthread.php?378736-Cycles-noise-reduction-with-VapourSynth
I'm using VapourSynth under Linux. Noise reduction is good, but there are problems with color banding. In some cases the banding is very noticeable. Here I share a set of images. In the video you can see the banding in the red walls and spheres:
https://www.dropbox.com/s/6miemtkv9a8q018/BlenderCycles-VapourSynth.zip?dl=0
I am not a programmer, I have no idea of scripting, so I'm a bit stuck here. So I would appreciate if you can take a look at the script and images, and if you can recommend me how to prevent the banding is so visible. Maybe we are doing something wrong with this script?
I know there are filters to debanding, but apparently they add noise to the image, and our main goal here is to remove the noise. So it would be great if you could recommend a better option to solve that problem.
I am making the video with this from terminal:
vspipe --y4m script.vpy - | ffmpeg -i pipe: -vcodec libx264 -crf 10 encoded.mkv
PS: I guess that people with little knowledge of the issues discussed in this forum (like me) are not very welcome, because the random questions are very difficult...
MonoS
3rd September 2015, 01:53
You're welcome here :)
Sorry for the rushed reply but it's 2am and i'm from my phone :p
www.pasteall.org/60924/python
Banding when using a denoising script is caused by processing thr image at a bitdepth too low, i modified the paste so that it use a 16bit pipeline [hoping that FT3dfilter support it].
I've also lowered the number of reference for motion estimation cause i've find degrain3 to strong.
Thsad of 400 is pretty high, try to use a lower value, something like 200,
Also i think you save your original blender render in jpg, don't do that, save it in png, even better if on png48, i've never used blender so i can't help you here.
Last tip, if the video you save is a temporary one to be reprocessed you can use a 10bit build of x264 on lossless mode [crf=0] and outputting a 4:4:4 video [--output-csp i444], or save it in png48 using imwri.write()
If it is the final render then let me know and wait utc 12:00 and i'll expand my explaination
Let me know if you have questions :)
feisty2
3rd September 2015, 02:18
Fft3d supports 8bits only
YAFU
3rd September 2015, 04:24
@MonoS, thank you for answer in those late hours of the night!
When using "png" the same banding is also generated. Blender supports many output formats and also 16 bits. So, is there some "Fft3d" alternative with 16 bits support (for vapoursynth)? I have seen that there is "Fft3dgpu"? Is that filter for vapoursynth and with 16-bit support? Generally Blender/Cycles users have high end GPU's.
feisty2
3rd September 2015, 04:29
dfttest (category wise, both are frequency denoisers)
but these 2 are pretty destructive to high frequencies, you got some better options actually, like KNLMeansCL
and it even works at 32bits precision (floating point)
YAFU
3rd September 2015, 05:18
Thank you. I compiled and installed "KNLMeansCL" in linux (need to install "opencl-headers", but I'm not sure if it will work because I use "nvidia" proprietary driver ).
But I have no idea how to implement or adapt the script. Where could I find any examples on how to use it?
feisty2
3rd September 2015, 05:20
http://forum.doom9.org/showthread.php?t=171379
feisty2
3rd September 2015, 05:48
example
import vapoursynth as vs
core = vs.get_core()
clp = core.imwri.Read('png-50/%04d.png', firstnum=1, alpha=False)
clp = core.fmtc.bitdepth (clp, bits=32, fulls=True, fulld=True, flt=True)
clp = core.fmtc.matrix (clp, mat="601", fulls=True, fulld=True)
def getvectors (src, pelclip, tr=6, pel=4, dct=0, thsad=400):
core = vs.get_core ()
src16 = core.fmtc.bitdepth (src, fulls=True, fulld=True, bits=16, flt=False)
supersoft = core.mv.Super (src16, pel=pel, chroma=False, hpad=32, vpad=32, pelclip=pelclip, sharp=2, rfilter=4, levels=0)
supersharp = core.mv.Super (src16, pel=pel, chroma=False, hpad=32, vpad=32, pelclip=pelclip, sharp=2, rfilter=2, levels=0)
def search (isb, delta):
vectors = core.mv.Analyse (supersoft, isb=isb, overlap=16, blksize=32, search=3, chroma=False, truemotion=True, delta=delta, trymany=True, searchparam=16, pelsearch=16, dct=dct, levels=0, divide=2, badrange=-24)
vectors = core.mv.Recalculate (supersoft, vectors, overlap=8, blksize=16, thsad=thsad//2, chroma=False, truemotion=True, search=3, searchparam=16, dct=dct, smooth=1, divide=2)
vectors = core.mv.Recalculate (supersharp, vectors, overlap=4, blksize=8, thsad=thsad//2, chroma=False, truemotion=True, search=3, searchparam=16, dct=dct, smooth=1, divide=2)
vectors = core.mv.Recalculate (supersharp, vectors, overlap=2, blksize=4, thsad=thsad//2, chroma=False, truemotion=True, search=3, searchparam=16, dct=dct, smooth=1, divide=0)
return vectors
bv = [search (True, i) for i in range (tr, 0, -1)]
fv = [search (False, i) for i in range (1, tr+1)]
vmulti = bv + fv
vmulti = core.std.Interleave (vmulti)
return vmulti
def degrainn (src, comp, pelclip, vmulti, tr=6, pel=4, thsad=400, thscd1=10000, thscd2=255):
core = vs.get_core ()
comp16 = core.fmtc.bitdepth (comp, fulls=True, fulld=True, bits=16, flt=False)
src16 = core.fmtc.bitdepth (src, fulls=True, fulld=True, bits=16, flt=False)
superclip = core.mv.Super (comp16, pel=pel, chroma=False, hpad=32, vpad=32, pelclip=pelclip, sharp=2, rfilter=2, levels=0)
def MDG1 (a):
bv = core.std.SelectEvery (vmulti, tr*2, tr-1-a)
fv = core.std.SelectEvery (vmulti, tr*2, tr+a)
MDG = core.mv.Degrain1 (src16, superclip, bv, fv, thsad=thsad, thscd1=thscd1, thscd2=thscd2, plane=0, limit=65535)
MDG = core.fmtc.bitdepth (MDG, fulls=True, fulld=True, bits=32, flt=True)
return MDG
MDGMulti = [MDG1 (i) for i in range (0, tr)]
MDGMulti = core.std.Interleave (MDGMulti)
def MDGMerge (start=None, a=2):
start = core.std.Merge (core.std.SelectEvery (MDGMulti, tr, 0), core.std.SelectEvery (MDGMulti, tr, 1), 0.5) if start is None else start
merge = core.std.Merge (start, core.std.SelectEvery (MDGMulti, tr, a), 1/(a+1))
a = a+1
clip = merge if a == tr else MDGMerge (start=merge, a=a)
return clip
return MDGMerge ()
def nrfinal (spatial, dif, peldif, vmulti, pel=4, tr=6, thsad=4800, thscd1=10000, thscd2=255):
core = vs.get_core ()
blankd = core.std.Expr ([dif], "0.5")
comp = degrainn (blankd, dif, peldif, vmulti, tr=tr, pel=pel, thsad=thsad, thscd1=thscd1, thscd2=thscd2)
NR = core.std.MergeDiff (spatial, comp)
return NR
def padding (src, left=0, right=0, top=0, bottom=0):
core = vs.get_core ()
w = src.width
h = src.height
clip = core.fmtc.resample (src, w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom, kernel="point", fulls=True, fulld=True)
return clip
spt = core.std.CropRel (core.knlm.KNLMeansCL(padding(clp,24,24,24,24), 0, 24, 4, h=3.2),24,24,24,24)
dif = core.std.MakeDiff(clp,spt)
vec = getvectors (spt, None)
clp = nrfinal (spt, dif, None, vec)
clp.set_output ()
jackoneill
3rd September 2015, 11:24
Can't you simply make Blender generate your images without that noise in them, or with less noise?
YAFU
3rd September 2015, 13:42
@feisty2, thanks. "vsedit" shows me the following error:
Failed to evaluate the script:
Python exception: matrix: output bitdepth not supported.
Traceback (most recent call last):
File "vapoursynth.pyx", line 1469, in vapoursynth.vpy_evaluateScript (src/cython/vapoursynth.c:23703)
File "/media/TEMPORAL/scrypt.vpy", line 5, in <module>
clp = core.fmtc.matrix (clp, mat="601", col_fam=vs.YUV, bits=32, fulls=True, fulld=True)
File "vapoursynth.pyx", line 1368, in vapoursynth.Function.__call__ (src/cython/vapoursynth.c:22272)
vapoursynth.Error: matrix: output bitdepth not supported.
And if I change that line 32 by 16, now I get the following error:
Failed to evaluate the script:
Python exception: knlm.KNLMeansCL: VapourSynthCreate error (clBuildProgram)!
Traceback (most recent call last):
File "vapoursynth.pyx", line 1469, in vapoursynth.vpy_evaluateScript (src/cython/vapoursynth.c:23703)
File "/media/TEMPORAL/scrypt.vpy", line 59, in <module>
spt = core.std.CropRel (core.knlm.KNLMeansCL(padding(clp,24,24,24,24), 0, 24, 4, h=3.2),24,24,24,24)
File "vapoursynth.pyx", line 1368, in vapoursynth.Function.__call__ (src/cython/vapoursynth.c:22272)
vapoursynth.Error: knlm.KNLMeansCL: VapourSynthCreate error (clBuildProgram)!
I'll try to find a simple script that makes use of "KNLMeansCL" to determine whether it is working properly on my installation.
@jackoneill. Yes, I could render with less noise increasing the render samples. But it means much greater render time by frame. You can spend hours/days rendering a few seconds of animation. That's why we are interested in reducing noise to save time with less samples. So, if by using images with more color depth I can avoid banding, that would be great.
MonoS
3rd September 2015, 13:59
@jackoneill. Yes, I could render with less noise increasing the render samples. But it means much greater render time by frame. You can spend hours/days rendering a few seconds of animation. That's why we are interested in reducing noise to save time with less samples. So, if by using images with more color depth I can avoid banding, that would be great.
As i expected, you are using a ray tracer, right??
If i remember right the "noise" you get it's not noise but lack of enough rays to build a proper pixel, so, if my understanding of the problem and the nature of the noise is right, you can substitute the first call to ft3dfilter with a gaussian blur [this will level out this lack of photons and make a better image for motion estimation], for the second call i don't know if it will be very useful, a lot of non static noise are already been removed by Degrain2
So, try removing the second call to ft3dfilter and substituting the first call with core.std.GBlur(ret, sigma=1.0) [IIRC GBlur don't work well with 16bit frames, you should try]
For png is to be expected some banding if you still use an 8bit pipeline, the use of png is needed to avoid jpeg compression artifact and chroma subsampling [you can turn off subsampling and use 100% quality, but you'll still get some little artifact and probably a bigger size than png].
Start saving your render in 16bit PNG then build up from this, now i'll take some look using your package.
EDIT: my apologies, the second call to ft3dfilter is required to remove quite a bit of remaining noise, i emulated it using dfttest but it cut out a lot of details as feisty2 said.
Also i made some errors in the script i sent you this morning, imwri read subsampled jpeg as RGB24 even if they in some sense are not, i'll post here the updated test script
input = core.fmtc.bitdepth(src, flt=True).fmtc.matrix(mat="601", col_fam=vs.YUV).fmtc.bitdepth(bits=16)
superF1 = core.generic.GBlur(input, 1.0)
superF2 = core.mv.Super(superF1, pel=2, sharp=1)
super = core.mv.Super(input)
#mvbw3 = core.mv.Analyse(superF2, isb=True, delta=3, overlap=4)
mvbw2 = core.mv.Analyse(superF2, isb=True, delta=2, overlap=4)
mvbw = core.mv.Analyse(superF2, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(superF2, isb=False, delta=1, overlap=4)
mvfw2 = core.mv.Analyse(superF2, isb=False, delta=2, overlap=4)
#mvfw3 = core.mv.Analyse(superF2, isb=False, delta=3, overlap=4)
ret = core.mv.Degrain2(clip=input, super=super, mvbw=mvbw, mvfw=mvfw, mvbw2=mvbw2, mvfw2=mvfw2, thsad=400)
ret = core.dfttest.DFTTest(ret, sigma=2.5).fmtc.bitdepth(bits=8, dmode=7)
ret.set_output()
this produced quite some nice [and washed out] result, here some screen
Frame 35: http://abload.de/img/nuovovapoursynthpytho77oeb.png
Frame 96: http://abload.de/img/nuovovapoursynthpytho4bqxt.png
last thing: there's already some banding in your original jpeg, you can't see it but if you apply some amplification you'll see it
frame 34: http://abload.de/img/nuovovapoursynthpythoqjodx.png
feisty2
3rd September 2015, 14:38
@YAFU
corrected
edit:.. just @ed the wrong guy... that's embarrassing
YAFU
3rd September 2015, 14:45
@MonoS, That's right, Cycles is a ray tracing renderer:
https://www.blender.org/manual/render/cycles/settings/light_paths.html
You can configure static noise pattern or random noise pattern. With static noise the noise reduction with the script does not work. The images I uploaded have random noise pattern.
I will analyze what you say and do some tests, it is a bit complicated to understand for me.
I'll upload a png sequence of 20 images at 16 bits for you can analyze if you want. But it will take some time because my bandwidth to upload is not good.
Thanks.
MonoS
3rd September 2015, 15:01
@MonoS, That's right, Cycles is a ray tracing renderer:
https://www.blender.org/manual/render/cycles/settings/light_paths.html
You can configure static noise pattern or random noise pattern. With static noise the noise reduction with the script does not work. The images I uploaded have random noise pattern.
I will analyze what you say and do some tests, it is a bit complicated to understand for me.
I'll upload a png sequence of 20 images at 16 bits for you can analyze if you want. But it will take some time because my bandwidth to upload is not good.
Thanks.
if you don't understand something don't be ashamed to ask, i've build up this knowledge across many years of experience across different subject [in which videogame and relative development are a crucial part :D].
The reason why with the static noise the script doesn't work is because the script try to distinguish between detail and noise using the movement of the camera and the object and applying denoising only on what is changed between frames [in the case of my example script, 2 previous, the current and 2 successive frames], with static noise, as the name says, the noise don't move so for the script the noise become detail.
Maybe someone more expert than me can come up with an intelligent idea on how to remove the static noise using the fact that it's static and so a mask can be created to modify only the affected pixels, who know
YAFU
3rd September 2015, 16:07
@MonoS, Thanks. Your tests look promising. I'll be doing some tests, perhaps this weekend.
Here I uploaded a sequence of png images at 16 bits. I have also included the blender scene in case any of you want to play with it :)
https://www.dropbox.com/s/xfndrsx5gwz7wkp/png%2016%20bit%20and%20scene.zip?dl=0
Download Blender (OpenSource, Free). Open the scene with Blender. The scene is set to use nvidia GPU (CUDA). If you do not have a good graphics card, in the right panel under "Render" in "Device" choose "CPU". Then on that panel a little below under "Performance" in "Tiles" you put a value of 32 in X and Y (32 is not related to bits, this is only frame size of each thread processor). To render the scene, in above menu in "Render" > "Render Animation". The images are saved by default in your "tmp" folder. Esc aborts rendering. If you want to play with the scene, the right mouse button selects objects. For navigate the 3D view (orbit) press the middle mouse button. You can play animation in the viewport (not rendered) by clicking the play button below in the timeline. What I say just if you want to spend a little fun time with Blender 3D :) . This scene is very simple just for testing and renders it relatively quickly.
Regarding noise reduction, I think random noise patterns is the right way to proceed, especially if the image has no quick/fast changes between frame and frame. Without knowing much about this, I think it would be relative easy to detect noise with static noise pattern, but then some algorithm should reconstruct the image below the noise considering neighbors pixels, and that would be quite difficult and maybe without good result.
@feisty2, do you know some very simple script where I can test whether "KNLMeansCL" is working well? I think OpenCL headres I installed to compile it only work with opensource drivers (I'm using "nvidia" driver), but I do not know.
feisty2
3rd September 2015, 16:16
##Load Vaporsynth
import vapoursynth as vs
core = vs.get_core()
##Load The Source Clip
clp = core.imwri.Read('png-50/%04d.png', firstnum=1, alpha=False)
clp = core.fmtc.bitdepth (clp, bits=32, fulls=True, fulld=True, flt=True)
clp = core.fmtc.matrix (clp, mat="601", fulls=True, fulld=True)
##The Actual KNLMeansCL
clp = core.knlm.KNLMeansCL(clp, d=0, a=24, s=4, h=3.2)
##Output
clp.set_output ()
YAFU
3rd September 2015, 16:40
Yes, I get the error
Failed to evaluate the script:
Python exception: knlm.KNLMeansCL: VapourSynthCreate error (clBuildProgram)!
Traceback (most recent call last):
File "vapoursynth.pyx", line 1469, in vapoursynth.vpy_evaluateScript (src/cython/vapoursynth.c:23703)
File "/media/TEMPORAL/scrypt.vpy", line 9, in <module>
clp = core.knlm.KNLMeansCL(clp, d=0, a=24, s=4, h=3.2)
File "vapoursynth.pyx", line 1368, in vapoursynth.Function.__call__ (src/cython/vapoursynth.c:22272)
vapoursynth.Error: knlm.KNLMeansCL: VapourSynthCreate error (clBuildProgram)!
I'll search what I need to compile correctly for nvidia in Linux.
MonoS
3rd September 2015, 17:34
I made some more test and consideration, and i noticed that after the first denoising stage the only noise left is on the low lights so i've modified the second denoising stage to use a mask
deno1 = core.mv.Degrain2(clip=input, super=super, mvbw=mvbw, mvfw=mvfw, mvbw2=mvbw2, mvfw2=mvfw2, thsad=400)
def f(x):
if x < 12000:
return 65535
else:
return 0
maskY = core.std.Lut(deno, [0], function=f).std.ShufflePlanes([0], vs.GRAY)
mask = core.std.ShufflePlanes([maskY, maskY, maskY], [0,0,0], vs.YUV)
deno2 = core.dfttest.DFTTest(deno, sigma=2.5)
ret = core.std.MaskedMerge(deno,deno2, mask)#.fmtc.bitdepth(bits=8, dmode=7)
ret.set_output()
#remove the # from the line below to see the mask
#maskY.set_output()
It still use dfttest because i don't want to install KNLMeansCL right now but would be enough to substitute the function call
feisty2
3rd September 2015, 17:43
Install? Sounds real complicated...
I didn't "install" knlmeanscl, just put the .dll in the plugin folder, then, it's just okay
Why u guys gotta "install" it?
YAFU
3rd September 2015, 18:03
@feisty2, dll is for windows. It is not easy to find binaries for Linux :(
Even developers usually share binaries for Windows, but only sources for Linux. But this is understandable, because each distro maintainers are responsible for putting the binaries in repositories. But for not very common applications is a bit more difficult to find them.
@MonoS, In mensje #237 in the first line I have replaced "src" by "clip=ret". Is it right?
EDIT:
otherwise I get the following error:
Failed to evaluate the script:
Python exception: name 'src' is not defined
Traceback (most recent call last):
File "vapoursynth.pyx", line 1469, in vapoursynth.vpy_evaluateScript (src/cython/vapoursynth.c:23703)
File "/media/TEMPORAL/scrypt.vpy", line 35, in <module>
input = core.fmtc.bitdepth(src, flt=True).fmtc.matrix(mat="601", col_fam=vs.YUV).fmtc.bitdepth(bits=16)
NameError: name 'src' is not defined
But maybe I'm doing something wrong because I'm building the script with parts of the lines you posted on each message.
I also needed this (in case some user read this thread in the future):
https://github.com/chikuzen/GenericFilters
https://github.com/HomeOfVapourSynthEvolution/VapourSynth-DFTTest
MonoS
3rd September 2015, 18:17
@feisty2: i hope this is enough of a reason to not "install" something XD http://abload.de/img/clipboard02wxobh.png [AKA i've other things to do]
@YAFU: I've made hack upon hack on the initial script you linked us, now mine look like this
src = core.imwri.Read("C:/Users/MonoS/Desktop/BlenderCycles-VapourSynth/images/%04d.png", firstnum=50)
input = core.fmtc.bitdepth(src, flt=True).fmtc.matrix(mat="601", col_fam=vs.YUV).fmtc.bitdepth(bits=16, dmode=7)
superF1 = DitherLumaRebuild(input, s0=1)
superF2 = core.mv.Super(superF1, pel=2, sharp=1)
super = core.mv.Super(input)
mvbw2 = core.mv.Analyse(superF2, isb=True, delta=2, overlap=4)
mvbw = core.mv.Analyse(superF2, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(superF2, isb=False, delta=1, overlap=4)
mvfw2 = core.mv.Analyse(superF2, isb=False, delta=2, overlap=4)
deno = core.mv.Degrain2(clip=input, super=super, mvbw=mvbw, mvfw=mvfw, mvbw2=mvbw2, mvfw2=mvfw2, thsad=400)
def f(x):
if x < 12000:
return 65535
else:
return 0
maskY = core.std.Lut(deno, [0,1,2], function=f).std.ShufflePlanes([0], vs.GRAY)
mask = core.std.ShufflePlanes([maskY, maskY, maskY], [0,0,0], vs.YUV)
ret = core.std.MaskedMerge(deno,core.dfttest.DFTTest(deno, sigma=2.5), mask)#.fmtc.bitdepth(bits=8, dmode=7)
now i don't know if in your script input and ret are the same clip
you don't need anymore GBlur, some testing showed me that it lower the final quality and destroy a lot of small details, so no need to use generics [and AFAIK they'll be included in the next main version of vapour]
If feisy said that dfttest is not the ideal solution, trust him, he surely made more extensive testing than me on that, so better link KNLMeansCL
Are_
3rd September 2015, 19:58
@YAFU: on gentoo you need to install nvidia-drivers and it's uvm kernel module, I don't know if it is included in your distro of if it is your problem at all.
YAFU
3rd September 2015, 22:11
hi Are_
Using Kubuntu 64 bits.
"nvidia_uvm" seems loaded into the kernel and nVidia OpenCL in Blender 3D seems to be working properly.
I asked in the KNLMeans thread to see if they can help me.
feisty2
4th September 2015, 08:30
@jackoneill
BlockFPS crashes mvtools on GRAY clips (I think something is wrong inside "mvblockfpsFree")
EDIT:
fixed, pulled a request on Git
mawen1250
5th September 2015, 13:10
For eliminating static noise, you might want to give BM3D (http://forum.doom9.org/showthread.php?t=172172) a try, which can do an excellent job for nearly all kinds of small noise patterns.
feisty2
5th September 2015, 15:17
xxx
sup = MSuper(last,chroma=False)
bv1 = MAnalyse(sup,isb=True,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=1,chroma=False)
fv1 = MAnalyse(sup,isb=False,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=1,chroma=False)
bv2 = MAnalyse(sup,isb=True,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=1,chroma=False)
fv2 = MAnalyse(sup,isb=False,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=1,chroma=False)
bv3 = MAnalyse(sup,isb=True,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=1,chroma=False)
fv3 = MAnalyse(sup,isb=False,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=1,chroma=False)
MDegrain3(last, sup, bv1, fv1, bv2, fv2, bv3, fv3, thsad=2000, thscd1=10000)
converttoy8 ()
http://i.imgur.com/10iTirI.png
import vapoursynth as vs
core = vs.get_core()
clp = xxx
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=32, flt=True)
clp2 = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=16)
sup = core.mvsf.Super(clp)
bv1 = core.mvsf.Analyze(sup,isb=True,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=1)
fv1 = core.mvsf.Analyze(sup,isb=False,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=1)
bv2 = core.mvsf.Analyze(sup,isb=True,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=1)
fv2 = core.mvsf.Analyze(sup,isb=False,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=1)
bv3 = core.mvsf.Analyze(sup,isb=True,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=1)
fv3 = core.mvsf.Analyze(sup,isb=False,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=1)
clp = core.mvsf.Degrain3(clp, sup, bv1, fv1, bv2, fv2, bv3, fv3, thsad=2000, thscd1=10000)
sup2 = core.mv.Super(clp2)
bv12 = core.mv.Analyse(sup2,isb=True,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=1)
fv12 = core.mv.Analyse(sup2,isb=False,blksize=16,overlap=8,delta=1,search=3,truemotion=True,dct=1)
bv22 = core.mv.Analyse(sup2,isb=True,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=1)
fv22 = core.mv.Analyse(sup2,isb=False,blksize=16,overlap=8,delta=2,search=3,truemotion=True,dct=1)
bv32 = core.mv.Analyse(sup2,isb=True,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=1)
fv32 = core.mv.Analyse(sup2,isb=False,blksize=16,overlap=8,delta=3,search=3,truemotion=True,dct=1)
clp2 = core.mv.Degrain3(clp2, sup2, bv12, fv12, bv22, fv22, bv32, fv32, thsad=2000, thscd1=10000)
clp2 = core.fmtc.bitdepth(clp2, fulls=True, fulld=True, bits=32, flt=True)
fnl = core.std.StackHorizontal([clp,clp2])
fnl.set_output ()
http://i.imgur.com/19xhwJh.png
@jackoneill
guess I just fixed dct 1-4 (fftw modes) in my floating point branch
tried to fix it on uint16_t, your original version, but failed
maybe you could try to fix it yourself
more details at https://github.com/IFeelBloated/MVTools_SF/blob/master/DCTFFTW.cpp
YAFU
7th September 2015, 13:30
Hello. I've been doing some experiments.
Apparently what mainly produces banding is this line at end in the original script:
ret = core.fft3dfilter.FFT3DFilter(ret,sigma=2.5, bt=5, bw=32, bh=32, ow=16, oh=16, sharpen=0.7)
http://www.pasteall.org/60466
I have understood that this line is to reduce fine grain noise, right?
I found a good way for those banding are not very noticeable. Basically, create a lossless video with the original script, but without that line.
Then apply the script to the resulting video, but in superF1 replacing with the values of that line that was removed:
import vapoursynth as vs
core = vs.get_core()
##
##ffmpeg with ffms2
core.std.LoadPlugin('/usr/lib/x86_64-linux-gnu/libffms2.so.3')
ret = core.ffms2.Source(source='/PATH_TO_VIDEO_HERE/encoded.mkv')
##
input = core.fmtc.bitdepth (clip=ret, bits=8)
superF1 = core.fft3dfilter.FFT3DFilter(input,sigma=2.5, bt=5, bw=32, bh=32, ow=16, oh=16, sharpen=0.7)
superF2 = core.mv.Super(superF1, pel=2, sharp=1)
super = core.mv.Super(input)
mvbw3 = core.mv.Analyse(superF2, isb=True, delta=3, overlap=4)
mvbw2 = core.mv.Analyse(superF2, isb=True, delta=2, overlap=4)
mvbw = core.mv.Analyse(superF2, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(superF2, isb=False, delta=1, overlap=4)
mvfw2 = core.mv.Analyse(superF2, isb=False, delta=2, overlap=4)
mvfw3 = core.mv.Analyse(superF2, isb=False, delta=3, overlap=4)
ret = core.mv.Degrain3(clip=input, super=super, mvbw=mvbw, mvfw=mvfw, mvbw2=mvbw2, mvfw2=mvfw2, mvbw3=mvbw3, mvfw3=mvfw3, thsad=400)
ret.set_output()
Then the noise reduction is similar to original script, but with less banding.
I guess that I've done it can be done from a single script without the intermediate step by creating these first video, but I have no idea about how to create this script. How could I do it?
The noise reduction in the kind of noise that renders from Blender 3D generate using this method/script is amazing.
It is a pity that Fft3d not support 16 bits because the result could be even better. Do you know if that filter is still under development and whether it plans to support 16-bit?
YAFU
7th September 2015, 16:41
Hello HolyWu.
It seems that in the HAvsFunc thread there are no instructions for Linux. Where should I copy havsfunc.py in Linux?
Regarding suggestions of MonoS, I was able to build this script with parts of code from his different messages, I do not know if I have done well:
http://www.pasteall.org/61017
For now I get better noise reduction with the original script using FFT3DFilter.
YAFU
7th September 2015, 19:24
Just in case this is useful to someone else, I explain:
I have installed at least three versions of python (I guess they have been left of different system updates). So I have different paths to "/pythonX.Y/site-packages" both in "/usr/local/lib" and "/usr/lib". So from linux terminal:
whereis vapoursynth
And you get "/usr/local/lib/vapoursynth" or "/usr/lib/vapoursynth" depending on where you've installed it. Generally if you have compiled without specified path, default it is installed in "/usr/local/lib/", and if you installed from a distribution package generally is installed in "/usr/lib". So depending on that copy "havsfunc.py" to "/usr/local/lib/pythonX.Y/site-packages" or "/usr/lib/pythonX.Y/site-packages". "X.Y" should be the highest version of python you had when you installed vapoursynth. In my case I have copied it to "/usr/local/lib/python3.4/site-packages". In the same path there were two files, "vapoursynth.la" and "vapoursynth.so".
I will study this little script and do some testing with these images that I have shared in previous posts in this thread.
Are_
7th September 2015, 20:00
If you don't want to deal with root access every time you want to update/install a new module:
# echo "/home/your-user/some-path-to-a-directory-with-all-your-modules" > /usr/local/lib/python3.4/site-packages/vapoursynth_modules.pth
YAFU
7th September 2015, 23:37
Ok Are_, I'll try that
MonoS
8th September 2015, 19:03
If someone don't come up with some suggestion, this is my "final suggestion"
The video outputted is this one http://www.mediafire.com/watch/mws7c9hgwwrsqjm/test.mkv
The script used this [i wrote some comments for you]
import vapoursynth as vs
import havsfunc as has
core = vs.get_core()
#Load imwri
core.std.LoadPlugin("C:/Program Files (x86)/VapourSynth/plugins64/imwri/imwri.dll")
#Read images
src = core.imwri.Read("C:/Users/MonoS/Desktop/BlenderCycles-VapourSynth/images/%04d.png", firstnum=50)
#converting input RGB images to YUV444
input = core.fmtc.bitdepth(src, flt=True).fmtc.matrix(mat="601", col_fam=vs.YUV).fmtc.bitdepth(bits=16, dmode=7)
#This should improve motion estimation for darken zones
superF1 = has.DitherLumaRebuild(input, s0=1)
superF2 = core.mv.Super(superF1, pel=2, sharp=1)
super = core.mv.Super(input)
#Do motion compesated denoising
mvbw2 = core.mv.Analyse(superF2, isb=True, delta=2, overlap=4)
mvbw = core.mv.Analyse(superF2, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(superF2, isb=False, delta=1, overlap=4)
mvfw2 = core.mv.Analyse(superF2, isb=False, delta=2, overlap=4)
deno = core.mv.Degrain2(clip=input, super=super, mvbw=mvbw, mvfw=mvfw, mvbw2=mvbw2, mvfw2=mvfw2, thsad=400)
#After first denoising stage the majority of the grain is on the darker zone, create a mask of only the dark zones
def f(x):
if x < 12000:
return 65535
else:
return 0
maskY = core.std.Lut(deno, [0,1,2], function=f).std.ShufflePlanes([0], vs.GRAY)
mask = core.std.ShufflePlanes([maskY, maskY, maskY], [0,0,0], vs.YUV)
#Do a second pass of spatial denoising only on the masked zones
ret = core.std.MaskedMerge(deno,core.dfttest.DFTTest(deno, sigma=2.5), mask)
#Delete # below to output a 8bit clip
#ret = core.fmtc.bitdepth(bits=8, dmode=7)
ret.set_output()
#Delete # below to output a video showing the difference between the the first and second denoise pass
#core.std.Interleave([deno, ret]).set_output()
#Delete # below to output the mask
#mask.set_output()
I also suggest a moderator to move all this discussion about removing ray tracing noise artifact into a new thread, we went a bit to OT imho
EDIT: i've thrown inside the script the jpg you sent us at the beginning, FAAAAR better result if you ask me
http://www.mediafire.com/watch/ypwrf9qv5ad6lfy/testjpg.mkv
YAFU
8th September 2015, 21:01
@MonoS, Thank you very much for your scripts and suggestions. I had not tasted much your scripts because I did not know how to create a functional script from what you said in each message, I really know very little about these issues and I am learning. With time I'm going to analyze what each filter do and learning how it works.
Edit: The comments you made into the last script are really helpful to learn, thanks.
In the BlenderArtists forum, "brothermechanic" has done new tests and he found a way to minimize banding:
http://www.blenderartists.org/forum/showthread.php?378736-Cycles-noise-reduction-with-VapourSynth&p=2933482&viewfull=1#post2933482
For now we are stuck with "fft3dfilter", it seems to be the best handling this kind of noise generated by Blender/Cycles. But I will continue testing to find the best 16 bits solution.
You see the example with "hard-denoise" filter. Similar that way should look material in cubes if they have no noise in render. However, in other situations it would be necessary to preserve details, without much noise reduction.
Thanks.
Boulder
14th September 2015, 04:04
Is there any possibility to get the functionality of MShow included? I use it quite often to adjust thscd1 and thscd2 to match the source better.
EDIT: Also, is it OK to simply resize to double the dimensions of the clip fed to Super as pelclip? In Avisynth 2.6, you need to do some shifting.
Boulder
15th September 2015, 16:54
OK, I got some more odd behaviour. It could be MVTools acting up but it's still quite interesting.
This one works properly, that is, Degrain1 does what it is supposed to do:
import vapoursynth as vs
import havsfunc as has
core = vs.get_core()
core.avs.LoadPlugin(r'c:/program files (x86)/avisynth/plugins/dgdecodenv.dll')
clp = core.avs.DGSource('c:/x265/hotfuzztest.dgi')
#clp = core.fmtc.bitdepth(clp, bits=16)
feed = has.DitherLumaRebuild(clp)
pelmdg = core.resize.Spline(clp,width=clp.width*2,height=clp.height*2)
pelprefilt = core.resize.Spline(feed,width=clp.width*2,height=clp.height*2)
superanalyse = core.mv.Super(feed,pel=2,chroma=True,rfilter=4, pelclip=pelprefilt)
supermdg = core.mv.Super(clp,pel=2,chroma=True,rfilter=4,levels=1, pelclip=pelmdg)
bv1 = core.mv.Analyse(superanalyse, dct=5, blksize=16, overlap=8, isb=True)
fv1 = core.mv.Analyse(superanalyse, dct=5, blksize=16, overlap=8)
finalclip = core.mv.Degrain1(clp, supermdg, bv1, fv1, thsad=400, thsadc=400, limit=5, limitc=6)
org = clp
final = core.std.Interleave(clips=[org,finalclip])
final.set_output()
If you uncomment the line "clp = core.fmtc.bitdepth(clp, bits=16)", Degrain1 doesn't seem to do anything.
feisty2
15th September 2015, 17:08
all 10 modes of dct are broken in the current binary, dct 5-10 have been fixed in the source code, but no binary available yet, dct 1-4 are just broken
I fixed all dct stuff in my floating point branch tho, if u wanna try it
Boulder
15th September 2015, 17:54
Because the "limit" and "limitc" parameters do not scale internally to the bit depth of the input clip, hence it can't really do anything for so low limits on 16-bit input. The range becomes 0 to 65535 for 16-bit clips.
Damn, I really start feeling like a newbie once more :)
all 10 modes of dct are broken in the current binary, dct 5-10 have been fixed in the source code, but no binary available yet, dct 1-4 are just broken
I fixed all dct stuff in my floating point branch tho, if u wanna try it
I was wondering why dct=5 is dead slow so it being broken that's probably the reason. Your binary seems to be for x64 so that's out of the question for the moment (because of DGDecodeNV.dll which cannot be loaded in VSx64).
feisty2
15th September 2015, 18:02
weird... Is it worth it? Stay on x86 just for a source filter.... That's new
Well, just replace that with ffms or lsmash, both got x64 binaries
Boulder
15th September 2015, 18:15
And both have their issues :) Besides, DG's product is much more convenient for my usage so I'll stick to x86 for the time being. Maybe I'll get around to building MVTools but there's no rush, I'll progress slowly anyway.
feisty2
15th September 2015, 18:21
And besides, there's avsreader... So, use dg whatever under avisynth x64, and avsreader will link to avisynth and output the avisynth script as a regular video clip
jackoneill
15th September 2015, 18:29
dct > 0 isn't slow because it's broken, it's just slow.
Does limit(c) even do anything? When I tested that, it barely had any effect.
MShow probably won't be added for a long time.
Boulder
17th September 2015, 04:31
Are the other options in MVTools functions scaled for 16-bit input (thsad etc.) or will they need to be scaled according to the input bit depth as well?
Boulder
17th September 2015, 07:06
Thanks!
cybersharky
17th September 2015, 11:24
Please can someone help with writing this function in python?
function McDegrainSharp(clip c, int "frames", float "bblur", float "csharp", bool "bsrch")
{ # Based on MCDegrain By Didee, http://forum.doom9.org/showthread.php?t=161594
# Also based on DiDee observations in this thread: http://forum.doom9.org/showthread.php?t=161580
# "Denoise with MDegrainX, do slight sharpening where motionmatch is good, do slight blurring where motionmatch is bad"
# In areas where MAnalyse cannot find good matches, the blur() will be dominant.
# In areas where good matches are found, the sharpen()'ed pixels will overweight the blur()'ed pixels
# when the pixel averaging is performed.
frames = default(frames, 2)
bblur = default(bblur, 0.6)
csharp = default(csharp, 0.6)
bsrch = default(bsrch, true)
bs = (c.width>960) ? 16 : 8
c2 = c.blur(bblur)
super = bsrch ? c2.MSuper(pel=2, sharp=1) : c.MSuper(pel=2, sharp=1)
super_rend = c.sharpen(csharp).MSuper(pel=2, sharp=1,levels=1)
backward_vec3 = MAnalyse(super, isb = true, delta = 3, blksize=bs, overlap=bs/2)
backward_vec2 = MAnalyse(super, isb = true, delta = 2, blksize=bs, overlap=bs/2)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, blksize=bs, overlap=bs/2)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, blksize=bs, overlap=bs/2)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, blksize=bs, overlap=bs/2)
forward_vec3 = MAnalyse(super, isb = false, delta = 3, blksize=bs, overlap=bs/2)
(frames<=0) ? c :\
(frames==1) ? c2.MDegrain1(super_rend, backward_vec1,forward_vec1,thSAD=400) :\
(frames==2) ? c2.MDegrain2(super_rend, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400) :\
c2.MDegrain3(super_rend, backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400)
return(last)
}
Are_
17th September 2015, 12:50
I'm not sure it's working correctly because I can't test it, but here you have it anyway. mcdegrainsharp.py (https://gist.github.com/4re/b5399b1801072458fc80)
Boulder
19th September 2015, 18:39
dct > 0 isn't slow because it's broken, it's just slow.The difference in performance between dct=0 and dct=5 is much less drastic in the Avisynth plugin. Is there any room for improvement (totally unoptimized code or something) or is it about as good as it gets?
jackoneill
19th September 2015, 22:11
The difference in performance between dct=0 and dct=5 is much less drastic in the Avisynth plugin. Is there any room for improvement (totally unoptimized code or something) or is it about as good as it gets?
If it's slower than the Avisynth plugin then yes, there is room for improvement. I don't know what makes it slower in this case.
Boulder
20th September 2015, 11:38
I made a quick test with 8-bit clips. The scripts are naturally not exactly the same but the operations are quite close to each other.
1.68 fps, Vapoursynth with dct=5
3.70 fps, Vapoursynth with dct=0
2.79 fps, Avisynth with dct=5
2.99 fps, Avisynth with dct=0
Tarutaru
23rd September 2015, 15:58
I'm not sure it's working correctly because I can't test it, but here you have it anyway. mcdegrainsharp.py (https://gist.github.com/4re/b5399b1801072458fc80)
Thanks, but when I apply this function, the color is changed...
import vapoursynth as vs
import mcdegrainsharp as mcds
core = vs.get_core()
ret = core.ffms2.Source(source='/foo/bar.mkv')
ret1 = mcds.mcdegrainsharp(ret)
ret = core.std.Interleave([ret,ret1])
ret.set_output()
Original:
https://na.cx/i/FbQhF3.png
Output:
https://na.cx/i/0d1JvY.png
Look at the grass between Lipton and the other tropper, they are not as green as the original....
Are_
23rd September 2015, 22:33
Yeah, indeed. Looks like generic.Blur is bugged when input is 8bit? Try again with the latest version please, keep in mind the weights for ssharp and bblur behave differently now.
Tarutaru
24th September 2015, 15:27
Yeah, indeed. Looks like generic.Blur is bugged when input is 8bit? Try again with the latest version please, keep in mind the weights for ssharp and bblur behave differently now.
It looks good with the new version:thanks:
Original:
https://na.cx/i/Rj64wd.png
Output:
https://na.cx/i/52ag3Z.png
Boulder
28th September 2015, 11:18
is it OK to simply resize to double the dimensions of the clip fed to Super as pelclip (if pel=2)? In Avisynth 2.6, you need to do some shifting.What about this question?
jackoneill
28th September 2015, 12:26
What about this question?
If shifting is needed in Avisynth, then it's needed here too.
Boulder
3rd January 2016, 17:16
I found a bug in the latest release. This code will crash MVTools, I'm getting a crash around frame 15. Sometimes frame 7 also causes it. You can also see that there's a lot of artifacts around the coloured area in several frames.
The crash doesn't occur if the line feed = has.DitherLumaRebuild(clp) is replaced by feed = clp.
The crash and artifacts disappear if the conversion to 16 bits is removed, or if you remove the last two lines with mv.Recalculate.
import vapoursynth as vs
import havsfunc as has
core = vs.get_core()
clp = core.ffms2.Source(r'u:\test-002.264')
clp = core.fmtc.bitdepth(clp, bits=16)
feed = has.DitherLumaRebuild(clp)
superanalyse = core.mv.Super(feed, pel=2, rfilter=4)
supermdg = core.mv.Super(clp, pel=2, rfilter=4, levels=1)
bv1 = core.mv.Analyse(superanalyse, dct=0, blksize=16, overlap=8, isb=True)
fv1 = core.mv.Analyse(superanalyse, dct=0, blksize=16, overlap=8, isb=False)
bv1 = core.mv.Recalculate(superanalyse, bv1, thsad=100, blksize=8, overlap=4, search=3)
fv1 = core.mv.Recalculate(superanalyse, fv1, thsad=100, blksize=8, overlap=4, search=3)
bv1 = core.mv.Recalculate(superanalyse, bv1, thsad=100, blksize=4, overlap=2, search=3)
fv1 = core.mv.Recalculate(superanalyse, fv1, thsad=100, blksize=4, overlap=2, search=3)
finalclip = core.mv.Degrain1(clp, supermdg, bv1, fv1, thscd1=300, thscd2=80)
output = finalclip
output.set_output()
Here's the sample clip to use to test and debug:
https://drive.google.com/file/d/0BzeF_1syecQwQjJZTFNhUFVXVk0/view?usp=sharing
jackoneill
3rd January 2016, 22:27
I found a bug in the latest release. This code will crash MVTools, I'm getting a crash around frame 15. Sometimes frame 7 also causes it. You can also see that there's a lot of artifacts around the coloured area in several frames.
I can reproduce this. Some integer variable probably overflows, because MVTools wasn't written with 16 bit input in mind. (Something similar has happened before.)
feisty2
4th January 2016, 13:21
I found a bug in the latest release. This code will crash MVTools, I'm getting a crash around frame 15. Sometimes frame 7 also causes it. You can also see that there's a lot of artifacts around the coloured area in several frames.
The crash doesn't occur if the line feed = has.DitherLumaRebuild(clp) is replaced by feed = clp.
The crash and artifacts disappear if the conversion to 16 bits is removed, or if you remove the last two lines with mv.Recalculate.
import vapoursynth as vs
import havsfunc as has
core = vs.get_core()
clp = core.ffms2.Source(r'u:\test-002.264')
clp = core.fmtc.bitdepth(clp, bits=16)
feed = has.DitherLumaRebuild(clp)
superanalyse = core.mv.Super(feed, pel=2, rfilter=4)
supermdg = core.mv.Super(clp, pel=2, rfilter=4, levels=1)
bv1 = core.mv.Analyse(superanalyse, dct=0, blksize=16, overlap=8, isb=True)
fv1 = core.mv.Analyse(superanalyse, dct=0, blksize=16, overlap=8, isb=False)
bv1 = core.mv.Recalculate(superanalyse, bv1, thsad=100, blksize=8, overlap=4, search=3)
fv1 = core.mv.Recalculate(superanalyse, fv1, thsad=100, blksize=8, overlap=4, search=3)
bv1 = core.mv.Recalculate(superanalyse, bv1, thsad=100, blksize=4, overlap=2, search=3)
fv1 = core.mv.Recalculate(superanalyse, fv1, thsad=100, blksize=4, overlap=2, search=3)
finalclip = core.mv.Degrain1(clp, supermdg, bv1, fv1, thscd1=300, thscd2=80)
output = finalclip
output.set_output()
Here's the sample clip to use to test and debug:
https://drive.google.com/file/d/0BzeF_1syecQwQjJZTFNhUFVXVk0/view?usp=sharing
tested your script (removed chroma and changed bitdepth to 32) on my floating point branch and didn't see any crash or artifacts...
weird, cuz my branch was forked from this master branch and should have suffered the same issue...
feisty2
4th January 2016, 13:39
import vapoursynth as vs
import havsfunc as has
core = vs.get_core()
clp = core.ffms2.Source("test-002.264")
feed = core.fmtc.bitdepth(has.DitherLumaRebuild(core.fmtc.bitdepth(clp, bits=16)), bits=32)
clp = core.fmtc.bitdepth(clp, bits=32)
y1 = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
u1 = core.std.Expr(core.std.ShufflePlanes(clp, planes=1, colorfamily=vs.GRAY),"x 0.5 +")
v1 = core.std.Expr(core.std.ShufflePlanes(clp, planes=2, colorfamily=vs.GRAY),"x 0.5 +")
y2 = core.std.ShufflePlanes(feed, planes=0, colorfamily=vs.GRAY)
u2 = core.std.Expr(core.std.ShufflePlanes(feed, planes=1, colorfamily=vs.GRAY),"x 0.5 +")
v2 = core.std.Expr(core.std.ShufflePlanes(feed, planes=2, colorfamily=vs.GRAY),"x 0.5 +")
clp = core.std.ShufflePlanes([y1,u1,v1], planes=[0,0,0], colorfamily=vs.YUV)
feed = core.std.ShufflePlanes([y2,u2,v2], planes=[0,0,0], colorfamily=vs.YUV)
superanalyse = core.mvsf.Super(feed, pel=2, rfilter=4)
supermdg = core.mvsf.Super(clp, pel=2, rfilter=4, levels=1)
bv1 = core.mvsf.Analyse(superanalyse, dct=0, blksize=16, overlap=8, isb=True)
fv1 = core.mvsf.Analyse(superanalyse, dct=0, blksize=16, overlap=8, isb=False)
bv1 = core.mvsf.Recalculate(superanalyse, bv1, thsad=100, blksize=8, overlap=4, search=3)
fv1 = core.mvsf.Recalculate(superanalyse, fv1, thsad=100, blksize=8, overlap=4, search=3)
bv1 = core.mvsf.Recalculate(superanalyse, bv1, thsad=100, blksize=4, overlap=2, search=3)
fv1 = core.mvsf.Recalculate(superanalyse, fv1, thsad=100, blksize=4, overlap=2, search=3)
finalclip = core.mvsf.Degrain1(clp, supermdg, bv1, fv1, thscd1=300, thscd2=80)
y = core.std.ShufflePlanes(finalclip, planes=0, colorfamily=vs.GRAY)
u = core.std.Expr(core.std.ShufflePlanes(finalclip, planes=1, colorfamily=vs.GRAY),"x 0.5 -")
v = core.std.Expr(core.std.ShufflePlanes(finalclip, planes=2, colorfamily=vs.GRAY),"x 0.5 -")
output = core.std.ShufflePlanes([y,u,v], planes=[0,0,0], colorfamily=vs.YUV)
output.set_output()
now with chroma, still no crash or artifacts...
jackoneill
4th January 2016, 14:33
tested your script (removed chroma and changed bitdepth to 32) on my floating point branch and didn't see any crash or artifacts...
weird, cuz my branch was forked from this master branch and should have suffered the same issue...
It turned out to be a bug introduced by me, in the 16 bit SAD functions. You don't use those.
Why I'm fixing bugs, can I have a piece of that video you used to show that dct=1 is broken, please? That particular frame, plus the five before and five after should do.
feisty2
4th January 2016, 15:11
https://mega.nz/#!ShFRRIpD!uf3IRi-Hg7PPnBVVgQhd1z34-VNZccj9keuW1yJbrKw
jackoneill
4th January 2016, 17:04
That one was integer overflow, and had nothing to do with the dct parameter.
Boulder
16th January 2016, 11:00
Were you able to reproduce and fix the issue?
jackoneill
16th January 2016, 12:52
Were you able to reproduce and fix the issue?
Yes. I'll tag v10 later if nothing else pops up.
jackoneill
18th January 2016, 13:07
This is v10. (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v10)
* Fix crash in BlockFPS with Gray input.
* Fix unspecified bug in the 8x8 and 16x16 SATD functions (fix by feisty2).
* Fix crash in Analyse/Recalculate due to a bug in the 2x2 and 2x4 16 bit SAD functions.
* Fix integer overflow in Degrain when thsad is large enough, which turned it into a very slow no-op.
Boulder
18th January 2016, 13:13
Thanks, will put it to test soon :)
Is it now safe to try dct=5?
jackoneill
18th January 2016, 13:20
Thanks, will put it to test soon :)
Is it now safe to try dct=5?
Wasn't it always safe?
Boulder
18th January 2016, 13:26
Wasn't it always safe?
http://forum.doom9.org/showthread.php?p=1738746#post1738746
Apparently it's fixed now. I recalled that there was some discussion earlier..
I'll have to test the performance, earlier it was much slower than in Avisynth.
jackoneill
18th January 2016, 13:50
http://forum.doom9.org/showthread.php?p=1738746#post1738746
Apparently it's fixed now. I recalled that there was some discussion earlier..
I'll have to test the performance, earlier it was much slower than in Avisynth.
Ah, yes. feisty2 also tried that with dct=5. The problem wasn't the dct parameter, it was that integer overflow with large thsad.
feisty2
18th January 2016, 14:10
Ah, yes. feisty2 also tried that with dct=5. The problem wasn't the dct parameter, it was that integer overflow with large thsad.
dct 5-10 are good now, dct 1-4 (fftw related modes) are still broken in v10...
Boulder
18th January 2016, 14:53
Ah, yes. feisty2 also tried that with dct=5. The problem wasn't the dct parameter, it was that integer overflow with large thsad.My thsad values usually max at 400 so I don't think that has been the case.
These were the results of my old test on an 8-bit clip:
1.68 fps, Vapoursynth with dct=5
3.70 fps, Vapoursynth with dct=0
2.79 fps, Avisynth with dct=5
2.99 fps, Avisynth with dct=0
But as I said, I'll try to run a new test soon.
jackoneill
18th January 2016, 15:11
dct 5-10 are good now, dct 1-4 (fftw related modes) are still broken in v10...
Broken how? That frame you showed was coming out of Degrain pretty much untouched, but it shouldn't anymore.
feisty2
18th January 2016, 15:26
Broken how? That frame you showed was coming out of Degrain pretty much untouched, but it shouldn't anymore.
that's the exact problem...
it should not but still looks pretty much untouched at thsad=2000
source
http://i.imgur.com/LOwbBO9.png
import vapoursynth as vs
core = vs.get_core()
clp = rule6
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=16)
superanalyse = core.mv.Super(clp, pel=2, rfilter=4)
supermdg = core.mv.Super(clp, pel=2, rfilter=4, levels=1)
bv1 = core.mv.Analyse(superanalyse, dct=1, blksize=16, overlap=8, isb=True)
fv1 = core.mv.Analyse(superanalyse, dct=1, blksize=16, overlap=8, isb=False)
bv1 = core.mv.Recalculate(superanalyse, bv1, thsad=100, blksize=8, overlap=4, search=3, dct=1)
fv1 = core.mv.Recalculate(superanalyse, fv1, thsad=100, blksize=8, overlap=4, search=3, dct=1)
bv1 = core.mv.Recalculate(superanalyse, bv1, thsad=100, blksize=4, overlap=2, search=3, dct=1)
fv1 = core.mv.Recalculate(superanalyse, fv1, thsad=100, blksize=4, overlap=2, search=3, dct=1)
bv2 = core.mv.Analyse(superanalyse, dct=1, blksize=16, overlap=8, isb=True, delta=2)
fv2 = core.mv.Analyse(superanalyse, dct=1, blksize=16, overlap=8, isb=False, delta=2)
bv2 = core.mv.Recalculate(superanalyse, bv2, thsad=100, blksize=8, overlap=4, search=3, dct=1)
fv2 = core.mv.Recalculate(superanalyse, fv2, thsad=100, blksize=8, overlap=4, search=3, dct=1)
bv2 = core.mv.Recalculate(superanalyse, bv2, thsad=100, blksize=4, overlap=2, search=3, dct=1)
fv2 = core.mv.Recalculate(superanalyse, fv2, thsad=100, blksize=4, overlap=2, search=3, dct=1)
clp = core.mv.Degrain2(clp, supermdg, bv1, fv1, bv2, fv2, thsad=2000)
clp.set_output ()
http://i.imgur.com/XVWZNgh.png
import vapoursynth as vs
core = vs.get_core()
clp = rule6
clp = core.std.ShufflePlanes(clp, planes=0, colorfamily=vs.GRAY)
clp = core.fmtc.bitdepth(clp, fulls=False, fulld=True, bits=32)
superanalyse = core.mvsf.Super(clp, pel=2, rfilter=4)
supermdg = core.mvsf.Super(clp, pel=2, rfilter=4, levels=1)
bv1 = core.mvsf.Analyse(superanalyse, dct=1, blksize=16, overlap=8, isb=True)
fv1 = core.mvsf.Analyse(superanalyse, dct=1, blksize=16, overlap=8, isb=False)
bv1 = core.mvsf.Recalculate(superanalyse, bv1, thsad=100, blksize=8, overlap=4, search=3, dct=1)
fv1 = core.mvsf.Recalculate(superanalyse, fv1, thsad=100, blksize=8, overlap=4, search=3, dct=1)
bv1 = core.mvsf.Recalculate(superanalyse, bv1, thsad=100, blksize=4, overlap=2, search=3, dct=1)
fv1 = core.mvsf.Recalculate(superanalyse, fv1, thsad=100, blksize=4, overlap=2, search=3, dct=1)
bv2 = core.mvsf.Analyse(superanalyse, dct=1, blksize=16, overlap=8, isb=True, delta=2)
fv2 = core.mvsf.Analyse(superanalyse, dct=1, blksize=16, overlap=8, isb=False, delta=2)
bv2 = core.mvsf.Recalculate(superanalyse, bv2, thsad=100, blksize=8, overlap=4, search=3, dct=1)
fv2 = core.mvsf.Recalculate(superanalyse, fv2, thsad=100, blksize=8, overlap=4, search=3, dct=1)
bv2 = core.mvsf.Recalculate(superanalyse, bv2, thsad=100, blksize=4, overlap=2, search=3, dct=1)
fv2 = core.mvsf.Recalculate(superanalyse, fv2, thsad=100, blksize=4, overlap=2, search=3, dct=1)
clp = core.mvsf.Degrain2(clp, supermdg, bv1, fv1, bv2, fv2, thsad=2000)
clp.set_output ()
http://i.imgur.com/iFXJCRm.png
Boulder
18th January 2016, 17:06
Has something changed in this release regarding the usage of the plugin?
I got this error: "AttributeError: There is no attribute or namespace named mv". Release 9 works fine.
Myrsloik
18th January 2016, 17:07
Has something changed in this release regarding the usage of the plugin?
I got this error: "AttributeError: There is no attribute or namespace named mv". Release 9 works fine.
It probably requires the R30 rc to be installed.
feisty2
18th January 2016, 17:08
Has something changed in this release regarding the usage of the plugin?
I got this error: "AttributeError: There is no attribute or namespace named mv". Release 9 works fine.
update your vaporsynth to R30
EDIT: oops... too slow
Boulder
18th January 2016, 17:09
It probably requires the R30 rc to be installed.OK, thought so. I still haven't upgraded my production environment since there's been no need to do that.
jackoneill
18th January 2016, 17:13
Has something changed in this release regarding the usage of the plugin?
I got this error: "AttributeError: There is no attribute or namespace named mv". Release 9 works fine.
I'll recompile with an older VapourSynth.h.
jackoneill
18th January 2016, 22:51
The v10 DLLs have been recompiled to work with VapourSynth older than r30.
that's the exact problem...
it should not but still looks pretty much untouched at thsad=2000
That was kind of related to the dct parameter. The code in the DCTFFTW class is fine, it was just given incorrect information in Recalculate. Analyse was not affected.
Boulder
19th January 2016, 05:01
Thanks, I'll run some tests today :)
Boulder
20th January 2016, 12:42
It seems that the performance of dct=5 is now at the expected level compared to the Avisynth equivalent and I've not been able to crash anything yet.
jackoneill
31st January 2016, 15:11
With help from the compiler, I found a few more of these integer overflow bugs, but there are just too many filters and parameters to test all the combinations myself. Therefore, please compile MVTools with GCC 4.9 or clang 3.3 or newer, like so:
./configure CXXFLAGS='-fsanitize=undefined'
make
and test your favourite scripts with a 16 bit video. If such a bug is encountered, you'll get a message in the console.
Boulder
1st February 2016, 05:12
Would you mind compiling such a build? It also seems that there are some other bugs corrected that affect the output (the Recalculate one). I don't have MinGW/MSYS set up for Vapoursynth and I'm not sure how to get things done with that.
jackoneill
1st February 2016, 12:37
Would you mind compiling such a build? It also seems that there are some other bugs corrected that affect the output (the Recalculate one). I don't have MinGW/MSYS set up for Vapoursynth and I'm not sure how to get things done with that.
Unfortunately I can't. UndefinedBehaviorSanitizer is not available for Windows yet.
Boulder
1st February 2016, 13:52
What about those corrections? If I understand correctly, Recalculate does nothing in the current release.
jackoneill
1st February 2016, 14:36
What about those corrections? If I understand correctly, Recalculate does nothing in the current release.
Okay, here is v11 (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v11), now with a Linux binary included.
* Fix a few more signed integer overflow bugs with 16 bit input in Analyse/Recalculate.
* Fix bug in Recalculate with 16 bit input and dct=1..4, which turned client filters into very slow no-ops.
Boulder
1st February 2016, 14:44
Thanks a lot, it's much appreciated :)
Are_
3rd February 2016, 14:12
With help from the compiler, I found a few more of these integer overflow bugs, but there are just too many filters and parameters to test all the combinations myself. Therefore, please compile MVTools with GCC 4.9 or clang 3.3 or newer, like so:
./configure CXXFLAGS='-fsanitize=undefined'
make
and test your favourite scripts with a 16 bit video. If such a bug is encountered, you'll get a message in the console.
Did that with a script I was having problems in the early days:
import vapoursynth as vs
core = vs.get_core()
clip = core.lsmas.LWLibavSource(rule6)
clip = core.fmtc.bitdepth(clip, bits=16)
sup = core.mv.Super(clip, pel=2)
bvec = core.mv.Analyse(sup, blksize=32, isb=True , chroma=True, search=3, searchparam=1)
fvec = core.mv.Analyse(sup, blksize=32, isb=False, chroma=True, search=3, searchparam=1)
bvec = core.mv.Recalculate(sup, bvec, blksize=8, search=3, searchparam=1)
fvec = core.mv.Recalculate(sup, fvec, blksize=8, search=3, searchparam=1)
clip = core.mv.BlockFPS(clip, sup, bvec, fvec, mode=3, thscd2=12, num=60000, den=1001)
clip[4678:10000].set_output()
And got:
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:731:40: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:730:40: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:931:65: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:930:65: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:1107:35: runtime error: signed integer overflow: 50 * 48436919 cannot be represented in type 'int [8]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44943708 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 45038739 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44992873 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44990206 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44944694 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44992873 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44990206 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 45038739 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 45038739 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44910136 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:436:35: runtime error: signed integer overflow: 50 * 43379226 cannot be represented in type 'int'
Fortunately, the visual glitches I had in the past are now gone.
Then I did test gmtc with this script:
import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
clip = core.fmtc.bitdepth(rule6, bits=16)
clip = haf.QTGMC(src, TFF=True, Preset="slower", Denoiser="KNLMeansCL", EZDenoise=2.0, Tuning="dv-hd", ChromaNoise=True)
clip = core.fmtc.bitdepth(clip, bits=10)
clip.set_output()
Results:
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f6b28be1b77 for type '__m64', which requires 8 byte alignment
0x7f6b28be1b77: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f6b294080c4 for type '__m64', which requires 8 byte alignment
0x7f6b294080c4: note: pointer points here
00 00 00 00 00 00 00 01 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f93ef33b297 for type '__m64', which requires 8 byte alignment
0x7f93ef33b297: note: pointer points here
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
^
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f93efb617e4 for type '__m64', which requires 8 byte alignment
0x7f93efb617e4: note: pointer points here
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
^
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:931:65: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:930:65: runtime error: left shift of negative value -4
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f93f14506a4 for type '__m64', which requires 8 byte alignment
0x7f93f14506a4: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
^
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f93f1c756a2 for type '__m64', which requires 8 byte alignment
0x7f93f1c756a2: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
Now this is strange, because it's crashing at 6 frames and I did finish this encode a few weeks ago on a full 25 min length video footage but that's maybe something in my hardware or setup :(
All of this test were run with latest git as for 01/02/16 16:34:36
I hope it helps.
jackoneill
3rd February 2016, 18:27
Thanks for testing!
I'll sort out the overflows. Those misaligned load errors are false positives, though. The x86 instruction in question must be movq, which doesn't require any alignment.
If it crashes, you should see why. :)
feisty2
4th February 2016, 17:34
Did that with a script I was having problems in the early days:
import vapoursynth as vs
core = vs.get_core()
clip = core.lsmas.LWLibavSource(rule6)
clip = core.fmtc.bitdepth(clip, bits=16)
sup = core.mv.Super(clip, pel=2)
bvec = core.mv.Analyse(sup, blksize=32, isb=True , chroma=True, search=3, searchparam=1)
fvec = core.mv.Analyse(sup, blksize=32, isb=False, chroma=True, search=3, searchparam=1)
bvec = core.mv.Recalculate(sup, bvec, blksize=8, search=3, searchparam=1)
fvec = core.mv.Recalculate(sup, fvec, blksize=8, search=3, searchparam=1)
clip = core.mv.BlockFPS(clip, sup, bvec, fvec, mode=3, thscd2=12, num=60000, den=1001)
clip[4678:10000].set_output()
And got:
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:731:40: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:730:40: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:931:65: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:930:65: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:1107:35: runtime error: signed integer overflow: 50 * 48436919 cannot be represented in type 'int [8]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44943708 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 45038739 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44992873 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44990206 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44944694 cannot be represented in type 'int'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44992873 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44990206 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 45038739 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 45038739 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:375:35: runtime error: signed integer overflow: 50 * 44910136 cannot be represented in type 'int [8][2]'
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.h:436:35: runtime error: signed integer overflow: 50 * 43379226 cannot be represented in type 'int'
Fortunately, the visual glitches I had in the past are now gone.
Then I did test gmtc with this script:
import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
clip = core.fmtc.bitdepth(rule6, bits=16)
clip = haf.QTGMC(src, TFF=True, Preset="slower", Denoiser="KNLMeansCL", EZDenoise=2.0, Tuning="dv-hd", ChromaNoise=True)
clip = core.fmtc.bitdepth(clip, bits=10)
clip.set_output()
Results:
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f6b28be1b77 for type '__m64', which requires 8 byte alignment
0x7f6b28be1b77: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f6b294080c4 for type '__m64', which requires 8 byte alignment
0x7f6b294080c4: note: pointer points here
00 00 00 00 00 00 00 01 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f93ef33b297 for type '__m64', which requires 8 byte alignment
0x7f93ef33b297: note: pointer points here
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
^
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f93efb617e4 for type '__m64', which requires 8 byte alignment
0x7f93efb617e4: note: pointer points here
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
^
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:931:65: runtime error: left shift of negative value -1
/var/tmp/portage/media-plugins/vapoursynth-mvtools-9999/work/vapoursynth-mvtools-9999/src/PlaneOfBlocks.cpp:930:65: runtime error: left shift of negative value -4
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f93f14506a4 for type '__m64', which requires 8 byte alignment
0x7f93f14506a4: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
^
/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include/emmintrin.h:704:24: runtime error: load of misaligned address 0x7f93f1c756a2 for type '__m64', which requires 8 byte alignment
0x7f93f1c756a2: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
Now this is strange, because it's crashing at 6 frames and I did finish this encode a few weeks ago on a full 25 min length video footage but that's maybe something in my hardware or setup :(
All of this test were run with latest git as for 01/02/16 16:34:36
I hope it helps.
overflows should be fixed by now
jackoneill
4th February 2016, 18:10
overflows should be fixed by now
What do you mean?
feisty2
4th February 2016, 18:13
What do you mean?
I pulled 2 requests that fixed the mentioned overflows on github
jackoneill
14th March 2016, 13:24
Are_: Any news about that crash? A backtrace, maybe? I can't test your script because KNLMeansCL requires a fancier video card than what I have.
Are_
14th March 2016, 16:06
OK, now this is a little embarrassing, first script was OK, and now runs without errors/warnings, but second script was ran with 8bit input. :(
Now I'm gonna make sure everything is proper.
import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
src = core.lsmas.LWLibavSource(r'rule6')
clip = src
clip = core.fmtc.bitdepth(clip, bits=16)
clip = haf.QTGMC(clip, TFF=True, Preset="slower", ShowSettings=False)
clip.set_output()
bt 8bit (https://paste.kde.org/pwikxqvoq/iv2asp)
bt 16bit (https://paste.kde.org/pp1ie8jgc/qu97uc)
stderr (https://paste.kde.org/pktkpdzqj/groqoi)
mvtools and vapoursynth are current git.
jackoneill
14th March 2016, 20:34
OK, now this is a little embarrassing, first script was OK, and now runs without errors/warnings, but second script was ran with 8bit input. :(
Now I'm gonna make sure everything is proper.
import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
src = core.lsmas.LWLibavSource(r'rule6')
clip = src
clip = core.fmtc.bitdepth(clip, bits=16)
clip = haf.QTGMC(clip, TFF=True, Preset="slower", ShowSettings=False)
clip.set_output()
bt 8bit (https://paste.kde.org/pwikxqvoq/iv2asp)
bt 16bit (https://paste.kde.org/pp1ie8jgc/qu97uc)
stderr (https://paste.kde.org/pktkpdzqj/groqoi)
mvtools and vapoursynth are current git.
Oops. That's a bug I introduced more recently. It's fixed now (plus another two).
Are_
14th March 2016, 20:46
Hurray! No errors, no warnings, nothing wrong to be seen. :)
jackoneill
14th March 2016, 21:12
Hurray! No errors, no warnings, nothing wrong to be seen. :)
Even with the script that uses KNLMeansCL?
Are_
14th March 2016, 21:33
Even with the script that uses KNLMeansCL?
Screw me, I was going too fast. :/
It works with 16bit video, but 8bit video produces this stderr (https://paste.kde.org/p614k64gv/oovkd7), I guess it's the same as before.
This is with the script I posted before, also, it becomes terribly slow (and the process eventually dies after a few frames).
jackoneill
14th March 2016, 22:19
Screw me, I was going too fast. :/
It works with 16bit video, but 8bit video produces this stderr (https://paste.kde.org/p614k64gv/oovkd7), I guess it's the same as before.
This is with the script I posted before, also, it becomes terribly slow (and the process eventually dies after a few frames).
Can you run it in gdb to see why it dies?
Are_
14th March 2016, 22:26
OK, not a segfault, it just runs out of memory, I have 12GB on this machine.
jackoneill
14th March 2016, 22:39
OK, not a segfault, it just runs out of memory, I have 12GB on this machine.
It doesn't happen with v11, does it?
Are_
14th March 2016, 22:47
Mmmh... yes, it does. I don't usually do much processing in 8bit, so I don't know if this is something only happening to me, if it's new or not. :/
Are_
14th March 2016, 23:21
I did try valgrind, but it refuses to run saying:
==28010== Memcheck, a memory error detector
==28010== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==28010== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==28010== Command: vspipe -p mvtools-test.vpy /dev/null
==28010==
vex amd64->IR: unhandled instruction bytes: 0x8F 0xE8 0x58 0xA3 0x51 0xD0 0x0 0x8F
vex amd64->IR: REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR: VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=NONE
vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0
==28010== valgrind: Unrecognised instruction at address 0x5a62eb3.
==28010== at 0x5A62EB3: PyUnicode_FromUnicode (in /usr/lib64/libpython3.5m.so.1.0)
==28010== by 0x5AFBC32: _PySys_Init (in /usr/lib64/libpython3.5m.so.1.0)
==28010== by 0x5AEEE46: _Py_InitializeEx_Private (in /usr/lib64/libpython3.5m.so.1.0)
==28010== by 0x4E37515: real_init() (vsscript.cpp:82)
==28010== by 0x4E37B46: _M_invoke<> (functional:1531)
==28010== by 0x4E37B46: operator() (functional:1520)
==28010== by 0x4E37B46: void std::__once_call_impl<std::_Bind_simple<void (*())()> >() (mutex:697)
==28010== by 0x61832F0: __pthread_once_slow (pthread_once.c:116)
==28010== by 0x4E3784D: __gthread_once (gthr-default.h:699)
==28010== by 0x4E3784D: call_once<void (&)()> (mutex:729)
==28010== by 0x4E3784D: vsscript_init (vsscript.cpp:93)
==28010== by 0x406AFE: main (vspipe.cpp:580)
==28010== Your program just tried to execute an instruction that Valgrind
==28010== did not recognise. There are two possible reasons for this.
==28010== 1. Your program has a bug and erroneously jumped to a non-code
==28010== location. If you are running Memcheck and you just saw a
==28010== warning about a bad jump, it's probably your program's fault.
==28010== 2. The instruction is legitimate but Valgrind doesn't handle it,
==28010== i.e. it's Valgrind's fault. If you think this is the case or
==28010== you are not sure, please let us know and we'll try to fix it.
==28010== Either way, Valgrind will now raise a SIGILL signal which will
==28010== probably kill your program.
==28010==
==28010== Process terminating with default action of signal 4 (SIGILL)
==28010== Illegal opcode at address 0x5A62EB3
==28010== at 0x5A62EB3: PyUnicode_FromUnicode (in /usr/lib64/libpython3.5m.so.1.0)
==28010== by 0x5AFBC32: _PySys_Init (in /usr/lib64/libpython3.5m.so.1.0)
==28010== by 0x5AEEE46: _Py_InitializeEx_Private (in /usr/lib64/libpython3.5m.so.1.0)
==28010== by 0x4E37515: real_init() (vsscript.cpp:82)
==28010== by 0x4E37B46: _M_invoke<> (functional:1531)
==28010== by 0x4E37B46: operator() (functional:1520)
==28010== by 0x4E37B46: void std::__once_call_impl<std::_Bind_simple<void (*())()> >() (mutex:697)
==28010== by 0x61832F0: __pthread_once_slow (pthread_once.c:116)
==28010== by 0x4E3784D: __gthread_once (gthr-default.h:699)
==28010== by 0x4E3784D: call_once<void (&)()> (mutex:729)
==28010== by 0x4E3784D: vsscript_init (vsscript.cpp:93)
==28010== by 0x406AFE: main (vspipe.cpp:580)
==28010==
==28010== HEAP SUMMARY:
==28010== in use at exit: 214,921 bytes in 177 blocks
==28010== total heap usage: 1,183 allocs, 1,006 frees, 337,862 bytes allocated
==28010==
==28010== LEAK SUMMARY:
==28010== definitely lost: 0 bytes in 0 blocks
==28010== indirectly lost: 0 bytes in 0 blocks
==28010== possibly lost: 0 bytes in 0 blocks
==28010== still reachable: 214,921 bytes in 177 blocks
==28010== suppressed: 0 bytes in 0 blocks
==28010== Reachable blocks (those to which a pointer was found) are not shown.
==28010== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==28010==
==28010== For counts of detected and suppressed errors, rerun with: -v
==28010== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Any idea why?
Are_
14th March 2016, 23:58
OK, somewhat I managed, had to recompile python without -march=native :(
Some valgrind gibberish (https://www.dropbox.com/s/62xro2q770bf4hj/mvtools-valgrind.tar.bz2?dl=0)
feisty2
15th March 2016, 05:02
Random question here, why did you convert all cpp code to c?
Is it like cpp sucks as a programming language?
jackoneill
15th March 2016, 18:05
feisty2: C is simpler. Most of MVTools doesn't really need to be C++. That is, the code is not much more complicated when converted to C. It seemed like a good idea at the time, but I've come to regret it because of all the bugs I introduced.
Are_: Unfortunately those logs are not much use. Valgrind is still finding some instructions it doesn't like. I am unable to reproduce the memory leak, so you'll just have to keep recompiling things without -march=native until Valgrind stops talking about illegal instructions.
Edit: I forgot, you could also try -fsanitize=leak.
Are_
17th March 2016, 14:54
I think it's output is still useless, but I may need a little assistance discovering what's the next package that needs to be rebuild without optimizations. :(
more valgrind logs (https://www.dropbox.com/s/0twajbp5hawfcn7/valgrind-logs.tar.bz2?dl=0)
EDIT: I did try -fsanitize=leak but I think it does not output anything significant, maybe the memory leak is not in mvtools at all.
jackoneill
17th March 2016, 17:33
I think it's output is still useless, but I may need a little assistance discovering what's the next package that needs to be rebuild without optimizations. :(
more valgrind logs (https://www.dropbox.com/s/0twajbp5hawfcn7/valgrind-logs.tar.bz2?dl=0)
EDIT: I did try -fsanitize=leak but I think it does not output anything significant, maybe the memory leak is not in mvtools at all.
That looks like your libc.
You compiled vspipe with -fsanitize=leak, like the gcc manual says, right?
Just out of curiosity, does it help to have core.max_cache_size=300 in the script? It shouldn't, because the cache is limited to 1 GiB by default.
jackoneill
17th March 2016, 20:32
Maybe a different approach is in order.
In my fork (https://github.com/dubhater/vapoursynth/commits/master) you will find a commit which makes VapourSynth print something like this before vspipe outputs any frames:
Requesting 20 frames from com.vapoursynth.ffms2/Source.
Process memory usage before: 46 MiB, after: 54 MiB, difference: 8.
Requesting 20 frames from com.vapoursynth.std/SeparateFields.
Process memory usage before: 54 MiB, after: 58 MiB, difference: 4.
Requesting 20 frames from fmtconv/resample.
Process memory usage before: 58 MiB, after: 65 MiB, difference: 7.
Requesting 20 frames from fmtconv/bitdepth.
Process memory usage before: 65 MiB, after: 83 MiB, difference: 18.
Requesting 20 frames from chikuzen.does.not.have.his.own.domain.scd/Detect.
The last filter mentioned should be the leaky one, if it runs out of memory after only six frames.
Are_
18th March 2016, 00:45
It looks like it's Degrain1: log (https://paste.kde.org/pfloc7efp/noz9w0)
core.max_cache_size=300 didn't make any difference.
jackoneill
18th March 2016, 08:53
It looks like it's Degrain1: log (https://paste.kde.org/pfloc7efp/noz9w0)
core.max_cache_size=300 didn't make any difference.
... Oh. This whole time I was testing with a normal MVTools. With -fsanitize=undefined I get the memory leak too. It must be something about those misaligned loads, because everything is fine if I pass isse=0 to Degrain1.
jackoneill
18th March 2016, 22:52
Right then. v12 is here (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v12), with a change that some people requested a long time ago.
* FlowFPS: enable multi-threading.
* Analyse, Recalculate: pass the motion vectors in frame properties instead of the frames themselves.
* Support systems other than x86.
* Analyse: add sanity checks for pnew, pzero, pglobal, plevel parameters.
* Recalculate: add sanity check for pnew parameter.
* FlowFPS, FlowInter, Mask: fix use of uninitialised memory, which made the output slightly different every time (bug inherited from the Avisynth plugin).
* Analyse, Recalculate: prevent possible crash with 4x4 blocks and 8 bit input.
* Analyse, Recalculate: fix block size sanity check when divide=True (bug inherited from the Avisynth plugin).
* Analyse, Recalculate: fix some more signed integer overflows with 16 bit input.
Oh yeah. If you have a CPU with many threads, let me know how fast FlowFPS is, compared to v11.
MonoS
26th March 2016, 22:03
Is it still possible to save the vectors data to a file??
jackoneill
26th March 2016, 23:13
Is it still possible to save the vectors data to a file??
Looks like it's not possible. Do you need to do that?
MonoS
26th March 2016, 23:22
Looks like it's not possible. Do you need to do that?
I used the write vector function in my helper script quite a lot, it helped me save quite a lot of encoding days.
jackoneill
28th March 2016, 16:14
I used the write vector function in my helper script quite a lot, it helped me save quite a lot of encoding days.
You'll be able to save the vectors once you update to VapourSynth R32.
Instead of saving the contents of the frames returned by Analyse, you'll need to save two frame properties: "MVTools_MVAnalysisData" and "MVTools_vectors". The first one has the same contents in every frame.
Fizick
28th March 2016, 17:47
Hi! Thanks for hard work!
Sorry, I am not ready to Vaporsynth yet, but I have intention to update some functions of MVTools for Avisynth (to add overlapping to MVBlockFps, improve masking, planar formats may be).
I was out of game... some time. Questions:
1. What version is (was) use for a base?
2. Any important bug is found?
What may be backported ?
MonoS
28th March 2016, 19:03
You'll be able to save the vectors once you update to VapourSynth R32.
Instead of saving the contents of the frames returned by Analyse, you'll need to save two frame properties: "MVTools_MVAnalysisData" and "MVTools_vectors". The first one has the same contents in every frame.
Thank you, waiting for the final R32 release and some documentation about that functionality :)
jackoneill
28th March 2016, 19:08
Hi! Thanks for hard work!
Sorry, I am not ready to Vaporsynth yet, but I have intention to update some functions of MVTools for Avisynth (to add overlapping to MVBlockFps, improve masking, planar formats may be).
I was out of game... some time. Questions:
1. What version is (was) use for a base?
2. Any important bug is found?
What may be backported ?
1. The base is your latest, version 2.5.11.3.
2. Depends what you consider important. There are these (https://github.com/dubhater/vapoursynth-mvtools/commit/4dcaa2cbf344a70e91031f0bf9b9a753e41faa7f) two bugs (https://github.com/dubhater/vapoursynth-mvtools/commit/6e78a6e74a31b867348b0046613f41df78a4d692). There are also several parameters that didn't have sanity checks.
I invite you to peruse readme.rst (https://github.com/dubhater/vapoursynth-mvtools#differences), the release notes (https://github.com/dubhater/vapoursynth-mvtools/releases), and the list of commits (https://github.com/dubhater/vapoursynth-mvtools/commits/master). You can also see the changes between two particular versions (https://github.com/dubhater/vapoursynth-mvtools/compare/v4...v5).
jackoneill
28th March 2016, 19:20
Thank you, waiting for the final R32 release and some documentation about that functionality :)
vector_clip = core.mv.Analyse(...)
frame = vector_clip.get_frame(0)
file.write(frame.props.MVTools_MVAnalysisData)
for i in range(vector_clip.num_frames):
frame = vector_clip.get_frame(i)
file.write(frame.props.MVTools_vectors)
Something like that (completely untested code). The point is that accessing those frame properties will give you Python "bytes" objects whose contents you can write to a file or whatever. VapourSynth R31 and older will only give you the bytes up to the first null byte. This has been fixed in git.
Boulder
3rd April 2016, 12:53
This part of a script crashes vspipe, pointing to libmvtools.dll:
import vapoursynth as vs
core = vs.get_core()
clp = core.dgdecodenv.DGSource(r'dictator.dgi')
superanalyse = core.mv.Super(clp, pel=2, chroma=False, rfilter=4)
bv1 = core.mv.Analyse(superanalyse, blksize=16, overlap=8, chroma=False, isb=True, delta=1)
fv1 = core.mv.Analyse(superanalyse, blksize=16, overlap=8, chroma=False, isb=False, delta=1)
Apparently it's the superclip creation part. If I just try to output 'superanalyse', the crash occurs.
jackoneill
3rd April 2016, 14:15
This part of a script crashes vspipe, pointing to libmvtools.dll:
import vapoursynth as vs
core = vs.get_core()
clp = core.dgdecodenv.DGSource(r'dictator.dgi')
superanalyse = core.mv.Super(clp, pel=2, chroma=False, rfilter=4)
bv1 = core.mv.Analyse(superanalyse, blksize=16, overlap=8, chroma=False, isb=True, delta=1)
fv1 = core.mv.Analyse(superanalyse, blksize=16, overlap=8, chroma=False, isb=False, delta=1)
Apparently it's the superclip creation part. If I just try to output 'superanalyse', the crash occurs.
Here is a fixed DLL: http://ulozto.net/xEsRa8NM/vapoursynth-mvtools-v12-win64-7z
Boulder
3rd April 2016, 14:22
Thanks, works perfectly :)
edcrfv94
4th April 2016, 07:10
mvtools v12
haf.QTGMC(src, Preset='Slow', TFF=True)
VapourSynthEditor will Crash, but v11 fine.
jackoneill
4th April 2016, 11:07
mvtools v12
haf.QTGMC(src, Preset='Slow', TFF=True)
VapourSynthEditor will Crash, but v11 fine.
Did you try this DLL from a few posts up? http://ulozto.net/xEsRa8NM/vapoursynth-mvtools-v12-win64-7z
edcrfv94
4th April 2016, 22:39
Did you try this DLL from a few posts up? http://ulozto.net/xEsRa8NM/vapoursynth-mvtools-v12-win64-7z
Work fine.Thanks
Tarutaru
5th April 2016, 17:41
Hi,
After upgrading to the latest version from Git, using RefineMotion=True in SMDegrain will throw this error:
# vspipe foo.vpy -
Filter Recalculate declared the size 1952x2486, but it returned a frame with the size 1952x1112.
Aborted (core dumped)
My input source is a 1920x1080 clip, don't know why it will return these strange resolution.
vpy code:
import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
ret = core.lsmas.LWLibavSource(source='/tmp/foo.bar')
ret = haf.SMDegrain(ret, RefineMotion=True)
ret.set_output()
Thanks!
jackoneill
5th April 2016, 18:28
Hi,
After upgrading to the latest version from Git, using RefineMotion=True in SMDegrain will throw this error:
# vspipe foo.vpy -
Filter Recalculate declared the size 1952x2486, but it returned a frame with the size 1952x1112.
Aborted (core dumped)
My input source is a 1920x1080 clip, don't know why it will return these strange resolution.
vpy code:
import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
ret = core.lsmas.LWLibavSource(source='/tmp/foo.bar')
ret = haf.SMDegrain(ret, RefineMotion=True)
ret.set_output()
Thanks!
It's fixed now.
1952 = 1920 + 16 + 16 (padding). The strange heights are due to the downscaled copies made for motion estimation. Look at the output of mv.Super if you're curious.
Tarutaru
5th April 2016, 18:56
It's fixed now.
1952 = 1920 + 16 + 16 (padding). The strange heights are due to the downscaled copies made for motion estimation. Look at the output of mv.Super if you're curious.
Thanks, works perfectly.
jackoneill
8th April 2016, 20:24
v13 (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v13) fixes the two bugs reported since v12.
Boulder
9th April 2016, 09:23
Thanks for the new build :)
Elegant
15th April 2016, 01:57
Was just porting a script an error about mv.Mask not supporting 16bit. GitHub mentions that all functions support up to 16bit. Bug?
MOMask1 = core.mv.Mask(clip=Input, vectors=FV1, kind=1, ml=2)
File "src\cython\vapoursynth.pyx", line 1383, in vapoursynth.Function.__call__ (src\cython\vapoursynth.c:25204)
vapoursynth.Error: Mask: input clip must be GRAY8, YUV420P8, YUV422P8, YUV440P8, or YUV444P8, with constant dimensions.
jackoneill
15th April 2016, 09:29
Was just porting a script an error about mv.Mask not supporting 16bit. GitHub mentions that all functions support up to 16bit. Bug?
MOMask1 = core.mv.Mask(clip=Input, vectors=FV1, kind=1, ml=2)
File "src\cython\vapoursynth.pyx", line 1383, in vapoursynth.Function.__call__ (src\cython\vapoursynth.c:25204)
vapoursynth.Error: Mask: input clip must be GRAY8, YUV420P8, YUV422P8, YUV440P8, or YUV444P8, with constant dimensions.
No, it's true. I never got around to it.
groucho86
26th April 2016, 18:16
Hi everyone,
I'm running VapourSynth R32 and MVTools V13 on a Mac (10.9.5).
I'm trying to frame-convert archival from 29.97i to 23.976p.
About two-thirds of the way through (regardless of the actual length of the video input), the video-output freezes and stays frozen until the end of the length of the video.
I'm dealing primarily with the ProRes material, but I tried an h.264 file and had the same problem. This happens with both lsmas and ffms2.
I did a quick test on a Windows 7 machine and had the same problem.
My vpy script looks like this:
import vapoursynth as vs
import havsfunc as haf
import mvsfunc as mvf
import mvmulti
core = vs.get_core()
core.std.LoadPlugin("/usr/local/lib/libmvtoolssf.dylib")
core.std.LoadPlugin("/usr/local/lib/libfmtconv.dylib")
core.std.LoadPlugin("/usr/local/lib/libscenechange.dylib")
core.std.LoadPlugin("/usr/local/lib/libtemporalsoften2.dylib")
core.std.LoadPlugin("/usr/local/lib/libffms2.4.dylib")
clip = core.ffms2.Source(source="/Volumes/NA_3_TEMP/2997-V1-0061_DWD2014FL-CAM1_8.mov")
#clip = core.lsmas.LibavSMASHSource(source="/Volumes/NA_3_TEMP/2997-V1-0061_DWD2014FL-CAM1_8.mov")
#clip = core.std.AssumeFPS(clip, fpsnum=30000, fpsden=1001)
#clip = core.std.Trim(clip, first=0, last=100)
super = core.mv.Super(clip)
backward_vec = core.mv.Analyse(super, isb = True)
forward_vec = core.mv.Analyse(super, isb = False)
clip = core.mv.FlowFPS(clip, super, backward_vec, forward_vec, num=24000, den=1001, ml=100)
clip.set_output()
I'm using ffmpeg (3.0.1) to output to ProRes:
vspipe /Users/jr/test2.vpy --y4m - | ffmpeg -f yuv4mpegpipe -i - -c:v prores -y -profile:v 2 -an "/Users/jr/export/2398export.mov"
Piping to MPV presented the same issue.
I tried QTGMC and it successfully created a 59.94p video. What am I doing incorrectly with MVTools?
Thank you for your help!
jackoneill
26th April 2016, 20:10
What am I doing incorrectly with MVTools?
Nothing. It was a bug in this fork of MVTools. I pushed the fix. Thanks for reporting it.
groucho86
26th April 2016, 22:39
Confirming that that fixed the issue. Thank you!
jackoneill
3rd June 2016, 18:18
A preview of v14, for anyone interested in testing the ports of MDepan, DepanEstimate, Depan, and DepanStabilize:
https://ulozto.net/x2Waehra/vapoursynth-mvtools-v13-win32-7z
https://ulozto.net/xtMUJakd/vapoursynth-mvtools-v13-win64-7z
mv.DepanAnalyse(clip clip, clip vectors[, clip mask, bint zoom=True, bint rot=True, float pixaspect=1.0, float error=15.0, bint info=False, float wrong=10.0, float zerow=0.05, int thscd1=400, int thscd2=130, bint fields=False, bint tff])
mv.DepanEstimate(clip clip[, float trust=4.0, int winx=0, int winy=0, int wleft=-1, int wtop=-1, int dxmax=-1, int dymax=-1, float zoommax=1.0, float stab=1.0, float pixaspect=1.0, bint info=False, bint show=False, bint fields=False, bint tff])
mv.DepanCompensate(clip clip, clip data[, float offset=0.0, int subpixel=2, float pixaspect=1.0, bint matchfields=True, int mirror=0, int blur=0, bint info=False, bint fields=False, bint tff])
mv.DepanStabilise(clip clip, clip data[, float cutoff=1.0, float damping=0.9, float initzoom=1.0, bint addzoom=False, int prev=0, int next=0, int mirror=0, int blur=0, float dxmax=60.0, float dymax=30.0, float zoommax=1.05, float rotmax=1.0, int subpixel=2, float pixaspect=1.0, int fitlast=0, float tzoom=3.0, bint info=False, int method=0, bint fields=False])
The latter three don't exactly belong in MVTools, but they're sort of related to MDepan, and DepanEstimate uses FFTW as well, and this is convenient, so here they are.
I haven't yet figured out how to make DepanCompensate and DepanStabilise work with anything other than YUV420P8.
All four filters are multithreaded. I'd be very grateful for some speed comparisons with the corresponding Avisynth plugins, both with a single thread and with many, e.g. 4+.
VS_Fan
4th June 2016, 07:04
A preview of v14, for anyone interested in testing the ports of MDepan, DepanEstimate, Depan, and DepanStabilize:
Thank you, this is great! The mjpeg videos from my old still camera will surely be good experimental subjects :D. I will happily do some tests over the week.
I haven't yet figured out how to make DepanCompensate and DepanStabilise work with anything other than YUV420P8.
I hope you can, since these videos are originally YUV422P8 @30fps, I would like to encode them with x264 @ YUV422P10
Boulder
4th June 2016, 08:30
I hope you can, since these videos are originally YUV422P8 @30fps, I would like to encode them with x264 @ YUV422P10You can encode them in 10-bit depth even though the source you feed to x264 is in 8 bits.
feisty2
5th June 2016, 07:47
v2.5.11.21 (22.04.2016 by Fizick)
•MflowXXX: remove limit of motion vectors length (was 127/pel).
any plan to merge this?
jackoneill
5th June 2016, 10:07
any plan to merge this?
Yes, eventually.
feisty2
5th June 2016, 12:32
Yes, eventually.
Okay... And "eventually" sounds kinda low priority, and I think it should be sort of high priority cuz it's like a nasty bug
MonoS
5th June 2016, 17:09
Okay... And "eventually" sounds kinda low priority, and I think it should be sort of high priority cuz it's like a nasty bug
can you post me the commit? i'll code this for both mine and dubhater repo
amayra
5th June 2016, 23:57
can you do something about SVPFlow ?
feisty2
6th June 2016, 00:39
can you do something about SVPFlow ?
I think the svp guys already did it
VS_Fan
6th June 2016, 06:36
The results of my tests: Encoding a "DepanEstabilized" 3600 frames (2 min) clip 640x480 @ 30fps, using x264 on my laptop (core i5 3rd gen, Win10)
DepanEstimate fps
AVS ST 27.77
AVS MT 28.18
VPY 32b 27.63
VPY 64b 30.32
DepanAnalise fps
AVS ST 17.68
AVS MT 21.55
VPY 32b 22.45
VPY 64b 25.02
DepanEstimate:
• It is faster than MDepan/ DepanAnalise in both avisynth and vapoursynth, but I don’t get rotation adjustments.
• In these tests, avisynth filters were faster than your VS port (32 bits).
MDepan (AVS) / DepanAnalize (VS):
• Your VS port is way faster, and the results are practically identical
• I prefer DepanAnalise results over the ones of DepanEstimate, I "feel" the motion adjustments smoother
My Scripts for reference:
AVS:
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\Probar\RgTools.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\Probar\DePan.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\Probar\DePanEstimate.dll")
#LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\Probar\mvtools-v2.5.11.22\mvtools2.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\Probar\mvtools-2.5.11.9-svp\mvtools2.dll")
SetMTMode(3,4)
LWLibavVideoSource("F:\TEMPX\CANON\MVI_2038.AVI", format="YUV420P8", fpsnum=30, fpsden=1, seek_threshold=60)
#Preroll(60)
original = last
SetMTMode(2)
pf = original.RemoveGrain(mode=4)
div = 2
pf = pf.BilinearResize(Width(original)/div,Height(original)/div)
pf = pf.RemoveGrain(mode=4)
pf = pf.BilinearResize(Width(original) ,Height(original))
super = MSuper(pf)
vectors = MAnalyse(super, isb = false)
#return mshow(super, vectors, showsad=true)
globalmotion = MDepan(pf, vectors, pixaspect=1.0, thSCD1=800, error=30.0, range=0) #, info=true) #, thSCD2=171
#globalmotion = DePanEstimate()
#return globalmotion
DepanStabilize(original, data=globalmotion, cutoff=0.33, pixaspect=1.0, method=1, zoommax=1.0, rotmax=10.0) #, mirror=15
return last
VPY:
import vapoursynth as vs
core = vs.get_core()
ret = core.lsmas.LWLibavSource(source=r"F:\TEMPX\CANON\MVI_2038.AVI", format="YUV420P8", fpsnum=30, fpsden=1)
pf = core.rgvs.RemoveGrain(clip=ret, mode=4)
div = 2
pf = core.resize.Bilinear(clip=pf, width=int(pf.width/div), height=int(pf.height/div))
pf = core.rgvs.RemoveGrain(clip=pf, mode=4)
pf = core.resize.Bilinear(clip=pf, width=pf.width*div, height=pf.height*div)
#globalmotion = core.mv.DepanEstimate(clip=pf, pixaspect=1.0)
super = core.mv.Super(clip=pf)
vectors = core.mv.Analyse(super=super, isb=False)
globalmotion = core.mv.DepanAnalyse(clip=pf, vectors=vectors, pixaspect=1.0, error=30.0, thscd1=800)
ret = core.mv.DepanStabilise(clip=ret, data=globalmotion, cutoff=0.33, zoommax=1.0, rotmax=10.0, pixaspect=1.0, method=1)
ret.set_output()
jackoneill
6th June 2016, 10:01
can you do something about SVPFlow ?
What would you have me do?
VS_Fan: Thanks for testing.
jackoneill
22nd June 2016, 11:50
https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v14
* BlockFPS, FlowFPS: Fix repeated frames in the last 33% of the clip when
reducing the frame rate (bug introduced at the beginning of this fork, probably).
* All filters that have a "fields" parameter: Fix handling of field-based clips
(was broken since the beginning of this fork).
* Add ports of MDepan, DepanEstimate, and Depan.
Changes from upstream, versions 2.5.11.20 and 2.5.11.21:
* BlockFPS: Remove parameter "thres", add parameter "ml".
* Compensate, Mask: Add parameter "time".
* Reject vector clips with negative delta where necessary.
* FlowXYZ: No longer limit motion vector length to -127..127.
The Depan filters now handle Gray, 4:2:0, 4:2:2, 4:4:4, and up to 16 bits.
feisty2
24th June 2016, 04:47
blockfps mode 6-8 are corrupted at bitdepth>8
import vapoursynth as vs
core = vs.get_core()
clp = rule6
clp = core.fmtc.bitdepth(clp,bits=8,fulls=False,fulld=True)
clp = core.std.ShufflePlanes(clp,0,vs.GRAY)
sup = core.mv.Super(clp)
bv = core.mv.Analyse(sup,8,overlap=4,delta=1,isb=True)
fv = core.mv.Analyse(sup,8,overlap=4,delta=1,isb=False)
clp = core.mv.BlockFPS(clp, sup, bv, fv, 50, 1, 8)
clp.set_output()
http://i.imgur.com/lNucJnc.png
import vapoursynth as vs
core = vs.get_core()
clp = rule6
clp = core.fmtc.bitdepth(clp,bits=16,fulls=False,fulld=True)
clp = core.std.ShufflePlanes(clp,0,vs.GRAY)
sup = core.mv.Super(clp)
bv = core.mv.Analyse(sup,8,overlap=4,delta=1,isb=True)
fv = core.mv.Analyse(sup,8,overlap=4,delta=1,isb=False)
clp = core.mv.BlockFPS(clp, sup, bv, fv, 50, 1, 8)
clp.set_output()
http://i.imgur.com/nZOpfvk.png
looks like a blank black frame, cuz
pDst_[w] = pOcc[w];
should be
pDst_[w] = static_cast<PixelType>(pOcc[w]) << (bitspersample - 8); //mask stuff are always 8bits, compensating scaling required at higher bitdepth
or do it manually
import vapoursynth as vs
core = vs.get_core()
clp = rule6
clp = core.fmtc.bitdepth(clp,bits=16,fulls=False,fulld=True)
clp = core.std.ShufflePlanes(clp,0,vs.GRAY)
sup = core.mv.Super(clp)
bv = core.mv.Analyse(sup,8,overlap=4,delta=1,isb=True)
fv = core.mv.Analyse(sup,8,overlap=4,delta=1,isb=False)
clp = core.mv.BlockFPS(clp, sup, bv, fv, 50, 1, 8)
clp = core.std.Expr(clp,"x 256 *")
clp.set_output()
http://i.imgur.com/AFZfo8Z.png
garbage, still, cuz
double l = 255 * pow(sad * dSADNormFactor, fGamma);
the expression is NOT linear, the result will be corrupted if the SAD remains unscaled, as ∂l/∂sad is not constant
jackoneill
24th June 2016, 12:53
blockfps mode 6-8 are corrupted at bitdepth>8
Maybe fixed. Thanks for testing.
jackoneill
1st July 2016, 19:31
https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v15
After years of waiting, one more MVTools filter is ported. From the original MVTools only MShow is left now.
* BlockFPS: Fix bug that prevented the use of the "ml" parameter (bug introduced in v14).
* BlockFPS: Maybe fix bad output with 16 bit input (bugs introduced in v6 and v14).
* DepanCompensate, DepanStabilise: Fix integer overflows with 16 bit input and subpixel=2 (bug introduced in v14).
* Rename all "isse" parameters to "opt". They work the same.
* Add filter Flow.
jackoneill
9th July 2016, 18:19
If QTGMC crashes, try https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v16.
* Compensate: Fix crash when overlap is used (bug introduced in v15).
kolak
27th July 2016, 12:38
Which parameters are mostly responsible for the speed when using FlowFPS?
I'm mainly interested in: search, searchparam, overlap, dct, trymany, mask and opt.
Boulder
27th July 2016, 12:47
I'd say dct is one that will surely affect speed.
jackoneill
27th July 2016, 13:21
Which parameters are mostly responsible for the speed when using FlowFPS?
I'm mainly interested in: search, searchparam, overlap, dct, trymany, mask and opt.
opt exists only for debugging purposes. As far as I know, it doesn't change the results.
dct > 0 definitely makes it much slower.
overlap > 0 makes it slower.
The search method matters too. Exhaustive will be slower than all the others, I guess.
If you want numbers, run some tests.
kolak
27th July 2016, 14:55
Wel, I'm not after some numbers, just idea about which parameters affect speed the most.
I have also different question.
I've noticed that search=6 does help a lot with artefacts when doing fps conversion on all up-down movements (sounds strange). In the same way opposite also works, so search=7 works for left-right movements.
Is there a way of switching search method based on dominant movement type? Sorry if this is silly question :) Problem is that this would have to work on "future" frames.
jackoneill
27th July 2016, 17:09
Wel, I'm not after some numbers, just idea about which parameters affect speed the most.
I have also different question.
I've noticed that search=6 does help a lot with artefacts when doing fps conversion on all up-down movements (sounds strange). In the same way opposite also works, so search=7 works for left-right movements.
Is there a way of switching search method based on dominant movement type? Sorry if this is silly question :) Problem is that this would have to work on "future" frames.
That's a question best directed at the original developers. I don't have the math skills to answer.
feisty2
27th July 2016, 18:35
Wel, I'm not after some numbers, just idea about which parameters affect speed the most.
I have also different question.
I've noticed that search=6 does help a lot with artefacts when doing fps conversion on all up-down movements (sounds strange). In the same way opposite also works, so search=7 works for left-right movements.
Is there a way of switching search method based on dominant movement type? Sorry if this is silly question :) Problem is that this would have to work on "future" frames.
read the doc
search, searchparam, pelsearch
search decides the type of search at every level, searchparam is an additional parameter (step, radius) for this search, and pelsearch is the radius parameter at finest (pel) level. Below are the possible values for the search type:
0 'OneTimeSearch'. searchparam is the step between each vectors tried (if searchparam is superior to 1, step will be progressively refined).
1 'NStepSearch'. N is set by searchparam. It's the most well known of the MV search algorithm.
2 Logarithmic search, also named Diamond Search. searchparam is the initial step search, there again, it is refined progressively.
3 Exhaustive search, searchparam is the radius (square side is 2*radius+1). It is slow, but it gives the best results, SAD-wise.
4 Hexagon search, searchparam is the range. (similar to x264).
5 Uneven Multi Hexagon (UMH) search, searchparam is the range. (similar to x264).
6 pure Horizontal exhaustive search, searchparam is the radius (width is 2*radius+1).
7 pure Vertical exhaustive search, searchparam is the radius (height is 2*radius+1).
kolak
27th July 2016, 19:55
I've read it and found that 6,7 works well depending on the movement type. That's why I asked if this can be dynamic with some "ahead" detection.
feisty2
27th July 2016, 20:01
The combo of 6,7 is 3
kolak
27th July 2016, 22:17
Ok, but it's a combo, not a dynamic switch between 6,7 so results are very different.
~SimpleX~
30th July 2016, 11:38
jackoneill, do you have any plans on 32bit clips support?
feisty2
30th July 2016, 11:44
jackoneill, do you have any plans on 32bit clips support?
http://forum.doom9.org/showthread.php?t=172525
~SimpleX~
30th July 2016, 11:55
feisty2, yup, I know you already made a 32-bit mvtools (thank you btw). Will this ever be merged with jackoneill's plugin? Or I should choose a plugin based on bitdepth in my scripts?
feisty2
30th July 2016, 11:59
feisty2, yup, I know you already made a 32-bit mvtools (thank you btw). Will this ever be merged with jackoneill's plugin? Or I should choose a plugin based on bitdepth in my scripts?
http://forum.doom9.org/showthread.php?p=1737735#post1737735
I would have discontinued my branch if the answer was yeah
jackoneill
30th July 2016, 12:08
jackoneill, do you have any plans on 32bit clips support?
I'd rather not do that.
feisty2
1st August 2016, 18:41
made 2 PRs on git, truemotion is broken at any bitdepth > 8
jackoneill
1st August 2016, 19:42
made 2 PRs on git, truemotion is broken at any bitdepth > 8
Thanks. I merged them.
feisty2
2nd August 2016, 17:41
good news and bad news here
bad news:
the SATD deduction I made last year was totally wrong (forgive me, my major is not signal processing...)
and you merged that incorrect stuff into your branch as well...
good news:
I made the double checked correct SATD implementation this time with a recursive Hadamard Ordered Walsh-Hadamard Transform
References:
https://en.wikipedia.org/wiki/Hadamard_transform
http://fourier.eng.hmc.edu/e161/lectures/wht/node2.html
static auto uninitialized = true;
static constexpr auto init_val = 1.;
static decltype(init_val + 0) hadamard_matrix_2x2[2][2];
static decltype(init_val + 0) hadamard_matrix_4x4[4][4];
static decltype(init_val + 0) hadamard_matrix_8x8[8][8];
static decltype(init_val + 0) hadamard_matrix_16x16[16][16];
static decltype(init_val + 0) hadamard_matrix_32x32[32][32];
template<int length = 2, typename T = double>
auto create_Hadamard_matrix(void *dst, const void *src) {
constexpr auto src_length = length >> 1;
const auto coeff = std::sqrt(2.);
auto actual_dst = reinterpret_cast<T(*)[length]>(dst);
auto actual_src = reinterpret_cast<const T(*)[src_length]>(src);
for (auto i = 0; i < src_length; ++i)
std::memcpy(actual_dst[i], actual_src[i], sizeof(actual_src[0]));
for (auto i = 0; i < src_length; ++i)
std::memcpy(actual_dst[src_length + i], actual_src[i], sizeof(actual_src[0]));
auto ptr = reinterpret_cast<T(*)[2][src_length]>(dst);
for (auto i = 0; i <length; ++i)
std::memcpy(ptr[i][1], ptr[i][0], sizeof(actual_src[0]));
ptr += src_length;
for (auto i = 0; i < src_length; ++i)
for (auto &x : ptr[i][1])
x = -x;
for (auto i = 0; i < length; ++i)
for (auto &x : actual_dst[i])
x /= coeff;
}
static auto SATD_init() {
create_Hadamard_matrix(hadamard_matrix_2x2, &init_val);
create_Hadamard_matrix<4>(hadamard_matrix_4x4, hadamard_matrix_2x2);
create_Hadamard_matrix<8>(hadamard_matrix_8x8, hadamard_matrix_4x4);
create_Hadamard_matrix<16>(hadamard_matrix_16x16, hadamard_matrix_8x8);
create_Hadamard_matrix<32>(hadamard_matrix_32x32, hadamard_matrix_16x16);
uninitialized = false;
}
template<int length = 2, typename T = double>
auto product_calc(const void *src, const void *hadamard, void *dst) {
auto actual_hadamard = reinterpret_cast<const T(*)[length]>(hadamard);
auto actual_src = reinterpret_cast<const T(*)[length]>(src);
auto actual_dst = reinterpret_cast<T(*)[length]>(dst);
auto dot_p = [&](auto row, auto column) {
T sum = 0;
for (auto i = 0; i < length; ++i)
sum += actual_hadamard[row][i] * actual_src[i][column];
return sum;
};
for (auto i = 0; i < length; ++i)
for (auto j = 0; j < length; ++j)
actual_dst[i][j] = dot_p(i, j);
}
template<int nBlkWidth, int nBlkHeight, typename PixelType>
auto Satd_C(const uint8_t *pSrc8, intptr_t nSrcPitch, const uint8_t *pRef8,
intptr_t nRefPitch) {
if (uninitialized)
SATD_init();
void *hadamard;
if (nBlkWidth == 32 && nBlkHeight == 32)
hadamard = hadamard_matrix_32x32;
else if (nBlkWidth == 16 && nBlkHeight == 16)
hadamard = hadamard_matrix_16x16;
else if (nBlkWidth == 8 && nBlkHeight == 8)
hadamard = hadamard_matrix_8x8;
else if (nBlkWidth == 4 && nBlkHeight == 4)
hadamard = hadamard_matrix_4x4;
else
hadamard = nullptr;
auto sum = 0.;
decltype(sum) _dif_block[nBlkHeight][nBlkWidth];
decltype(sum) _transformed_block[nBlkHeight][nBlkWidth];
for (auto y = 0; y < nBlkHeight; ++y) {
for (auto x = 0; x < nBlkWidth; ++x) {
auto pSrc = reinterpret_cast<const PixelType *>(pSrc8);
auto pRef = reinterpret_cast<const PixelType *>(pRef8);
_dif_block[y][x] = static_cast<decltype(sum)>(pSrc[x]) - pRef[x];
}
pSrc8 += nSrcPitch;
pRef8 += nRefPitch;
}
product_calc<nBlkWidth>(_dif_block, hadamard, _transformed_block);
for (auto &x : _transformed_block)
for (auto y : x)
sum += std::abs(y);
return sum;
}
bad news again:
my implementation is C++14 inside out, not sure if I could translate it to C properly so didn't make any PR this time
edit:typo
hydra3333
3rd August 2016, 08:32
vapoursynth newbie seeking clarification :- I want a script to mimic my old avisynth script and process all planes but now using the vapoursynth mvtools ... is the below correct ? If not, what is it doing, and what should it be instead ?
vsource = icore.mv.Degrain1(vsource, super, backward_vec1, forward_vec1, thsad=400, plane=4)
avisynth:
MDegrain1(super, backward_vec1,forward_vec1,thSAD=400,plane=4)
jackoneill
3rd August 2016, 10:24
vapoursynth newbie seeking clarification :- I want a script to mimic my old avisynth script and process all planes but now using the vapoursynth mvtools ... is the below correct ? If not, what is it doing, and what should it be instead ?
vsource = icore.mv.Degrain1(vsource, super, backward_vec1, forward_vec1, thsad=400, plane=4)
avisynth:
MDegrain1(super, backward_vec1,forward_vec1,thSAD=400,plane=4)
The "plane" parameter works the same.
jackoneill
21st August 2016, 15:27
good news and bad news here
bad news:
the SATD deduction I made last year was totally wrong (forgive me, my major is not signal processing...)
and you merged that incorrect stuff into your branch as well...
good news:
I made the double checked correct SATD implementation this time with a recursive Hadamard Ordered Walsh-Hadamard Transform
References:
https://en.wikipedia.org/wiki/Hadamard_transform
http://fourier.eng.hmc.edu/e161/lectures/wht/node2.html
Any reason why I shouldn't just remove the SATD functions entirely?
feisty2
21st August 2016, 15:41
Any reason why I shouldn't just remove the SATD functions entirely?
because they are the components from avisynth mvtools..?
well, SATD transforms the difference to frequency domain(Hadamard Transform = Discrete Fourier Transform mathematically on a 2^n * 2^n square block) and it helps with shimmering and fading sometimes like dct=1, but much faster than that
Myrsloik
21st August 2016, 15:48
I have a simple question. Has anyone ever tried SAD but with the average value of the input blocks adjusted? I mean the main point of this exercise is to reduce the whole block average into a single coefficient to reduce its influence a lot. There should be some faster but still good for 90% of the times trick.
And saying it's in avisynth is a bad excuse. Temporalsoften is in avisynth and that's nothing to be proud of.
feisty2
21st August 2016, 15:57
more specific? adjusted how, and mode 6-10 are hybrid SAD/SATD modes, and faster than mode 5(100% SATD)
VS_Fan
23rd August 2016, 11:54
I was trying to remember what's the purpose of using SATD in mvtools, so I googled a little, and found:
SATD allows mvtools to better track motion when there are rapidly changing levels of brightness (http://forum.doom9.org/showthread.php?p=1472189#post1472189)
https://www.svp-team.com/wiki/Plugins:_SVPflow
Use SATD function instead of SAD on finest level. Extremely slow, do not use it!
Use SATD function instead of SAD on every coarse level, improves motion vector estimation at luma flicker and fades.
I couldn't find much more.
And then I thought: if people at VideoLAN / MulltiCoreWare implemented the asm functions for SATD for x265? Could they be used? As I’m not a developer, I can't answer that question. Is this a possibility?
In the search (https://www.google.com/webhp?ie=utf-8&oe=utf-8#q=x265+satd+asm+site:videolan.org&start=30) I saw things like:
[x265] [PATCH] primitives: asm: update: implementation of satd(sse2) (https://mailman.videolan.org/pipermail/x265-devel/2013-June/000010.html)
[x265] [PATCH] primitives: asm: satd: fix for 32 bit issue (https://mailman.videolan.org/pipermail/x265-devel/2013-June/000024.html)
Could those be used for mvtools-VapourSynth ???
feisty2
23rd August 2016, 12:30
No, because stupid asm fixed SATD to a certain bitdepth(say, 8bits)
That's exactly why asm SATD functions from avisynth mvtools are useless
feisty2
23rd August 2016, 14:16
I was trying to remember what's the purpose of using SATD in mvtools
there are several approaches available to calculate the difference between 2 macroblocks.
1. SAD, sum of the absolute difference between each pair of samples
2. dct=1, transform both current block and the reference block to frequency domain, and calculate the sum of the absolute difference between each pair of transformed samples
3. SATD, get the difference block between 2 macroblocks, and transform that difference block to frequency domain and calculate the sum of the absolute value of each sample in that transformed difference block
basically, dct=5(SATD) is the compromise between dct=0(SAD) and dct=1(frequency domain SAD)
VS_Fan
23rd August 2016, 20:19
Let me rephrase my thought: In the same search at videolan, I though I saw 8, 10 (may be 12) bit_depth sse2 and/or avx optimizations for SATD calculation.
My question is then: No matter what the original video clip bit_depth is, could you use a “simplified” 8, 10 or 12 bit temporary version of the clip for the motion estimation? (reusing the x265 SATD asm optimizations)
Edit: By the way, thanks for the explanation :)
Nevilne
23rd August 2016, 20:22
You will actually get more useful motion estimation from even blurring the search clip.
Doesn't stop people here from doing stuff like nnedi for subpixel clips.
jackoneill
23rd August 2016, 20:33
Let me rephrase my thought: In the same search at videolan, I though I saw 8, 10 (may be 12) bit_depth sse2 and/or avx optimizations for SATD calculation.
My question is then: No matter what the original video clip bit_depth is, could you use a “simplified” 8, 10 or 12 bit temporary version of the clip for the motion estimation? (reusing the x265 SATD asm optimizations)
I considered it, but: http://forum.doom9.org/showthread.php?p=1695761#post1695761
feisty2
23rd August 2016, 20:43
Let me rephrase my thought: In the same search at videolan, I though I saw 8, 10 (may be 12) bit_depth sse2 and/or avx optimizations for SATD calculation.
My question is then: No matter what the original video clip bit_depth is, could you use a “simplified” 8, 10 or 12 bit temporary version of the clip for the motion estimation? (reusing the x265 SATD asm optimizations)
Edit: By the way, thanks for the explanation :)
SATD is a pretty simple transform and not hard to program at all...
Why not just re-program it in c/c++ like I did and it would be generic to all sample types
VS_Fan
23rd August 2016, 21:24
Don’t waste your time at this, moreover it would be misleading. We can explicitly convert the high-bitdepth clips to 8 bits for analysis. Anyway, I think there is a definite benefit to run the analysis on 10–12 bits. I often remap the luma channel to increase the contrast is some specific ranges (generally the dark parts), and keeping 8 bits crunches other ranges, reducing the accuracy of the analysis on fine textures.
I hope you can come up with a neat strategy to deal with SATD.
I congratulate and thank you all for the VapourSynth's 5th birthday!!! 2 days in advance :D
kolak
25th August 2016, 16:45
Would anyone consider making mvtools faster and better as a paid project?
feisty2
25th August 2016, 16:57
Would anyone consider making mvtools faster and better as a paid project?
I assume you're that "anyone" since you're the only one that has ever asked about this..
jackoneill's wishlist
(https://gist.github.com/dubhater/12a6af383dd006999ba3)
edit:typo
kolak
25th August 2016, 17:26
Are these ebooks?
I will buy all of them+ many more :)
jackoneill
25th August 2016, 17:33
Would anyone consider making mvtools faster and better as a paid project?
Which parts faster? Which parts better? Better in what way?
Yes, ebooks.
kolak
26th August 2016, 00:31
I'm mainly interested in frame rate interpolation part.
There would be quite specific problems to "solve" as well as speeding up whole conversion process, ideally by about 2x.
I will send you pm.
jackoneill
17th September 2016, 09:43
good news and bad news here
I fixed the SATD functions. Please test: http://savedonthe.net/download/914/vapoursynth-mvtools-satd-win64.html
feisty2
17th September 2016, 14:02
it works, but the result looks slightly different from my implementation
mine looks closer to dct=1, and yours closer to dct=0 (set thSAD to 10000 in MDeGrain and you will see the difference)
not sure why..
jackoneill
17th September 2016, 16:00
it works, but the result looks slightly different from my implementation
mine looks closer to dct=1, and yours closer to dct=0 (set thSAD to 10000 in MDeGrain and you will see the difference)
not sure why..
It's the same code used by MVTools for Avisynth and x264.
jackoneill
23rd October 2016, 14:47
v17 brings more speed for certain configurations, larger blocks, and a bug fix or two: https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v17
* Analyse, Recalculate: Fix bug that broke 16 bit processing (patches by feisty2).
* Analyse, Recalculate: Support block sizes of 64x32, 64x64, 128x64, and 128x128.
* Analyse, Recalculate: Make dct=1..4 a bit faster on x86.
* FlowFPS, FlowInter: Add AVX2 code.
* Analyse, Recalculate: Fix SATD functions used when dct=5..10 and the input is 16 bit.
* Analyse, Recalculate: Allow dct=5..10 with blocks larger than 16x16.
feisty2
23rd October 2016, 15:27
...
time to update my branch of mvtools as well...
and oyster and plum
dammit
Mystery Keeper
23rd October 2016, 16:19
Thanks for your awesome work! Why don't you two consolidate your efforts and make one version that supports all formats?
hydra3333
24th October 2016, 11:14
Thank you indeed.
luigizaninoni
24th October 2016, 11:30
Trying to build on Linux Mint, gives error:
make: *** No rule to make target 'src/CopyCode.c', needed by 'src/CopyCode.lo'. Stop.
jackoneill
24th October 2016, 16:14
Trying to build on Linux Mint, gives error:
make: *** No rule to make target 'src/CopyCode.c', needed by 'src/CopyCode.lo'. Stop.
That's because I changed some file names. To fix it:
make distclean
./configure
make
luigizaninoni
24th October 2016, 16:58
That's because I changed some file names. To fix it:
make distclean
./configure
make
Works fine. Thanks
feisty2
18th November 2016, 21:02
satd is yet again broken..
broken like not even activated
import vapoursynth as vs
core = vs.get_core()
clp = rule6
clp = core.fmtc.bitdepth(clp,bits=16,fulls=False,fulld=True)
clp = core.std.ShufflePlanes(clp,0,vs.GRAY)
sup = core.mv.Super(clp)
bv1a = core.mv.Analyse(sup,delta=1,blksize=32,overlap=16,search=3,dct=5,isb=True)
bv2a = core.mv.Analyse(sup,delta=2,blksize=32,overlap=16,search=3,dct=5,isb=True)
bv3a = core.mv.Analyse(sup,delta=3,blksize=32,overlap=16,search=3,dct=5,isb=True)
fv1a = core.mv.Analyse(sup,delta=1,blksize=32,overlap=16,search=3,dct=5,isb=False)
fv2a = core.mv.Analyse(sup,delta=2,blksize=32,overlap=16,search=3,dct=5,isb=False)
fv3a = core.mv.Analyse(sup,delta=3,blksize=32,overlap=16,search=3,dct=5,isb=False)
bv1b = core.mv.Analyse(sup,delta=1,blksize=32,overlap=16,search=3,dct=0,isb=True)
bv2b = core.mv.Analyse(sup,delta=2,blksize=32,overlap=16,search=3,dct=0,isb=True)
bv3b = core.mv.Analyse(sup,delta=3,blksize=32,overlap=16,search=3,dct=0,isb=True)
fv1b = core.mv.Analyse(sup,delta=1,blksize=32,overlap=16,search=3,dct=0,isb=False)
fv2b = core.mv.Analyse(sup,delta=2,blksize=32,overlap=16,search=3,dct=0,isb=False)
fv3b = core.mv.Analyse(sup,delta=3,blksize=32,overlap=16,search=3,dct=0,isb=False)
clpa = core.mv.Degrain3(clp, sup, bv1a, fv1a, bv2a, fv2a, bv3a, fv3a,thscd1=16320,thsad=2000)
clpb = core.mv.Degrain3(clp, sup, bv1b, fv1b, bv2b, fv2b, bv3b, fv3b,thscd1=16320,thsad=2000)
clp = core.std.Expr([clpa,clpb],"x y - abs 10000 *")
clp.set_output()
got a blank black clip, which means dct=5 is doing SAD actually...
feisty2
9th February 2017, 10:01
I added floating point support to MMask, you can back-port it to your branch and make your version of MMask work on higher precision if you want to.
https://github.com/IFeelBloated/vapoursynth-mvtools-sf/blob/master/src/MVMask.cpp
Boulder
15th February 2017, 17:21
I've been trying to track a weird problem in which VapourSynth Editor will slowly use up all the memory after refreshing the script enough times. I use a custom denoising function to process the videos.
I was able to find out that feeding an external clip to mv.Super causes a memory leak:
Core freed but 12 filter instances still exist
Core freed but 12 filter instances still exist
Core freed but 458496000 bytes still allocated in framebuffers
Core freed but 458496000 bytes still allocated in framebuffers
This is the part where it happens:
prefilt = core.dfttest.DFTTest(feed, tbsize=1, sigma=5, sigma2=5, sbsize=16, sosize=8)
pelmdg = core.fmtc.resample(clip=clp, scale=2, kernel='spline64', center=False)
pelprefilt = core.fmtc.resample(clip=prefilt, scale=2, kernel='spline64', center=False)
superanalyse = core.mv.Super(clp, pel=2, chroma=True, rfilter=4, pelclip=pelprefilt)
supermdg = core.mv.Super(clp, pel=2, chroma=True, rfilter=4, levels=1, pelclip=pelmdg)
One question: is it even sensible to use a denoised external super clip upsized with a sharp method? Or is it generally better to let the internal functions do things?
feisty2
15th February 2017, 17:55
I've been trying to track a weird problem in which VapourSynth Editor will slowly use up all the memory after refreshing the script enough times. I use a custom denoising function to process the videos.
I was able to find out that feeding an external clip to mv.Super causes a memory leak:
Core freed but 12 filter instances still exist
Core freed but 12 filter instances still exist
Core freed but 458496000 bytes still allocated in framebuffers
Core freed but 458496000 bytes still allocated in framebuffers
This is the part where it happens:
prefilt = core.dfttest.DFTTest(feed, tbsize=1, sigma=5, sigma2=5, sbsize=16, sosize=8)
pelmdg = core.fmtc.resample(clip=clp, scale=2, kernel='spline64', center=False)
pelprefilt = core.fmtc.resample(clip=prefilt, scale=2, kernel='spline64', center=False)
superanalyse = core.mv.Super(clp, pel=2, chroma=True, rfilter=4, pelclip=pelprefilt)
supermdg = core.mv.Super(clp, pel=2, chroma=True, rfilter=4, levels=1, pelclip=pelmdg)
no, it should be
superanalyse = core.mv.Super(prefilt, pel=2, chroma=True, rfilter=4, pelclip=pelprefilt)
One question: is it even sensible to use a denoised external super clip upsized with a sharp method? Or is it generally better to let the internal functions do things?
the difference is very small in general, but sensible, NNEDI is (kind of) noticeably better than internal functions.
Boulder
15th February 2017, 18:40
no, it should be
superanalyse = core.mv.Super(prefilt, pel=2, chroma=True, rfilter=4, pelclip=pelprefilt)
Sorry, got that the wrong way around when investigating. The reference clip is 'prefilt' in the function itself :)
the difference is very small in general, but sensible, NNEDI is (kind of) noticeably better than internal functions.OK, I think I'll keep things intact for now.
jackoneill
15th February 2017, 20:41
I've been trying to track a weird problem in which VapourSynth Editor will slowly use up all the memory after refreshing the script enough times. I use a custom denoising function to process the videos.
I was able to find out that feeding an external clip to mv.Super causes a memory leak:
Yes, there is a memory leak in Super. Does this DLL (http://savedonthe.net/download/1046/vapoursynth-mvtools-leaky-win64.html) work better?
Boulder
16th February 2017, 16:48
Works great, no more leaks :) Thanks a lot!
Pat357
12th April 2017, 22:57
jackoneill : the fixed libmvtools.dll (fixed mem-leak) has some unwanted dependencies like libgcc_s_seh1.dll and libstdc++6.dll.
Because I don't know what the fix is for the mem-leak and on github ( https://github.com/dubhater/vapoursynth-mvtools ) I do not see any
fix for the mem-leak either, recompiling from the unfixed same source would not make much sense.
Could you please make a fixed (no-mem-leak) version for it ?
jackoneill
14th April 2017, 14:41
jackoneill : the fixed libmvtools.dll (fixed mem-leak) has some unwanted dependencies like libgcc_s_seh1.dll and libstdc++6.dll.
Because I don't know what the fix is for the mem-leak and on github ( https://github.com/dubhater/vapoursynth-mvtools ) I do not see any
fix for the mem-leak either, recompiling from the unfixed same source would not make much sense.
Could you please make a fixed (no-mem-leak) version for it ?
Sorry about that. I totally forgot.
Here is v18. (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v18)
* Super: Fix memory leak when pelclip is used.
Pat357
24th April 2017, 22:21
In the MVtools doc is:
"Block sizes of 64x32, 64x64, 128x64, and 128x128 are supported."
Are smaller specified blksizes (like blksize=16) just ignored ? ..as I get no error.
Why only supporting the bigger blocks ?
Would you consider supporting also blksizes=16x16, 32x16, 32x32 or even 8x8, 16x8 ?
MonoS
24th April 2017, 22:30
In the MVtools doc is:
"Block sizes of 64x32, 64x64, 128x64, and 128x128 are supported."
Are smaller specified blksizes (like blksize=16) just ignored ? ..as I get no error.
Why only supporting the bigger blocks ?
Would you consider supporting also blksizes=16x16, 32x16, 32x32 or even 8x8, 16x8 ?
They are supported, the documentation only states the differences between the vapoursynth version and the original avisynth one.
jackoneill
5th June 2017, 21:16
satd is yet again broken..
broken like not even activated
import vapoursynth as vs
core = vs.get_core()
clp = rule6
clp = core.fmtc.bitdepth(clp,bits=16,fulls=False,fulld=True)
clp = core.std.ShufflePlanes(clp,0,vs.GRAY)
sup = core.mv.Super(clp)
bv1a = core.mv.Analyse(sup,delta=1,blksize=32,overlap=16,search=3,dct=5,isb=True)
bv2a = core.mv.Analyse(sup,delta=2,blksize=32,overlap=16,search=3,dct=5,isb=True)
bv3a = core.mv.Analyse(sup,delta=3,blksize=32,overlap=16,search=3,dct=5,isb=True)
fv1a = core.mv.Analyse(sup,delta=1,blksize=32,overlap=16,search=3,dct=5,isb=False)
fv2a = core.mv.Analyse(sup,delta=2,blksize=32,overlap=16,search=3,dct=5,isb=False)
fv3a = core.mv.Analyse(sup,delta=3,blksize=32,overlap=16,search=3,dct=5,isb=False)
bv1b = core.mv.Analyse(sup,delta=1,blksize=32,overlap=16,search=3,dct=0,isb=True)
bv2b = core.mv.Analyse(sup,delta=2,blksize=32,overlap=16,search=3,dct=0,isb=True)
bv3b = core.mv.Analyse(sup,delta=3,blksize=32,overlap=16,search=3,dct=0,isb=True)
fv1b = core.mv.Analyse(sup,delta=1,blksize=32,overlap=16,search=3,dct=0,isb=False)
fv2b = core.mv.Analyse(sup,delta=2,blksize=32,overlap=16,search=3,dct=0,isb=False)
fv3b = core.mv.Analyse(sup,delta=3,blksize=32,overlap=16,search=3,dct=0,isb=False)
clpa = core.mv.Degrain3(clp, sup, bv1a, fv1a, bv2a, fv2a, bv3a, fv3a,thscd1=16320,thsad=2000)
clpb = core.mv.Degrain3(clp, sup, bv1b, fv1b, bv2b, fv2b, bv3b, fv3b,thscd1=16320,thsad=2000)
clp = core.std.Expr([clpa,clpb],"x y - abs 10000 *")
clp.set_output()
got a blank black clip, which means dct=5 is doing SAD actually...
It is indeed doing SAD. I accidentally made dct=5..10 behave like dct=0 in v17. I think v19 will happen soon.
jackoneill
7th June 2017, 20:37
v19 is here. (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v19)
* Super: Fix small bug in SSE2 code used with rfilter=3 and 8 bit input.
* Super: Fix bug in SSE2 code used with sharp=0 and 8 bit input.
* Analyse, Recalculate: Fix bug that made dct=5..10 behave like dct=0 (bug introduced in v17).
* Store SAD in 64 bit integers instead of 32 bit integers. This is required
because YUV444P16 video with 128x128 blocks could produce SADs
too large for 32 bit integers. Motion vectors produced by v18 or older
will not work with this version. Only users who stored the motion vectors
from Analyse/Recalculate on disk have to worry about this.
* Degrains: Put an upper limit on the legal values of thsad/thsadc to avoid
an overflow. The exact value of the limit depends on bit depth,
subsampling, and block size. It's probably fairly high.
MonoS
14th June 2017, 21:07
Hi, using a script like that
import vapoursynth as vs
import nnedi3_resample as edi
import havsfunc as has
core = vs.get_core()
def Denoise2(src, denoise, blksize, fast, truemotion):
overlap = int(blksize / 2)
pad = blksize + overlap
src = core.fmtc.resample(src, src.width+pad, src.height+pad, sw=src.width+pad, sh=src.height+pad, kernel="point")
super = core.mv.Super(src)
rep = has.DitherLumaRebuild(src, s0=1)
superRep = core.mv.Super(rep)
bvec2 = core.mv.Analyse(superRep, isb = True, delta = 2, blksize=blksize, overlap=overlap, truemotion=truemotion)
bvec1 = core.mv.Analyse(superRep, isb = True, delta = 1, blksize=blksize, overlap=overlap, truemotion=truemotion)
fvec1 = core.mv.Analyse(superRep, isb = False, delta = 1, blksize=blksize, overlap=overlap, truemotion=truemotion)
fvec2 = core.mv.Analyse(superRep, isb = False, delta = 2, blksize=blksize, overlap=overlap, truemotion=truemotion)
fin = core.mv.Degrain2(src, super, bvec1,fvec1,bvec2,fvec2, denoise)
fin = core.std.CropRel(fin, 0, pad, 0, pad)
return fin
src = core.lsmas.LWLibavSource("").fmtc.bitdepth(bits=16)
den = Denoise2(src, 200, blksize=16, fast=False, truemotion=False)
den.set_output()
i get poor denoising in bright area of the image, this doesn't happens when i first upscale the clip to 444 using
res = edi.nnedi3_resample(src, src.width ,src.height, sigmoid=True, invks=True, csp=vs.YUV444P16, curves="709")
i've checked the luma plane and there are no differences with the original(tried with a makediff and fmtc.histluma() call)
Is this a "known issue" or am i doing something wrong?
VS_Fan
15th June 2017, 01:26
Is this a "known issue" or am i doing something wrong?
It is most probably related to the luma:chroma SAD ratio weighting.
Pinterf explained it in this mvtools for avisynth forum post (https://forum.doom9.org/showthread.php?p=1806028#post1806028). He also recently released a version (2.7.18.22 – 2017-05-12) of mvtools for avisynth with a new parameter "scaleCSAD" to fine tune this ratio. See this forum post (https://forum.doom9.org/showthread.php?p=1806836#post1806836)
Both in avisynth and vapoursynth, instead of converting to 444, you could filter (mdegrain, etc) planes separately, and then combine them together again with ShufflePlanes.
MonoS
15th June 2017, 18:40
It is most probably related to the luma:chroma SAD ratio weighting.
Pinterf explained it in this mvtools for avisynth forum post (https://forum.doom9.org/showthread.php?p=1806028#post1806028). He also recently released a version (2.7.18.22 – 2017-05-12) of mvtools for avisynth with a new parameter "scaleCSAD" to fine tune this ratio. See this forum post (https://forum.doom9.org/showthread.php?p=1806836#post1806836)
I took a look at those two posts and i can't understand how the thsad of the chroma planes should influence the luma plane.
Both in avisynth and vapoursynth, instead of converting to 444, you could filter (mdegrain, etc) planes separately, and then combine them together again with ShufflePlanes.
If i denoise both sending the planes parameter with 0 or using ShufflePlanes to denoise only the luma i get the same poor performance in bright spot.
I should also mention that i'm talking about the luma plane, chroma planes, afaik are ok.
EDIT: i'll send a sample asap
VS_Fan
16th June 2017, 03:31
I took a look at those two posts and i can't understand how the thsad of the chroma planes should influence the luma plane.
It’s not the thSAD parameter (well, not only). It’s related to the mvtools internal SAD calculations made during ‘analyze’ or ‘recalculate’ to find the motion vectors. The luma:chroma weighting is:
4:2 for YV12 (4:2:0 subsampling)
4:4 for YV16 (4:2:2 subsampling)
4:8 for YV24 (4:4:4 subsampling)
That means: with 444 subsampling mvtools will base its calculations on twice as much chroma data than luma data. That’s why you get “cleaner” results. The chroma planes have typically less noise than the luma plane. So, with such a low value for thSAD (denoise=200) mvtools picks up the right vectors easier for chroma planes than it can with luma data.
I saw three ways to improve your script:
The ‘denoise’ value (thSAD parameter) is half of the default value. Leave it at default (400)
You are resizing the clip prior to processing with mvtools, with the very basic ‘point’ kernel, and at the end you are cropping the borders. You should avoid that. Use the hpad & vpad parameters for super instead. And if you really want crop the borders, you can resize after mdegrain with a better kernel and then crop.
DitherLumaRebuild “allows tweaking for pumping up the darks” (comment by the author). This may be leading you to oversaturate the bright areas. Try without it. You could use some other prefilter.
Like this:def Denoise2(src, denoise, blksize, fast, truemotion):
overlap = int(blksize / 2)
pad = blksize #+ overlap
#src = core.fmtc.resample(src, src.width+pad, src.height+pad, sw=src.width+pad, sh=src.height+pad, kernel="point")
super = core.mv.Super(src, hpad=pad, vpad=pad)
#rep = has.DitherLumaRebuild(src, s0=1)
# Optional - Some other prefilter:
rep = core.dfttest.DFTTest(clip=src, tbsize=1, sigma=2.0)
superRep = core.mv.Super(rep, hpad=pad, vpad=pad)
bvec2 = core.mv.Analyse(superRep, isb = True, delta = 2, blksize=blksize, overlap=overlap, truemotion=truemotion)
bvec1 = core.mv.Analyse(superRep, isb = True, delta = 1, blksize=blksize, overlap=overlap, truemotion=truemotion)
fvec1 = core.mv.Analyse(superRep, isb = False, delta = 1, blksize=blksize, overlap=overlap, truemotion=truemotion)
fvec2 = core.mv.Analyse(superRep, isb = False, delta = 2, blksize=blksize, overlap=overlap, truemotion=truemotion)
fin = core.mv.Degrain2(src, super, bvec1,fvec1,bvec2,fvec2, denoise)
#fin = core.std.CropRel(fin, 0, pad, 0, pad)
return fin
src = core.lsmas.LWLibavSource("").fmtc.bitdepth(bits=16)
den = Denoise2(src, 400, blksize=16, fast=False, truemotion=False)
den.set_output()
MonoS
16th June 2017, 22:39
So, if i understand correctly, those weighting are using during the analyze function to search for the proper motion vector, doing the analysis in 444 change some values and "improve" the denoising on the luma plane, am i correct?
Regarding your suggestion:
I usually use thsad around 150 up to 500 to obtaining different level of denoising, 200 for me is for a low-to-mid denoising.
i'm not resizing the clip, i'm simply padding it as I, when i did extensive test some years ago, noticed bad denoising on the bottom and right edge, even with padding, so i've started to pad my clip by myself, this method achieved very nice results.
AFAIK DitherLumaRebuild is commonly used for prefiltering the clip before doing motion analysis, i found this trick in one of cretindesalpes post and on vs QTGMC port.
Anyway i think you are right suggesting to use a stronger denoising, using 400 on the 420 clip it obtain similar result in those areas with weak denoising, but i would prefere to avoid using such strong, in my opinion, thsad.
VS_Fan
17th June 2017, 18:33
So, if i understand correctly, those weighting are using during the analyze function to search for the proper motion vector, doing the analysis in 444 change some values and "improve" the denoising on the luma plane, am i correct?
Right, but resampling to 444 doesn’t necessarily “improve” denoising. It just gives different results: For YUV colorspaces the amount of data used to represent luma and chroma for any pixel in each frame depends on the chroma subsampling (https://en.wikipedia.org/wiki/Chroma_subsampling). Mvtools’ analyze filter uses all data for each pixel to construct the blocks, unless you specify chroma=False.
From the mvtools doc at avisynth’s site (http://avisynth.nl/index.php/MVTools#About_MVTools): At analysis stage plugin divides frames by small blocks and try to find for every block in current frame the most similar (matching) block in second frame (previous or next). The relative shift of these blocks is motion vector. The main measure of block similarity is sum of absolute differences (SAD) of all pixels of these two blocks compared. SAD is a value which says how good the motion estimation was.
I usually use thsad around 150 up to 500 to obtaining different level of denoising, 200 for me is for a low-to-mid denoising.
This is my personal preference: For my 4:2:2 video sources I process each plane separately. I consider luma and chroma very different animals, so I tweak the corresponding thSAD and even thscd1 & thscd2 to lower values for chroma.
i'm not resizing the clip, i'm simply padding it as I, when i did extensive test some years ago, noticed bad denoising on the bottom and right edge, even with padding, so i've started to pad my clip by myself, this method achieved very nice results.
I can see now. There could have been a bug in earlier versions of the plugin, but you don’t need to do that any more
Anyway i think you are right suggesting to use a stronger denoising, using 400 on the 420 clip it obtain similar result in those areas with weak denoising, but i would prefere to avoid using such strong, in my opinion, thsad.
You could try mdegrain1, which will risk a lot less detail destruction while you use larger values for thsad.
MonoS
19th June 2017, 22:16
So what may be happening is this: Upscaling the chroma planes mvtools think that less of the image is changed because we have 2*2 chroma pixel that are very similar, so the same thsad result in more similar blocks and so more strong denoise, am i right?
feisty2
20th June 2017, 16:18
I understand now why you rewrote this thing like, entirely...
the code was full of weird bullshit and insanely fucking stupid stuff..
I managed to upgrade FakeBlockData and FakePlaneOfBlocks to normal C++14 but got stuck at FakeGroupOfPlanes
there's this bloody "update()" function throughout MVTools code,
it's like
void FakeBlockData::Update(const int *array) {
vector.x = array[0];
vector.y = array[1];
vector.sad = array[2];
}
in FakeBlockData and I recoded it to
auto Update(const VectorStructure *NewVectorPointer) {
Vector = *NewVectorPointer;
}
and in FakePlaneOfBlocks
void FakePlaneOfBlocks::Update(const int *array) {
array += 0;
for (int i = 0; i < nBlkCount; i++) {
blocks[i].Update(array);
array += N_PER_BLOCK;
}
}
I, again recoded it like
auto Update(const void *VectorStream) {
auto StreamCursor = reinterpret_cast<const VectorStructure *>(VectorStream);
for (auto i = 0; i < nBlkCount; ++i) {
blocks[i].Update(StreamCursor);
++StreamCursor;
}
}
.....
and there's one in FakeGroupOfPlanes like
void FakeGroupOfPlanes::Update(const int *array) {
const int *pA = array;
validity = GetValidity(array);
pA += 2;
for (int i = nLvCount_ - 1; i >= 0; i--)
pA += pA[0];
pA++;
pA = array;
pA += 2;
for (int i = nLvCount_ - 1; i >= 0; i--) {
planes[i]->Update(pA + 1);
pA += pA[0];
}
}
I mean like, dude, what the fuck??? this one is 11 out of 10 kinda wicked fucked up, all that weird abnormal pointer arithmetics with "pA" makes it impossible to recode...
I guess you should know all about that wicked update() function cuz you once converted MVTools to C
could you help me with this and explain that "FakeGroupOfPlanes::Update()", please?
jackoneill
20th June 2017, 16:52
and there's one in FakeGroupOfPlanes like
void FakeGroupOfPlanes::Update(const int *array) {
const int *pA = array;
validity = GetValidity(array);
pA += 2;
for (int i = nLvCount_ - 1; i >= 0; i--)
pA += pA[0];
pA++;
pA = array;
pA += 2;
for (int i = nLvCount_ - 1; i >= 0; i--) {
planes[i]->Update(pA + 1);
pA += pA[0];
}
}
I mean like, dude, what the fuck??? this one is 11 out of 10 kinda wicked fucked up, all that weird abnormal pointer arithmetics with "pA" makes it impossible to recode...
I guess you should know all about that wicked update() function cuz you once converted MVTools to C
could you help me with this and explain that "FakeGroupOfPlanes::Update()", please?
Well, see, half that function is redundant: https://github.com/dubhater/vapoursynth-mvtools/commit/9c89c7f919a90c16195ca55f9e963a13e02d2912#diff-6195dbc5362ec3b3fc298d79f802d212L110
feisty2
20th June 2017, 17:10
something I failed to understand
const int *pA = array + 2;
what's that "+2"? some kind of offset value? will it be affected if I change the structure of vector stream? like if I change "sad" in the vector to double?
and this,
pA += pA[0];
I suppose it should be something like
constexpr auto StreamHeaderOffset = 2;
auto pA = reinterpret_cast<const VectorStructure *>(array + StreamHeaderOffset);
auto MoveOnToTheNextVector = [](auto &VectorPointer) {
constexpr auto AbsoluteVectorSize = sizeof(std::decay_t<decltype(*VectorPointer)>);
constexpr auto RelativeVectorSize = AbsoluteVectorSize / sizeof(int);
auto ForwardDistance = VectorPointer->x / RelativeVectorSize;
VectorPointer += ForwardDistance;
};
MoveOnToTheNextVector(pA);
?
and that's why I hate C and old C++ so much cuz it's like fucking deciphering assembly code, what's so hard about defining weird constants with constexpr variables with proper names and writing some nested closure functions to tell others what the hell you're doing exactly?
jackoneill
20th June 2017, 18:06
something I failed to understand
const int *pA = array + 2;
what's that "+2"? some kind of offset value? will it be affected if I change the structure of vector stream? like if I change "sad" in the vector to double?
and this,
pA += pA[0];
This is what Analyse and Recalculate attach to each frame they return, and what the "array" parameter points to:
int total_size; // Size of the entire thing, i.e. the last int you may access is array[total_size - 1]
int validity; // 0 if the frame is too close to the beginning or end of the clip, otherwise 1
int first_level_size;
VECTOR first_level_vectors[first_level_size];
int second_level_size;
VECTOR second_level_vectors[second_level_size];
...
int last_level_size;
VECTOR last_level_vectors[last_level_size];
int divided_extra_level_size; // may not exist
VECTOR divided_extra_level_vectors[divided_extra_level_size]; //may not exist
So that +2 skips over the total size and validity. And then pA += pA[0] skips over the "current" level.
You may have noticed that all those size fields store numbers of ints, rather than numbers of bytes. This is probably because everything in there used to be an int (the sizes, validity, VECTOR's members, other things that used to be stored there). This is weird already, and it would have become weirder when I made the type of VECTOR::sad int64_t, so since v19 all these sizes store numbers of bytes.
feisty2
20th June 2017, 20:00
thanks for the detailed explanation, I can now finally reshape that weird piece of shit into something readable...
auto Update(const std::int32_t *VectorStream) {
constexpr auto StreamHeaderOffset = 2;
auto StreamCursor = VectorStream + StreamHeaderOffset;
auto GetValidity = [&]() {
return VectorStream[1] == 1;
};
auto UpdateVectorsForEachLevel = [&](auto Level) {
constexpr auto LevelHeaderOffset = 1;
auto LevelLength = StreamCursor[0];
auto CalibratedStreamCursor = reinterpret_cast<const VectorStructure *>(StreamCursor + LevelHeaderOffset);
planes[Level]->Update(CalibratedStreamCursor);
StreamCursor += LevelLength;
};
validity = GetValidity();
for (auto Level = nLvCount_ - 1; Level >= 0; --Level)
UpdateVectorsForEachLevel(Level);
}
guess Imma stick to the int-based size for now cuz I don't want no extra trouble...
just for comparison, this was the original version
void FakeGroupOfPlanes::Update(const int *array) {
const int *pA = array;
validity = GetValidity(array);
pA += 2;
for (int i = nLvCount_ - 1; i >= 0; i--)
pA += pA[0];
pA++;
pA = array;
pA += 2;
for (int i = nLvCount_ - 1; i >= 0; i--) {
planes[i]->Update(pA + 1);
pA += pA[0];
}
}
now you see why I said modern C++ is python with pointers :p
Boulder
9th July 2018, 12:35
Would it be possible to have the 'star' motion search method from x265 included in MVTools?
jackoneill
9th July 2018, 16:02
Would it be possible to have the 'star' motion search method from x265 included in MVTools?
It probably is.
But instead here is v20 with a small bug fix. (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v20)
* Fix green edges in the output of FlowBlur, FlowFPS, BlockFPS when pelclip is used and pel=2 (bug introduced in v12).
Boulder
9th July 2018, 16:25
It probably is.
But instead here is v20 with a small bug fix. (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v20)
Thank you for even considering it, and thanks for the fix :) It's always nice to see plugins being maintained.
edcrfv94
31st July 2018, 05:36
Vapoursynth mvtools not support DegrainN?(some script need tr=6)
Wolfberry
31st July 2018, 06:32
1. Binary Part: Extended Degrain to Degrain24 (24, it's my lucky number!)
2. Resurrected vmulti features from MVTools 2.6.0.5, implemented via a python module, "tr" works up to 24, guess no one will ever use a time radius > 24.... maybe?
3. Resurrected StoreVect and RestoreVect from MVTools 2.6.0.5, implemented via a python module
vmulti demos:
1. DegrainN
import vapoursynth as vs
import mvmulti
core = vs.core
sup = core.mvsf.Super(clp)
vec = mvmulti.Analyze(sup,tr=6,blksize=8,overlap=4)
vec = mvmulti.Recalculate(sup,vec,tr=6,blksize=4,overlap=2)
clp = mvmulti.DegrainN(clp, sup, vec, tr=6)
clp.set_output()
DegrainN is available in mvsf (mvtools single precision), the python module can be obtained here (https://github.com/IFeelBloated/vapoursynth-mvtools-sf/blob/master/src/mvmulti.py)
edcrfv94
29th October 2018, 07:28
vapoursynth mvtools v20
c_in = src
sup_a = core.mv.Super(c_in, pel=2)
sup = sup_a
analyse_args_df = dict(blksize=16, overlap=8, search=5, searchparam=4, dct=5)
bVec1 = core.mv.Analyse(sup_a, isb=True, delta=1, **analyse_args_df)
fVec1 = core.mv.Analyse(sup_a, isb=False, delta=1, **analyse_args_df)
bVec2 = core.mv.Analyse(sup_a, isb=True, delta=2, **analyse_args_df)
fVec2 = core.mv.Analyse(sup_a, isb=False, delta=2, **analyse_args_df)
bVec3 = core.mv.Analyse(sup_a, isb=True, delta=3, **analyse_args_df)
fVec3 = core.mv.Analyse(sup_a, isb=False, delta=3, **analyse_args_df)
compensate_args_df = dict(thsad=400)
bc1 = core.mv.Compensate(c_in, sup, bVec1, **compensate_args_df)
fc1 = core.mv.Compensate(c_in, sup, fVec1, **compensate_args_df)
bc2 = core.mv.Compensate(c_in, sup, bVec2, **compensate_args_df)
fc2 = core.mv.Compensate(c_in, sup, fVec2, **compensate_args_df)
bc3 = core.mv.Compensate(c_in, sup, bVec3, **compensate_args_df)
fc3 = core.mv.Compensate(c_in, sup, fVec3, **compensate_args_df)
cmp = core.std.Interleave([bc3, bc2, bc1, c_in, fc1, fc2, fc3])
#cmp = core.std.Interleave([fc3, fc2, fc1, c_in, bc1, bc2, bc3])
AviSynth+ mvtools-2.7.33
c_in = last
sup_a = c_in.MSuper(pel=2)
sup = sup_a
vec_norm = sup_a.MAnalyse(multi=true, delta=3, blksize=16, overlap=8, search=5, searchparam=4, DCT=5)
cmp = c_in.MCompensate(sup, vec_norm, tr=3, thSAD=400)
or
c_in = last
sup_a = c_in.MSuper(pel=2)
sup = sup_a
#vec = sup_a.MAnalyse(multi=true, delta=3, blksize=16, overlap=8, search=5, searchparam=4, DCT=5)
#cmp = c_in.MCompensate(sup, vec, tr=3, thSAD=400)
bVec1 = MAnalyse(sup_a, isb=True, delta=1, blksize=16, overlap=8, search=5, searchparam=4, dct=5)
fVec1 = MAnalyse(sup_a, isb=False, delta=1, blksize=16, overlap=8, search=5, searchparam=4, dct=5)
bVec2 = MAnalyse(sup_a, isb=True, delta=2, blksize=16, overlap=8, search=5, searchparam=4, dct=5)
fVec2 = MAnalyse(sup_a, isb=False, delta=2, blksize=16, overlap=8, search=5, searchparam=4, dct=5)
bVec3 = MAnalyse(sup_a, isb=True, delta=3, blksize=16, overlap=8, search=5, searchparam=4, dct=5)
fVec3 = MAnalyse(sup_a, isb=False, delta=3, blksize=16, overlap=8, search=5, searchparam=4, dct=5)
bc1 = MCompensate(c_in, sup, bVec1, thsad=400)
fc1 = MCompensate(c_in, sup, fVec1, thsad=400)
bc2 = MCompensate(c_in, sup, bVec2, thsad=400)
fc2 = MCompensate(c_in, sup, fVec2, thsad=400)
bc3 = MCompensate(c_in, sup, bVec3, thsad=400)
fc3 = MCompensate(c_in, sup, fVec3, thsad=400)
cmp = Interleave(bc3, bc2, bc1, c_in, fc1, fc2, fc3)
#cmp = Interleave(fc3, fc2, fc1, c_in, bc1, bc2, bc3)
Very different from the reslts of AviSynth version, not sure which one correct.
jackoneill
13th March 2019, 16:52
v21 (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v21) fixes three bugs:
* BlockFPS, Flow, FlowFPS, FlowInter: Fix crash with certain blksize/overlapv
ratios, like 8/2. Thanks to pinterf for finding the cause and the solution.
* Flow, FlowBlur, FlowFPS, FlowInter: Fix crash due to motion vectors pointing
outside the frame. Thanks to pinterf for finding the cause and the solution.
* Analyse: Fix use of an uninitialised variable. Only dct modes 2, 6, and 9 were
affected. The result was probably just nondeterministic output. This
uninitialised variable was inherited from the Avisynth plugin, version 2.5.11.3.
ChaosKing
13th March 2019, 17:03
Awesome!
ChaosKing
2nd November 2019, 10:02
Isn't it time for a v22 - AVX2 booster edition? :D
Or at least a test build so we can test it?
jackoneill
2nd November 2019, 17:00
Isn't it time for a v22 - AVX2 booster edition? :D
Or at least a test build so we can test it?
I should figure out issue #38 first.
tormento
6th April 2020, 10:57
I should figure out issue #38 first.
Would you please add MDegrainN (up to 6, at least)?
I need it to run G41Fun.py (https://github.com/Selur/VapoursynthScriptsInHybrid/blob/master/G41Fun.py) on noisy material.
I have tried MVTools single precision but it's simply too slow to have any use of it, at least the one without AVX2 requirement.
Boulder
4th May 2020, 18:40
Thank you for the new release (https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v22) :thanks:
Lemmy said that speed is good for you.
bin.n2f
4th May 2020, 21:44
Would you please add MDegrainN (up to 6, at least)?
I need it to run G41Fun.py (https://github.com/Selur/VapoursynthScriptsInHybrid/blob/master/G41Fun.py) on noisy material.
I have tried MVTools single precision but it's simply too slow to have any use of it, at least the one without AVX2 requirement.
yes please
Boulder
5th May 2020, 05:22
I'm getting quite strange results considering the possible speed increases on my Ryzen 3900X. I would have expected the new Zen generation to be able to utilize the AVX2 optimizations really well, because they did help the first gen one when I tested Stephen R. Savage's early builds.
The first 2500 frames using vspipe:
v21 : 57.25 fps
v22 : 55.14 fps
Test script, normal Blu-ray source.
clp = core.dgdecodenv.DGSource(r"test.dgi")
degrain16 = core.fmtc.bitdepth(clp, bits=16)
superanalyse8 = core.mv.Super(clp, pel=2, chroma=True, rfilter=4, sharp=1)
supermdg16 = core.mv.Super(degrain16, pel=2, chroma=True, rfilter=4, levels=1, sharp=1)
analyze_args = dict(blksize=16, overlap=8, search=5, searchparam=8, pelsearch=8, truemotion=False)
degrain_args_16 = dict(thsad=200, thsadc=100, limit=1*256, limitc=2*256, thscd1=300, thscd2=80)
bv1_8 = core.mv.Analyse(superanalyse8, isb=True, delta=1, **analyze_args)
fv1_8 = core.mv.Analyse(superanalyse8, isb=False, delta=1, **analyze_args)
finalclip8 = core.mv.Degrain1(degrain16, supermdg16, bv1_8, fv1_8, **degrain_args_16)
finalclip8.set_output()
Boulder
13th May 2020, 15:59
What does MFinest actually do? There's no real documentation anywhere to be found.
jackoneill
14th May 2020, 08:15
What does MFinest actually do? There's no real documentation anywhere to be found.
If you look at the output of Super with pel=2 you'll see at the bottom of the frame 4 identically-sized images, and with pel=4 you'll see 16 identically-sized images. Those 4 or 16 images are actually one large image. I imagine they are stored like that so that Super doesn't waste lots of RAM in the top part of the frame.
Finest takes those 4 or 16 images and reassembles them into one (separate) image for the filters that need it. I think it's mostly the Flow* filters. They automatically invoke Finest when they need it.
I think this hack could be eliminated in the VapourSynth version because the various images produced by Super could be attached to the source frame as separate frame properties. If someone had the motivation to look into that.
Pat357
15th May 2020, 23:02
I'm getting quite strange results considering the possible speed increases on my Ryzen 3900X. I would have expected the new Zen generation to be able to utilize the AVX2 optimizations really well, because they did help the first gen one when I tested Stephen R. Savage's early builds.
The first 2500 frames using vspipe:
v21 : 57.25 fps
v22 : 55.14 fps
What is so strange about these results ? I would expect better speed from a Ryzen 3900... did you limit the nr. of threads ?
Which was the optimized build ?
Tested your script with 1920x1080 YUV420P8 clip on my i7940X (14c/28t):
Mvtools R22 (optimized by Stephen R. Savage)
>vspipe -e 1999 boulder.vpy .
Output 2000 frames in 14.63 seconds (136.66 fps)
Mvtools R23 (current version)
vspipe -e 1999 boulder.vpy .
Output 2000 frames in 17.34 seconds (115.37 fps)
I hope Stephen finds the time to optimize this new version :)
Boulder
16th May 2020, 12:37
What is so strange about these results ? I would expect better speed from a Ryzen 3900... did you limit the nr. of threads ?
Which was the optimized build ?
Tested your script with 1920x1080 YUV420P8 clip on my i7940X (14c/28t):
Mvtools R22 (optimized by Stephen R. Savage)
>vspipe -e 1999 boulder.vpy .
Output 2000 frames in 14.63 seconds (136.66 fps)
Mvtools R23 (current version)
vspipe -e 1999 boulder.vpy .
Output 2000 frames in 17.34 seconds (115.37 fps)
I hope Stephen finds the time to optimize this new version :)
R22 was the first official build with AVX2 optimizations. The thing looks like a compiler issue, the libraries built with MSVC are faster.
https://github.com/dubhater/vapoursynth-mvtools/issues/47
feisty2
17th May 2020, 12:10
Would you please add MDegrainN (up to 6, at least)?
I need it to run G41Fun.py (https://github.com/Selur/VapoursynthScriptsInHybrid/blob/master/G41Fun.py) on noisy material.
I have tried MVTools single precision but it's simply too slow to have any use of it, at least the one without AVX2 requirement.
I might be able to add mvmulti functionalities (MAnalyze, MRecalculate, MCompensate, MFlow with radius, and MDegrainN) and cosine annealing ("thsad2") to this branch as well if the branch owner allows C++20 snippets in the code base.
tormento
17th May 2020, 12:33
I might be able to add mvmulti functionalities (MAnalyze, MRecalculate, MCompensate, MFlow with radius, and MDegrainN) and cosine annealing ("thsad2") to this branch as well if the branch owner allows C++20 snippets in the code base.
Great. I hope the SMDegrain script will be modified too.
Boulder
17th May 2020, 12:39
I might be able to add mvmulti functionalities (MAnalyze, MRecalculate, MCompensate, MFlow with radius, and MDegrainN) and cosine annealing ("thsad2") to this branch as well if the branch owner allows C++20 snippets in the code base.
Would you mind taking a stab at the scaling of vectors between different bitdepths (in case jackoneill doesn't have the interest to do it)?
feisty2
17th May 2020, 13:04
the thing is I'm not sure if jackoneill would accept C++20 code for 2 reasons
1) it breaks compatibility with tons of older compilers, in fact, GCC 10.1 is the only compiler that supports most of C++20 features currently.
2) the inserted snippets would have a very different coding style, it would look much more similar to dynamically typed languages than typical statically typed languages with a nominal type system (C, Java, C++98 (excluding template metaprogramming), etc.) some people find such code much easier to read and write and others find it hard to decipher. people have different coding mindsets, I personally think in structural typing and find type declarations useless, but lots of people rely on nominal typing and find code without type declarations hard to understand. jackoneill might also reject my code because he/she thinks the code is hard to maintain.
and I don't wanna create yet another mvtools branch if jackoneill decides not to merge my code.
Pat357
17th May 2020, 20:34
R22 was the first official build with AVX2 optimizations. The thing looks like a compiler issue, the libraries built with MSVC are faster.
https://github.com/dubhater/vapoursynth-mvtools/issues/47
Is there a MSVC compiled version for the new R23 available somewhere ?
I not smart enough to do it myself without a ready available .sln and other settings...
ChaosKing
18th May 2020, 08:11
Thx HolyWu
Tested with SMDegrain and the clang version is the fastest, up to 3fps faster compared to R23. MSVC is the slowest, even slower then R23. ICL is a tiny bit slower then clang.
Tested with Ryzen 2600 on 1080p source.
Ranking
clang
icl
R23 release
msvc
tormento
18th May 2020, 11:50
I am losing a bit the thread. Has been MDegrain up to 6 and N implemented or not?
feisty2
18th May 2020, 11:55
no, judging from jackoneill's lack of response, I don't think he/she will merge C++20 code, and I don't wanna create another mvtools branch.
your best shot is with the floating point branch if you do need arbitrary radius MDegrain and cosine annealing
tormento
18th May 2020, 12:48
no, judging from jackoneill's lack of response, I don't think he/she will merge C++20 code, and I don't wanna create another mvtools branch.
your best shot is with the floating point branch if you do need arbitrary radius MDegrain and cosine annealing
Too slow. I will keep on using AVS+. What a pity.
feisty2
19th August 2020, 07:33
is this a typo? https://github.com/dubhater/vapoursynth-mvtools/blob/master/src/MVFlowBlur.c#L392
shouldn't it be d.blur * 256. / 100?
jackoneill
19th August 2020, 12:56
is this a typo? https://github.com/dubhater/vapoursynth-mvtools/blob/master/src/MVFlowBlur.c#L392
shouldn't it be d.blur * 256. / 100?
It looks deliberate. It's 200 again just a few lines above.
ChaosKing
2nd January 2023, 11:34
Happy new year
https://github.com/dubhater/vapoursynth-mvtools/commit/b5d58cb7ca1cfe27bdcb30fbcff67254580b7ab9
Adub
5th January 2023, 22:15
Haha you’re welcome. ;)
Thanks for posting this, I’d neglected to. A few more cleanups have been made since then as well. May minorly increase speed, but only minorly.
I’m still working on more updates in my free time. I’m working on AVX2 degrain cleanups and then hopefully incorporating more x264 code for higher bit depths, but we’ll see about that.
Longer term id like to add some basic DegrainN support (but limit it to radius 6 for now), add high bit depth degrain AVX and SSE2 code, support block size 24 (with a simple C implementation for now), and add high bit depth support to Mask. I say all that, but it’s not all trivial amounts of work, and I’m doing this in my random free time, so we’ll see how it goes.
amayra
22nd June 2024, 21:13
is this abandoned project?
avs version still under development unlike vapoursynth plug-in
I wouldn't say it's abandoned. The author accepts pull requests, so we can still work as a community to improve it.
I have one or two changes I've been meaning to create PR's for, I just haven't gotten time to do it yet.
So not abandoned, but in maintenance mode for now.
Adub
6th August 2024, 17:15
We've just released Version 24 of MVTools: https://github.com/dubhater/vapoursynth-mvtools/releases/tag/v24
This is the last version that support Vapoursynth API version 3. We've already done the work to port to API version 4, which will be released in Version 25 here shortly.
Please enjoy this not abandoned project. :sly:
Myrsloik
11th May 2026, 14:52
An update. There is now API4 support and mvtools can be installed from pypi. If you have v25 or v26 YOU REALLY SHOULD UPDATE TO v27 TO AVOID MMEORY LEAKS.
Selur asks for porting DX12 motion estimation to VS MAnalyse. Can any VS programmer helps ?
The AVS+ version is there - https://github.com/DTL2020/mvtools/blob/9eedb9d0850f638fc43212fb515cf048f9b9a58f/Sources/MVAnalyse.h#L34 (look for DX12_ME define and #ifdef blocks in .h and .cpp files). This feature is completely excludable for non-DX12 builds to be possible (not loads d3d12.dll and not require DX12 to be installed).
Myrsloik
21st June 2026, 13:26
I'm currently working on cleaning up and optimizing mvtools and I'm curious about which pel values you actually use so I can spend more time optimizing them. For example I suspect few people ever use pel=1.
Does anyone ever use pel=1?
Do you all leave it at the default pel=2?
Is the only option you'd ever consider pel=4?
Selur
21st June 2026, 14:37
Does anyone ever use pel=1?
=> yes
QTGMCs presets ("Draft", "Ultra Fast", "Super Fast", "Very Fast", "Faster", "Fast", "Medium") use pel=1.
So, I suspect quite a few people use pel=1.
Adub
21st June 2026, 15:48
It’s common enough to use pel 1 with 4k content. I believe some versions of SMDegrain are tuned to use pel 4 for SD content, pel 2 for HD, and pel 1 for UHD.
Selur
21st June 2026, 16:07
@myrsloik: mvtools v29 is not available via pip atm.
Myrsloik
21st June 2026, 16:43
@myrsloik: mvtools v29 is not available via pip atm.
Fixed
Selur
21st June 2026, 18:01
Thanks :) (works now)
spend more time optimizing them. For example I suspect few people ever use pel=1.
Pel=1 is the only supported format by intel SIMD with more SAD computing instructions like mpsadbw in SSE and AVX2 and vdbpsadbw in AVX512. The original mvtools super clip sub-parts placement in memory for pel 2 and 4 are not compatible with these instructions. So the only workaround is to feed x2 or x4 upsampled clip as super clip and call MAnalyse with pel=1 (and use SIMD acceleration for SAD computing in the best way) and call MScaleVect to downscale MVs from pel 1 to 2 or 4.
See example of usage of mpsadbw for search=3 (isotropic exhaustive) with AVX2 of blocksize 8x8 and search radius 2 and pel 1-https://github.com/DTL2020/mvtools/blob/9eedb9d0850f638fc43212fb515cf048f9b9a58f/Sources/PlaneOfBlocks_avx2.cpp#L554
Also mvtools pel 2 and 4 data storage format is not friendly with the memory subsystem of current computer architectures - for full-pel search radius
pel 2 requires fetching from 4 different memory areas for ref area
pel 4 requires fetching from 16 different memory areas for ref area.
With pel=1 all columns of ref area are contiguous in memory and a single memory request to the start column takes 1 full cacheline with full ref area for search in many cases (or 2 cachelines in rare cases of large search radius). With pel 2 Esa search needs 2 cachelines minimum and interleaved usage for each ref row and with pel 4 Esa search needs 4 cache lines or more for each row of ref area.
This causes more CPU caches load (also by auto hardware prefetchers) and more SDRAM pages switching (also more virtual pages translations). Even with a single mvtools binary, RAW tests show MAnalyse(super_pel=1)+MScaleVect(for pel 2) is visibly faster in comparison with MAnalyse(super_pel=2). Though in complex scripts (like QTGMC) it may not be true.
Myrsloik
8th July 2026, 21:38
I spent many hours cleaning up MVTools and it has resulted in the vastly superior MVUtensils (https://forum.doom9.org/showthread.php?p=2032851#post2032851). It's an almost drop-in replacement.
As of this I'm also announcing that vapoursynth-mvtools is put on life support. If it crashinates it will be fixed but don't expect anything else.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.