Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

Reply
 
Thread Tools Search this Thread Display Modes
Old 13th September 2015, 18:09   #1  |  Link
Boulder
Pig on the wing
 
Boulder's Avatar
 
Join Date: Mar 2002
Location: Hollola, Finland
Posts: 4,399
Request for help to convert some Avisynth functions

I'm trying to make the switch from Avisynth 2.6 to Vapoursynth as Avisynth has become very unstable ever since I got an i7. I'm currently trying to get the hang of the syntax and convert the stuff I always use to process videos.

I'm having some difficulties in converting the predenoiser helper functions that I use. Could someone please take a look at them and show some magic? There could be some native alternatives in Vapoursynth that I don't know of so feel free to customize if needed

Code:
function Prefilter (clip c, int "th", bool "chromamotion")
{
chromamotion = default(chromamotion, true)
output = Flux5framesT(c,th=th,chromamotion=chromamotion)
return output
}

function Flux5framesT(clip c, int "th", int "thC", bool "chromamotion")
{
chromamotion = default(chromamotion, true)
th  = default(th, 2)
thC = default(thC, chromamotion ? th : 0)
med = chromamotion ? ytouv(c.utoy8().median5t(), c.vtoy8().median5t(), c.median5t()) : c.median5t().mergechroma(c)
avg = c.temporalsoften(2, th, thC, 24, 2)
output = interleave(c, med, avg).clense(grey=!chromamotion).selectevery(3,1)
return output
}

function median5t(clip src)
{
function min(clip a, clip b) {return mt_logic(a, b, mode="min")}
function max(clip a, clip b) {return mt_logic(a, b, mode="max")}
src
last + trim(framecount()-1,-1).loop(5)
bcmin = min(SelectEvery(2, -1), SelectEvery(2, 0))
bcmax = max(SelectEvery(2, -1), SelectEvery(2, 0))
demin = bcmin.SelectEvery(1, 1)
demax = bcmax.SelectEvery(1, 1)
x = max(bcmin, demin)
y = min(bcmax, demax)
a = SelectEvery(2, -2)
f = SelectEvery(2, 3)
Interleave(a, x, y, f).Clense(grey=true).SelectEvery(4, 1, 2)
trim(0,length=src.framecount())
}
__________________
And if the band you're in starts playing different tunes
I'll see you on the dark side of the Moon...
Boulder is offline   Reply With Quote
Old 13th September 2015, 22:59   #2  |  Link
Are_
Registered User
 
Join Date: Jun 2012
Location: Ibiza, Spain
Posts: 259
I guess it can be greatly improved, because it is a pretty straight conversion without much thinking. And not really tested, I leave that to you. :P

Code:
import vapoursynth as vs


def prefilter(clip, thr=2, chromamotion=True):
    core = vs.get_core()
    return flux5framest(clip, thr=thr, chromamotion=chromamotion)


def flux5framest(clip, thr=2, thrc=None, chromamotion=True):
    core = vs.get_core()

    if chromamotion is True:
        thrc = thr if thrc is None else thrc
    else:
        thrc = 0

    if chromamotion is True:
        y = core.std.ShufflePlanes(clip, planes=0, colorfamily=vs.GRAY)
        u = core.std.ShufflePlanes(clip, planes=1, colorfamily=vs.GRAY)
        v = core.std.ShufflePlanes(clip, planes=2, colorfamily=vs.GRAY)
        med = core.std.ShufflePlanes([median5t(y), median5t(u), median5t(v)], planes=[0, 0, 0], colorfamily=vs.YUV)
    else:
        y = core.std.ShufflePlanes(clip, planes=0, colorfamily=vs.GRAY)
        med = core.std.ShufflePlanes([median5t(y), clip, clip], planes=[0, 1, 2], colorfamily=vs.YUV)

    avg = core.focus.TemporalSoften(clip, radius=2, luma_threshold=thr, chroma_threshold=thrc, scenechange=24, mode=2)
    res = core.std.Interleave([clip, med, avg]).rgvs.Clense(planes=[0, 1, 2] if chromamotion is True else 0).std.SelectEvery(cycle=3, offsets=1)

    return res

