前言
TS流这个是MPEG国际组织规定的音视频封装的标准,机顶盒接收的都是这种格式的数据。DVB-T、DVB-S、DVB-C(地面机顶盒、卫星机顶盒、有线机顶盒)解析的都是TS流数据。
TS流背景介绍
在介绍具体字段,参数这些头疼,烦人的东西之前,我觉得有必要先介绍下TS流的应用背景,有了这个概念,再去深入学习,将如虎添翼。TS流最经典的应用就是我们平时生活中的数字高清电视。我们看的电视码流就是TS封装格式的码流,电视码流发送过来后,就会由我们的机顶盒进行解封装,解码,然后传给电视机进行播放。这里就有一个问题,我们看电视,有很多的频道,节目,对应码流是怎么区分的呢?(TIPS,频道和节目的关系,比如我们有中央电视台综合频道,下属CCTV-1~CCTV14这些节目)TS流引入了PAT和PMT两张表格的概念来解决这个问题。
PAT和PMT
TS流是以每188字节为一包,我们可以称为ts packet。这个ts packet有可能是音视频数据,也有可能是表格。举例说明,TS流的包顺序为:
PAT,PMT,DATA,DATA,,,,,,PAT,PMT,DATA,DATA,,,,,,
每隔一段时间,发送一张PAT表,紧接着发送一张PMT表,接着发送DATA(音视频)数据。
那么你可能要问了,有了这2张表格怎么区分频道,节目呢?PAT表格里面包含所有PMT表格的信息,一个PMT表格对应一个频道,比如中央电视台综合频道。而一个PMT里面包含所有节目的信息,比如CCTV1~CCTV14。在实际情况中我们是有很多频道的,所以PMT表格可不止一张,有可能是PAT,PMT,PMT,PMT,,,DATA,DATA,,,,PAT,PMT,PMT,,,DATA,DATA这样的形式。除了这个设定外,每个频道或节目都有自己的标识符(PID),这样当我们拿到一个DATA,解析出里面的PID,就知道是什么节目,并且也知道所属频道是什么了。我们看电视的时候,会收到所有节目的DATA,当我们正在看某个节目的时候,机顶盒会把这个节目的DATA单独过滤出来,其它的舍弃。
TS packet格式讲解
ts packet我们知道一包是188字节,它分为ts header和ts body。其中ts header里面会有个PID字段标识着当前ts body的类型。ts body有可能是表格,也有可能是DATA,表格没什么好说的,我们说下DATA的结构。DATA包
其实就是PES包,而PES包是对ES的封装,PES包分为PES头加ES。这里的ES是原始流,是指经过压缩后的H264,aac等格式的音视频数据。那么帧数据,PES包,ts packet包的对应关系是什么样的呢?一帧数据封装成一个PES包(含PES头和ES),这个PES包如果小于188字节,那么一个ts packet就可以放下了。最终ts packet一包的格式就是ts header+填充字节+PES包(PES头+ES)。填充字节的意思是如果ts header加上PES包不满188字节,这个时候肯定要填充下使其凑满188字节发送。是不是很简单?那么我们知道视频帧是很大的,往往大于188字节,这个时候怎么存放呢?还是把一个视频帧放入一个PES包。然后分别放在几个ts packet包即可。结构如下:
第一个ts packet:ts header+PES头+部分ES
第二个ts packet:ts header+部分ES
...
最后一个ts packet:ts header+填充字节+部分ES
PES头加上这些部分ES,就是一个PES包。
具体字段解析
具体字段请参考ISOIEC 13818-1.pdf文档,看起来应该没什么困难,这里不再累述。
但是其中ts header里的payload_unit_start_indicator和pes header里的PES_packet_length这两个字段,在解析ts流的时候至关重要,新手可能比较困惑,不懂其意,我得好好讲讲。
payload_unit_start_indicator有两个值,0或1,具体的意思我们来举个例子。假设有两个视频帧,每个视频帧假设都需要3个ts packet包来存放一个PES包。那么一共有6个ts packet,它们的payload_unit_start_indicator的值为1,0,0,1,0,0,值为1代表一个帧的开始,下一个1就是新的一帧的开始了。
PES_packet_length顾名思义就是PES包的长度,但是注意,它是2个字节存储的,这意味着,最大只能表示65535,一旦视频帧很大,超过这个长度,怎么办,就把PES_packet_length置为0,这是ISO标准规定的。所以在解析的时候,不能以PES_packet_length为准,要参考payload_unit_start_indicator。
pts dts pcr单位
pts:显示时间戳,单位是毫秒*90
dts:解码时间戳,单位是毫秒*90
pcr:节目时钟参考,单位是毫秒90300