1. 程式人生 > >vlc源碼分析(二) 播放流程

vlc源碼分析(二) 播放流程

.net ges bmp pre https 學習 ref lock 流媒體

http://www.cnblogs.com/jiayayao/p/6752388.html

  當點擊播放文件或者輸入要播放的文件後,vlc會執行一系列的流程。

  首先需要了解視頻以及流媒體處理及播放的流程,由鏈接中的描述,視頻以及流媒體處理時,首先要解協議(http,rtmp,rtsp等),然後是解封裝(mp4,mkv,avi等),獲得音頻碼流和視頻碼流,分別解碼後,再根據時間戳進行同步。使用vlc點擊播放後,就是這一系列的流程。

  點擊播放支持RTSP協議的攝像頭後,vlc會開啟線程對輸入的文件或者url進行分析(src/playlist/preparser.c),根據視頻源屬性做一些準備工作,包括:

  ->InputSourceInit()

    ->input_SplitMRL()分解url

    ->demux_New()創建分離器,如果是一個mp4文件,則會動態加載libmp4庫,以此類推

    ->demux_Control()調用libmp4的Control函數,以此類推

    ......

    ->InitPrograms()根據文件或url屬性創建解碼器(decoder),創建過程會加載對應模塊

  之後就是從網絡或者本地獲取數據,堆棧如下。從堆棧中可以看到,接收線程從網絡中接收數據,如果數據有封包格式(如mp4,mkv,ts等,也就是編碼後的裸數據),則首先進行的是解封裝,將解封包後的數據組成block(可以理解為是一個結構體,這個結構體可以用來保存一幀圖像,也可以用來保存一幀圖像的一部分數據),放入數據fifo中;解碼線程從數據fifo中取出block來解碼,交由其他渲染模塊去顯示。不同的是,攝像頭並沒有封裝視頻格式,而是傳輸的編碼後的裸數據。

技術分享

  同理,播放一個本地mp4文件的堆棧如下。播放本地文件就沒有了解協議的步驟,但是使用了libmp4進行了拆包。

技術分享

  放入數據fifo中的數據還沒有被解碼,另外還有兩個解碼線程(音頻和視頻)不斷的從各自的隊列中取數據解碼,視頻解碼線程的堆棧如下。解碼線程首先從上述數據fifo中取出數據,使用已經根據數據源格式創建好的解碼器解碼,之後將解碼後的數據放到圖像fifo中。

技術分享

  最後是渲染線程的堆棧,渲染線程不斷的從圖像fifo中取出數據渲染到窗體上。

技術分享

  程序的整體框圖如下。當RTSP session建立的時候,程序根據RTSP會話得到的SDP信息創建視頻解碼器和音頻解碼器,兩個解碼器有各自的fifo,用於存放需要解碼的數據。RTP數據到來後,經過Demux,分別放入兩個fifo中,然後兩個解碼線程分別從各自的fifo中取出視頻和音頻數據解碼。解碼後的音頻數據直接播放,解碼後的視頻數據放入picture_fifo_t中,由渲染線程負責顯示。

技術分享

  附:

  配置好的Windows版vlc工程下載:https://github.com/jiayayao/vlc_2.1.0-vs_2010,下載後使用vs2010可以直接編譯運行,調試學習非常方便。

vlc源碼分析(二) 播放流程