def median5t(clip):
    core = vs.get_core()

    def logic_max(c1, c2):
        return core.std.Expr([c1, c2], expr=['x y max'])

    def logic_min(c1, c2):
        return core.std.Expr([c1, c2], expr=['x y min'])

    last = core.std.DuplicateFrames(clip, frames=[clip.num_frames-1] * 5)
    bcmin = logic_min(core.std.DuplicateFrames(last, frames=[0]).std.SelectEvery(cycle=2, offsets=1), core.std.SelectEvery(last, cycle=2, offsets=0))
    bcmax = logic_max(core.std.DuplicateFrames(last, frames=[0]).std.SelectEvery(cycle=2, offsets=1), core.std.SelectEvery(last, cycle=2, offsets=0))
    demin = core.std.DeleteFrames(bcmin, frames=0)
    demax = core.std.DeleteFrames(bcmax, frames=0)
    x = logic_max(bcmin, demin)
    y = logic_min(bcmax, demax)
    a = core.std.DuplicateFrames(last, frames=[0]).std.SelectEvery(cycle=2, offsets=0)
    f = core.std.DeleteFrames(last, frames=0).std.SelectEvery(cycle=2, offsets=1)
    last = core.std.Interleave([a, x, y, f]).rgvs.Clense(planes=0).std.SelectEvery(cycle=4, offsets=[1, 2])
    return core.std.Trim(last, length=clip.num_frames)

Last edited by Are_; 14th September 2015 at 13:51. Reason: Fixed some stupid mistake
Are_ is offline   Reply With Quote
Old 14th September 2015, 03:53   #3  |  Link
Boulder
Pig on the wing
 
Boulder's Avatar
 
Join Date: Mar 2002
Location: Hollola, Finland
Posts: 4,399
Thanks a lot, looks like you deciphered the negative offset in SelectEvery I'll try to test it today so that I can continue building the rest of the denoising process..
__________________
And if the band you're in starts playing different tunes
I'll see you on the dark side of the Moon...
Boulder is offline   Reply With Quote
Old 14th September 2015, 16:23   #4  |  Link
Boulder
Pig on the wing
 
Boulder's Avatar
 
Join Date: Mar 2002
Location: Hollola, Finland
Posts: 4,399
I did some very quick testing and at least the effects seem the same as with the Avisynth equivalent. Will need to test it a bit more though to make sure

I'm using DGDecodeNV to decode my sources. I found out that the Vapoursynth prefilter function has an issue with some sources. The source filter reports some videos as "FPS: 120000/5005" and some as 24000/1001. Naturally, both return the same result but Interleave chokes with the first case with "vapoursynth.Error: Interleave: clip property mismatch". Using AssumeFPS helps there.
__________________
And if the band you're in starts playing different tunes
I'll see you on the dark side of the Moon...
Boulder is offline   Reply With Quote
Old 26th September 2015, 04:58   #5  |  Link
hydra3333
Registered User
 
Join Date: Oct 2009
Location: crow-land
Posts: 497
Quote:
Originally Posted by Boulder View Post
I'm using DGDecodeNV to decode my sources.
So do I. And the vanilla dgdecode.

Thanks for the examples above, that helps.

I'm not quite sure of the end-user advantages vapoursynth brings though.

As a non-python person, I am still considering trying out vapoursynth but have a few silly beginner queries since do not know where to start.

Is there a step by step beginners thread somewhere ?

Is there a portable non-installer version ?

Is there a consolidated sample script collection somewhere ? eg using qtgmc, mvtools, debglock_qed, lsfmod, mdegrain 1/2/3 (and their interlaced equivalent), re-interlacing pal progressive->TFF, fft3dfilter, interframe, and whatnot.

With the example functions above there are lots of core = vs.get_core()" ... is that because it's in a function (?terminology?) and only one is necessary for the main body ?

Any links or advice would be most welcome.
hydra3333 is offline   Reply With Quote
Old 26th September 2015, 11:26   #6  |  Link
Are_
Registered User
 
Join Date: Jun 2012
Location: Ibiza, Spain
Posts: 259
Quote:
Originally Posted by hydra3333 View Post
I'm not quite sure of the end-user advantages vapoursynth brings though.
Multi-threading, 64bit, active development.
Quote:
As a non-python person, I am still considering trying out vapoursynth but have a few silly beginner queries since do not know where to start.

Is there a step by step beginners thread somewhere ?
Not really, maybe the main docs from vapoursynth?
Quote:
Is there a portable non-installer version ?
No, there are no portable versions of python, so there can't be one for vapoursynth (as far as I know).
Quote:
Is there a consolidated sample script collection somewhere ? eg using qtgmc, mvtools, debglock_qed, lsfmod, mdegrain 1/2/3 (and their interlaced equivalent), re-interlacing pal progressive->TFF, fft3dfilter, interframe, and whatnot.
I don't quite follow what are you trying to say there, havsfunc? Plugin/function list form the main docs?
Quote:
With the example functions above there are lots of core = vs.get_core()" ... is that because it's in a function (?terminology?) and only one is necessary for the main body ?
This is because that's not a vapoursynth script itself, but a loadable module to load that specific functions, so that's specific to modules. Every module has to load the core inside every function it has to prevent bad stuff from happening.
For a main script it only needs it at the top of it, even in a main script there were to be many functions non of them will need to create a core instance inside of them.


