《FFMPEG/FFPLAY 源碼剖析》是由楊書良2011年于上海所著,作者博客地址:MCODEC,以及這本書籍的電子版下載地址。
注:原作者保留本電子書修改和正式出版的所有權利。最終讀者可以自由復制和傳播本電子書,但不得修改其內容,并且要保證內容的完整性。
1 目錄
這段時間想要學習一下播放器的搭建,于是住準備開始學習播放器的“王者核心”——FFmpeg。師兄推薦了一本解讀源碼的大作——FFMPEG/FFPLAY 源碼剖析,于是便開始了對這本書的大致探索。
最初整體一翻給我的感覺就像是正在看FFmpeg的API文檔一樣,從目錄分模塊份文件的形式上就感到了一股“技術字典”般濃濃的觀感。全書除前言外總體分了五部分講解作者眼中的FFmpeg的“靈魂”,分別是概述、libavutil、libavformat、libavcodec以及ffplay。總體分為了三個部分:原理介紹、代碼介紹、項目示例。這樣一看,這本“技術字典”好像還是很有可讀性的。
2 概述
該部分主要講解了ffplay源碼的文件結構、播放原理、SDL的使用以及AVI格式封裝和典型壓縮算法的介紹。
-
首先是有關FFplay的總體結構,先大致對作者“提取”出的“靈魂”文件們有一個大致了解。
注:本處暫時沒有按原書詳細列出各個文件功能,詳細內容會在下面部分給出,圖中帶有 “ * ” 的節點表示文件夾,沒有星號也沒有后綴的節點是.c/.h文件的合寫。
文件層次圖 -
播放器原理
播放器播放一般分為七個基本模塊(過濾器),按廣度順序:讀文件模塊,解復用模塊 ,視頻解碼模塊,音頻解碼音頻,顏色空間轉換模塊,視頻顯示模塊,音頻播放模塊。
各模塊流程
其中讀文件模塊是將文件不斷以流的形式輸送到后面的各個模塊中。解復用模塊主要作用就是識別文件的類型和媒體數據的格式(遍歷),并針對類型做出一些簡單的預處理,同時負責后續的時鐘同步。后續的音視頻解碼模塊主要任務就是解碼數據包并傳遞時鐘的同步信息,最終通過音視頻播放模塊根據同步信息播放出音畫信息。顏色空間轉換模塊主要針對YUV與RGB兩種數據的轉換,根據不同要求進行輸出。 FFplay播放器
FFplay本質上也遵循上述的播放流程:
讀文件模塊(libavformat):最底層是解協議(本地/tcp/udp/http/pipe/...),中間抽象層負責中轉(URLContext),最上層實現讀媒體文件功能(ByteIOContext)。
解復用模塊(libavformat):底層是解復用結構(AVIContext/TCPContext/...),上層通過priv_data獲取下層數據并分離出音視頻裸數據(AVFormatContext)通過streams傳遞下去。
解碼模塊(libavcodec):可由AVCoder統一表述,上層是AVCoderContext相關的結構及基礎程序,下層是具體解碼器的結構和相關程序。
顏色空間轉換模塊(libavcodec):將解碼出的YUV格式數據轉換成目的系統支持的色彩格式。
渲染模塊(SDL):調用SDL庫進行音視頻渲染播放。
ffplay.c文件:相當于 directShow里面的 GraphEdit,可以簡單理解成一個支撐大平臺,支撐大框架。它聲明并 實例化其他的數據結構/模塊,并且把其他數據結構/模塊串聯起來,最后把其他數據結構/模塊關聯到VideoState數據結構,同時控制程序的啟動暫停停止等。FFmpeg瘦身時的具體變動
1)只保留簡單的兩個壓縮算法和avi格式
2)樣例視頻從神奇的321×321轉壓常見的320×320
3)刪除不用支撐的文件格式和媒體編解碼算法相關代碼
4)刪除不支持的平臺相關代碼
5)刪除一些不用支撐的功能
6)寫死某些參數又精簡了很多函數的實現
7)把沒有實際使用的幾乎所有變量和函數也刪掉了
8)為便于理解修改了部分函數命名
8)其他必要改動ffplay框架詳講、AVI格式介紹、SDL使用及壓縮算法介紹詳見原書,不作贅述