typedef struct _M_PAT_MAP_TYPE
{
unsigned program_number:16;
unsigned reserved:3;
unsigned program_map_pid:13;
}M_PAT_MAP_TYPE;
//PAT表结构体
typedef struct TS_PAT
{
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; //最后一个分段的号码
std::vector<TS_PAT_Program> program;
unsigned reserved_3 : 3; // 保留位
unsigned network_PID : 13; //网络信息表(NIT)的PID,节目号为0时对应的PID为network_PID
unsigned CRC_32 : 32; //CRC32校验码
} TS_PAT;
pat 解析示例代码:buffer[pos+0]是pat数据的开始位置:
packet->table_id = buffer[pos];
packet->section_syntax_indicator = buffer[pos+1] >> 7;
packet->zero = buffer[pos+1] >> 6 & 0x1;
packet->reserved_1 = buffer[pos+1] >> 4 & 0x3;
packet->section_length = ((buffer[pos+1] & 0x0F) << 8) + buffer[pos+2];
packet->transport_stream_id = buffer[pos+3] << 8 | buffer[pos+4];
packet->reserved_2 = buffer[pos+5] >> 6;
packet->version_number = buffer[pos+5] >> 1 & 0x1F;
packet->current_next_indicator = (buffer[pos+5] << 7) >> 7;
packet->section_number = buffer[pos+6];
packet->last_section_number = buffer[pos+7];
pos = pos + 8;
int n = 0;
for ( n = 0; n < packet->section_length - 12 ; n += 4 )//获取中间所有的pat节目信息
{
unsigned program_num = buffer[pos+ n ] << 8 | buffer[pos + 1 + n ];//节目号
printf("pat_handle 22222222 program_num:%x\n",program_num);
if ( program_num == 0x00)
{
packet->network_PID = (buffer[pos + 2 + n ] & 0x1F) << 8 | buffer[pos + 3 + n ];
packet->reserved_3 = buffer[pos + 2 + n ] >> 5;
ts_nit_pid = packet->network_PID;
}
else
{
unsigned program_map_pid = (buffer[pos + 2 + n] & 0x1F) << 8 | buffer[pos + 3 + n];
unsigned program_number = program_num;
{
PAT_program[pat_no].reserved = buffer[pos + 2 + n ] >> 5;
PAT_program[pat_no].program_map_pid = (buffer[pos + 2 + n] & 0x1F) << 8 | buffer[pos + 3 + n];
printf("========program_map_pid:%d :%x\n",pat_no,PAT_program[pat_no].program_map_pid);
PAT_program[pat_no].program_number = program_num;
ts_pmt_pid = PAT_program[pat_no].program_map_pid;
pat_no++;
}
}
}
TS_PMT_Stream
{
unsigned stream_type:8; /* type of elementary stream */
unsigned reserved_1:3;
unsigned elementary_pid:13; /* elementary stream pid number */
unsigned reserved_2:4;
unsigned es_info_length:12; /* length of descriptor */
unsigned descriptor;
}M_PMT_MAP_TYPE;
//PMT 表结构体
typedef struct TS_PMT
{
unsigned table_id : 8; //固定为0x02, 表示PMT表
unsigned section_syntax_indicator : 1; //固定为0x01
unsigned zero : 1; //0x01
unsigned reserved_1 : 2; //0x03
unsigned section_length : 12;//首先两位bit置为00,它指示段的byte数,由段长度域开始,包含CRC。
unsigned program_number : 16;// 指出该节目对应于可应用的Program map PID
unsigned reserved_2 : 2; //0x03
unsigned version_number : 5; //指出TS流中Program map section的版本号
unsigned current_next_indicator : 1; //当该位置1时,当前传送的Program map section可用;
//当该位置0时,指示当前传送的Program map section不可用,下一个TS流的Program map section有效。
unsigned section_number : 8; //固定为0x00
unsigned last_section_number : 8; //固定为0x00
unsigned reserved_3 : 3; //0x07
unsigned PCR_PID : 13; //指明TS包的PID值,该TS包含有PCR域,
//该PCR值对应于由节目号指定的对应节目。
//如果对于私有数据流的节目定义与PCR无关,这个域的值将为0x1FFF。
unsigned reserved_4 : 4; //预留为0x0F
unsigned program_info_length : 12; //前两位bit为00。该域指出跟随其后对节目信息的描述的byte数。
std::vector<TS_PMT_Stream> PMT_Stream; //每个元素包含8位, 指示特定PID的节目元素包的类型。该处PID由elementary PID指定
unsigned reserved_5 : 3; //0x07
unsigned reserved_6 : 4; //0x0F
unsigned CRC_32 : 32;
} TS_PMT;
pmt 解析示例代码:buffer[pos+0]是pmt数据的开始位置:
packet->table_id = buffer[pos + 0];
packet->section_syntax_indicator = buffer[pos + 1] >> 7;
packet->zero = buffer[pos + 1] >> 6 & 0x01;
packet->reserved_1 = buffer[pos + 1] >> 4 & 0x03;
packet->section_length = (buffer[pos + 1] & 0x0F) << 8 | buffer[pos + 2];
packet->program_number = buffer[pos + 3] << 8 | buffer[pos + 4];
packet->reserved_2 = buffer[pos + 5] >> 6;
packet->version_number = buffer[pos + 5] >> 1 & 0x1F;
packet->current_next_indicator = (buffer[pos + 5] << 7) >> 7;
packet->section_number = buffer[pos + 6];
packet->last_section_number = buffer[pos + 7];
packet->reserved_3 = buffer[pos + 8] >> 5;
packet->pcr_pid = ((buffer[pos + 8] << 8) | buffer[pos + 9]) & 0x1FFF;
ts_pcr_pid = packet->pcr_pid;
packet->reserved_4 = buffer[pos + 10] >> 4;
packet->program_info_length = (buffer[pos + 10] & 0x0F) << 8 | buffer[pos + 11];
int p = 12;
if ( packet->program_info_length != 0 )
pos += packet->program_info_length;
for ( ; p <= (packet->section_length + 2 ) - 4; )
{
printf("post + p = %d\n", pos + p);
unsigned long stream_type = buffer[pos + p];
printf("--- 0x%x stream type:%x\n",buffer[pos + p],stream_type);
//unsigned long elementary_pid = ((buffer[pos + p+1] << 3) | buffer[pos + p+2]) & 0x1FFF;
//unsigned long es_info_length = (buffer[pos + p+3] & 0x0F) << 8 | buffer[pos + p+4];
unsigned long elementary_pid = ((buffer[pos + p+1] & 0x1F)<<8) + buffer[pos + p+2];
unsigned long es_info_length = ((buffer[pos + p+3] & 0x0F)<<8)+ buffer[pos + p+4];
}
p = p + es_info_length ;
p += 5;
get_pmt = 1;
}