ffmpeg是多媒體領域應用最廣泛的一個開源框架,包含了傳輸協議、視頻格式、編解碼、圖像濾鏡、語音處理等功能,並可以與cuda、opencv等這個領域的其他軟體對接,幾乎是事實上的音視頻標準庫。
它的架構清晰簡潔,大體上分為這幾個部分:
1,傳輸協議,
tcp、udp、http、rtmp、rtsp等常見協議的支持,本地文件也被實現為一個協議file。
2,視頻封裝格式,
ts、flv、mp4、mp3、mov等等,市面上常見的格式,幾乎沒有ffmpeg解析不了的。
3,編解碼協議,
視頻的H264、H265、vp8等,
音頻的mp3、aac、opus等,
大概支持幾十種編解碼協議,常見的不常見的都有,最流行的還是H264和aac。
4,圖像濾鏡和語音濾鏡,
圖像和語音的處理,在ffmpeg裡都是通過avfilter,它是ffmpeg提供的對解碼後的圖像和語音進行處理的一個框架。
5,模塊化設計,
ffmpeg的模塊化設計,足以與nginx和Linux內核相媲美,添加第三方模塊或者自定義模塊都非常方便。
它自帶的各個功能也是以模塊的形式管理的,可以在編譯之前靈活配置。
上圖是ffmpeg官網的下載頁面,可以看到最新的版本為4.3.1。
下圖為解壓後的文件夾,我的是4.2.1,小版本之間的API一般不會有大的改動,除非大版本號換了。
那個綠色的configure文件,就是ffmpeg的配置生成腳本。
它是一個shell腳本,可以根據用戶選擇的配置項生成所需的Makefile,然後直接make -j4就可以編譯所需的版本了。
ffmpeg的編譯需要yasm彙編器,可以直接sudo apt-get安裝。
如果ffmpeg需要的版本與apt-get默認安裝的不一致時,也可以去下載源碼自己編譯安裝。
Linux的軟體安裝現在也是sudo apt-get install 軟體名就行,就算自己下載編譯基本也是./configure,然後make -j4,最後sudo make install。
比windows的滑鼠一路next還是稍微麻煩點,但靈活呀:(
視頻的三要素:寬度width、高度height、像素格式pix_fmt。
音頻的三要素:採樣率sample_rate、聲道數channels、採樣格式sample_fmt。
視頻常見的是1280x720,yuv420p。
音頻常見的是44100(44.1k)、2聲道、S16,或者48000(48k)、2聲道、S16。
他們都有播放時間PTS和解碼時間DTS。
ffmpeg是圍繞這8個參數處理的,其中dts一般不需要過於關注,重點是pts,它確定了音視頻的每一幀的播放時間。
ffmpeg(多媒體框架都一樣)的視頻數據流是這樣的:
流媒體伺服器->傳輸協議->解封裝demux->解碼decode->音視頻原始流->avfilter濾鏡->音畫同步->輸出(編碼encode->封裝mux->傳輸協議->保存本地或推流伺服器)。
美顏、美聲之類的處理,都可以在avfilter中實現為一個濾鏡,或多個濾鏡組合。
ffmpeg的例子代碼在doc/examples目錄,實際做項目時可以參考。
文件名可以看出大概是哪方面的例子。
ffmpeg的主要是數據結構:
1,AVFrame,
存儲的是原始音視頻幀的數據,剛採集的,解碼後的,編碼前的,都是這類數據。
2,AVPacket,
編碼後的,解碼前的,壓縮數據。
H264、AAC的數據包,都是這類,需要解碼之後才能獲得AVFrame數據。
3,AVFormatContext,
一個視頻文件,或者直播流的結構體,在播放時使用avfortmat_open_input()函數打開,如果是編碼輸出則使用
avformat_alloc_output_context2()。
4,AVStream,
表示視頻中的一路視頻或者音頻流,文件或者直播點播流裡可以包含多路視頻音頻流,每一路就是一個AVStream。
5,AVCodec,AVCodecContext,
解碼器或者編碼器,及他們對應的上下文結構體。
6,AVFilter,AVFilterContext,
視頻或者音頻濾鏡,和他們對應的上下文結構體。
編解碼器和濾鏡是提前寫好、編譯在ffmpeg庫裡的,他們的上下文則是應用程式使用的時申請的。
協議和封裝格式相關代碼在libavformat目錄。
濾鏡相關代碼在libavfilter目錄。
編解碼相關代碼在libavcodec目錄。
libavutil目錄為一些常用的公共函數。
libswscale為圖像的釋放處理函數,libswresample為聲音的重採樣函數,例如44.1k轉48k,5.1聲道轉2聲道,等等。
fftools則是自帶的視頻處理工具,ffmpeg和ffplay的代碼都在這個目錄。