什么是TS?
TS(Transport Stream,传输流),一种常见的视频封装格式,是基于MPEG-2的封装格式(所以也叫MPEG-TS),后缀为.ts
TS的分层
TS文件分为三层,如下所示(可以倒序更好理解)
-
TS层(Transport Stream):在PES层基础上加入了数据流识别信息和传输信息
-
PES层(Packet Elemental Stream):在ES层基础上加入时间戳(PTS/DTS)等信息。
-
ES层(Elementary Stream):压缩编码后的音视频数据。
TS层
ts包大小固定为188字节,ts层分为三个部分:ts header、adaption field、payload。
-
ts header固定4个字节
-
adaption field可能存在也可能不存在,主要作用是给不足188字节的数据做填充。
-
payload是PES数据,或者PAT,PMT等。
-
ts Header+adaption field格式如下:
pid决定了负载内容的类型,主要包括:PAT表,PMT表,视频流,音频流。常用的PID值:
调整字段
PAT表结构(指明PMT表的PID值)
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//表示这个字节之后有用的字节数,包括CR0
unsigned transport_stream_id :16//传输流的ID,区别于一个网络中其他多路
unsigned reserved_2 :2//第二个保留位
unsigned version_number :5//表示PAT的版本号
unsigned current_next_indicator :1//表示发送的PAT是当前有效还是下一个有效
unsigned section_number :8//如果PAT分段传输,那么此值每次递增1
unsigned last_section_number :8//最后一个分段的号码
for(int i = 0;i < N; i++)
{
unsigned Program_number :16//节目号
unsigned Reversed_3 :3//保留位
if(Program_number == 0)
{
Network_id :13//网络信息表NIT的PID
}
else
Program_MAP_PID :13//节目映射表的PID,每个 节目都有一个
}
unsigned CRC_32 :32//CRC32校验码
}TS_PAT
PMT指明音视频流的PID值
补充说明
- 打包ts流时PAT和PMT表是没有调整字段的,不够的长度直接补0xff即可
- 视频流和音频流都需要加adaptation field,通常加在一个帧的第一个ts包和最后一个ts包里,中间的ts包不加。
PES层
- PES(Packetized Elementary Stream,打包的ES),在ES层的基础上加入了时间戳(PTS/TDS)等信息。
- ES数据包比较大,加入PES头时需将ES进行分割,只在第一个分割的ES上加PES头,如下图所示
- PES packet length一指示PES包中跟随该字段最后字节的字节数。0值指示PES包长度 既末指示也未限定并且仅在这样的PES包中才被允许,该PES包的有效载荷由来自传输流包中所包含的视频基本流的字节组成。
- PES结构如下: