vbc s教程合集vcb07avi基礎與入門_第1頁
vbc s教程合集vcb07avi基礎與入門_第2頁
vbc s教程合集vcb07avi基礎與入門_第3頁
vbc s教程合集vcb07avi基礎與入門_第4頁
vbc s教程合集vcb07avi基礎與入門_第5頁
已閱讀5頁,還剩9頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、VCB-Studio07: AviSynth 基礎與入門0. 前言這篇需要6:VS 基礎與入門作為前置盡管avs 早于 vs 存在了十幾年,上手寫一個 hello world 級別的也比 vs 容易,但是 avs的參數傳遞機制,使得想深入學習 avs 的使用,比 vs 其實來的。本假定你通過 vs,已經對變量、參數傳遞等有了最基本的認識,這樣,當我們討論avs 特有的一些機制的時候,不至于從零開始。AviSynth 主頁和文檔:AviSynth+主頁和文檔: 詞典:avs 目前最新版是avs 2.6.0,只有 32bit;avs+是avs 的一個改良mod,優勢在于,有64bit 版本。盡管以

2、 vcb-s 對于avs+的使用,全局 64bit 化是可行的,但是因為懶,所以直到轉 vs 之前,vcb-s 一直使用 32bit版本的 avs。如果你希望使用 64bit 的avs,建議使用avs+。有 vs 的存在,avs 的意義不是很大,至少作為高質量、復雜處理的壓制,vs 優秀的內存管理機制、原生的多線程優化,和各種新科技濾鏡,讓它對比 avs 已然優勢明顯。但是 vcb-s 系列依舊講述 avs,因為很多以前的和是基于avs 的,我們需要保證大家能理解并繼承上個的智慧結晶。1. 簡單的 avs以下是一個簡單的,以 YUV420P16 的格式讀入一個 mkv,并轉為 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 原生不支持多線程,但是支持設置最大使用內存。這里我們用 setMemoryMax()來設置最大使用 1000MB。除了系統設置(比如 setMemoryMax),avs 的主要內容一般由兩種語句:賦值句和輸出句。賦值句

