日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

PAT、PMT、SDT详解

發(fā)布時(shí)間:2024/4/14 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PAT、PMT、SDT详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://blog.chinaunix.NET/uid-24322243-id-2620180.html

下面針對(duì)解復(fù)用程序詳細(xì)分析一下PAT,PMT和SDT三類表格的格式.

PAT---Program Association Table,節(jié)目關(guān)聯(lián)表?。PAT表攜帶以下信息:?
(1)?TS流ID--- transport_stream_id,該ID標(biāo)志唯一的流ID
(2)節(jié)目頻道號(hào)-- program_number,該號(hào)碼標(biāo)志TS流中的一個(gè)頻道,該頻道可以包含很多的節(jié)目(即可以包含多個(gè)Video PID和Audio PID)
(3)?PMT的PID--- program_map_PID,表示本頻道使用的哪個(gè)PID做為PMT的PID,因?yàn)榭梢杂泻芏嗟念l道,因此DVB規(guī)定PMT的PID可以由用戶自己定義.

PAT表定義如下:?各字段含義如下:

table_id:8 bits,標(biāo)志本表格的類型,應(yīng)該是0x00

section_syntax_indicator:1 bit,段語(yǔ)法標(biāo)志,應(yīng)該是''1'' ''0'':固定的''0'',這是為了防止和ISO13818Video流格式中的控制字沖突而設(shè)置的.

Reserved:保留的2bits,保留位一般都是''0''

section_length:12bits的段大小,單位是Bytes.

transport_stream_id:16bits的當(dāng)前流ID,DVB內(nèi)唯一.(事實(shí)上很多都是自定義的TS ID)version_number:5bits版本號(hào)碼,標(biāo)注當(dāng)前節(jié)目的版本.這是個(gè)非常有用的參數(shù),當(dāng)檢測(cè)到這個(gè)字段改變時(shí),說(shuō)明TS流中的節(jié)目已經(jīng)變化?了,程序必須重新搜索節(jié)目.

current_next_indicator:1bit:當(dāng)前還是未來(lái)使用標(biāo)志符,一般情況下為''0''

section_number:8bits當(dāng)前段號(hào)碼

last_section_number:8bits最后段號(hào)碼(section_number和?last_section_number的功能是當(dāng)PAT內(nèi)容>184字節(jié)時(shí),PAT表會(huì)分成多個(gè)段(sections),解復(fù)用程序必須在全部接?收完成后再進(jìn)行PAT的分析)

for()開始,就是描述了當(dāng)前流中的頻道數(shù)目(N),每一個(gè)頻道對(duì)應(yīng)的PMT PID是什么.解復(fù)用程序需要和上圖類似的循環(huán)來(lái)接收所有的頻道號(hào)碼和對(duì)應(yīng)的PMT PID,并把這些信息在緩沖區(qū)中保存起來(lái).在后部的處理中需要使用到PMT PID.

CRC_32:本段的CRC校驗(yàn)值,一般是會(huì)忽略的.N是一個(gè)變量,計(jì)算方法是N=(section_length-9)/4.

從以上分析我們可以發(fā)現(xiàn),PAT表主要包含頻道號(hào)碼和每一個(gè)頻道對(duì)應(yīng)的PMT的PID號(hào)碼,這些信息我們?cè)谔幚?span lang="en-us">PAT表格的時(shí)候會(huì)保存起來(lái),以后會(huì)使用到?這些數(shù)據(jù).例如我們可以定義這樣的數(shù)據(jù)結(jié)構(gòu)保存這些信息:

typedef struct

{

int channel_number;

int pmt_pid;

}PMT_ITEM;

PMT_ITEM pmt[64];

?

PMT, Program Map Table,節(jié)目影射表?如果一個(gè)TS流中含有多個(gè)頻道,
那么就會(huì)包含多個(gè)PID不同的PMT表.檢測(cè)是否PMT的偽代碼如下:
void Process_Packet(unsigned char*buff)
{ int I;

int PID=GETPID(buff);

if(PID==0x0000)

{

Process_PAT(buff+4);

?}

else if(PID==.....)
{ }

else

{ for(i=0;i<64;i++)
{ if(PID==pmt[i].pmt_pid)

{ Process_PMT(buff+4); break; }
} } }
PMT表中包含的數(shù)據(jù)如下:

(1)?當(dāng)前頻道中包含的所有Video數(shù)據(jù)的PID

(2)?當(dāng)前頻道中包含的所有Audio數(shù)據(jù)的PID

(3)?和當(dāng)前頻道關(guān)聯(lián)在一起的其他數(shù)據(jù)的PID(如數(shù)字廣播,數(shù)據(jù)通訊等使用的PID)

?

PMT定義如下:?各字段含義如下:

table_id:8bits的ID,應(yīng)該是0x02

section_syntax_indicator:1bit的段語(yǔ)法標(biāo)志,應(yīng)該是''1'' ''0'':固定是''0'',如果不是說(shuō)明數(shù)據(jù)有錯(cuò).

reserved:2bits保留位,應(yīng)該是''00''

