头像
Holy
核心会员
核心会员
帖子: 235
注册时间: 2010-09-24 9:28

HAvsFunc-r30

此為我將 AviSynth 函數移植到 VapourSynth 的腳本。
https://github.com/HomeOfVapourSynthEvolution/havsfunc

由於 VapourSynth 內部並無有關場序的 flag,我必須在 QTGMC 增加一個必要參數 'TFF'。設置 TFF 為 true 是指 top field first,為 false 是指 bottom field first。若未指定 TFF 的話則會報錯。SMDegrain 及 ivtc_txt60mc 也是相同參數,如果在 SMDegrain 設了 interlaced=True,必須同時設定 'tff' 參數才行。從 VapourSynth R27 版本開始,幀屬性 _FieldBased 已可用來設定 TFF 或 BFF。濾鏡會優先使用源的幀屬性中指定的 _FieldBased,僅當源的幀屬性中不存在 _FieldBased 時才會使用 'TFF' 參數的值。

另外,Yadif 似乎無法在 VapourSynth 上成功載入,所以我將 QTGMC 裡 "Ultra Fast" preset 的 EdiMode 預設值改為 nnedi3。

使用範例:
首先,將 havsfunc.py 放到 Python\Lib\site-packages 目錄下。

代码: 全选

from vapoursynth import core
import havsfunc as haf

clip = yourclip
clip = haf.QTGMC(clip, Preset='Medium', TFF=True)
上次由 Holy 在 2018-04-04 21:34,总共编辑 55 次。
图片
头像
06_taro
核心会员
核心会员
帖子: 998
注册时间: 2010-09-22 18:32
来自: United Kingdom
联系: 网站

Re: 【置顶】現代版的Avisynth --> Vapoursynth

先感謝移植,其實前幾天自己把AAD、ALMerge、ChromaShift、ContraSharpening、Deblock_QED、Dehalo_Alpha、Derainbow、FastLineDarkenMOD、FineSharp、GradFun2DBmod、HQDering、LSFmod、MinBlur、Soothe、TempGaussMC、TAA、YAHR還有沒放出來過的NRDB、TDB、TDGMC、TDR、TMask之類的都port完了,考慮到以後像TemporalSoften、dither之類的很多濾鏡都會有vs的native版本,以及很可能會引入原生的high bpp yuv420pX的支持,而且vs的API說不定還會修改(之前就已經改過一次造成不少東西需要修改了),暫時不想放出來…

順便提個建議,avs的script改成vs版的時候其實最好不要在濾鏡函數內傳遞core,使用vs時core應該作為一個object,丟給一個class,由__init__函數來統一初始化,之後class內的函數可以像原生dll函數或者avs函數那樣直接使用,像這樣:
[syntax lang="python" filename="teapot.py"]
class tAvsFunc(object):
def __init__(self, core, path='C:\\Media\\VapourSynth\\filters\\', \
avspath='C:\\Media\\AviSynth\\plugins\\'):
self.avs = core.avs
self.std = core.std
if core.list_functions().find('Spline16Resize') == -1:
self.avs.LoadPlugin(path=path+'avisynthfilters.dll')

def ChromaShift(self, clip, x=0., y=0.):
return self.avs.MergeChroma(clip, \
self.avs.Spline16Resize(clip, clip.width, clip.height, x, y, clip.width+x, clip.height+y))[/syntax]

要使用的時候
[syntax lang="python"]import vapoursynth as vs
# ported AviSynth Funcion Class
import teapot
core = vs.Core()
core.avs.LoadPlugin(path=r'C:\Media\AviSynth\plugins\DGAVCDecodeDI.dll')
ret = core.avs.DGSource(dgi=r'E:\IDM_Download\z\VapourSynth\Samples\test.mp4')
tp = teapot.tAvsFunc(core)
ret = tp.ChromaShift(ret, .5, .5)[/syntax]這樣使用方式更符合namespace/module.class.function的格式,一個class內core只傳遞一次,如果一個class內有多個函數,調用起來會很方便(像這樣)。如果有一個函數要調用另一個腳本函數,譬如在SMDegrain裡調用MinBlur,把它們放在同一個class內仍然可以保持簡單的初始化方式,但是以後如果有其他工具也要調用就很方便,不會像現在這樣MinBlur被限定在SMDegrain裡,而沒法被單獨拿出來用,或者需要修改成在MinBlur裡再傳遞一次core。

