• 沒有找到結果。

第四章 尋找合適模組機制

4.4 尋找合適的解碼器模組程序

4.4.1 取得四字元碼

在ps module 進行 MPEG-2 PS 的解多工程序時,並不是一開始就能夠取得四 字元碼,也就說ps module 並不是在一開始進行 MPEG-2 PS 解多工程序時,就能 夠馬上確認出 audio 和 video 的編碼格式。因為一個 MPEG-2 PS 是由許多 pack 組合而成的,每個pack 都是由一個 pack header 加上多個 PES packet 所形成的,

所以我們把MPEG-2 PS 的結構大致上分為三個階層:第一層為 pack header,第 二層為system header,第三層為 PES,每一層都是由特殊的起始碼所開始的,而 視訊位元流以及音訊位元流則是存在PES packet 中。

因此當ps module 在開始進行 MPEG-2 PS 解多工程序時,會先解多工出 pack header 並解析 pack header;之後再解多工出 system header 並解析 system header,

而接下來會將pack 所包含的 PES packet 一個一個的解多工出來並解析每一個 PES packet,每個 PES packet 的 PES payload 為視訊位元流或音訊位元流等其他資料類 型。如果發現解多工出來的PES packet 資料類型為 PSM(program stream map),那 麼在解析此PES packet 時才能夠確認出 audio 和 video 的編碼格式並取得相對應 的四字元碼。所以ps module 在開始進行解多工程序時,並不是馬上先找出 PSM PES packet 來確認 audio 和 video 的編碼格式,而是要經過一層一層的解多工之

後,直到解多工出PSM PES packet,然後再經過解析 PSM PES packet 來確認出 audio 和 video 的編碼格式並取得相對應的四字元碼。而接下來將會說明如何從 PSM PES packet 當中確認出 audio 和 video 的編碼格式並取得相對應的四字元碼。

如下圖4.14 所示,一個完整的 pack header 會包有其它訊息欄位以及 system header,而 system header 是由 system_header_start_code:0x000001BB 所開始的,

並且在System header 中的 stream_id 欄位會定義此一 PS 的 video stream 和 audio stream 的類型,從表 2.1 中可以知道,當 stream_id 的值在 0xE0~0xEF 間,表示 此PS 中的 PES payload 包含了 video stream;如果位於 0xC0~0xDF 間的話表示此 PS 中的 PES payload 包含了 audio stream。

pack

start code 01 SCR program

mux rate ... syste m PES 1 . . . PES n

he ade r PES payload

stre am id ...

PES start code

PES packe t le ngth

圖4.14:header of MPEG-2 PS

Stream_id Stream coding 1011 1100 Program_stream_map

1011 1101 Private_stream_1 1011 1110 Paddinf_stream 1011 1111 Private_stream_2 110x xxxx

(C0~DF)

ISO/IEC 13818-3 or ISO/IEC 11172-3 audio stream 1110 xxxx

(E0~EF)

ITU-T Rec.H.262│ISO/IEC 13818-2 or ISO/IEC 11172-3 video stream

1111 0000 ECM_stream 1111 0001 EMM_stream

1111 0010 ITU-T Rec.H.222.0│ISO/IEC 13818-1 Annex A or ISO/IEC 13818-6 DSMCC stream

1111 0011 ISO/IEC_13522_stream 1111 0100 ITU-T Rec.H.222│type A 1111 0101 ITU-T Rec.H.222│type B 1111 0110 ITU-T Rec.H.222│type C 1111 0111 ITU-T Rec.H.222│type D 1111 1000 ITU-T Rec.H.222│type E 1111 1001 Ancillary_stream

1111 (1010-1110) reserved data stream 1111 1111 program_stream_directory

表2.1 stream_id assignments

至於PES header 中的 stream_id 欄位表示其 payload data 的為 video stream 或 是audio stream,舉例來說:當 PES header 中的 stream_id=

0xE0 時,表示此 PES 所攜帶的 payload data 為 video stream;而如果 PES header 的stream_id=0xBC,表示此 PES 為 PSM(program stream map),它所挾帶

stream_type 和 elementary_stream_id 這兩個欄位的訊息可以表示這一個 PS 中的 PES payload 的編碼格式。假設 program_stream_map 的 elementary_stream_id

=0xE0,stream_type 為 0x02,根據表 2.2 可以知道 stream_type 為 0x02 為保留型 別,定義為mpeg-2 video codec,因此只要是 PES header 中的 stream_id 為 0xE0 的話,代表此video stream 編碼格式為 mpeg-2 video。

value Description

0x00 ITU-T│ISO/IEC Reserved 0x01 ISO/IEC 11172 video

0x02 ITU-T Rec.H.262│ISO/IEC 13818-2 or ISO/IEC 11172-2 constrained parameter video stream

0x03 ISO/IEC 11172 audio 0x04 ISO/IEC 13818-3 audio

