格式预览

TS 是一种封装格式,简称为 MPEG2-TS。TS 为 Transport Stream 的缩写,意为传输流,用于传输混合后的多媒体数据流。TS由188个字节的 Packet 重复组成,Packet 由4个字节的头和184个字节的 Data 组成。
TS 的格式 参考资料
TS 格式预览.svg

TS 封装了媒体的视频流和音频流,因此在上面的 Packet 中存在视频流也存在音频流,Packet 还定义了 PAT 和 PMT Packet 用来寻找紧随其后的码流。简单来说 PAT 定义如何查找 PMT 包,PMT 包定义了如何查找 Video 包和 Audio 包。
简单的画成如下的图(真实的字段比较多,下面只选取 Packet 中关键的字段,用于介绍他们之间的关系)
TS 格式预览2.svg

TS 表头

TS 包的表头由4个字节组成,起始值是以0x47 作为同步头,后面有很多重要的标识,比如上文提到的如何判断是 PAT 还是 PMT 或者其他的包的 PID

sync_byte 8b 同步字节,固定为0x47
transport_error_indicator 1b 传输错误指示符,表明在ts头的adapt域后由一个无用字节,通常都为0,这个字节算在adapt域长度内
payload_unit_start_indicator 1b 负载单元起始标示符,一个完整的数据包开始时标记为1
transport_priority 1b 传输优先级,0为低优先级,1为高优先级,通常取0
pid 13b pid值
transport_scrambling_control 2b 传输加扰控制,00表示未加密
adaptation_field_control 2b 是否包含自适应区,‘00’保留;‘01’为无自适应域,仅含有效负载;‘10’为仅含自适应域,无有效负载;‘11’为同时带有自适应域和有效负载。
continuity_counter 4b 递增计数器,从0-f,起始值不一定取0,但必须是连续的

这里关键的参数 PID 可以表示 Packet 包的类型,0x00 代表 PAT。从流中找到 PAT 后,根据格式概览中的介绍,我们就可以根据 PAT 记录的 PMT 的 PID ,在随后的流中找出 PMT 包,然后再从 PMT 中找到视频流和音频流。

TS adaptation field

adaptation_field_length 1B 自适应域长度,后面的字节数
flag 1B 取0x50表示包含PCR或0x40表示不包含PCR
PCR 5B Program Clock Reference,节目时钟参考,用于恢复出与编码端一致的系统时序时钟STC(System Time Clock)。
stuffing_bytes xB 填充字节,取值0xff

自适应区的长度要包含传输错误指示符标识的一个字节。pcr是节目时钟参考,pcr、dts、pts都是对同一个系统时钟的采样值,pcr是递增的,因此可以将其设置为dts值,音频数据不需要pcr。如果没有字段,ipad是可以播放的,但vlc无法播放。打包ts流时PAT和PMT表是没有adaptation field的,不够的长度直接补0xff即可。视频流和音频流都需要加adaptation field,通常加在一个帧的第一个ts包和最后一个ts包里,中间的ts包不加。


TS 包体

总览

在分析 TS 包体前,先看一下TS 包中大概的二进制分布。TS 分层格式.drawio
TS 分层格式.svg

ES(Elementary Stream)流是基本码流,包含音频,视频和数据的连续码流,是编码器出来的数据流,也可以是编码过的视频数据流(h264),音频流 AAC等。ES 流经过 PES打包器后转换为 PES 包。

PES(Packet Elementary Stream)是用来传递 ES 的一种数据结构,可以认为是 ES组,PES 流包含头和 Payload。TS (Transport Stream) 流是在 PES 层增加了数据流识别和传输的信息,固定长度为188字节。可以包含多个节目表,TS 会在固定的 PID 间隔后发送 PAT 表和 PMT 表。

如上面的示意图,我们可以将 TS 流分成三个层级。在工具中参看对应如下的图
Screen Shot 2021-03-16 at 3.15.19 PM.png
由于一个TS 包大小只有188个字节,如何封装像 h264 这样的流呢。可以将 h264原始流切割后封装为 PES,然后 PES 分割为TS 包,所以多个TS 包才能发送一个 h264的 I 帧数据,如果不足188个字节使用 0xff 填充。在每帧开始前需要插入一个 h264 AUD 分隔符单元,这个可以在后面介绍的时候看到。