section_length:16bits段長(zhǎng)度,從program_number開始,到CRC_32(包含)的字節(jié)總數(shù).?program_number:16bits的頻道號(hào)碼,表示當(dāng)前的PMT關(guān)聯(lián)到的頻道.換句話就是說(shuō),當(dāng)前描述的是program_number頻道的?信息.

reserved:2bits保留位,應(yīng)該是''00''

version_number:版本號(hào)碼,如果PMT內(nèi)容有更新,則version_number會(huì)遞增1通知解復(fù)用程序需要重新接收節(jié)目信息,否則?version_number是固定不變的.

current_next_indicator:當(dāng)前未來(lái)標(biāo)志符,一般是0

section_number:當(dāng)前段號(hào)碼

last_section_number:最后段號(hào)碼,含義和PAT中的對(duì)應(yīng)字段相同,請(qǐng)參考PAT部分.?reserved:3bits保留位,一般是''000''.

PCR_PID:13bits的PCR PID,具體請(qǐng)參考ISO13818-1,解復(fù)用程序不使用該參數(shù).

reserved:4bits保留位,一般是''0000''

program_info_length:節(jié)目信息長(zhǎng)度(之后的是N個(gè)描述符結(jié)構(gòu),一般可以忽略掉,這個(gè)字段就代表描述符總的長(zhǎng)度,單位是Bytes)?緊接著就是頻道內(nèi)部包含的節(jié)目類型和對(duì)應(yīng)的PID號(hào)碼了.

stream_type:8bits流類型,標(biāo)志是Video還是Audio還是其他數(shù)據(jù).

reserved:3 bits保留位.

elementary_PID:13bits對(duì)應(yīng)的數(shù)據(jù)PID號(hào)碼(如果stream_type是Video,那么這個(gè)PID就是Video PID,如果stream_type標(biāo)志是Audio,那么這個(gè)PID就是Audio PID)

reserved:4 bits保留位.

ES_info_length:和program_info_length類似的信息長(zhǎng)度(其后是N2個(gè)描述符號(hào))?CRC_32:32bits段末尾是本段的CRC校驗(yàn)值,一般忽略.

?

從以上的分析可以看出,只要我們處理了PMT,那么我們就可以獲取頻道中所有的PID信息,例如當(dāng)前頻道包含多少個(gè)Video,共多少個(gè)Audio,和其?他數(shù)據(jù),還能知道每種數(shù)據(jù)對(duì)應(yīng)的PID分別是什么.?這樣如果我們要選擇其中一個(gè)Video和Audio收看,那么只需要把要收看的節(jié)目的Video PID和Audio PID保存起來(lái),在處理Packet的時(shí)候進(jìn)行過(guò)濾即可實(shí)現(xiàn).?比較全面實(shí)現(xiàn)解復(fù)用的偽代碼如下:

int Video_PID=0x07e5,Audio_PID=0x07e6;

void Process_Packet(unsigned char*buff)

{ int I; int PID=GETPID(buff);

if(PID==0x0000) { Process_PAT(buff+4); }

else if(PID==Video_PID) { SaveToVideoBuffer(buff+4); }

else if(PID==Audio_PID) { SaveToAudioBuffer(buff+4); }

else

{ for( i=0;i<64;i++)

{ if(PID==pmt[i].pmt_pid) { Process_PMT(buff+4); Break; }

} } }

以上偽代碼可以實(shí)現(xiàn)基本的解復(fù)用:檢測(cè)所有的頻道,檢測(cè)所有stream的PID,選擇特定的節(jié)目進(jìn)行播放.只要讀取每個(gè)Packet的188字節(jié)的內(nèi)?容,然后每次都調(diào)用Process_Packet()即可實(shí)現(xiàn)簡(jiǎn)單的解復(fù)用.?介紹到這里,我們就可以總結(jié)一下DVB搜臺(tái)的原理了.(好!洗耳恭聽!)?機(jī)?頂盒先調(diào)整高頻頭到一個(gè)固定的頻率(如498MHZ),如果此頻率有數(shù)字信號(hào),則COFDM芯片(如MT352)會(huì)自動(dòng)把TS流數(shù)據(jù)傳送給MPEG- 2 decoder. MPEG-2 decoder先進(jìn)行數(shù)據(jù)的同步,也就是等待完整的Packet的到來(lái).然后循環(huán)查找是否出現(xiàn)PID== 0x0000的Packet,如果出現(xiàn)了,則馬上進(jìn)入分析PAT的處理,獲取了所有的PMT的PID.接著循環(huán)查找是否出現(xiàn)PMT,如果發(fā)現(xiàn)了,則自動(dòng)進(jìn)?入PMT分析,獲取該頻段所有的頻道數(shù)據(jù)并保存.如果沒有發(fā)現(xiàn)PAT或者沒有發(fā)現(xiàn)PMT,說(shuō)明該頻段沒有信號(hào),進(jìn)入下一個(gè)頻率掃描.?從以上描述可以看出,機(jī)頂盒搜索頻率是隨機(jī)發(fā)生的,要使每次機(jī)頂盒都能搜索到信號(hào),則要求TS流每隔一段時(shí)間就發(fā)送一?次PAT和PMT.事實(shí)上DVB傳輸系統(tǒng)就是這么做的.因此無(wú)論何時(shí)接入終端系統(tǒng),系統(tǒng)都能馬上搜索到節(jié)目并正確解復(fù)用實(shí)現(xiàn)播放.不僅僅如此,其他數(shù)據(jù)也?都是交替?zhèn)魉偷?span lang="en-us">.比如第一個(gè)Packet可能是PAT,第二個(gè)Packet可能是PMT,而第三個(gè)Packet可能是Video 1,第四個(gè)Packet可能是Video 2,?只要系統(tǒng)傳輸速度足夠快(就是稱之為"碼率"的東東),實(shí)現(xiàn)實(shí)時(shí)播放是沒有任何問題的.?到這里雖然實(shí)現(xiàn)了解復(fù)用,但可以看出,使用的PID都是枯燥的數(shù)字,如果調(diào)臺(tái)要用戶自己輸入數(shù)字那可是太麻煩了,而且還容易輸入錯(cuò)?誤,操作非常不直觀,即使做成一個(gè)菜單讓用戶選擇也是非常的呆板.針對(duì)這個(gè)問題,DVB系統(tǒng)提出了一個(gè)SDT表格,該表格標(biāo)志一個(gè)節(jié)目的名稱,并且能和?PMT中的PID聯(lián)系起來(lái),這樣用戶就可以通過(guò)直接選擇節(jié)目名稱來(lái)選擇節(jié)目了.

