TS码流解析-3-解析PAT表
程序员文章站
2022-03-05 12:13:17
...
任务三
解析PAT表,并且获取码流里面跟节目相关的PID
相关知识
我们首先来查看下PAT表的结构,如下图所示
在这个结构里面,我们需要关注的是program_number以及program_map_PID。
我们获取到PAT的表之后,对其中的section进行解析,把我们需要的信息取出来,然后存入数据结构,这个任务就算完成了。
解析过程
1 流程图
2 数据结构定义
typedef struct pat_info
{
unsigned int program_number :16;
unsigned int reserved :3;
unsigned int program_number_pid :13;
struct pat_info *next;
}PAT_INFO;
3 代码
static PAT_INFO *insert_pat_info_to_link(PAT_INFO *pat_info_link_head, PAT_INFO additive_node)
{
PAT_INFO *new_pat_info_node = NULL;
new_pat_info_node = (PAT_INFO*)malloc(sizeof(PAT_INFO));
if (NULL == new_pat_info_node)
{
log("malloc error!\n");
return pat_info_link_head;
}
new_pat_info_node->program_number = additive_node.program_number;
new_pat_info_node->program_number_pid = additive_node.program_number_pid;
new_pat_info_node->reserved = additive_node.reserved;
// head insert
new_pat_info_node->next = pat_info_link_head;
return new_pat_info_node;
}
PAT_INFO *create_pat_info_link(FILE *ts_file, unsigned int package_length, int first_sync_position)
{
SECTION *pat_table = NULL;
SECTION *current_handle_section = NULL;
int current_read_position = 0;
int end_read_position = 0;
PAT_INFO swap_pat_node = {0};
PAT_INFO *pat_info_link_head = NULL;
if ((NULL==ts_file) || (first_sync_position<0) || (0==package_length))
{
log("function parse_pmt parameter error");
return pat_info_link_head;
}
pat_table = create_section_link(ts_file, package_length, first_sync_position, PAT_TABLE_ID, PAT_PID, eit_check);
if (NULL == pat_table)
{
log("get PAT table error!\n");
return pat_info_link_head;
}
current_handle_section = pat_table;
while (current_handle_section != NULL)
{
current_read_position = SECTION_HEAD_LENGTH;
end_read_position = current_handle_section->section_length - SECTION_CRC_LENGTH;
while (current_read_position < end_read_position)
{
swap_pat_node.program_number = (current_handle_section->section_buffer[current_read_position] << 8) |
current_handle_section->section_buffer[current_read_position + 1];
swap_pat_node.program_number_pid = (current_handle_section->section_buffer[current_read_position + 2] & 0x1f) << 8 |
current_handle_section->section_buffer[current_read_position + 3];
current_read_position += PROGRAM_INFO_LENGTH;
if (NETWORK_PID == swap_pat_node.program_number)
{
continue;
}
pat_info_link_head = insert_pat_info_to_link(pat_info_link_head, swap_pat_node);
}
current_handle_section = current_handle_section->next;
}
log("-----------------------------------PAT-----------------------------------\n");
show_pat_info(pat_info_link_head);
destroy_section_link(pat_table);
pat_table = NULL;
return pat_info_link_head;
}
相对来说,解析PAT表的难度不大,需要注意的是读取字节的位置一定要准确,是读取当前位置呢,还是读取下一个位置一定要清楚,不然整个读取过程都会乱套的。
下一篇: Simplify Path