節目映射表提供節目號與組成它們的所有原始碼流之間的映射,其PID由所在TS中的PAT表指定,PMT以program_map_section的形式進行TS打包。
我們知道,單路節目的TS是由具有相同時間基點的PES流複用而成的,典型情況下包含一路視頻PES流、多路音頻PES流,還有teletext、subtitle等PES,各路PES的PID就在這張表中指定。因此,解析這張表就可以知道一路節目是由哪些PES組成的,其PID是多少?這樣有利於解碼器根據找出相應的PID,進行音視頻解碼。
PMT section的header部分爲8個字節,由表標識符(以區別於其他table)、section長度、節目號、版本號、section號、最後一個section號組成。緊接着會提供本節目進行收發同步參考的PCR PID,節目信息長度及其描述符(描述符會單獨分析),節目所含的基本流信息。
【語法結構】
表中:
Table id:8bit域,在TS流中Program map section將置爲0x02。
Section syntax indicator:1bit域,對於PMT表,設置爲1。
Zero:1bit域,設置爲0。
Reserved:2bit域,預留爲11(0x3)。
Section length:12bit域,首先兩位bit置爲00,它指示段的byte數,由段長度域開始,包含CRC字段4個字節,因此在寫解析代碼時需要注意。
Program number:16bit域,它指出該節目對應於可應用的Program map PID。一個節目定義僅含一個TS流的Progrmn map section。這意味着一個節目的定義不超過1016Byte。
Reserved:2bit域,預留爲11(0x3)。
Version number:5bit域,指出TS流中Program map section的版本號。當段中有關信息發生變化,版本號將以32爲模加1。版本號是關於一個節目的定義,因此版本號是關於單一段的定義,該字段用於service中各組成部分的信息發生更新,例如當視頻PID變化。
Current next indicator:1bit域,當該位置1時,當前傳送的Program map section可用;當該位置0時,指示當前傳送的Program map section不可用,下一個TS流的Program map section有效。
Section number:8bit域,總是置爲0x00(因爲PMT表裏表示一個service的信息,一個section的長度足夠)。
Last section number:8bit域,該域的值總是0x000。
Reserved:3bit域,預留爲111(0x7)。
PCR PID:13bit域,指明TS包的PID值,該TS包含有PCR域,該PCR值對應於由節目號指定的對應節目。如果對於私有數據流的節目定義與PCR無關,這個域的值將爲0×1FFF。
Reserved:4bit域,預留爲1111(0xF)。
Program info length:12bit域,前兩位bit爲00。該域指出跟隨其後對節目信息的描述的byte數。
Stream type:8bit域,指示特定PID的節目元素包的類型。該處PID由elementary PID指定。該域值爲0×2時,指示ITU-TRECH262|ISO/IEC13818-2video或ISO/IEC11172-2constrained parameter video stream。
【碼流示例】
Program_number爲0x65的TS包以及PMT如下:
上面的數據解析如下圖:
ErrorCode_t ParsePMTHead(U8* pSectionData, PMT_HEAD *pHead)
{
ErrorCode_t err = NO_ERROR;
if(NULL == pSectionData || NULL == pHead)
{
err = ERROR_FAME;
}
else
{
pHead->m_uTableID = pSectionData[0]; /*恆爲0x02*/
pHead->m_uSectLen = SECTION_LENGTH(pSectionData[1], pSectionData
[2]); /*PMT section的長度*/
pHead->m_uServiceId= USHORT_LENGTH(pSectionData[3], pSectionData
[4]); /*節目號,program_number*/
pHead->m_uVersion = (pSectionData[5] & 0x3E) >> 1;
pHead->m_PCRPID = PID_LENGTH(pSectionData[8] , pSectionData
[9]); /*PCR PID*/
//描述符長度,循環
pHead->m_uProgLen = SECTION_LENGTH(pSectionData[10], pSectionData
[11]); /*節目信息的長度*/
pHead->m_pProgData = pSectionData + 12; /*節目信息循環開始地址*/
//流信息長度,循環
pHead->m_uStreamInfoLen = (pHead->m_uSectLen) - (pHead-
>m_uProgLen) - 13; /*流描述信息長度*/
/*流描述數據開始地址*/
pHead->m_pStreamData = (pHead->m_pProgData) + pHead->m_uProgLen;
err = NO_ERROR;
}
return err;
}