0x05 ITU-T Rec.H.222.0│ISO/IEC 13818-1private_sections

0x06 ITU-T Rec.H.222.0│ISO/IEC 13818-1PES packets containing private data

0x07 ISO/IEC 13522 MHEG

0x08 ITU-T Rec.H.222.0│ISO/IEC 13818-1 Annex A DSM CC

0x09 ITU-T Rec.H.222.1 0x0A ISO/IEC 13818-6 type A 0x0B ISO/IEC 13818-6 type B 0x0C ISO/IEC 13818-6 type C 0x0D ISO/IEC 13818-6 type D

0x0E ITU-T Rec. H.222.0 | ISO/IEC 13818-1 auxiliary 0x0F ISO/IEC 13818-7 Audio with ADTS transport syntax 0x10 ISO/IEC 14496-2 Visual

0x11 ISO/IEC 14496-3 Audio with the LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1

0x12 ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packet

0x13 ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC14496_sections

0x14 ISO/IEC 13818-6 Synchronized Download Protocol 0x15-0x7F ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved 0x80-0xFF User Private

表 2.2 stream type assignment

所以當ps module 在解析 MPEG-2 PS 時,就是藉由 PSM 內的 stream_type 以及elementary_stream_id 這兩個欄位,判斷 audio stream 和 video stream 的編碼 格式為何,並且設定相對應的codec type,也就是以四字元碼來表示什麼樣的 codec type。而設定四字元碼的部分則是在 ps_track_fill()函數來完成(如下圖 4.15),而在 設定完audio 和 videocodec type 的四字元型態之後,就會利用所設定的 audio codec type 和 video codec type 尋找合適的解碼器模組。

圖4.15:ps_track_fill()函數內部分程式碼

以前面所舉的例子來說,假設PSM 的 elementary_stream_id=0xE0,stream_type 為0x02,代表此 video stream 編碼格式為 mpeg-2 video,因此在上圖 4.15 所以就 可以看到設定相對應的四字元碼"mpgv",資料型態為 VIDEO_ES,而這些設定值 都儲存在fmt 這個結構變數內(下圖 4.16)。

圖4.16:es_format_Init()函數內部分程式碼

經由解多工器在解析影音資料的過程中,可以得知video 和 audio 的編碼格 式,並且設定相對的四字元碼,因此接下來我們就要說明如何利用所設定的四字 元碼來尋找合適的解碼器模組。

4.4.2 利用四字元碼尋找合適解碼器模組

想要選擇合適的decoder module,會藉由呼叫 module_Need()函數來尋找合適 的decoder module。在 module_Need()函數內有兩階段的篩選動作,在經過第一階 段的篩選之後,decoder modules 共有 26 個;第二階段則是會去呼叫每個 decoder module 的起始函數。基本上,每個 decoder modules 的起始函數內,都有不同的 比對條件以初始條件,只要其中一個條件不符合,那就會回傳一個表示錯誤訊息 的值,並測試下一個module。但是這些 decoder modules 的起始函數內都有一個 共同的比對條件,就是必須要比對先前所設定的四字元碼。每個decoder module 所針對codec type 都不同,例如下圖 4.16 所顯示 libmpeg2 module,此 module 只 針對四字元碼為"mpgv"、"mpg1"、"PIM1"、"VCR2"、"mp2v"、"mpg2"、"hdv2"

這幾種編碼格式來解碼,而p_dec->fmt_in.i_codec 所儲存的就是先前針對影音編 碼格式所設定的四字元碼,比對的過程中如果設定的四字元碼沒有此 module 所 支援的編碼格式,那麼就表示此 module 並不是合適的 decoder module,則回傳 VLC_EGENERIC 值並測試下一個 decoder module。

圖4.17:libmpeg2 module 起始函數部分程式碼

這個四字元碼所代表的就是某種audio 或是 video 的編碼格式,在每個 decoder module 內的起始函數內所要比對的四字元碼,是表示此 decoder module 可以針對

這幾種編碼格式來解碼。所以解多工器在解析影音資料的過程中所設定 video 和 audio 的編碼格式相對的四字元碼,如果符合某個 decoder module 內的起始函數內 所要比對的四字元碼,表示此decoder module 可以對這種編碼格式進行解碼動作。

所以可以了解到VLC 尋找一個合適的解碼器模組的方法,就是在解多工器在 解析影音資料的過程中確認出 audio 和 video 的編碼格式,並且設定相對應的四 字元碼;之後第二階段的篩選時,進到decoder module 的起始函數內,測試是否 符合起始函數內的比對條件以初始條件,若符合某個解碼器模組的起始函數內的 比對條件和初始條件,那麼也就代表選擇了此模組為合適的解碼器模組,因此 VLC 才能使用此解碼器模組來進行解碼的程序。

相關文件