// 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;
}
|