1. 概要
PAT:节目关联表,与PMT成对出现,包含所有的频道编号;是解析ts数据的起点。
PAT数据结构如下:
PAT数据结构
字段分析:
TS头:参考TS协议之PES(数据包),已做过解释这里不多做解释。
PAT信息体:
字段 | 字段描述 |
表id | PAT设置为0x0 |
段语法标志位 | 固定位1 |
0 | 固定为0 |
保留位 | 固定为0x11(每一位都是1) |
分段长度 | 分段长度后面直到CRC字段的长度(不包括分段长度) |
传输流id | 由用户规定。该字段充当标签,标识网络内此传输流有别于任何其他多路复用流 |
保留位 | 固定为0x11(每一位都是1) |
版本号 | 指示符 设置为‘1’时,版本号 必须为当前有效的节目相关表的版本号。指示符 设置为‘0’时,版本号 为下一个有效的节目相关表的版本号。 |
指示符 | 1:发送的节目相关表为当前有效的。 0:发送的该表尚未有效并且下一个表将生效。 |
分段号 | 有可能一个PAT描述很多PMT,导致PAT很长,所以PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段 |
最后一个分段号 | 最后一个分段的号码 |
节目单 | 该字段是一个容器,该容器内可能有很多个节目 |
CRC32校验 | CRC32校验,是对除CRC32字段外PAT所有字段的校验 |
节目单:
字段 | 字段描述 |
节目号 | 0:表明这是NIT(网络信息表)非0:这是PMT(节目信息表) |
保留位 | 固定为0x11(每一位都是1) |
网络信息表 | 与节目信息表只能存在一个,用于标识传输流中一个特定的网络,提供网络相关的信息,如网络识别符、传输参数等;个网络都有一个唯一的network_PID(网络信息表)值。 |
节目信息表 | 用于指向每个节目的节目映射表(PMT),每个节目都有一个唯一的program_map_PID(节目信息表)值。 |
2. PAT代码结构
typedef struct TS_PAT_Program
{
unsigned program_number :16; //节目号
unsigned reserved_3 : 3; // 保留位
unsigned program_map_PID :13; //节目映射表的PID,节目号大于0时对应的PID,每个节目对应一个
}TS_PAT_Program;
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 network_PID : 13; //网络信息表(NIT)的PID,节目号为0时对应的PID为network_PID
unsigned CRC_32 : 32; //CRC32校验码
} TS_PAT;
上述代码可见节目单字段是一个容器:std::vector program;容器容每个TS_PAT_Program结构对用一个PMT,所以当PMT很多的时候可能超过188个字节,要进行分段;
在TS传输过程中,就是遍历该容器通过查找program_map_PID字段找到对应的PMT。
文档已上传:PAT文档下载
后续会更新更多音视频相关技术,关注一下。