順便mvtools那些函數使用的clip其實很適合用list或者tuple這些數據結構,譬如(例子來源: Chikuzen's example):
[syntax lang="python"]
class MVTools(object):
def __init__(self, core, path='C:\\AviSynth2\\plugins\\mvtools2.dll'):
self.avs = core.avs
if core.list_functions().find('MSuper') == -1:
self.avs.LoadPlugin(path=path)

def superclip(self, clip, pel=2, chroma=True, sharp=2):
return self.avs.MSuper(c1=clip, chroma=chroma, sharp=sharp)

def analyseclip(self, super, delta, blksize=8, overlap=4):
return [[self.avs.MAnalyse(
c1=super, delta=d, blksize=blksize, isb=b, overlap=overlap)
for b in (True, False)]
for d in range(1, delta + 1)]

def mdegrain1(self, clip, pel=2, chroma=True, sharp=2, blksize=8,
overlap=4, thSAD=400):
super = self.superclip(clip, pel, chroma, sharp)
vec = self.analyseclip(super, 1, blksize, overlap)
return self.avs.MDegrain1(
c1=clip, c2=super, c3=vec[0][0], c4=[0][1], thSAD=thSAD)

def mdegrain2(self, clip, pel=2, chroma=True, sharp=2, blksize=8,
overlap=4, thSAD=400):
super = self.superclip(clip, pel, chroma, sharp)
vec = self.analyseclip(super, 2, blksize, overlap)
return self.avs.MDegrain2(
c1=clip, c2=super, c3=vec[0][0], c4=vec[0][1], c5=vec[1][0],
c6=vec[1][1], thSAD=thSAD)

def mdegrain3(self, clip, pel=2, chroma=True, sharp=2, blksize=8,
overlap=4, thSAD=400):
super = self.superclip(clip, pel, chroma, sharp)
vec = self.analyseclip(super, 3, blksize, overlap)
return self.avs.MDegrain3(
c1=clip, c2=super, c3=vec[0][0], c4=vec[0][1], c5=vec[1][0],
c6=vec[1][1], c7=vec[2][1], c8=vec[2][2], thSAD=thSAD)

def mflowblur(self, clip, pel=2, chroma=True, sharp=2, blksize = 8,
overlap=4, blur=15):
super = self.superclip(clip, pel, chroma, sharp)
vec = self.analyseclip(super, 1, blksize, overlap)
return self.avs.MFlowBlur(
c1=clip, c2=super, c3=vec[0][0], c4=vec[0][1], blur=blur)[/syntax]整個結構的可讀性會高很多,自己維護起來也很簡單不少。

另外有個tip,python裡雖然沒有bool ? expr1 : expr2的運算符,不過True和False本身是等同於1與0的integer的,所以不一定需要寫成if...else...,例如[syntax lang="python"]
if chroma:
Chr = 3
else:
Chr = 1[/syntax]如果比較少的話這樣寫更清晰,但是很多函數初始化時有大量這種語句,實際上等同於[syntax lang="python"]Chr = chroma * 3 or 1[/syntax]
像[syntax lang="python"]if tr > 3:
if3 = True
else:
if3 = False[/syntax]更是直接寫成if3 = tr > 3就行了(其實avs裡if3 = tr > 3 ? True : False就是多餘的,直接if3 = tr > 3就夠了…)

最後,幫助文檔可以作為__doc__部分,例如上面的ChromaShift,寫文檔的話可以直接[syntax lang="python"]class tAvsFunc(object):
'''\
tAvsFunc(core, path, avspath): taro's ported AviSynth filters:
core - VapourSynth Core
path - VapourSynth's filter path
avspath - AviSynth filter path'''
def __init__(self, core, path='C:\\Media\\VapourSynth\\filters\\', \
avspath='C:\\Media\\AviSynth\\plugins\\'):
self.avs = core.avs
self.std = core.std
if core.list_functions().find('Spline16Resize') == -1:
self.avs.LoadPlugin(path=path+'avisynthfilters.dll')

def ChromaShift(self, clip, x=0., y=0.):
'''\
ChromaShift(clip, x, y): Shift chroma with subpixel accuracy, basic function by IanB, made standalone by McCauley
x - horizontal shift, positive values shift the chroma to left, negative values to right
y - vertical shift, positive values shift the chroma upwards, negative values downwards'''
return self.avs.MergeChroma(clip, \
self.avs.Spline16Resize(clip, clip.width, clip.height, x, y, clip.width+x, clip.height+y))[/syntax]這樣可以作為python的幫助文檔用print函數直接輸出,使用一些IDE的話使用腳本時想不起來參數可以很方便地列出來查看,而不需要去打開讀取濾鏡的.py文件
つまんねー事聞くなよ!

I, personally, for me, believe (obviously sometimes) that my OS choice is right. That's me. I'm not telling you that you should believe it. Learn the facts, and the origins behind the facts, and make up your own damn mind. That's why you have one. (source)

Follow me: @06_taro

304——
为纪念伟大的宇宙史上最强压制304先生,联合国教科文组织决定,将每年的第304天,即平年的10月31日或者闰年的10月30日,定为世界304日。
头像
Holy
核心会员
核心会员
帖子: 235
注册时间: 2010-09-24 9:28

Re: 【置顶】現代版的Avisynth --> Vapoursynth

感謝 taro 菊苣賜教,獲益良多~
图片
头像
dgwxx
管理猿
帖子: 771
注册时间: 2010-09-19 20:42
联系: 网站

Re: LSFmod v1.9与SMDegrain v2.1d移植

请允许我单独分出主题来。题目是我擅自起的,Holy觉得不满请更改题目。
日常推 @dgwxx: 基本没什么技术的话题,欢迎没事看看消遣。
► 显示剧情透露 平庸的rip
► 显示剧情透露 “不知道”的五大理由
头像
tnti
帖子: 46
注册时间: 2011-12-06 22:52

Re: Holy's ported AviSynth functions for VapourSynth

你让国内下不到被墙网盘的情何以堪 谁去用网盘分流下
我觉得一般底片都太清晰,生活不是如此的,我不喜欢那种清晰度,我总试着模糊些。
概念都是正确的废话
头像
dgwxx
管理猿
帖子: 771
注册时间: 2010-09-19 20:42
联系: 网站

Re: Holy's ported AviSynth functions for VapourSynth

tnti 写了:你让国内下不到被墙网盘的情何以堪 谁去用网盘分流下
顶楼有附件。
日常推 @dgwxx: 基本没什么技术的话题,欢迎没事看看消遣。
► 显示剧情透露 平庸的rip
► 显示剧情透露 “不知道”的五大理由
头像
Holy
核心会员
核心会员
帖子: 235
注册时间: 2010-09-24 9:28

Re: Holy's ported AviSynth functions for VapourSynth

Updated r2. Worked around memory leak problem in Bob. The memory consumption of QTGMC should be much lesser now.
图片
manofman
帖子: 119
注册时间: 2012-09-01 4:39

Re: Holy's ported AviSynth functions for VapourSynth

測試了r2的QTGMC,memory用量有改進了。但不知道為什麼在vd預覽時,一開始導入文件時,內存依然在800MB左右,它是隨著decode更多的幀數,內存才慢慢降到330MB
头像
Holy
核心会员
核心会员
帖子: 235
注册时间: 2010-09-24 9:28

Re: Holy's ported AviSynth functions for VapourSynth

不只是 VFW 預覽時,送給 x264 壓也是一樣的,壓了一會後內存佔用就降了,不知道為啥。
图片
BBA
帖子: 16
注册时间: 2012-06-21 21:59

Re: HAvsFunc-r4

{:cat_2} 其实我想问个目前VS能做的AA方式...或是taro大把port过的TAA分享出来(死

回到 “VapourSynth”