筆者才開始學習音視頻開發,主要是通過閱讀劉歧、趙文傑編著的《FFmpeg從入門到精通》以及雷霄驊博士博客總結寫的入門心得體會。
官方文檔資料
FFmpeg官方文檔:https://ffmpeg.org/documentation.html
FFmpeg官方wiki:http://trac.ffmpeg.org/wiki
中文經典資料
雷霄驊博士csdn鏈接:https://blog.csdn.net/leixiaohua1020
ChinaFFmpeg:http://bbs.chinaffmpeg.com
除了以上這些信息,還可以通過 Google、百度等搜索引擎獲得大量相關資料。
本文這里簡單介紹一下 FFmpeg 是什么?
一、FFmpeg的定義
FFmpeg 既是一款音視頻編解碼工具,同時也是一組音視頻編解碼開發套件,作為編解碼開發套件,它為開發者提供了豐富的音視頻的調用接口。
FFMpeg 提供了多種媒體格式的封裝和解封裝,包括多種音視頻編碼、多種協議的流媒體、多種色彩格式轉換、多種采樣率轉換、多種碼率轉換等;FFmpeg 框架提供了多種豐富的插件模塊,包含封裝與解封裝的插件、編碼與解碼的插件等。
FFmpeg 中的 “FF” 指的是 “Fast Forward”,FFmpeg 中的 “mpeg” 則是 “Moving Picture Experts Group(動態圖像專家組)”。
PS:有不少人不清楚 “FFmpeg” 應該怎么讀。它讀作 “ef ef em peg”。
二、FFmpeg的基本組成模塊
FFmpeg 框架的基本組成包括 AVFormat、AVCodec、AVFilter、AVDevice、AVUtil 等模塊庫。下面針對這些模塊做一個大概的介紹。
(1)FFmpeg的封裝模塊AVFormat
AVFormat 中實現了目前多媒體領域中的絕大多數媒體封裝格式,包括封裝和解封裝,如 MP4、FLV、KV、TS 等文件封裝格式,RTMP、RTSP、MMS、HLS 等網絡協議封裝格式。 FFmpeg 是否支持某種媒體封裝格式,取決於編譯時是否包含了該格式的封裝庫。根據實際需求,可進行媒體封裝格式的拓展,增加自己定制的封裝格式,即在 AVFormat 中增加自己的封裝處理模塊。
(2)FFmpeg的編解碼板塊AVCodec
AVCodec 中實現了目前多媒體領域絕大多數常用的編解碼格式,既支持編碼,也支持解碼。AVCodec 除了支持 MPEG4、AAC、MJPEG 等自帶的媒體編解碼格式之外,還支持第三方的編解碼器,如 H.264(AVC)編碼,需要使用 x264 編碼器;H.265(HEVC)編碼,需要使用 X265 編碼器;MP3(mp3lame)編碼,需要使用 libmp3lame 編碼器。如果希望增加自己的編碼格式,或者硬件編解碼,則需要在 AVCodec 中增加相應的編解碼模塊。
(3)FFmpeg的濾鏡模塊AVFilter
AVFilter 庫提供了一個通用的音頻、視頻、字幕等濾鏡處理框架。在 AVFilter 中,濾鏡框架可以有多個輸入或多個輸出。
(4)FFmpeg的視頻圖像轉換計算模塊swscale
swscale 模塊提供了高級別的圖像轉換 API,例如它允許進行圖像縮放和像素格式轉換,常見於將圖像從 1080p 轉換成 720p 或者 480p 等的縮放,或者將圖像數據從 YUV420P 轉換成 YUYV,或者 YUV 轉 RGB 等圖像格式轉換。
(5)FFmpeg的音頻轉換計算模塊swresample
swresample 模塊提供了高級別的音頻重采樣 API。例如它允許操作音頻采樣、音頻通道布局轉換與布局調整。
三、FFmpeg的主要工作流程
FFmpeg 的主要工作流程相對比較簡單,具體如下:
1)解封裝(Demuxing)
2)解碼(Decoding)
3)編碼(Encoding)
4)封裝(Muxing)
其中需要經過 6 個步驟,具體如下:
1)讀取輸入源
2)進行音視頻的解封裝
3)解碼每一幀音視頻數據
4)編碼每一幀音視頻數據
5)進行音視頻的重新封裝
6)輸出到目標
FFmpeg 整體處理的工作流程與步驟如下圖所示:
四、FFmpeg的相關術語
媒體流(Stream):表示在時間軸上的一段連續的數據,比如一段聲音數據、一段視頻數據或者一段字母數據,可以是壓縮的,也可以是非壓縮的,壓縮的數據需要關聯特定的編解碼器。
數據幀/數據包(Frame/Packet):通常一個媒體流是由大量的數據幀組成的,對於壓縮數據,幀對應着編解碼器的最小處理單元,分屬於不同媒體流的數據幀交錯存儲與容器之中。
編解碼器:編解碼器是以幀為單位實現壓縮數據和原始數據之間的相互轉換的。
前面介紹的術語,就是 FFmpeg 中抽象出來的概念。其中:
1. AVFormatContext:就是對容器或者媒體文件層次的抽象。
2. AVStream:在文件中(容器里面)包含了多路流(音頻流、視頻流、字幕流),AVStream 就是對流的抽象。
3. AVCodecContext 與 AVCodec:在每一路流中都會描述這路流的編碼格式,對編解碼器格式以及編解碼器的抽象就是 AVCodecContext 與 AVCodec。
4. AVPacket 與 AVFrame:對於編碼器或者解碼器的輸入輸出部分,也就是壓縮數據以及原始數據的抽象就是 AVPacket 與 AVFrame。
5. AVFilter:除了編解碼之外,對音視頻的處理肯定是針對於原始數據的處理,也就是針對 AVFrame 的處理,使用的就是 AVFilter。
五、FFmpeg的一些應用場景
下面介紹一下 FFmpeg 都用在了哪里(在這里僅列幾個我所知的,其實遠比這個多)。說白了就是為了說明:FFmpeg 是非常重要的。
使用 FFmpeg 作為內核視頻播放器:
- Mplayer,ffplay,射手播放器,暴風影音,KMPlayer,QQ影音...
使用 FFmpeg 作為內核的 Directshow Filter:
- ffdshow,lav filters...
使用 FFmpeg 作為內核的轉碼工具:
- ffmpeg,格式工廠...
事實上,FFmpeg 的音視頻編解碼功能確實太強大了,幾乎囊括了現存所有的音視頻編碼標准,因此只要做音視頻開發,幾乎離不開它。
參考:
劉歧、趙文傑編著的《FFmpeg從入門到精通》第1章