一个简单的从指定MPEG2/TS文件中获取PMT PID的函数,
注意代码中的注释。
#define MAKE_PID(p) (((p[0]<<8) + p[1]) & 0x1fff)
- ushort GetPmtPid(const char* filename)
- {
- #define TSPACKET_SIZE 188
- ushort pid;
- uchar buf[TSPACKET_SIZE];
- uchar* p = buf;
- FILE* fp;
- fp = fopen(filename, "rb");
- if (fp == NULL) {
- fprintf(stderr, "Failed to open the file %s: %s\n", filename, strerror(errno));
- return 0;
- }
- while (fread(buf, 1, TSPACKET_SIZE, fp) == TSPACKET_SIZE) {
- if (buf[0] != MPEG_TS_SYNC_BYTE) {
- fprintf(stderr, "No sync byte where one was expected!\n");
- break;
- }
- p = buf;
- pid = MAKE_PID((p+1));
- if ( pid != 0 ) {
- // 不是PAT包
- continue;
- }
- // Skip the TS header
- p += MPEG_TS_HEADER_SIZE; //@MPEG_TS_HEADER_SIZE = 4
- // Adaptation field exist or not
- if ((buf[3] >> 4 & 0x03) & 0x2) {
- fprintf(stderr, "Adaptation field exist\n");
- p += 1 + p[0]; // p[0]是Adaptation field长度, 1为长度域
- }
- // p[0] 为 Point field长度, 1为Point field
- p += 1 + p[0];
- // 8 为PAT表头长度,如果定义了表头,则用sizeof运算符
- p += 8;
- // NIT Program exist??
- if( *((ushort*)p) == 0) {
- p += 4; // PAT的节目结构为4字节
- }
- p += 2; // 节目号为两个字节
- fclose(fp);
- return MAKE_PID(p);
- }
- fclose(fp);
- return 0;
- }