本文來自OnVideo視頻創作云平臺聯合創始人劉歧在LiveVideoStackCon的講師熱身分享,劉歧分享了FFmpeg的基本原理、使用方法及開發方法。在10月19-20日的LiveVideoStackCon 2018上,劉歧還將分享如何通過FFmpeg實現視頻版權保護的方法。
大家好我是劉歧,目前和幾個朋友一起創辦了視頻云創作平臺OnVideo,主要負責做一些新功能預研和整體方向把控。
今天主要從四個方面來介紹一下FFmpeg的濾鏡深度應用:
1. Filter基本原理
2. Filter使用方法
3. Filter開發基礎
4. Filter開發
一. Filter基本原理
基本原理的理解可以從以下六點出發:
線性屬性:濾鏡是一個線性的屬性,是一步接著一步的往下走的,當然也可以有多線程的,但是多線程的實現不是特別好,一般的實現都是通過單線程來線性處理的。
輸入輸出標簽:濾鏡都有輸入和輸出的標簽。
濾鏡名
濾鏡參數:當我們在使用某一類濾鏡時,需要知道對應的參數大小,如位置,寬高等。
內置變量:在使用濾鏡時,可以用到它的很多內置變量,如幀率,PTS等,這些變量可以在命令行中使用,在調用API時也會用到。
壓縮前、解壓后的YUV/RGB/PCM數據:對數據進行濾鏡處理時使用的都是原始數據,也就是未壓縮的數據。
線性處理圖解
如上圖所示,從濾鏡線性處理圖中可以看出,對每一個的濾鏡處理過程必須要有輸入和輸出,比如在最后濾鏡8的位置沒有輸出1來承接它的結果,則會報錯。另外,如從濾鏡1到濾鏡2的過程,濾鏡1的輸出Out可以作為濾鏡2的輸入In,從濾鏡2再往后,濾鏡2的輸出Out可以分為兩部分,分別作為其它濾鏡處理的輸入。
原始數據處理
濾鏡的處理都是基于原始數據來進行的,比如視頻圖像的每一幀,當然也包括音頻。如上圖所示,每一幀可以有前后的多個層,一般情況下是兩層,當有多層時,如Frame1是三層,則可以先處理前兩層,處理之后合并成一層,再跟另一層一起去做處理。當處理完Frame1后送到編碼器進行編碼,再依次處理Frame2、Frame3、Frame4,處理完后均送到編碼器進行壓縮編碼為另一個格式,比如H.264。
二. Filter使用方法
1. 常用濾鏡
常用的濾鏡中重點的是:scale、trim、overlay、yadif、rotate、movie
比如常用的scale 可以用來做縮放,trim可以做比較精確的幀級的剪切,overlay可以來實現視頻混流,畫中畫或多畫面等疊加處理,rotate來做旋轉,movie可以加載第三方的視頻等等,yadif可以在攝像機上做隔行掃描,在PC端的播放器可以做去交錯。另外,還有delogo、crop、colorkey、chromakey、zoompan; delogo可以用來模糊化某一區域,crop用于圖像區域剪切,colorkey和chromakey是用于摳圖的,chromakey以YUV輸入為主,colorkey以RGB輸入為主,zoompan可以將圖像放大。
2. 命令行
ffmpeg -filters
通過這一命令,可以列出所有的濾鏡,但需要弄清楚每一個濾鏡的作用,比如上圖的adelay,它的作用是音頻轉音頻,延緩一個或更多的音頻通道。在濾鏡參數里面還包括timeline support、slice threading、command support,等在后面也會有介紹。
ffmpeg -h filters=rotate
當某個濾鏡不知道它里面都有什么參數或者參數怎么用時,那么可以通過上面這條help命令去查看濾鏡的內容。比如在上圖,查看旋轉(rotate)濾鏡,可以看出它支持slice threading,而在最下面可以看到還支持timeline操作,并且輸入和輸出都是Video格式,再下面就是rotate的一些參數,值得注意的是,在FFmpeg里面,尤其濾鏡這部分,為了讓大家在輸入參數時候更簡單,它會把很長的參數提供一個簡化的名稱。
命令行的使用開頭都是:filter_complex,然后再在后面接一些字符串,如下:
下面列出幾個例子的命令行使用:
1. 跑馬燈
[0:v][1:v]overlay=x='if(gte(t,0),-w+(mod(n,W+w))+5,NAN)':y=0[out]
應用場景如新聞播放時畫面下方的小欄預告,從右跑到左。
2. 圖像旋轉
[1:v]rotate=a=60*PI/180:ow=180:oh=180[v1];[0:v][v1]overlay=x=-20:y=-20[o]
3.delogo(模糊化某一區域)
delogo=x=72:y=32:w=168:h=86:band=1:show=1
下圖為以上三條命令行處理后的展示效果:
在FFmpeg的ffplay里可以通過dumpgraph對濾鏡的處理過程增加更深的了解,可以看看下面這個例子:
./ffplay-dumpgraph1-flavfi"movie=a.flv[l];movie=logo.png[r];[l][r]overlay=x=0:y=0"
在濾鏡處理的過程中是先加載第一個電影,然后再加載一張PNG圖片,為了疊加處理比較方便會先將它們轉換成YUV,再進行疊加運算,最后輸出到一個buffersink中。
3. API
濾鏡Filter的API結構包括:
AVFilterContext:濾鏡的上下文
AVFilterInOut:濾鏡的輸入、輸出
AVFilterGraph:濾鏡的圖結構
AVFilter:濾鏡的具體處理類
AVFilterPad:包括輸入的Pad和輸出的Pad
調用API的分為兩個大的步驟:
第一步,濾鏡的初始化
初始化部分首先要確定In的Buffer和Out的Buffersink,接下來就是創建一個濾鏡的Graph,再就是做一個濾鏡的解析,最后就是通用配置。
第二步,濾鏡處理
濾鏡處理過程是先解碼,解碼之后將幀加入到Buffer,再調用濾鏡處理模塊,處理之后輸出到Buffersink。
濾鏡API的使用方法跟之前命令行的使用方法是一樣的,只是略微有一點差別。如果我們不會使用多輸入多輸出的方式,對于API的使用實際上它的輸入也可以用字符串處理的方式,就是命令行里邊的處理方式,如以下官方demo的代碼:
跑馬燈
[0:v][1:v]overlay=x='if(gte(t,0),-w+(mod(n,W+w))+5,NAN)':y=0[out]
圖像旋轉
[1:v]rotate=a=60*PI/180:ow=180:oh=180[v1];[0:v][v1]overlay=x=-20:y=-20[o]
Delogo(模糊化某一區域)
delogo=x=72:y=32:w=168:h=86:band=1:show=1
從上面的介紹可以看出,命令行與API實質上并沒有太大的區別。
三. Filter開發基礎
1. Module結構
在上面的Module結構里面,可以很清晰的看出步驟流程,先要在濾鏡的類里面注冊它所對應的所有信息,如濾鏡名,上下文等等;下一步就是對Input和Output的處理,對幀的濾鏡處理正常都是在一個Input里面處理的;
再就是要看濾鏡是否支持Timeline,比如做一些動態的變量,跑馬燈之類的,也要有時間線的概念。在這個里面也有一些對應的內置函數,可以把他們理解為一些數字運算的接口。以及下面還有一些變量名的定義。
2. 加入到FFmpeg中
添加濾鏡的時候,主要是往下面兩個里面添加:
四. Filter開發
在這一部分,為大家做了FFMPEG添加新濾鏡的過程的錄像,錄像地址為http://bbs.chinaffmpeg.com/add_filter.mp4,有興趣的同學可以看一下
首先建立了一個zoomscale的濾鏡文件,建立完這個文件之后,創建對應的context,然后把剛才講到的那些接口都寫進來,定義zoomscale公共的類,下面我們實現了一個filter _frame,它會把里面的input給釋放掉,讓它變成一個NULL,此時顯示的前景圖像就會變成一個純綠色的圖像,如果說這里有process commode,那么就可以在做zmq的時候用,如果沒有的話,可以留空。關鍵是filter_frame,可以當作濾鏡處理的一個入口,而get_video_buffer可以把它理解為我們看到的很多demo里面寫到的get_video_buffer,即創建一個幀的對應Buffer,將其添加至Makefile之后,繼續添加一個avfilter。這是FFmpeg4.0之前的版本,在后面新版本里面,采用的是數組的形式,也就沒有列表那么麻煩,速度會更快一些,添加完之后,可以通過config進行查看配置,每次config完之后,會有整體的一個輸出。添加完成后,進行編譯,之后可以在avfilter庫里直接查看濾鏡是否已經加到FFmpeg的應用程序里,然后調用API部分,直接把字符串傳進來就可以使用了。
-
攝像機
+關注
關注
3文章
1583瀏覽量
59957 -
ffmpeg
+關注
關注
0文章
46瀏覽量
7379
原文標題:劉歧:FFmpeg Filter深度應用
文章出處:【微信號:livevideostack,微信公眾號:LiveVideoStack】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論