< > 筆記


內容摘自《ffmpeg/ffplay源碼剖析》

 

1.播放器一般原理

可以直觀的看到播放這個媒體文件的基本模塊(filter),七個模塊按廣度順序:讀文件模塊(source filter),解復用模塊(Demux filter),視/音頻解碼模塊(Decode filter),顏色空間轉換模塊(Color Space converter filter),視頻/音頻播放模塊(Render filter)。

 

Source filter 源過濾器的作用是為下級demux filter 以包的形式源源不斷的提供數據流,在下一級的demux filter 看來,本地文件和網絡數據是一樣的

Demux filter 解復用過濾器的作用是識別文件類型,媒體類型,分離出各媒體原始數據流,打上時鍾信息后 送給下級decoder filter。

Decoder filter 解碼過濾器的作用就是解碼數據包,並且把同步時鍾信息傳遞下去。

Color space converter filte r 顏色空間轉換過濾器的作用是把視頻解碼器解碼出來的數據轉換成當前顯示系統 支持的顏色格式

Render filter 渲染過濾器的作用就是在適當的時間渲染相應的媒體,對視頻媒體就是直接顯示圖像,對音頻 就是播放聲音

GraphEdit 應用程序可以看成是一個支撐平台,支撐框架。它容納各種filter,在filte r 間的傳遞一些通訊消息, 控制filter 的運行(啟動暫停停止),維護filter 運行狀態

 

2.ffplay播放器原理

1)source filter讀文件模塊,分3層。最底層的是file ,pipe ,tcp,udp,http 等這些具體的本地文件或網絡協議(注意ffplay 把file 也當協議看待);中間抽象層用URLContext 結構來統一表示底層具體的本地文件或網絡協議,相關操作也只是簡單的中轉一下調用底層具體文件或協議的支撐函數;最上層用ByteIOContext 結構來擴展URLProtocol 結構成內部有緩沖機制的廣泛意義上的文件,並且僅僅由ByteIOContext  對模塊外提供服務。此模塊主要有libavformat 目錄下的file.c,avio.h, avio.c, aviobuf.c 等文件,實現讀媒體文件功能。

ByteIOContext  接口
URLContext  抽象
file ,pipe ,tcp,udp,http  文件                       

 

2)Demux filter 解復用模塊,可以簡單的分為兩層,底層是AVIContext,TCPContext,UDPContext 等等這些具體媒體的解復用結構和相關的基礎程序,上層是AVInputFormat 結構和相關的程序。上下層之間由AVInputFormat 相對應的AVFormatContext 結構的priv_data 字段關聯AVIContext 或TCPContext 或UDPContext 等等具體的文件 格式。AVInputFormat 和具體的音視頻編碼算法格式由AVFormatContext 結構的streams 字段關聯媒體格式,streams 相當於demux filter 的output pin,解復用模塊分離音視頻裸數據通過streams 傳遞給下級音視頻解碼器。此模塊 主要有libavformat 目錄下的avidec.c,utils_format.c 文件。

AVInputFormat   
AVIContext,TCPContext,UDPContext   

3)Decoder filter 解碼模塊, 也可以簡單的分為兩層, 由AVCodec 統一表述。上層是AVCodec 對應的 AVCodecContext 結構和相關的基礎程序,底層是TSContext,MsrleContext 等等這些具體的編解碼器內部使用的 結構和相關的基礎程序。AVCodecContext 結構的priv_data 字段關聯TSContext,MsrleContext 等等具體解碼器上 下文。此模塊主要有libavcodec 目錄下的msrle.c,truespeech.c,truespeech_data.h,utils_codec.c 等文件。

 

 

主要數據結構關系圖:

有一些是動態與靜態的關系,比如, URLProtocol 和URLContext,AVInputFormat 和AVFormatContext, AVCodec 和AVCodecContext。ffplay 把其他的每個大功能抽象成一個相當於C++中COM 接口的數據結構,着重於功能函數,同時這些功能函數指針在編譯的時候就能靜態確定。每一個大功能都要支持多種類型的廣義數據,ffplay 把這多種類型的廣義數據的共同的部分抽象成對應的Context 結構,這些對應的context 結構着重於動態性,其核心成員只能在程序運行時動態確定其值。並且COM接口類的數據結構在程序運行時有很多很多實例,而相應的Context 類只有一個實例,這里同時體現了數據結構的划分原則,如果有一對多的關系就要分開定義。

有一些是指針表述的排他性包含關系(因為程序運行時同一類型的多種數據只支持一種,所以就有排他性)。 比如,AVCodecContext 用priv_data 包含MsrleContext 或TSContext,AVFormatContext 用priv_data 包含AVIContext 或其他類Context,AVStream 用priv_data 包含AVIStream 或其他類Stream。由前面數據結構的動態與靜態關系 可知,ffplay 把多種類型的廣義數據的共同部分抽象成context 結構,那么廣義數據的各個特征不同部分就抽象成 各種具體類型的context,然后用priv_data 字段表述的指針排他性的關聯起來。由於瘦身后的ffplay 只支持有限 類型,所以AVFormatContext 只能關聯包含AVIContext,AVStream 只能關聯包含AVIStream。

 

3.視音頻處理的簡單流程:

音視頻數據流簡單流程, 由ByteIOContext(URLContext/URLProtocol) 表示的廣義輸入文件, 在 AVStream(AVIStreamt)提供的特定文件容器流信息的指引下,用AVInputFormat(AVFormatContext /AVInputFormat )接口的read_packet()函數讀取完整的一幀數據,分別放到音頻或視頻PacketQueue(AVPacketList/AVPacket)隊列 中,這部分功能由decode_thread 線程完成。對於視頻數據,video_thread 線程不停的從視頻PacketQueue 隊列中 取出視頻幀,調用AVCodec(AVCodecContext/MsrleContext)接口的decode()函數解碼視頻幀,在適當延時后做顏 色空間轉化並調用SDL 庫顯示出來。對於音頻數據, SDL 播放庫播放完緩沖區的PCM 數據后, 調用 sdl_audio_callback()函數解碼音頻數據,並把解碼后的PCM 數據填充到SDL 音頻緩存播放。當下次播放完后, 再調用sdl_audio_callback()函數解碼填充,如此循環不已。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM