typedef struct PAT_Packet_tag
{
unsigned table_id : 8;
unsigned section_syntax_indicator : 1;
unsigned zero : 1;
unsigned reserved_1 : 2;
unsigned section_length : 12;
unsigned transport_stream_id : 16;
unsigned reserved_2 : 2;
unsigned version_number : 5;
unsigned current_next_indicator : 1;
unsigned section_number : 8;
unsigned last_section_number : 8;
unsigned program_number : 16;
unsigned reserved_3 : 3;
unsigned network_PID : 16;
// }
unsigned CRC_32 : 32;
} PAT_Packet;
int Parse_PAT(unsignedchar *pTSBuf, PAT_Packet *packet)
{
TS_header TSheader;
if (Parse_TS_packet_header(pTSBuf, &TSheader) != 0)
return -1;
if (TSheader.payload_unit_start_indicator == 0x01)
{
if (TSheader.PID == 0x0)
{
int iBeginlen = 4;
int adaptation_field_length = pTSBuf[4];
switch(TSheader.adaption_field_control)
{
case 0x0:
return -1;
case 0x1:
iBeginlen += pTSBuf[iBeginlen] + 1;
break;
case 0x2:
return -1;
case 0x3:
if (adaptation_field_length > 0)
{
iBeginlen += 1;
iBeginlen += adaptation_field_length;
}
else
{
iBeginlen += 1;
}
iBeginlen += pTSBuf[iBeginlen] + 1;
break;
default:
break;
}
unsignedchar *pPAT = pTSBuf + iBeginlen;
packet->table_id = pPAT[0];
packet->section_syntax_indicator = pPAT[1] >> 7;
packet->zero = pPAT[1] >> 6 & 0x1;
packet->reserved_1 = pPAT[1] >> 4 & 0x3;
packet->section_length = (pPAT[1] & 0x0F) << 8 |pPAT[2];
packet->transport_stream_id = pPAT[3] << 8 | pPAT[4];
packet->reserved_2 = pPAT[5] >> 6;
packet->version_number = pPAT[5] >> 1 & 0x1F;
packet->current_next_indicator = (pPAT[5] << 7) >> 7;
packet->section_number = pPAT[6];
packet->last_section_number = pPAT[7];
int len = 0;
len = 3 + packet->section_length;
packet->CRC_32 = (pPAT[len-4] & 0x000000FF) << 24
| (pPAT[len-3] & 0x000000FF) << 16
| (pPAT[len-2] & 0x000000FF) << 8
| (pPAT[len-1] & 0x000000FF);
int n = 0;
for ( n = 0; n < (packet->section_length - 12); n += 4 )
{
packet->program_number = pPAT[8 + n ] << 8 | pPAT[9 + n ];
packet->reserved_3 = pPAT[10 + n ] >> 5;
if ( packet->program_number == 0x00)
{
packet->network_PID = (pPAT[10 + n ] & 0x1F) << 8 |pPAT[11 + n ];
}
else
{
program_map_PID = (pPAT[10 + n] & 0x1F) << 8 |pPAT[11 + n];
}
}
return 0;
}
}
return -1;
}