音视频封装格式:MPTG2-TS

TS流主要是广电领域使用,我们看到的电视节目就是TS流封装,然后再在机顶盒解码解封装和播放。我们看电视有很多频道,比如CCTV、地方卫视等。

而同一个频道还有很多节目,就像CCTV频道下面,在同一时刻就有CCTV1-CCTV14这些节目,那么这些频道、节目、音视频码流又是如何在TS里面进行区分呢?又是如何支持随机播放呢?又是怎么完成音画同步呢?

仔细想想这就是TS复杂的原因,我们在互联网中可能借用了这种封装,只是传了一路视频和音频,所以很多字段我们并不理解,原因就是因为我们只使用了比较简单的一种场景。

通常TS流的后缀是.ts、.mpg或者.mpeg,多数播放器直接支持这种格式的播放。

TS流生成和解析的过程

TS流的形成过程:

1、 将原始音视频数据压缩之后,压缩结果组成一个基本码流(ES)。

2、 对ES(基本码流)进行打包形成PES。

3、 在PES包中加入时间戳信息(PTS/DTS)。

4、 将PES包内容分配到一系列固定长度的传输包(TS Packet)中。

5、 在传输包中加入定时信息(PCR)。

6、 在传输包中加入节目专用信息(PSI) 。

7、 连续输出传输包形成具有恒定比特率的MPEG-TS流。

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

TS流的解析过程,可以说是生成的逆过程:

1、从复用的MPEG-TS流中解析出TS包;

2、从TS包中获取PAT及对应的PMT(PSI中的表格);

3、从而获取特定节目的音视频PID;

4、通过PID筛选出特定音视频相关的TS包,并解析出PES;

5、从PES中读取到PTS/DTS,并从PES中解析出基本码流ES;

6、将ES交给解码器,获得压缩前的原始音视频数据。

TS码流整体结构

MPEG-2中规定TS传输包的长度是固定的,长度为188字节。标准规定每个TS包只能包含一个基本流的数据,不存在跨基本流的情况。

所有的TS包都分为包头和净荷部分。TS包中可以填入很多东西(填入的东西都是填入到净荷部分),有:视频、音频、数据(包括PSI、SI以及其它任何形式的数据)。TS只是传输层的协议,所以比较多的面向错误处理的误码纠正。

TS包头

TS包的包头提供关于传输方面的信息:同步、有无差错、有无加扰、PCR(节目参考时钟)等标志。TS包的包头长度不固定,前32比特(4个字节)固定,后面可能跟有自适应字段(适配域)。

TS负载的类型

TS包负载部分可以分成两种类型:

视频、音频的PES包以及辅助数据。

节目专用信息PSI,包括下面几种:

PAT:节目关联表。提供了节目好和对应PMT表格的PID的对应关系

PMT:节目映射表。定义了与特定节目相关的PID信息,例如:音频包的pid,视频包的pid

CAT:条件接收表。用于流加扰情况下配置参数。

NIT:网络信息表。可选的,标准未详细定义

TSDT:传输流描述表。可选的。

PAT

TS流中会定期出现PAT表。PAT表提供了节目号和对应PMT表格的PID的对应关系。

PMT

PMT在传送流中用于指示组成某一套节目的视频、音频和数据在传送流中的位置,即对应的TS包的PID值,以及每路节目的节目时钟参考(PCR)字段的位置。

PES

PES包使用固定的24位起始码0x000001和一个8位的stream-id,用于说明当前包的类型。PES包中可以包含DTS/PTS等时间戳信息。整体结构如下图:

PES包非定长,音频的PES包小于等于64K,视频的一般为一帧一个PES包。一帧图象的PES包通常要由许多个TS包来传输。MPEG-2中规定,一个PES包必须由整数个TS包来传输。如果承载一个PES包的最后一个TS包没能装满,则用填充字节来填满。

获取TS包中的音视频数据

每个TS包的前4个字节的包头里都有一个PID,首先,一个个遍历TS包,我们找到PID为0的TS包,这个包叫PAT,这个PAT包里包含了PMT的PID号,所以我们再遍历TS包又又可以找到名为PMT的TS包,PMT里有什么呢?PMT里包含了video TS包的PID和它的codec,audio TS包的PID和它的codec 。有了codec我们知道要选择什么解码器,有PID我们就可以获得解码数据。

一帧视频就是一个PES包。一个PES包是分配在连续的几个TS包中,所以如果我们要获得一帧数据,那么我们需要把连续的几个TS包里的数据全部取出来才能组合成一个PES。那我们怎么知道一个PES的开始和结尾呢?那我们还是一个个遍历每一个TS包,寻找包头里payload_unit_start_indicator为1包,这个标志位代表着是一个PES的开始,那么我从这开始,一直到下一个payload_unit_start_indicator为1,这中间的TS包组成起来就是一个PES。

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

猜你喜欢

转载自blog.csdn.net/m0_60259116/article/details/126645982