4、的含義和 vs 的賦值句大致相同,表現為 變量=表的結構。比如 a = "00000.mkv"就是一個賦值句。avs 的函數不再有各種域,只要載入了,直接就可以用。avs 的函數一般來自兩種地方,第一種是濾鏡原生 dll,第二種是寫好的庫,后綴名為 avsi。這兩個種文件一般放在 avs 根目錄的 plugins 文件夾內,這樣 avs 就可以自動載入。輸出句,表現為直接將表作,比如:LWLibavSource(a,format="yuv420p16",stacked=true)dither_convert_yuv_to_rgb(chromak=&quo

5、t;lanczos",taps=4,noring=true,lsb_in=true)這兩句就是兩個輸出句。avs 中,隨時隨地維護一個叫做 last 的 clip,這個 clip 要么為空值,要么出的結果:上一個輸出類型為 clip 的輸出句,輸SetMemoryMax(1000) <- 這句是系統設置,不產生 lasta = "00000.mkv" <- 這句是賦值句,不產生 lastLWLibavSource(a,format="yuv420p16",stacked=true) <- 這句結束后,last 為 lwlvs

6、載入的 YUVdither_convert_yuv_to_rgb(chromak="lanczos",taps=4,noring=true,lsb_in=true) <- 這句結束后,last 為dither_convert_yuv_to_rgb 轉為的 RGB24雖然語法上,avs的輸出句。輸出句輸出非 clip 的類型,但是 last 并去。一般而言,也沒有必要寫出非 clip 輸出avs 結束的時候,輸出最后一個輸出句的結果,相當于輸出 last。如果 last 為空(全程沒有一個 clip 類型的輸出句),返回效果是 Not a Clip 的報錯信息。2. A

7、VS 函數的調用和參數傳遞無論是賦值句,還是輸出句,avs 進行運算主要也是通過函數進行的。函數的調用,以及參數的傳遞,跟 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 = "")其規則跟VapourSynth 也幾乎一致:除了 source,其他的可以缺省。默認值,source 在調用時候必須給定,其他的則有些時候,比如 CSMod16 的avsi 里,function header 是這么寫的:CSmod16(clip filtered, clip "source", clip "pclip", bool "lsb_in&qu

9、ot;, bool "lsb", int "dither"規則是:沒有被引號括起來的都是必須輸入的(上文中僅 filtered 一個),用引號括起來的是可以缺省的(上文中剩下所有)avs 的參數傳遞一般有 4 種:1. 賦值性傳遞/關鍵字傳遞(keyword argument), 在 avs 的 doc 里面被稱為 named arguments。這點跟 vs 相似;2. 直接傳遞/位置性傳遞(positional argument),在 avs 的 doc 中被稱為argument list。這點也跟 vs 很相似;所以 LWLibavSource(a

10、,format="yuv420p16",stacked=true),a 是直接傳遞,format="yuv420p16"和stacked=true 則是賦值性傳遞。3. 串聯式傳遞,在avs 中被稱為 OOP Notation,跟 vs 的串聯性傳遞相似,都是讓前一個運算結果作為后一個函數的第一位輸入,比如:AVISource("fraps.avi").dither_convert_rgb_to_yuv()。 串聯式的傳遞在 vs 中不普遍(主要是這玩意最近才加入),avs 中卻是普遍使用的,因為從 avs 最初設計這種方式就存在。4

11、. last 傳遞,是指當函數第一位輸入是一個 clip,且第一位輸入沒有被關鍵字傳遞或串聯傳遞,且總輸入的參數不足以填滿所有必須輸入,且 last 不為空,那么系統將 last 作為函數的第一位輸入。這是 avs 特有的一種傳遞方式。舉個例子:第 4 點是新手最容易弄混的地方。我們來拆開強調一次:(1). 第一位輸入是一個 clip 類型輸入,其實這個絕大多數 avs 濾鏡都符合條件(除了源濾鏡一般第一個輸入是字符串), 一般你看doc 都是mt_edge (clip, string "mode", int "thY1") 這種上來一個第一個是 cli

12、p。注意這里 clip 指定的時候是沒有變量名稱的,這意味著沒有辦法進行賦值性傳遞。而之前CSMod16 上來是: CSmod16(clip filtered, clip "source", clip "pclip",) 這時候你就可以用CSMod16(filtered=dbed) 類似方式進行賦值性傳遞。(2). 沒有被關鍵字或者串聯傳遞。比如我們看下面這個例子: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 的找到):可見這個濾鏡上來強制輸入一個 clip src。(有變量名 src,意味著可以進行src=這樣的賦值性傳遞。) 而看上文,我們只是通過賦值性傳遞,指定了幾個可選性的參數,src 這個 input 沒有被賦值性傳遞載入,也沒有被串聯輸入。(3). 總輸入的參數不足以填滿所有必須輸入。我們輸入的必須參數是 0 個,而濾鏡要求的必須參數是 1 個。(4).

14、 last 不為空。在執行dither_convert_rgb_to_yuv 之前,last 的確不為空,著 lwlvs 輸出的結果。(1)+(2)+(3)+(4)同時滿足,系統就會把 last 傳遞給函數,作為函數第一個強制性輸入的參數。last 以及 last 傳遞的引入,本質上是為了簡化 avs 的語法和書寫的。一般你看到入門級別的 avs 全是輸出性語句,沒有任何賦值性語句,其實就是不斷地更新 last 并作為下一個函數的輸入:AVISource("fraps.avi") #讀入fraps 錄制的avi,RGB 格式dither_convert_rgb_to_yuv

15、() #轉為 YUV 格式,準備壓制用 vs 寫你一般得這么寫(無視最近串聯式寫法,輸出句改賦值句,最后手動指定輸入。):src = core.avisource.AVISource("fraps.avi")res = mvf.ToRGB(src) res.set_output()但是avs,同樣類型的寫法可以玩出花,以下所有段落,都屬于常見寫法,效果都是一樣的:AVISource("fraps.avi").dither_convert_rgb_to_yuv() #用串聯傳遞dither_convert_rgb_to_yuv(AVISource(&quo