Quote:
Any links or advice would be most welcome.
Main vapoursynth docs are very good. :P
Are_ is offline   Reply With Quote
Old 26th September 2015, 15:34   #7  |  Link
hydra3333
Registered User
 
Join Date: Oct 2009
Location: crow-land
Posts: 497
Thank you.
Quote:
Originally Posted by Are_ View Post
I don't quite follow what are you trying to say there, havsfunc? Plugin/function list form the main docs
I have had a look at those pages and will give it a try.

I was looking for a set of example scripts with each of those functions being called with various settings. I gather sometimes there's overlap in parameter naming with ?reserved words? and you need to pass the parameter name with a preceding underscore ?

Not being sure of anything, the syntax mostly, I was looking for some smarter-than-me's actual working scripts to pinch and recycle for my own purposes. Particularly around qtgmc at fast, medium , and high settings similar to
Code:
QTGMC(Preset="Fast",EdiThreads=8,Sharpness=1.2,SLMode=1) 
QTGMC(Preset="Slow",EdiThreads=8,Sharpness=1.2,SLMode=1)
QTGMC(Preset="Very Slow",EdiThreads=8,Sharpness=1.2,SLMode=2,EZKeepGrain=1.2,NoiseProcess=2)
I did find what looks to be a portable python in https://www.python.org/downloads/windows/ , but it appears as if vapoursynth only comes an an installer.

Can vapoursynth be installed and run alongside avisynth without them interfering with each other ?
hydra3333 is offline   Reply With Quote
Old 26th September 2015, 15:51   #8  |  Link
Mystery Keeper
Beyond Kawaii
 
Mystery Keeper's Avatar
 
Join Date: Feb 2008
Location: Russia
Posts: 684
VapourSynth consists of two parts:
1) The core and the API it exposes. It can be used by any application and is unaware of any scripting at all.
2) vsscript - a Python module which is installed into Python distribution and is loaded BY Python when the script is evaluated.
So, VapourSynth installer needs to know where Python is installed. And vsscript needs to know where the core is installed. Thus, no portable version.
__________________
...desu!
Mystery Keeper is offline   Reply With Quote
Old 26th September 2015, 15:58   #9  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Ikea Chair
Posts: 1,852
I think it's theoretically possible to make a portable version but I'm too lazy to identify all the problems. Loading a pile of dlls that can be located anywhere is very annoying though. I do however plan on supporting per user installs some day though. That's usually good enough.
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 27th September 2015, 02:22   #10  |  Link
Mystery Keeper
Beyond Kawaii
 
Mystery Keeper's Avatar
 
Join Date: Feb 2008
Location: Russia
Posts: 684
In my opinion, the best solution would be a small and portable scripting library that doesn't depend on anything else.
__________________
...desu!
Mystery Keeper is offline   Reply With Quote
Old 27th September 2015, 11:41   #11  |  Link
Are_
Registered User
 
Join Date: Jun 2012
Location: Ibiza, Spain
Posts: 259
@hydra3333

At your questions on how a basic vapoursynth script should look:

Code:
import vapoursynth as vs
# This above is mandatory in every file, it loads vapoursynth in python.

import havsfunc as haf
import finesharp
# These are optional imports, you can import it directly or make an alias like we did with vapoursynth

core = vs.get_core()
# This is mandatory too

def a_random_function(clip, cool_setting=0):
    clip = core.do.something(clip, a_setting=cool_setting)
    return clip
# This is how you define your functions, no need to create another core because it is already created outside of it.

clip = core.lsmas.LWLibavSource(r'/path/to/my/video.m2ts')
# In avisynth wen we don't define were the output of a plug-in goes, it automatically goes to a hidden variable "last", not in vapoursynth.
# Here we need to explicitly send it somewhere, "clip" in this example.

clip = haf.QTGMC(clip, Preset="Very Slow", Sharpness=1.2, SLMode=2, EZKeepGrain=1.2, NoiseProcess=2)
# No EdiThreads because vapoursynth manages all of this internally.

clip = finesharp.sharpen(clip)
clip = a_random_function(clip, 2)

clip.set_output()
# This is also needed, without it the script will not return a video

Last edited by Are_; 27th September 2015 at 13:02.
Are_ is offline   Reply With Quote
Old 27th September 2015, 14:56   #12  |  Link
hydra3333
Registered User
 
Join Date: Oct 2009
Location: crow-land
Posts: 497
Thank you for your response, it's a good start for me.
hydra3333 is offline   Reply With Quote
Old 28th September 2015, 05:19   #13  |  Link
hydra3333
Registered User
 
Join Date: Oct 2009
Location: crow-land
Posts: 497
Just a link-to for posterity

"Check if porting is proper" http://forum.doom9.org/showthread.php?t=172673
hydra3333 is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 21:00.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.