多个 TS 包的排版如下多个 TS 包的结构.drawio
多个 TS 包的结构.svg

  • Adaptation 中包含了 pcr(program clock reference) 是节目的参考时钟,因此可以设置为 dts 值,PES1 到 PESN 代表使用 TS 打包了一个 H264的一块完整数据,比如 sps+pps+IDR 帧一组数据。
  • PAT 和 PMT 表由于长度往往不够188,不够的长度使用 0xff 填充。

PAT 包

PAT 全称Program Association Table,中文名字是节目关联表。PAT 表数据部分格式说明如下,可以看到 PAT 表中可以关联多个 PMT 表。

table_id 8b PAT表固定为0x00
section_syntax_indicator 1b 固定为1
zero 1b 固定为0
reserved 2b 固定为11
section_length 12b 后面数据的长度
transport_stream_id 16b 传输流ID,固定为0x0001
reserved 2b 固定为11
version_number 5b 版本号,固定为00000,如果PAT有变化则版本号加1
current_next_indicator 1b 固定为1,表示这个PAT表可以用,如果为0则要等待下一个PAT表
section_number 8b 固定为0x00
last_section_number 8b 固定为0x00
开始循环
program_number 16b 节目号为0x0000时表示这是NIT,节目号为0x0001时,表示这是PMT
reserved 3b 固定为111
PID 13b 节目号对应内容的PID值 PMT 的 id
结束循环
CRC32 32b 前面数据的CRC32校验码

比如下图通过工具分析到的 PAT 表
Screen Shot 2021-03-15 at 7.32.06 PM.png

PMT 包

PMT 全称为Program Map Table, 中文名称为节目映射表。它的各个字段的含义如下,在 PMT 中也有一个循环表示可以包含映射多个音视频流。

table_id 8b PMT表取值随意,0x02
section_syntax_indicator 1b 固定为1
zero 1b 固定为0
reserved 2b 固定为11
section_length 12b 后面数据的长度
program_number 16b 频道号码,表示当前的PMT关联到的频道,取值0x0001
reserved 2b 固定为11
version_number 5b 版本号,固定为00000,如果PAT有变化则版本号加1
current_next_indicator 1b 固定为1
section_number 8b 固定为0x00
last_section_number 8b 固定为0x00
reserved 3b 固定为111
PCR_PID 13b PCR(节目参考时钟)所在TS分组的PID,指定为视频PID
reserved 4b 固定为1111
program_info_length 12b 节目描述信息,指定为0x000表示没有
开始循环
stream_type 8b 流类型,标志是Video还是Audio还是其他数据,h.264编码对应0x1b,aac编码对应0x0f,mp3编码对应0x03
reserved 3b 固定为111
elementary_PID 13b 与stream_type对应的PID
reserved 4b 固定为1111
ES_info_length 12b 描述信息,指定为0x000表示没有
结束循环
CRC32 32b 前面数据的CRC32校验码

下面是用工具分析到的 h264 的流和 AAC 的流对应的 PID 值。
Screen Shot 2021-03-16 at 5.04.23 PM.png

PES 层

PES 层封装了音视频流,由于 TS 大小为188个字节,而 PES 包的 Payload 最大可以为 65526个字节。所以 TS 包分割 PES 包进行重新封装。这一点也可以看出 TS 是名副其实的传输流,而 PES才是原始码流的封装。
PES 结构.svg

pes start code 3B 开始码,固定为0x000001
stream id 1B 音频取值(0xc0-0xdf),通常为0xc0
视频取值(0xe0-0xef),通常为0xe0
pes packet length 2B 后面pes数据的长度,0表示长度不限制,
只有视频数据长度会超过0xffff
flag 1B 通常取值0x80,表示数据不加密、无优先级、备份的数据
flag 1B 取值0x80表示只含有pts,取值0xc0表示含有pts和dts
pes data length 1B 后面数据的长度,取值5或10
pts 5B 33bit值
dts 5B 33bit值

我们看一下 PES 的数据二进制,这个包是一个视频的TS包,可以看到如下一个 TS 包中 PES数据,以及 PES 数据中 的H264的数据。关于 H264的数据结构参考H264 编码分析

Screen Shot 2021-03-16 at 6.03.35 PM.png
我们通过工具看一下它的结构
image.png

本文分析的视频在此tscvonvert-edit.ts.zip,分析工具用的 010editor 和 Elecard System Analyzer。工具在参考文档中。