?

SDT, Service description section,服務(wù)描述段

SDT可以提供的信息包括:

(1)?該節(jié)目是否在播放中

(2)?該節(jié)目是否被加密

(3)?該節(jié)目的名稱

SDT定義如下:?各字段定義如下:

table_id:8bits的ID,可以是0x42,表示描述的是當(dāng)前流的信息,也可以是0x46,表示是其他流的信息(EPG使用此參數(shù))

section_syntax_indicator:段語(yǔ)法標(biāo)志,一般是''1''

reserved_future_used:2bits保留未來(lái)使用

reserved:1bit保留位,防止控制字沖突,一般是''0'',也有可能是''1''

section_length:12bits的段長(zhǎng)度,單位是Bytes,從transport_stream_id開始,到CRC_32結(jié)束(包含)

transport_stream_id:16bits當(dāng)前描述的流ID

reserved:2bits保留位

version_number:5bits的版本號(hào)碼,如果數(shù)據(jù)更新則此字段遞增1

current_next_indicator:當(dāng)前未來(lái)標(biāo)志,一般是''0'',表示當(dāng)前馬上使用.?original_netword_id:16bits的原始網(wǎng)絡(luò)ID號(hào)

reserved_future_use:8bits保留未來(lái)使用位?接下來(lái)是N個(gè)節(jié)目信息的循環(huán):

service_id:16 bits的服務(wù)器ID,實(shí)際上就是PMT段中的program_number.?reserved_future_used:6bits保留未來(lái)使用位

EIT_schedule_flag:1bit的EIT信息,1表示當(dāng)前流實(shí)現(xiàn)了該節(jié)目的EIT傳送?EIT_present_following_flag:1bits的EIT信息,1表示當(dāng)前流實(shí)現(xiàn)了該節(jié)目的EIT傳送?running_status:3bits的運(yùn)行狀態(tài)信息:1-還未播放?2-幾分鐘后馬上開始,3-被暫停播出,4-正在播放,其他---保留

free_CA_mode:1bits的加密信息,''1''表示該節(jié)目被加密.?緊?接著的是描述符,一般是Service descriptor,分析此描述符可以獲取servive_id指定的節(jié)目的節(jié)目名稱.具體格式請(qǐng)參考?EN300468中的Service descriptor部分.

?

分析完畢,則節(jié)目名稱和節(jié)目號(hào)碼已經(jīng)聯(lián)系起來(lái)了.機(jī)頂盒程序就可以用這些節(jié)目名稱代替?PID讓用戶選擇,從而實(shí)現(xiàn)比較友好的用戶界面!?下面參考一下<>中的界面和顯示信息.?上?圖是<>打開三個(gè)不同的碼流文件(*.ts)形成的PID信息和節(jié)目名稱.用戶?可以通過(guò)切換節(jié)目名稱的下拉列表框切換節(jié)目,也可以通過(guò)"視頻流"和"音頻流"下拉列表框切換Video和Audio!這些數(shù)據(jù)都是通過(guò)分析PAT, PMT和SDT得到的.?(轉(zhuǎn)載自網(wǎng)路)


http://blog.csdn.net/blackboyofsnp/article/details/4665409

// 所有原創(chuàng)文章轉(zhuǎn)載請(qǐng)注明作者及鏈接
//?blackboycpp(AT)gmail.com
// QQ群: 135202158

對(duì)TS流的分析, 涉及到對(duì)PAT,PMT等等的分析, 具體內(nèi)容見iso/iec 13838系列文檔,

本文只給出自己寫的一些和TS分析想關(guān)的代碼, 簡(jiǎn)單的分析足夠了, 不考慮復(fù)雜情況:

