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 : 13;
// }
unsigned CRC_32 : 32;
} PAT_Packet;
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)
{
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
;
}
unsigned
char
*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;
}