提取 PAT PMT C语言
时间: 2023-11-23 21:09:20 浏览: 138
PAT(Program Association Table)和PMT(Program Map Table)是数字视频广播领域中的两个协议。
在C语言中,提取PAT和PMT需要进行以下步骤:
1. 打开TS文件,读取TS包,获取PAT表的PID值。
2. 读取TS包,判断PID是否为PAT表的PID值,如果是则解析PAT表。
3. 解析PAT表,获取PMT表的PID值。
4. 读取TS包,判断PID是否为PMT表的PID值,如果是则解析PMT表。
5. 解析PMT表,获取视频流和音频流的PID值。
6. 读取TS包,判断PID是否为视频流或音频流的PID值,如果是则提取数据。
下面是示例代码:
```c
#include <stdio.h>
typedef struct {
unsigned char table_id;
unsigned char section_syntax_indicator;
unsigned short section_length;
unsigned short transport_stream_id;
unsigned char version_number;
unsigned char current_next_indicator;
unsigned char section_number;
unsigned char last_section_number;
unsigned int program_number;
unsigned char reserved_3;
unsigned int network_PID;
unsigned int program_map_PID;
} PAT;
typedef struct {
unsigned char table_id;
unsigned char section_syntax_indicator;
unsigned short section_length;
unsigned int program_number;
unsigned char reserved_3;
unsigned char version_number;
unsigned char current_next_indicator;
unsigned char section_number;
unsigned char last_section_number;
unsigned short PCR_PID;
unsigned short program_info_length;
unsigned int stream_type;
unsigned short elementary_PID;
unsigned short ES_info_length;
} PMT;
int main() {
FILE *fp = fopen("test.ts", "rb");
if (fp == NULL) {
printf("Open file failed!\n");
return -1;
}
unsigned char buffer[188];
PAT pat;
PMT pmt;
while (fread(buffer, 1, 188, fp) == 188) {
// 判断PID是否为PAT表的PID值
if (buffer[1] == 0x00) {
pat.table_id = buffer[0];
pat.section_syntax_indicator = (buffer[1] >> 7) & 0x01;
pat.section_length = ((buffer[1] & 0x0f) << 8) | buffer[2];
pat.transport_stream_id = (buffer[3] << 8) | buffer[4];
pat.version_number = (buffer[5] >> 1) & 0x1f;
pat.current_next_indicator = buffer[5] & 0x01;
pat.section_number = buffer[6];
pat.last_section_number = buffer[7];
pat.network_PID = ((buffer[8] & 0x1f) << 8) | buffer[9];
pat.program_map_PID = ((buffer[10] & 0x1f) << 8) | buffer[11];
}
// 判断PID是否为PMT表的PID值
else if (buffer[1] == pmt.program_map_PID) {
pmt.table_id = buffer[0];
pmt.section_syntax_indicator = (buffer[1] >> 7) & 0x01;
pmt.section_length = ((buffer[1] & 0x0f) << 8) | buffer[2];
pmt.program_number = (buffer[3] << 8) | buffer[4];
pmt.version_number = (buffer[5] >> 1) & 0x1f;
pmt.current_next_indicator = buffer[5] & 0x01;
pmt.section_number = buffer[6];
pmt.last_section_number = buffer[7];
pmt.PCR_PID = ((buffer[8] & 0x1f) << 8) | buffer[9];
pmt.program_info_length = ((buffer[10] & 0x0f) << 8) | buffer[11];
int i = 12 + pmt.program_info_length;
while (i < 12 + pmt.section_length - 4) {
pmt.stream_type = buffer[i];
pmt.elementary_PID = ((buffer[i+1] & 0x1f) << 8) | buffer[i+2];
pmt.ES_info_length = ((buffer[i+3] & 0x0f) << 8) | buffer[i+4];
i += 5 + pmt.ES_info_length;
}
}
// 提取视频流或音频流的数据
else if (buffer[1] == pmt.elementary_PID) {
// TODO: 提取数据
}
}
fclose(fp);
return 0;
}
```
阅读全文