16、t;fraps.avi") #用直接傳遞AVISource("fraps.avi")dither_convert_rgb_to_yuv(last) #用直接傳遞,注意last 可以作為一個表參與直接傳遞AVISource("fraps.avi")dither_convert_rgb_to_yuv(src=last) #同理,last 可以作為表進行賦值傳遞AVISource("fraps.avi")last.dither_convert_rgb_to_yuv() #同理,last 還可以用于串聯傳遞src=AVISource

17、("fraps.avi")src.dither_convert_rgb_to_yuv() #串聯傳遞src=AVISource("fraps.avi")dither_convert_rgb_to_yuv(src=src) #賦值傳遞, vs中我們也見過,前一個 src 是變量,后一個是表。src=AVISource("fraps.avi")dither_convert_rgb_to_yuv(src) #直接傳遞,這里src 就作為一個表。但是以下所有紅字寫法都是不可行的(黑字是改正版本):src=AVISource("fra

18、ps.avi")dither_convert_rgb_to_yuv()錯的是,第一句是賦值句,觸發avslast,所以到了下一句,沒有 last 可以丟給濾鏡作為輸入。除了上文的改正方法,另一種改正寫法為:src=AVISource("fraps.avi")src #通過這一句做一個輸出語句,avs 將dither_convert_rgb_to_yuv()lastAVISource("fraps.avi")convert=dither_convert_rgb_to_yuv()錯的是,第二句是賦值句,觸發 avslast,最終 last 是AVI

