第四章 VLC 解多工器與解碼器模組
4.1 解多工器模組
4.1.1 PS 解多工器模組
Mpeg-2 programstream 是由許多 pack 所組成,每個 pack 是由一個 pack header 再加 上多個PES(Packetized Elementary Stream)所組成的,許多 PES 組成一個 PS 前必須要加 上Pack header 和 System header,每一個 header 都是由一序列固定的起始碼,其中可區
分出資料的每層架構,而PS 大致上可分成三層。
如4.2 圖所示每一個 PES 所代表的就是一個 audio PES 或者 video PES 或是其他類 型PES。所以解多工器模組就會一層層的的解析出 audio PES 和 video PES,並再從 audio PES 和 video PES 當中取出 PES payload,而這些 PES paylaod 就是第二章我們所提到的
解多工函數
資料輸出系統模組 解多工模組資訊
資料讀取系統模組
36
video bistream 或 audio bistream,最後這些 bistream 就會由解碼器模組來進行解碼動作。
圖4.2 mpeg-2 programstream 結構圖
在 module_Need()函數要測試 ps.c 解多工器模組是否為適合的模組時,會先檢查讀 到的header 是否為 mpeg-2 programstream pack header 的標準格式,每個 pack 的最外層 的pack header 是由 4 bytes 的 pack_start_code:oxooooo1BA 開始,所以 module_Need()函 數中 p_tmp->p_module->pf_activate 會指向 ps.c 模組中的開啟測試函數 Open()來測試 pack header 是否大於 4 bytes,若小於 4 bytes 代表不為 mpeg-2 programstream 的格式,
就會回傳錯誤訊息給module_Need()函數然後 p_tmp->p_module->pf_activate 就會指向下 一個模組的開啟測試函數進行條件比對。
37
if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) {
msg_Err( p_demux, "cannot peek" );
return VLC_EGENERIC;
}
圖 4.3 判斷 pack header 是否大於 4 bytes
ps.c 模組的開啟測試函數中會呼叫解多工模組結構中讀取資料函數來讀取 MPEG-2 header 資訊,並判斷其 header 資訊是否有符合的必需條件如上圖 4.3 所示。因為 pack_start_code 在標準中就是定義為 4 個 bytes 的長度所以在 ps.c 模組的開啟測試函數 就會先判斷header 的長度是否為 4 個 bytes 的基本條件,接著就會判定讀取 pack header 的資訊是不是符合mpeg-2 programstream 的標準格式,如圖 4.4 所示。
if( p_peek[0] != 0 || p_peek[1] != 0 ||
p_peek[2] != 1 || p_peek[3] < 0xb9 ) {
msg_Warn( p_demux, "this does not look like an MPEG PS stream, "
"continuing anyway" );
}
圖 4.4 判斷是否符合 mpeg-2 programstream 的標準格式
若符合其開啟的條件後,就會開始設定解多工模組結構 demux_t 中的解多工函數的 callback functions,也就是說 ps.c 模組中所定義的解多工函數 Demux()將被用來進行解多 工程序,這些callback functions 所指向的解多工函數才是真正解多工器模組對影音資料 解多工的地方,然後就會回傳VLC_SUCCESS 訊息告訴 module_Need()函式已經找到最
佳的解多工器模組,在結束 Open()函數後整個解多工模組結構就會設定完成,如圖 4.5
所示。之後解多工函數會在MainLoop()函數中不斷被呼叫。
38
p_demux->pf_demux = Demux;
p_demux->pf_control = Control;
圖4.5 ps.c 模組設定 callback function
當 MainLoop()函數呼叫 p_demux->pf_demux 時會傳入整個解多工器模組結構 demux_t 後進行解多工程序,此時 ps.c 模組的所有資訊都存在解多工器模組結構中,所 以呼叫p_demux->pf_demux 時就等於在呼叫 ps.c 所定義的解多工函數 Demux()進行解多 工程序。
在 mpeg-2 programstream 中有一個重要的特性,就是每個 PES 都具有共同的時間基 準(time base) ,所以同一個 PS 中所有的 PES(Packetized Elementary stream)都享有共同 的時間基準,當MainLoop()函數呼叫 ps.c 模組中的 Demux()函數進行解多工程序時會先 做同步檢查的動作以達到對影像和聲音同步的解碼,之後就會開始解析PS 中的 header,
藉由header 的資訊可以判斷 video stream 和 audio stream 的編碼格式來取得四字元。