




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、VCB-Studio07: AviSynth 基礎(chǔ)與入門0. 前言這篇需要6:VS 基礎(chǔ)與入門作為前置盡管avs 早于 vs 存在了十幾年,上手寫一個(gè) hello world 級(jí)別的也比 vs 容易,但是 avs的參數(shù)傳遞機(jī)制,使得想深入學(xué)習(xí) avs 的使用,比 vs 其實(shí)來的。本假定你通過 vs,已經(jīng)對(duì)變量、參數(shù)傳遞等有了最基本的認(rèn)識(shí),這樣,當(dāng)我們討論avs 特有的一些機(jī)制的時(shí)候,不至于從零開始。AviSynth 主頁和文檔:AviSynth+主頁和文檔: 詞典:avs 目前最新版是avs 2.6.0,只有 32bit;avs+是avs 的一個(gè)改良mod,優(yōu)勢(shì)在于,有64bit 版本。盡管以
2、 vcb-s 對(duì)于avs+的使用,全局 64bit 化是可行的,但是因?yàn)閼?,所以直到轉(zhuǎn) vs 之前,vcb-s 一直使用 32bit版本的 avs。如果你希望使用 64bit 的avs,建議使用avs+。有 vs 的存在,avs 的意義不是很大,至少作為高質(zhì)量、復(fù)雜處理的壓制,vs 優(yōu)秀的內(nèi)存管理機(jī)制、原生的多線程優(yōu)化,和各種新科技濾鏡,讓它對(duì)比 avs 已然優(yōu)勢(shì)明顯。但是 vcb-s 系列依舊講述 avs,因?yàn)楹芏嘁郧暗暮褪腔赼vs 的,我們需要保證大家能理解并繼承上個(gè)的智慧結(jié)晶。1. 簡單的 avs以下是一個(gè)簡單的,以 YUV420P16 的格式讀入一個(gè) mkv,并轉(zhuǎn)為 RGB32 顯示
3、:SetMemoryMax(1000)a = "00000.mkv"LWLibavSource(a,format="yuv420p16",stacked=true)dither_convert_yuv_to_rgb(chromak="lanczos",taps=4,noring=true,lsb_in=true)avs 原生不支持多線程,但是支持設(shè)置最大使用內(nèi)存。這里我們用 setMemoryMax()來設(shè)置最大使用 1000MB。除了系統(tǒng)設(shè)置(比如 setMemoryMax),avs 的主要內(nèi)容一般由兩種語句:賦值句和輸出句。賦值句
4、的含義和 vs 的賦值句大致相同,表現(xiàn)為 變量=表的結(jié)構(gòu)。比如 a = "00000.mkv"就是一個(gè)賦值句。avs 的函數(shù)不再有各種域,只要載入了,直接就可以用。avs 的函數(shù)一般來自兩種地方,第一種是濾鏡原生 dll,第二種是寫好的庫,后綴名為 avsi。這兩個(gè)種文件一般放在 avs 根目錄的 plugins 文件夾內(nèi),這樣 avs 就可以自動(dòng)載入。輸出句,表現(xiàn)為直接將表作,比如:LWLibavSource(a,format="yuv420p16",stacked=true)dither_convert_yuv_to_rgb(chromak=&quo
5、t;lanczos",taps=4,noring=true,lsb_in=true)這兩句就是兩個(gè)輸出句。avs 中,隨時(shí)隨地維護(hù)一個(gè)叫做 last 的 clip,這個(gè) clip 要么為空值,要么出的結(jié)果:上一個(gè)輸出類型為 clip 的輸出句,輸SetMemoryMax(1000) <- 這句是系統(tǒng)設(shè)置,不產(chǎn)生 lasta = "00000.mkv" <- 這句是賦值句,不產(chǎn)生 lastLWLibavSource(a,format="yuv420p16",stacked=true) <- 這句結(jié)束后,last 為 lwlvs
6、載入的 YUVdither_convert_yuv_to_rgb(chromak="lanczos",taps=4,noring=true,lsb_in=true) <- 這句結(jié)束后,last 為dither_convert_yuv_to_rgb 轉(zhuǎn)為的 RGB24雖然語法上,avs的輸出句。輸出句輸出非 clip 的類型,但是 last 并去。一般而言,也沒有必要寫出非 clip 輸出avs 結(jié)束的時(shí)候,輸出最后一個(gè)輸出句的結(jié)果,相當(dāng)于輸出 last。如果 last 為空(全程沒有一個(gè) clip 類型的輸出句),返回效果是 Not a Clip 的報(bào)錯(cuò)信息。2. A
7、VS 函數(shù)的調(diào)用和參數(shù)傳遞無論是賦值句,還是輸出句,avs 進(jìn)行運(yùn)算主要也是通過函數(shù)進(jìn)行的。函數(shù)的調(diào)用,以及參數(shù)的傳遞,跟 vs 有類似性。比如我們看 LWLibavSource 的 doc:LWLibavSource(string source, int stream_index = -1, int threads = 0, bool cache = true, intseek_mode = 0, int seek_threshold = 10, bool dr = false, int fpsnum = 0, int fpsden = 1, bool repeat =false, int
8、dominance = 0, bool stacked = false, string format = "", string decoder = "")其規(guī)則跟VapourSynth 也幾乎一致:除了 source,其他的可以缺省。默認(rèn)值,source 在調(diào)用時(shí)候必須給定,其他的則有些時(shí)候,比如 CSMod16 的avsi 里,function header 是這么寫的:CSmod16(clip filtered, clip "source", clip "pclip", bool "lsb_in&qu
9、ot;, bool "lsb", int "dither"規(guī)則是:沒有被引號(hào)括起來的都是必須輸入的(上文中僅 filtered 一個(gè)),用引號(hào)括起來的是可以缺省的(上文中剩下所有)avs 的參數(shù)傳遞一般有 4 種:1. 賦值性傳遞/關(guān)鍵字傳遞(keyword argument), 在 avs 的 doc 里面被稱為 named arguments。這點(diǎn)跟 vs 相似;2. 直接傳遞/位置性傳遞(positional argument),在 avs 的 doc 中被稱為argument list。這點(diǎn)也跟 vs 很相似;所以 LWLibavSource(a
10、,format="yuv420p16",stacked=true),a 是直接傳遞,format="yuv420p16"和stacked=true 則是賦值性傳遞。3. 串聯(lián)式傳遞,在avs 中被稱為 OOP Notation,跟 vs 的串聯(lián)性傳遞相似,都是讓前一個(gè)運(yùn)算結(jié)果作為后一個(gè)函數(shù)的第一位輸入,比如:AVISource("fraps.avi").dither_convert_rgb_to_yuv()。 串聯(lián)式的傳遞在 vs 中不普遍(主要是這玩意最近才加入),avs 中卻是普遍使用的,因?yàn)閺?avs 最初設(shè)計(jì)這種方式就存在。4
11、. last 傳遞,是指當(dāng)函數(shù)第一位輸入是一個(gè) clip,且第一位輸入沒有被關(guān)鍵字傳遞或串聯(lián)傳遞,且總輸入的參數(shù)不足以填滿所有必須輸入,且 last 不為空,那么系統(tǒng)將 last 作為函數(shù)的第一位輸入。這是 avs 特有的一種傳遞方式。舉個(gè)例子:第 4 點(diǎn)是新手最容易弄混的地方。我們來拆開強(qiáng)調(diào)一次:(1). 第一位輸入是一個(gè) clip 類型輸入,其實(shí)這個(gè)絕大多數(shù) avs 濾鏡都符合條件(除了源濾鏡一般第一個(gè)輸入是字符串), 一般你看doc 都是mt_edge (clip, string "mode", int "thY1") 這種上來一個(gè)第一個(gè)是 cli
12、p。注意這里 clip 指定的時(shí)候是沒有變量名稱的,這意味著沒有辦法進(jìn)行賦值性傳遞。而之前CSMod16 上來是: CSmod16(clip filtered, clip "source", clip "pclip",) 這時(shí)候你就可以用CSMod16(filtered=dbed) 類似方式進(jìn)行賦值性傳遞。(2). 沒有被關(guān)鍵字或者串聯(lián)傳遞。比如我們看下面這個(gè)例子:LWLibavSource("00000.mkv",format="yuv420p16",stacked=true)dither_convert_yuv
13、_to_rgb(chromak="lanczos",taps=4,noring=true,lsb_in=true)dither_convert_yuv_to_rgb()的 doc 如下(可以在dither_tools 的找到):可見這個(gè)濾鏡上來強(qiáng)制輸入一個(gè) clip src。(有變量名 src,意味著可以進(jìn)行src=這樣的賦值性傳遞。) 而看上文,我們只是通過賦值性傳遞,指定了幾個(gè)可選性的參數(shù),src 這個(gè) input 沒有被賦值性傳遞載入,也沒有被串聯(lián)輸入。(3). 總輸入的參數(shù)不足以填滿所有必須輸入。我們輸入的必須參數(shù)是 0 個(gè),而濾鏡要求的必須參數(shù)是 1 個(gè)。(4).
14、 last 不為空。在執(zhí)行dither_convert_rgb_to_yuv 之前,last 的確不為空,著 lwlvs 輸出的結(jié)果。(1)+(2)+(3)+(4)同時(shí)滿足,系統(tǒng)就會(huì)把 last 傳遞給函數(shù),作為函數(shù)第一個(gè)強(qiáng)制性輸入的參數(shù)。last 以及 last 傳遞的引入,本質(zhì)上是為了簡化 avs 的語法和書寫的。一般你看到入門級(jí)別的 avs 全是輸出性語句,沒有任何賦值性語句,其實(shí)就是不斷地更新 last 并作為下一個(gè)函數(shù)的輸入:AVISource("fraps.avi") #讀入fraps 錄制的avi,RGB 格式dither_convert_rgb_to_yuv
15、() #轉(zhuǎn)為 YUV 格式,準(zhǔn)備壓制用 vs 寫你一般得這么寫(無視最近串聯(lián)式寫法,輸出句改賦值句,最后手動(dòng)指定輸入。):src = core.avisource.AVISource("fraps.avi")res = mvf.ToRGB(src) res.set_output()但是avs,同樣類型的寫法可以玩出花,以下所有段落,都屬于常見寫法,效果都是一樣的:AVISource("fraps.avi").dither_convert_rgb_to_yuv() #用串聯(lián)傳遞dither_convert_rgb_to_yuv(AVISource(&quo
16、t;fraps.avi") #用直接傳遞AVISource("fraps.avi")dither_convert_rgb_to_yuv(last) #用直接傳遞,注意last 可以作為一個(gè)表參與直接傳遞AVISource("fraps.avi")dither_convert_rgb_to_yuv(src=last) #同理,last 可以作為表進(jìn)行賦值傳遞AVISource("fraps.avi")last.dither_convert_rgb_to_yuv() #同理,last 還可以用于串聯(lián)傳遞src=AVISource
17、("fraps.avi")src.dither_convert_rgb_to_yuv() #串聯(lián)傳遞src=AVISource("fraps.avi")dither_convert_rgb_to_yuv(src=src) #賦值傳遞, vs中我們也見過,前一個(gè) src 是變量,后一個(gè)是表。src=AVISource("fraps.avi")dither_convert_rgb_to_yuv(src) #直接傳遞,這里src 就作為一個(gè)表。但是以下所有紅字寫法都是不可行的(黑字是改正版本):src=AVISource("fra
18、ps.avi")dither_convert_rgb_to_yuv()錯(cuò)的是,第一句是賦值句,觸發(fā)avslast,所以到了下一句,沒有 last 可以丟給濾鏡作為輸入。除了上文的改正方法,另一種改正寫法為:src=AVISource("fraps.avi")src #通過這一句做一個(gè)輸出語句,avs 將dither_convert_rgb_to_yuv()lastAVISource("fraps.avi")convert=dither_convert_rgb_to_yuv()錯(cuò)的是,第二句是賦值句,觸發(fā) avslast,最終 last 是AVI
19、Source 輸出的 RGB,而不是轉(zhuǎn)換后的。除了把第二句換為輸出句,一個(gè)簡單的修復(fù)是:AVISource("fraps.avi") convert=dither_convert_rgb_to_yuv() convertsrc=AVISource("fraps.avi")convert=src.dither_convert_rgb_to_yuv()同理,整個(gè)是個(gè)賦值句,觸發(fā) last?,F(xiàn)在,我們來看看更復(fù)雜的。再來回顧一下CSMod16,看看當(dāng)年雯姐在帖子里說了哪種教科書式錯(cuò)法():CSmod16(clip filtered, clip "so
20、urce")無視其他參數(shù),我們知道CSMod16 可以只輸入一個(gè) clip filtered,這種情況下,它對(duì) filtered 做銳化;CSMod16 還可以輸入兩個(gè) clip,一個(gè)是 filtered,一個(gè)是 source,這種情況下,它以 source 做對(duì)比,對(duì) filtered進(jìn)行補(bǔ)償性銳化。(銳化和補(bǔ)償性銳化在中有說,簡單總結(jié):銳化,就是把圖像往銳利方向去調(diào),往往造成畫風(fēng)突變;而補(bǔ)償性銳化,則是對(duì)源進(jìn)行降噪等處理后,拿處理后的東西進(jìn)行銳化,而銳利度比源高,以此試圖補(bǔ)償降噪等處理造成的,而非意在改變畫風(fēng))假設(shè)用 dfttest 降噪,然后再用CSmod16 做補(bǔ)償性銳化:L
21、WLibavsource = lastSource("00001.m2ts",threads=1)denoised = source.dfttest()denoised.CSmod16(source)最后一句,使用了串聯(lián)式傳遞,所以第一個(gè) clip 類型強(qiáng)制性輸入的 input(filtered)會(huì)被設(shè)置為 denoised,而這時(shí)候我們還輸入了一個(gè)source,這個(gè) source 將會(huì)被傳遞給剩下 input 中第一個(gè),也就是 clip "source".典型的錯(cuò)誤寫法如下:LWLibavsource = last dfttest()Source(&q
22、uot;00001.m2ts",threads=1)CSmod16(source)為什么這是錯(cuò)的?因?yàn)镃SMod16 只需要一個(gè)強(qiáng)制性輸入,這時(shí)候,我們已經(jīng)指定了 source,這個(gè) source 會(huì)被賦值給filtered,然后,avs 認(rèn)為所有 input 傳遞完畢,并無缺少,所以這樣的效果就是 CSMod16 只輸入了一個(gè) clip,對(duì)源執(zhí)行銳化。下文的寫法是完全正確的:LWLibavsource = last dfttest()Source("00001.m2ts",threads=1)last.CSmod16(source)這時(shí)候,通過串聯(lián)賦值,filt
23、ered 會(huì)被賦值為 last(注意,dfttest()執(zhí)行后,last 會(huì)被更新),然后多輸入的source會(huì)被傳遞給 clip "source"。CSMod16 收到了兩個(gè) input。同理,最后一句還可以改為 CSMod16(last, source), 一樣可以正確工作??偨Y(jié)一下,avs 的參數(shù)傳遞機(jī)制如下:1. 如果是串聯(lián)性賦值句,把上游輸出的 clip 作為濾鏡第一個(gè)強(qiáng)制性的 clip 輸入;2. 執(zhí)行所有賦值性傳遞,如果有重復(fù)(包括:串聯(lián)性傳遞第一個(gè) input 的同時(shí),賦值性傳遞第一個(gè) input,比如denoised.CSMod16(filtered=la
24、st), 等于說filtered 同時(shí)被指定為 denoised 和 last),報(bào)錯(cuò);3. 清點(diǎn)所有剩下的直接傳遞,如果不足以滿足所有的強(qiáng)制輸入,且函數(shù)非串聯(lián),且第一個(gè) input 沒有被賦值性傳遞, 且 last 存在,那么把 last 設(shè)置為第一個(gè) input4. 把所有剩下的直接傳遞,按照順序,賦值給剩下的 input。5. 如果有任何類型不匹配,或者強(qiáng)制輸入的數(shù)量還是不夠,報(bào)錯(cuò)。3. 一些簡單的編輯在本章中,我們講述一些avs 中常見的用法,方便大家學(xué)習(xí)和上手3.1 裁剪和縮放裁剪靠的是 Crop, 縮放靠的是 Spline36Resizedoc 分別為:假設(shè)我們讀入一個(gè)原生 4:3
25、,通過加黑邊做成 1920x1080 的個(gè)像素),然后縮放成 720p:,我們先把它切割成 1440x1080(就是左右各 240src = Crop(src, 240, 0, -240, 0)/*注意這里 crop 的用法和 vs 是不同的:如果right 和 bottem>0,那么指定的是成品寬和高; 如果right 和 bottem<=0,那么指定的是切割的像素。vs 里面,CropRel 永遠(yuǎn)是切割的像素,且要求>=0。最后說一下,你看到的這個(gè)跟C+一般的,就是avs 里大范圍注釋的方法。所以這到這里avs*/還沒完呢,下面還有個(gè)縮放到 720pSpline36Res
26、ize(960,720)3.2 分割與合并分割靠的是 trim (合并靠的是 Slice()Trim 的用法跟 vs 里的基本一致,比如說我們要 Trim 出開頭 100 幀:LSMASHSource(".mp4")Trim(0,100-1)#也可以用 Trim(0,-100),-100 是什么意思看 docavs 里面的 trim 就沒有語法糖了。合并的用法就有點(diǎn)特殊了。首先,avs 里面,要想合并,必須要求參數(shù)一致(這點(diǎn)跟 vs 不同),然后 avs 是支持音頻的,合并分音頻同步合并(AlignedSplice)和不同步合并(UnalignedSplice),區(qū)別 do
27、c 里有寫,同步合并會(huì)把第一個(gè)的音頻通過切割或者加靜音,來保證第二個(gè)接上后,音軌是吻合的。同步合并,可以通過+來實(shí)現(xiàn);非同步可以用+。當(dāng)你的 avs 沒有載入音軌/不需要在意音軌,這倆方式?jīng)]有區(qū)別。v1=AVISource("fraps1.avi")v2=AVISource("fraps2.avi") v1+v2Dither_convert_RGB_to_YUV() # avs 是不分大小寫的3.3 簡單的降噪,去色帶和加字幕降噪用的是 RemoveGrain(), 去色帶用的是 f3kdb(), 加字幕用的是 TextSub()一樣,去找找 doc。有
28、的時(shí)候 doc 會(huì)附帶在濾鏡的包里。src = RemoveGrain(src, 11, 4) #注意這里不再跟 vs 一樣用11,4 的數(shù)組寫法f3kdb(12,32,24,24,0,0)TextSub(".ass")4. AVS 里面對(duì)性質(zhì)(clip property)的同 vs,avs 里面可以直接一些關(guān)于和幀本身的性質(zhì),比如說的總長度,幀率,一幀的長寬,類型等。這部分在中有詳細(xì)解釋,我們只列舉最常用的幾個(gè):clip. FrameCount 返回 clip 的總幀數(shù)。所以要切掉src = Trim(src, 1, src.FrameCount-1)的首幀(第 0 幀)
29、,可以這么寫:注意,這里的FrameCount 其實(shí)是一個(gè)函數(shù):int FrameCount(clip)之所以可以寫成 last.FrameCount 這樣的形式,是因?yàn)椋?. 這實(shí)際上是串聯(lián)傳遞,將 last 傳遞給 clip 作為輸入;2. 如果不需要再寫任何參數(shù),avs 可以將函數(shù)括號(hào)省略。所以你完全可以寫成函數(shù)的形式:src = Trim(src, 1, FrameCount(src)-1)clip.width, clip.height 返回 clip 的寬和高。比如我們想縮放 last 到 1/2 大?。篠pline36Resize(width/2, height/2)這個(gè)寫法,用
30、last 用到了的地步。首先 width() 和 height() 這兩個(gè)函數(shù),沒有任何輸入(所以連括號(hào)都省了),那么系統(tǒng)把 last 拉來做輸入;然后,spline36resize 缺輸入,系統(tǒng)再把 last 拉過來。等效于:last.Spline36Resize(width(last)/2, height(last)/2)avs 里面除法是/,如果參與運(yùn)算的都是整數(shù),那做整數(shù)除法,比如 1080/23=46。如果參與運(yùn)算的有浮點(diǎn),那做浮點(diǎn)數(shù)除法,比如 1080/23.0=46.9565 你可以用 Int() Float()這些函數(shù)做強(qiáng)制類型轉(zhuǎn)換。比如說我們要把一個(gè)長寬縮小到 2/3,并且保證長寬都是 16 的倍數(shù):w = round( width(last)/1.5/16) * 16 #round 是將一個(gè)實(shí)數(shù)四舍五入到最近的整數(shù)h = round(height(last)/1.5/16) * 16 Spline36Resize(w, h)假設(shè)我們有個(gè) 1600x900 的:round(width(last)/1.5/16)*16 = round(1066.666/16)*16 = round(66.66)*16=67*16=1072round(height(las
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二手汽車家具買賣合同
- 餐飲服務(wù)回訪協(xié)議
- 編制合同范本
- 返聘員工職責(zé)與待遇合同
- 餐飲業(yè)訂單管理系統(tǒng)開發(fā)合同
- 物業(yè)管理設(shè)施設(shè)備租賃協(xié)議
- 智能城市停車系統(tǒng)開發(fā)合同
- 農(nóng)業(yè)生產(chǎn)基地農(nóng)資供應(yīng)協(xié)議
- 文化交流活動(dòng)組織協(xié)議
- 酒店住宿管理服務(wù)協(xié)議
- 2025年年中考物理綜合復(fù)習(xí)(壓軸特訓(xùn)100題55大考點(diǎn))(原卷版+解析)
- 2025上海房屋租賃合同模板
- T-SCSTA001-2025《四川省好住房評(píng)價(jià)標(biāo)準(zhǔn)》
- 西紅門鎮(zhèn)生活垃圾轉(zhuǎn)運(yùn)站及環(huán)衛(wèi)停車場(chǎng)工程報(bào)告表
- 2025年信息系統(tǒng)監(jiān)理師考試題(附答案)
- 機(jī)械裝配技術(shù)試題及答案
- GB/T 44971-2024土壤硒含量等級(jí)
- 醫(yī)院檢驗(yàn)科實(shí)驗(yàn)室生物安全程序文件SOP
- 病原學(xué)檢測(cè)陰性肺結(jié)核診斷流程T∕CHATA 008-2020
- 尾礦庫基礎(chǔ)知識(shí)最全PPT資料課件
- dgt801系列數(shù)字式發(fā)電機(jī)變壓器組保護(hù)裝置調(diào)試大綱
評(píng)論
0/150
提交評(píng)論