?

[cpp]?view plaincopy
  • //??
  • //??
  • //??TS流結(jié)構(gòu)定義??
  • //??
  • //??
  • ??
  • #ifndef?ZZQ_TS_H_??
  • #define?ZZQ_TS_H_??
  • ??
  • #include?<vector>??
  • using?namespace?std;??
  • typedef??unsigned?char??byte;??
  • typedef??unsigned?int???bits;??
  • ??
  • #define??TSPKT_LENGTH??188??
  • ??
  • //-----------------------------------------------------------------------------??
  • //?結(jié)構(gòu)體??
  • //-----------------------------------------------------------------------------??
  • //?TS包構(gòu)成偽代碼??
  • ??
  • //?TS包頭部??
  • //?WARNING!!!??暫時(shí)沒有考慮修改區(qū)以及修改區(qū)內(nèi)可選字段的處理??
  • struct?ts_header??
  • {??
  • ????bits??sync_byte????????????????????:?8;??
  • ????bits??transport_error_indicator????:?1;??
  • ????bits??payload_unit_start_indicator?:?1;??
  • ????bits??transport_priority???????????:?1;??
  • ????bits??PID??????????????????????????:?13;??
  • ????bits??transport_scrambling_control?:?2;??
  • ????bits??adaptation_field_control?????:?2;??
  • ????bits??continuity_counter???????????:?4;??
  • };??
  • //?TS包中的修改字段(adaptation?field)??
  • struct?ts_adaptation_field??
  • {??
  • ????bits??adaptation_field_length?:?8;??
  • ????bits??discontinuity_idicator??:?1;??
  • ????bits??random_access_indicator?:?1;??
  • ????bits??elementary_stream_priority_indicator?:?1;??
  • ????bits??flags???????????????????:?5;?//?5?flags??
  • };??
  • ??
  • //?PAT中的可變段??
  • struct?ts_pat_section??
  • {??
  • ????bits??program_number?:?16;??
  • ????bits??reserved???????:?3;??
  • ????bits??PID????????????:?13;??
  • };??
  • typedef?vector<ts_pat_section>??vec_pat_section;??
  • //?PAT表,?P138-PAT的結(jié)構(gòu),?文檔P61??
  • struct?ts_pat??
  • {??
  • ????bits??table_id?????????????????:?8;??//?0x00??
  • ????bits??section_syntax_indicator?:?1;??//?1??
  • ????bits??zero?????????????????????:?1;??//?0??
  • ????bits??reserved_1???????????????:?2;??//?11??
  • ????bits??section_length???????????:?12;???
  • ????bits??transport_stream_id??????:?16;?//?傳輸數(shù)據(jù)流識(shí)別??
  • ????bits??reserved_2???????????????:?2;??//?"11"??
  • ????bits??version_number???????????:?5;??
  • ????bits??current_next_indicator???:?1;??
  • ????bits??section_number???????????:?8;??
  • ????bits??last_section_number??????:?8;??
  • ????//?....?TODO??
  • ????vec_pat_section?network_section;??
  • ????vec_pat_section?pmt_section;??
  • ????bits??crc32????????????????????:?32;??
  • };??
  • ??
  • //?Stream_type分配表,?P85??
  • #define??ST_Reserved????????0x00?//?ITU-T?|?ISO/IEC?Reserved??
  • #define??ST_VIDEO_1?????????0x01?//?ISO/IEC?11172?Video??
  • #define??ST_VIDEO_2?????????0x02?//?ITU-T?Rec.?H.262?|?ISO/IEC?13818-2?Video?or?ISO/IEC?11172-2?constrained?parameter?video?stream??
  • #define??ST_AUDIO_1?????????0x03?//?ISO/IEC?11172?Audio??
  • #define??ST_AUDIO_2?????????0x04?//?ISO/IEC?13818-3?Audio??
  • #define??ST_PRIVATE_SECTIONS????????0x05?//?ITU-T?Rec.?H.222.0?|?ISO/IEC?13818-1?private_sections??
  • #define??ST_PES_PKT_PRIVATE_DATA????0x06?//?ITU-T?Rec.?H.222.0?|?ISO/IEC?13818-1?PES?packets?containing?private?data??
  • #define??ST_MHEG????????????0x07?//?ISO/IEC?13522?MHEG??
  • #define??ST_DSMCC???????????0x08?//?ITU-T?Rec.?H.222.0?|?ISO/IEC?13818-1?Annex?A?DSM?CC??
  • #define??ST_H2221???????????0x09?//?ITU-T?Rec.?H.222.1??
  • #define??ST_TYPEA???????????0x0A?//?ISO/IEC?13818-6?type?A??
  • #define??ST_TYPEB???????????0x0B?//?ISO/IEC?13818-6?type?B??
  • #define??ST_TYPEC???????????0x0C?//?ISO/IEC?13818-6?type?C??
  • #define??ST_TYPED???????????0x0D?//?ISO/IEC?13818-6?type?D??
  • #define??ST_AUXILIARY???????0x0E?//?ISO/IEC?13818-1?auxiliary??
  • //?0x0F-0x7F:?ITU-T?Rec.?H.222.0?|?ISO/IEC?13818-1?Reserved??
  • //?0x80-0xFF:?User?Private??
  • //?PMT表中的ES段??
  • struct?ts_pmt_es_section??
  • {??
  • ????bits??stream_type??????????????:?8;??
  • ????bits??reserved_1???????????????:?3;??
  • ????bits??elementary_PID???????????:?13;??
  • ????bits??reserved_2???????????????:?4;??
  • ????bits??ES_info_length???????????:?12;??
  • };??
  • typedef?vector<ts_pmt_es_section>??vec_pmt_section;??
  • ??
  • //?PMT表,?書P138?-?PMT的結(jié)構(gòu)??
  • struct?ts_pmt??
  • {??
  • ????bits??table_id?????????????????:?8;??//?0x02??
  • ????bits??section_syntax_indicator?:?1;??//?1??
  • ????bits??zero?????????????????????:?1;??//?0??
  • ????bits??reserved_1???????????????:?2;??//?11??
  • ????bits??section_length???????????:?12;??
  • ????bits??program_number???????????:?16;??
  • ????bits??reserved_2???????????????:?2;??//?11??
  • ????bits??version_number???????????:?5;??
  • ????bits??current_next_indicator???:?1;??
  • ????bits??section_number???????????:?8;??
  • ????bits??last_section_number??????:?8;??
  • ????bits??reserved_3???????????????:?3;??//?111??
  • ????bits??PCR_PID??????????????????:?13;??
  • ????bits??reserved_4???????????????:?4;??//?1111??
  • ????bits??program_info_length??????:?12;??
  • ????vec_pmt_section??es_section;??
  • ????bits??crc32????????????????????:?32;??
  • };??
  • ??
  • //?PES包構(gòu)成偽代碼??P43??
  • ??
  • ??
  • //?Steam?ID分配表,??文檔P47??
  • #define??SID_PROGRAM_STREAM_MAP?????0xBC??
  • #define??SID_PRIVATE_STREAM_1???????0xBD??
  • #define??SID_PADDING_STREAM?????????0xBE??
  • #define??SID_PRIVATE_STREAM_2???????0xBF??
  • #define??SID_AUDIO_STREAM???????????0xC0?//?110x?xxxx,?stream?number?x?xxxx??
  • #define??SID_VIDEO_STREAM???????????0xE0?//?1110?xxxx,?stream?number?xxxx??
  • #define??SID_ECM_STREAM?????????????0xF0??
  • #define??SID_EMM_STREAM?????????????0xF1??
  • #define??SID_DSMCC_STREAM???????????0xF2??
  • #define??SID_13522_STREAM???????????0xF3??
  • #define??SID_TYPEA??????????????????0xF4??
  • #define??SID_TYPEB??????????????????0xF5??
  • #define??SID_TYPEC??????????????????0xF6??
  • #define??SID_TYPED??????????????????0xF7??
  • #define??SID_TYPEE??????????????????0xF8??
  • #define??SID_ANCILLARY_STREAM???????0xF9??
  • //?1111?1010?~?1111?1110,?reserved?data?stream??
  • #define??SID_PROGRAM_STREAM_DIRECTORY???0xFF??
  • ??
  • //?PES包中的可選包頭部??
  • struct?optional_pes_header??
  • {??
  • ????bits??prefix???????????????????:?2;?//?"10"??
  • ????bits??pes_scrambling_control???:?2;??
  • ????bits??pes_priority?????????????:?1;??
  • ????bits??data_alignment_indicator?:?1;??
  • ????bits??copyright????????????????:?1;??
  • ????bits??original_or_copy?????????:?1;??
  • ????//?7?flags?start??
  • ????bits??PTS_DTS_flags????????????:?2;??
  • ????bits??ESCR_flag????????????????:?1;??
  • ????bits??ES_rate_flag?????????????:?1;??
  • ????bits??DSM_trick_mode_flag??????:?1;??
  • ????bits??additional_copy_info_flag:?1;??
  • ????bits??PES_CRC_flag?????????????:?1;??
  • ????bits??PES_extension_flag???????:?1;??
  • ????//?7?flags?end??
  • ????bits??pes_header_data_length???:?8;??
  • ????//?WARNING!!!?目前只使用?PTS,?DTS??
  • ????bits??PTS_H????????????????????:?3;??//?32..30??
  • ????bits??PTS_M????????????????????:?15;?//?29..15??
  • ????bits??PTS_L????????????????????:?15;?//?14..0??
  • ????bits??DTS_H????????????????????:?3;??//?32..30??
  • ????bits??DTS_M????????????????????:?15;?//?29..15??
  • ????bits??DTS_L????????????????????:?15;?//?14..0??
  • };??
  • ??
  • //?PES包頭部,?文檔P43,?書P131??
  • struct?pes_header??
  • {??
  • ????bits??packet_start_code_prefix?:?24;??
  • ????bits??stream_id????????????????:?8;??
  • ????bits??pes_packet_length????????:?16;??
  • ????//?之后是optional?PES?header,?即任意包頭,?它的有無(wú)由stream_id決定??
  • ????bool??ophdr_flag;??
  • ????optional_pes_header?ophdr;??//?如果聲明為指針,?會(huì)帶來(lái)一些內(nèi)存問題??
  • ????//byte*??es_data;???//?實(shí)際數(shù)據(jù)指針??
  • ????int???offset;???//?實(shí)際數(shù)據(jù)偏移??
  • ??????
  • ????pes_header()??
  • ????{??
  • ????????ophdr_flag?=?false;??
  • ????????offset?=?-1;??
  • ????}??
  • ????~pes_header()??
  • ????{}??
  • };??
  • ??
  • //-----------------------------------------------------------------------------??
  • //?位段結(jié)構(gòu)調(diào)整函數(shù)??
  • //-----------------------------------------------------------------------------??
  • int?adjust_ts_header(ts_header*?pkt,?byte*?buff);??
  • int?adjust_ts_pat(ts_pat*?pkt,?byte*?buff);??
  • int?adjust_ts_pmt(ts_pmt*?pkt,?byte*?buff);??
  • int?adjust_ts_pes_header(pes_header*?pkt,?byte*?buff);??
  • __int64??get_pts_from_pes(pes_header&?pkt);??
  • __int64??get_dts_from_pes(pes_header&?pkt);??
  • #endif??
  • ?

    [cpp]?view plaincopy
  • //??
  • //??
  • //??TS流相關(guān)函數(shù)??
  • //??
  • //??
  • #include?<stdio.h>??
  • #include?"zzq_TS.h"??
  • ??
  • int?adjust_ts_header(ts_header*?pkt,?byte*?buff)??
  • {??
  • ????if(pkt?==?NULL?||?buff?==?NULL)??
  • ????{???return?1;???}??
  • ????pkt->sync_byte?=?buff[0];??
  • ????pkt->transport_error_indicator?=?buff[1]?>>?7;??
  • ????pkt->payload_unit_start_indicator?=?buff[1]?>>?6?&?0x01;??
  • ????pkt->transport_priority?=?buff[1]?>>?5?&?0x01;??
  • ????pkt->PID?=?(buff[1]?&?0x1f)<<8?|?buff[2];??
  • ????pkt->transport_scrambling_control?=?buff[3]?>>?6;??
  • ????pkt->adaptation_field_control?=?buff[3]?>>?4?&?0x03;??
  • ????pkt->continuity_counter?=?buff[3]?&?0x03;??
  • ????return?0;??
  • }??
  • ??
  • int?adjust_ts_pat(ts_pat*?pkt,?byte*?buff)??
  • {??
  • ????if(pkt?==?NULL?||?buff?==?NULL)??
  • ????{???return?1;???}??
  • ????pkt->table_id?=?buff[0];??
  • ????pkt->section_syntax_indicator?=?buff[1]?>>?7;??
  • ????pkt->zero?=?buff[1]?>>?6?&?0x1;??
  • ????pkt->reserved_1?=?buff[1]?>>?4?&?0x3;??
  • ????pkt->section_length?=?(buff[1]?&?0x0f)?<<?8?|?buff[2];??
  • ????pkt->transport_stream_id?=?buff[3]?<<?8?|?buff[4];??
  • ????pkt->reserved_2?=?buff[5]?>>?6;??
  • ????pkt->version_number?=?buff[5]?>>?1?&?0x1f;??
  • ????pkt->current_next_indicator?=?(buff[5]?<<?7)?>>?7;??
  • ????pkt->section_number?=?buff[6];??
  • ????pkt->last_section_number?=?buff[7];??
  • ????//?get?crc32??
  • ????int?len?=?3?+?pkt->section_length;??
  • ????pkt->crc32?=?(buff[len-4]?&?0x000000ff)?<<?24?|??
  • ?????????????????(buff[len-3]?&?0x000000ff)?<<?16?|??
  • ?????????????????(buff[len-2]?&?0x000000ff)?<<?8??|??
  • ?????????????????(buff[len-1]?&?0x000000ff);??
  • ????//?get?variable?section??
  • ????for(int?i=0;?i<pkt->section_length-4-8;?i+=4?)??
  • ????{??
  • ????????ts_pat_section?sec;??
  • ????????sec.program_number?=?buff[8+i]?<<?8?|?buff[9];??
  • ????????sec.reserved?=?buff[10+i]?>>?5;??
  • ????????sec.PID?=?(buff[10+i]?<<?3)?<<?5?|?buff[11+i];??
  • ????????if(sec.program_number?==?0x0)??
  • ????????????pkt->network_section.push_back(sec);??
  • ????????else??
  • ????????????pkt->pmt_section.push_back(sec);??
  • ????}??
  • ????return?0;??
  • }??
  • ??
  • int?adjust_ts_pmt(ts_pmt*?pkt,?byte*?buff)??
  • {??
  • ????if(pkt?==?NULL?||?buff?==?NULL)???
  • ????{???return?1;???}??
  • ????pkt->table_id?=?buff[0];??
  • ????pkt->section_syntax_indicator?=?buff[1]?>>?7;??
  • ????pkt->zero?=?buff[1]?>>?6;??
  • ????pkt->reserved_1?=?buff[1]?>>?4;??
  • ????pkt->section_length?=?(buff[1]?&?0x0f)?<<?8?|?buff[2];??
  • ????pkt->program_number?=?buff[3]?<<?8?|?buff[4];??
  • ????pkt->reserved_2?=?buff[5]?>>?6;??
  • ????pkt->version_number?=?buff[5]?>>?1?&?0x1f;??
  • ????pkt->current_next_indicator?=?(buff[5]?<<?7)?>>?7;??
  • ????pkt->section_number?=?buff[6];??
  • ????pkt->last_section_number?=?buff[7];??
  • ????pkt->reserved_3?=?buff[8]?>>?5;??
  • ????pkt->PCR_PID?=?((buff[8]?<<?8)?|?buff[9])?&?0x1fff;??
  • ????pkt->reserved_4?=?buff[10]?>>?4;??
  • ????pkt->program_info_length?=?(buff[10]?&?0x0f)?<<?8?|?buff[11];??
  • ????//?get?crc32??
  • ????int?len?=?pkt->section_length?+?3;??
  • ????pkt->crc32?=?(buff[len-4]?&?0x000000ff)?<<?24?|??
  • ?????????????????(buff[len-3]?&?0x000000ff)?<<?16?|??
  • ?????????????????(buff[len-2]?&?0x000000ff)?<<?8??|??
  • ?????????????????(buff[len-1]?&?0x000000ff);??
  • ????//?skip?program?description??
  • ????int?pos?=?12?+?pkt->program_info_length;??
  • ????for(?;?pos?<=?(pkt->section_length-4);?pos+=5)??
  • ????{??
  • ????????ts_pmt_es_section?sec;??
  • ????????sec.stream_type?=?buff[pos];??
  • ????????sec.reserved_1?=?buff[pos+1]?>>?5;??
  • ????????sec.elementary_PID?=?((buff[pos+1]?<<?8)?|?buff[pos+2])?&?0x1fff;??
  • ????????sec.ES_info_length?=?(buff[pos+3]?&?0x0f)?<<?8?|?buff[pos+4];??
  • ????????pkt->es_section.push_back(sec);??
  • ????????pos?+=?sec.ES_info_length;??
  • ????}??
  • ????return?0;??
  • }??
  • ??
  • int?adjust_ts_pes_header(pes_header*?pkt,?byte*?buff)??
  • {??
  • ????if(pkt?==?NULL?||?buff?==?NULL)???
  • ????{???return?1;???}??
  • ????//?0000?0000?0000?0000?0000?0001?:?0x000001??
  • ????pkt->packet_start_code_prefix?=?(buff[0]?&?0x0000ff)?<<?16?|??
  • ????????????????????????????????????(buff[1]?&?0x0000ff)?<<?8??|??
  • ????????????????????????????????????(buff[2]?&?0x0000ff);??
  • ????//if(pkt->packet_start_code_prefix?!=?0x000001)??return?2;??
  • ????byte?sid?=?buff[3];?//?aux??
  • ????pkt->stream_id?=?buff[3];??
  • ????pkt->pes_packet_length?=?buff[4]?<<?8?|?buff[5];??
  • ????if(sid?!=?SID_PROGRAM_STREAM_MAP?&&??
  • ???????sid?!=?SID_PADDING_STREAM?&&??
  • ???????sid?!=?SID_PRIVATE_STREAM_2?&&??
  • ???????sid?!=?SID_ECM_STREAM?&&??
  • ???????sid?!=?SID_EMM_STREAM?&&??
  • ???????sid?!=?SID_PROGRAM_STREAM_DIRECTORY?&&??
  • ???????sid?!=?SID_DSMCC_STREAM?&&??
  • ???????sid?!=?SID_TYPEE??
  • ??????)??
  • ????{??
  • ????????pkt->ophdr_flag?=?true;??
  • ????????pkt->ophdr.prefix?=?buff[6]?>>?6;?//?"10"?:?2??
  • ????????//if(pkt->ophdr->prefix?!=?2)?return?2;??
  • ????????pkt->ophdr.pes_scrambling_control?=?buff[6]?>>?4?&?0x03;??
  • ????????pkt->ophdr.pes_priority?=?buff[6]?>>?3?&?0x01;??
  • ????????pkt->ophdr.data_alignment_indicator?=?buff[6]?>>?2?&?0x01;??
  • ????????pkt->ophdr.copyright?=?buff[6]?>>?1?&?0x01;??
  • ????????pkt->ophdr.original_or_copy?=?buff[6]?&?0x01;??
  • ????????pkt->ophdr.PTS_DTS_flags?=?buff[7]?>>?6?&?0x03;??
  • ????????pkt->ophdr.ESCR_flag?=?buff[7]?>>?5?&?0x01;??
  • ????????pkt->ophdr.ES_rate_flag?=?buff[7]?>>?4?&?0x01;??
  • ????????pkt->ophdr.DSM_trick_mode_flag?=?buff[7]?>>?3?&?0x01;??
  • ????????pkt->ophdr.additional_copy_info_flag?=?buff[7]?>>?2?&?0x01;??
  • ????????pkt->ophdr.PES_CRC_flag?=?buff[7]?>>?1?&?0x01;??
  • ????????pkt->ophdr.PES_extension_flag??=?buff[7]?&?0x01;??
  • ????????pkt->ophdr.pes_header_data_length?=?buff[8];??
  • ????????if(pkt->ophdr.PTS_DTS_flags?==?0x2)?//?"10"??
  • ????????{??
  • ????????????//?以下移位操作,?都將各位串靠左對(duì)齊??
  • ????????????pkt->ophdr.PTS_H?=?buff[9]?<<?3?&?0xe0;?//?3?bits??
  • ????????????pkt->ophdr.PTS_M?=?(buff[10]?<<?8)?|?(buff[11]?&?0xfe);?//?15?bits??
  • ????????????pkt->ophdr.PTS_L?=?(buff[12]?<<?8)?|?(buff[13]?&?0xfe);?//?15?bits??
  • ????????}??
  • ????????else?if(pkt->ophdr.PTS_DTS_flags?==?0x3)?//?"11"??
  • ????????{??
  • ????????????//?以下移位操作,?都將各位串靠左對(duì)齊??
  • ????????????pkt->ophdr.PTS_H?=?buff[9]?<<?3?&?0xe0;?//?3?bits??
  • ????????????pkt->ophdr.PTS_M?=?(buff[10]?<<?8)?|?(buff[11]?&?0xfe);?//?15?bits??
  • ????????????pkt->ophdr.PTS_L?=?(buff[12]?<<?8)?|?(buff[13]?&?0xfe);?//?15?bits??
  • ????????????pkt->ophdr.DTS_H?=?buff[14]?<<?3?&?0xe0;??
  • ????????????pkt->ophdr.DTS_M?=?(buff[15]?<<?8)?|?(buff[16]?&?0xfe);?//?15?bits??
  • ????????????pkt->ophdr.DTS_L?=?(buff[17]?<<?8)?|?(buff[18]?&?0xfe);?//?15?bits??
  • ????????}??
  • ????????//??
  • ????????//??ESCR,?ES_rate之類的目前不處理??
  • ????????//?6?+?3:?(24+8+16)?+?(2+2+1+1+1+1+8+8)??
  • ????????pkt->offset?=?6?+?3?+?pkt->ophdr.pes_header_data_length;??
  • ????}??
  • ????else?if(sid?==?SID_PROGRAM_STREAM_MAP?||??
  • ????????????sid?==?SID_PRIVATE_STREAM_2?||??
  • ????????????sid?==?SID_ECM_STREAM?||??
  • ????????????sid?==?SID_EMM_STREAM?||??
  • ????????????sid?==?SID_PROGRAM_STREAM_DIRECTORY?||??
  • ????????????sid?==?SID_DSMCC_STREAM?||??
  • ????????????sid?==?SID_TYPEE??
  • ???????????)??
  • ????{??
  • ????????pkt->offset?=?6;??
  • ????}??
  • ????else?if(sid?==?SID_PADDING_STREAM)??
  • ????{??
  • ????????pkt->offset?=?-1;??
  • ????}??
  • ??????
  • ????return?0;??
  • }??
  • ??
  • __int64??get_pts_from_pes(pes_header&?pkt)??
  • {??
  • ????if(pkt.ophdr_flag?==?false)?return?-1;??
  • ????if(pkt.ophdr.PTS_DTS_flags?!=?0x2?&&?pkt.ophdr.PTS_DTS_flags?!=?0x3)??
  • ????????return?-1;??
  • ????__int64?H?=?0,?M?=?0,?L?=?0;??
  • ????L?=?pkt.ophdr.PTS_L?>>?1?|?pkt.ophdr.PTS_M?<<?14;??
  • ????M?=?pkt.ophdr.PTS_M?>>?2?|?pkt.ophdr.PTS_H?<<?13;??
  • ????L?=?pkt.ophdr.PTS_H?>>?3;??
  • ????return?(H<<32)?|?(M<<16)?|?L;??
  • }??
  • __int64??get_dts_from_pes(pes_header&?pkt)??
  • {??
  • ????if(pkt.ophdr_flag?==?false)?return?-1;??
  • ????if(pkt.ophdr.PTS_DTS_flags?!=?0x3)??
  • ????????return?-1;??
  • ????__int64?H?=?0,?M?=?0,?L?=?0;??
  • ????L?=?pkt.ophdr.DTS_L?>>?1?|?pkt.ophdr.DTS_M?<<?14;??
  • ????M?=?pkt.ophdr.DTS_M?>>?2?|?pkt.ophdr.DTS_H?<<?13;??
  • ????L?=?pkt.ophdr.DTS_H?>>?3;??
  • ????return?(H<<32)?|?(M<<16)?|?L;??
  • }?
  • 總結(jié)

    以上是生活随笔為你收集整理的PAT、PMT、SDT详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。