// Program Association Table
typedef
struct
PAT_Packet_tag
{
unsigned table_id : 8;
//固定为0x00 ,标志是该表是PAT
unsigned section_syntax_indicator : 1;
//段语法标志位,固定为1
unsigned zero : 1;
//0
unsigned reserved_1 : 2;
// 保留位
unsigned section_length : 12;
//表示这个字节后面有用的字节数,包括CRC32
unsigned transport_stream_id : 16;
//该传输流的ID,区别于一个网络中其它多路复用的流
unsigned reserved_2 : 2;
// 保留位
unsigned version_number : 5;
//范围0-31,表示PAT的版本号
unsigned current_next_indicator : 1;
//发送的PAT是当前有效还是下一个PAT有效
unsigned section_number : 8;
//分段的号码。PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段
unsigned last_section_number : 8;
//最后一个分段的号码
// for(i=0; i<N; i++)
// {
unsigned program_number : 16;
unsigned reserved_3 : 3;
unsigned network_PID : 16;
// 或者program_map_PID
unsigned CRC_32 : 32;
// }
} PAT_Packet;
// Parse PAT
int
Parse_PAT(unsigned
char
*pTSBuf, PAT_Packet *packet)
{
TS_header TSheader;
if
(Parse_TS_packet_header(pTSBuf, &TSheader) != 0)
return
-1;
if
(TSheader.payload_unit_start_indicator == 0x01)
// 表示含有PSI或者PES头
{
if
(TSheader.PID == 0x0)
// 表示PAT
{
int
iBeginlen = 4;
int
adaptation_field_length = pTSBuf[4];
switch
(TSheader.adaption_field_control)
{
case
0x0:
// reserved for future use by ISO/IEC
return
-1;
case
0x1:
// 无调整字段,仅含有效负载
iBeginlen += pTSBuf[iBeginlen] + 1;
// + pointer_field
break
;
case
0x2:
// 仅含调整字段,无有效负载
return
-1;
case
0x3:
// 调整字段后含有效负载
if
(adaptation_field_length > 0)
{
iBeginlen += 1;
// adaptation_field_length占8位
iBeginlen += adaptation_field_length;
// + adaptation_field_length
}
else
{
iBeginlen += 1;
// adaptation_field_length占8位
}
iBeginlen += pTSBuf[iBeginlen] + 1;
// + pointer_field
break
;
default
:
break
;
}
unsigned
char
*pPAT = pTSBuf + iBeginlen;
packet->table_id = pTSBuf[0];
packet->section_syntax_indicator = pTSBuf[1] >> 7;
packet->zero = pTSBuf[1] >> 6 & 0x1;
packet->reserved_1 = pTSBuf[1] >> 4 & 0x3;
packet->section_length = (pTSBuf[1] & 0x0F) << 8 | pTSBuf[2];
packet->transport_stream_id = pTSBuf[3] << 8 | pTSBuf[4];
packet->reserved_2 = pTSBuf[5] >> 6;
packet->version_number = pTSBuf[5] >> 1 & 0x1F;
packet->current_next_indicator = (pTSBuf[5] << 7) >> 7;
packet->section_number = pTSBuf[6];
packet->last_section_number = pTSBuf[7];
int
len = 0;
len = 3 + packet->section_length;
packet->CRC_32 = (pTSBuf[len-4] & 0x000000FF) << 24
| (pTSBuf[len-3] & 0x000000FF) << 16
| (pTSBuf[len-2] & 0x000000FF) << 8
| (pTSBuf[len-1] & 0x000000FF);
int
n = 0;
for
( n = 0; n < (packet->section_length - 12); n += 4 )
{
packet->program_number = pTSBuf[8 + n ] << 8 | pTSBuf[9 + n ];
packet->reserved_3 = pTSBuf[10 + n ] >> 5;
if
( packet->program_number == 0x00)
{
packet->network_PID = (pTSBuf[10 + n ] & 0x1F) << 8 | pTSBuf[11 + n ];
}
else
{
// 有效的PMT的PID,然后通过这个PID值去查找PMT包
program_map_PID = (pTSBuf[10 + n] & 0x1F) << 8 | pTSBuf[11 + n];
}
}
return
0;
}
}
return
-1;
}
联系客服