第三章 VLC 播放程式流程架構
3.2 VLC 重要函數說明
3.2.2 InputSourceInit()函數
VLC 在開啟一個多媒體檔案時的來源有可能是從網路,也有可能是電腦硬碟內的
檔案。然而檔案又可以分成很多不同的格式,常見的多媒體檔案格式包括MPEG-1、
MPEG-2 外,另外還有 Real Video、QuickTime、WMV、MPEG4 及 H.264…等格
式,在這麼多的多媒體檔案格式中,VLC 是如何找到適合的資源存取、解多工器、
解碼器這修重要的模組呢?下面我們會說明 VLC 是如何尋找適合模組的重要函數 module_Need()。
16
InputSourceInit()這個函數會根據我們多媒體資料的來源和封包格式來找到進行解 多工程序時所需的資源存取和解多工器解碼器的模組。下面會說明InputSourceInit()函數 中一些重要的函式。在此函數會傳入2 個重要參數,一個當然是 input_thread_t 型態的 指標變數*p_input,另一個是型態 input_source_t 的結構指標變數*in;其成員定義了資源 存取、解多工器模組的資訊,圖3.8 所示;而結構 in 也是結構 p_input 中的一個成員。為 了找到適合的模組在InputSourceInit()函數中會呼叫 module_Need()函數並找到適合的模 組並儲存其位址,必需注意的是在這個 Input thread 下會找到資源存取、解多工器、解 碼器這三個主要模組,然而真正會在 Input thread 下執行動作的只有資源存取、解多工 器 這 兩 個 模 組 , 解 碼 器 模 組 則 是 在 Decoder thread 下 執 行 。 下 面 我 們 會 說 明 InputSourceInit()函數中有那些重要的函數。
access_t *p_access;
stream_t *p_stream;
demux_t *p_demux;
圖3.8 input_source_t 部分成員
1. MRLSplit():
主要用來對我們所選擇的影音資料的來源做分析,如圖3.9 所示,MRLSplit()函數先 分解MRL(Media Resource Locator)的 access、demux、path 這 3 個部分,並分別儲存 在psz_access、psz_demux、psz_path 這些字串指標,如圖 3.10 所示,這些資訊也會 存在解多工器模組中並會在訊息視窗列印出來。
MRLSplit( VLC_OBJECT(p_input), psz_dup,
&psz_access, &psz_demux, &psz_path );
圖3.9 MRLSplit()函數參數
17
圖3.10 MRLSplit()函數的訊息 2. access2_New():
如圖 3.11 所示,是用來尋找適合資源存取模組,由於 VLC 的檔案來源可能是網路
也有可能是從電腦的資料夾中的檔案,而在截取網路資源的時候可能會有不同的 Data
rate 或是網路協定,所以須要不同的資源存取模組來開啟不同來源的檔案。其中會利用 module_need()函數就是來尋找適合的模組,若 module_need()函數沒找到適合的資源存
取模組的話就代表我們檔案的來源有問題,當然整個 VLC 就無法繼續播放資料。在後
面我們會針對module_need()這個重要的函數來討論。
/* Now try a real access */
in->p_access = access2_New( p_input, psz_access, psz_demux, psz_path, b_quick );
圖 3.11 access2_New()函數
18
以開啟電腦中檔案的例子來說,前面的 MRLSplit()函數會先找出欲開啟檔案的路徑 用 psz_path 指標變數指來儲存並提供欲開啟檔案的路徑給資源存取模組。然後在 VLC
中開啟電腦中的檔案大致上可分成四種資源存取模組,分別是 Dvdnav.c、Vcd.c、
Directory.c、File.c,我們會以常用的三個來討論。VLC 一開始就會依照模組分數依序用 Dvdnav.c 模組來判斷欲開啟檔案是否 DVD 格式,然後再用 Vcd.c 來判斷是否為 VCD 格 式,若不為以上兩種格式最後才用File.c 來開啟在電腦中的影音檔案。如圖3.12 所示,
File.c 模組會對要開啟檔案的路徑作是否有錯誤的檢查,只要路徑沒有錯誤就會用 File.c 模組來當作資源存取模組並開始設定開檔所需的callback functions。
p_access->pf_read = Read;
p_access->pf_block = NULL;
p_access->pf_seek = Seek;
p_access->pf_control = Control;
圖3.12 File.c 的 callback functions
3. stream_AccessNew():
如圖 3.13 所示,是為資源存取模組及解多工器模組之間建起一個溝通的橋樑並將 讀取到的多媒體資料處理成一連串的streams 或 blocks 的資料讀取系統模組,會利用一 個型態stream_t 結構來設定開啟資料時所需的 callback functions,所以在解多工器模組
會呼叫資料讀取系統模組來取得資料並進行解多工的程序。
in->p_stream = stream_AccessNew( in->p_access, b_quick );
圖 3.13 stream_AccessNew()函數
4. demux2_New():
一部影片為了壓縮大小或其影片品質會將影像和聲音資料封裝成很多不同格式的 封包(i.e avi,mp4...) ,在每一個不同格式的封包中其影像和聲音資料都有不同的 hearder
19
來區分,為了要將一個封包內的影像和聲音資料給分離成 video bitstreame 和 audio bitstreame,就必須靠解多工器模組來完成,如圖 3.14 所示,而 demux2_New()函數就是 VLC 中用來找適合的解多工器模組。
.
in->p_demux = demux2_New( p_input, psz_access, psz_demux, psz_path, in->p_stream, p_input->p_es_out, b_quick ); 函數的迴圈中會不斷呼叫解多工器模組來將影片分解成 audio bitstream 和 video
bitstream,此時解多工器模組就會呼叫讀取資料系統模組中讀取資料的函數來呼叫資源
存取模組來讀取資料流並進行解多工程序。
20