19、Source 輸出的 RGB,而不是轉換后的。除了把第二句換為輸出句,一個簡單的修復是:AVISource("fraps.avi") convert=dither_convert_rgb_to_yuv() convertsrc=AVISource("fraps.avi")convert=src.dither_convert_rgb_to_yuv()同理,整個是個賦值句,觸發 last。現在,我們來看看更復雜的。再來回顧一下CSMod16,看看當年雯姐在帖子里說了哪種教科書式錯法():CSmod16(clip filtered, clip "so

20、urce")無視其他參數,我們知道CSMod16 可以只輸入一個 clip filtered,這種情況下,它對 filtered 做銳化;CSMod16 還可以輸入兩個 clip,一個是 filtered,一個是 source,這種情況下,它以 source 做對比,對 filtered進行補償性銳化。(銳化和補償性銳化在中有說,簡單總結:銳化,就是把圖像往銳利方向去調,往往造成畫風突變;而補償性銳化,則是對源進行降噪等處理后,拿處理后的東西進行銳化,而銳利度比源高,以此試圖補償降噪等處理造成的,而非意在改變畫風)假設用 dfttest 降噪,然后再用CSmod16 做補償性銳化:L

21、WLibavsource = lastSource("00001.m2ts",threads=1)denoised = source.dfttest()denoised.CSmod16(source)最后一句,使用了串聯式傳遞,所以第一個 clip 類型強制性輸入的 input(filtered)會被設置為 denoised,而這時候我們還輸入了一個source,這個 source 將會被傳遞給剩下 input 中第一個,也就是 clip "source".典型的錯誤寫法如下:LWLibavsource = last dfttest()Source(&q

22、uot;00001.m2ts",threads=1)CSmod16(source)為什么這是錯的?因為CSMod16 只需要一個強制性輸入,這時候,我們已經指定了 source,這個 source 會被賦值給filtered,然后,avs 認為所有 input 傳遞完畢,并無缺少,所以這樣的效果就是 CSMod16 只輸入了一個 clip,對源執行銳化。下文的寫法是完全正確的:LWLibavsource = last dfttest()Source("00001.m2ts",threads=1)last.CSmod16(source)這時候,通過串聯賦值,filt

23、ered 會被賦值為 last(注意,dfttest()執行后,last 會被更新),然后多輸入的source會被傳遞給 clip "source"。CSMod16 收到了兩個 input。同理,最后一句還可以改為 CSMod16(last, source), 一樣可以正確工作。總結一下,avs 的參數傳遞機制如下:1. 如果是串聯性賦值句,把上游輸出的 clip 作為濾鏡第一個強制性的 clip 輸入;2. 執行所有賦值性傳遞,如果有重復(包括:串聯性傳遞第一個 input 的同時,賦值性傳遞第一個 input,比如denoised.CSMod16(filtered=la

24、st), 等于說filtered 同時被指定為 denoised 和 last),報錯;3. 清點所有剩下的直接傳遞,如果不足以滿足所有的強制輸入,且函數非串聯,且第一個 input 沒有被賦值性傳遞, 且 last 存在,那么把 last 設置為第一個 input4. 把所有剩下的直接傳遞,按照順序,賦值給剩下的 input。5. 如果有任何類型不匹配,或者強制輸入的數量還是不夠,報錯。3. 一些簡單的編輯在本章中,我們講述一些avs 中常見的用法,方便大家學習和上手3.1 裁剪和縮放裁剪靠的是 Crop, 縮放靠的是 Spline36Resizedoc 分別為:假設我們讀入一個原生 4:3

25、,通過加黑邊做成 1920x1080 的個像素),然后縮放成 720p:,我們先把它切割成 1440x1080(就是左右各 240src = Crop(src, 240, 0, -240, 0)/*注意這里 crop 的用法和 vs 是不同的:如果right 和 bottem>0,那么指定的是成品寬和高; 如果right 和 bottem<=0,那么指定的是切割的像素。vs 里面,CropRel 永遠是切割的像素,且要求>=0。最后說一下,你看到的這個跟C+一般的,就是avs 里大范圍注釋的方法。所以這到這里avs*/還沒完呢,下面還有個縮放到 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 就沒有語法糖了。合并的用法就有點特殊了。首先,avs 里面,要想合并,必須要求參數一致(這點跟 vs 不同),然后 avs 是支持音頻的,合并分音頻同步合并(AlignedSplice)和不同步合并(UnalignedSplice),區別 do

27、c 里有寫,同步合并會把第一個的音頻通過切割或者加靜音,來保證第二個接上后,音軌是吻合的。同步合并,可以通過+來實現;非同步可以用+。當你的 avs 沒有載入音軌/不需要在意音軌,這倆方式沒有區別。v1=AVISource("fraps1.avi")v2=AVISource("fraps2.avi") v1+v2Dither_convert_RGB_to_YUV() # avs 是不分大小寫的3.3 簡單的降噪,去色帶和加字幕降噪用的是 RemoveGrain(), 去色帶用的是 f3kdb(), 加字幕用的是 TextSub()一樣,去找找 doc。有

28、的時候 doc 會附帶在濾鏡的包里。src = RemoveGrain(src, 11, 4) #注意這里不再跟 vs 一樣用11,4 的數組寫法f3kdb(12,32,24,24,0,0)TextSub(".ass")4. AVS 里面對性質(clip property)的同 vs,avs 里面可以直接一些關于和幀本身的性質,比如說的總長度,幀率,一幀的長寬,類型等。這部分在中有詳細解釋,我們只列舉最常用的幾個:clip. FrameCount 返回 clip 的總幀數。所以要切掉src = Trim(src, 1, src.FrameCount-1)的首幀(第 0 幀)

29、,可以這么寫:注意,這里的FrameCount 其實是一個函數:int FrameCount(clip)之所以可以寫成 last.FrameCount 這樣的形式,是因為:1. 這實際上是串聯傳遞,將 last 傳遞給 clip 作為輸入;2. 如果不需要再寫任何參數,avs 可以將函數括號省略。所以你完全可以寫成函數的形式:src = Trim(src, 1, FrameCount(src)-1)clip.width, clip.height 返回 clip 的寬和高。比如我們想縮放 last 到 1/2 大小:Spline36Resize(width/2, height/2)這個寫法,用

30、last 用到了的地步。首先 width() 和 height() 這兩個函數,沒有任何輸入(所以連括號都省了),那么系統把 last 拉來做輸入;然后,spline36resize 缺輸入,系統再把 last 拉過來。等效于:last.Spline36Resize(width(last)/2, height(last)/2)avs 里面除法是/,如果參與運算的都是整數,那做整數除法,比如 1080/23=46。如果參與運算的有浮點,那做浮點數除法,比如 1080/23.0=46.9565 你可以用 Int() Float()這些函數做強制類型轉換。比如說我們要把一個長寬縮小到 2/3,并且保證長寬都是 16 的倍數:w = round( width(last)/1.5/16) * 16 #round 是將一個實數四舍五入到最近的整數h = round(height(last)/1.5/16) * 16 Spline36Resize(w, h)假設我們有個 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等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論