MPEG-TS码流

前言

好记性不如烂笔头,学过的东西没有用的话过了几个月就忘得差不多了,所以写写博客记录一下学习过程中的一些“线索”,便于日后自己再“复习”的时候勾起我的回忆。

正文

mpeg在ISO/IEC 13818-1中定义了封装格式,一种是Program stream(ps)另一种是Transport stream(ts), program stream主要针对存储,transport stream主要针对传输(容错性比较好)。program stream只能封装一个频道(一路音频流和一路视频流),而transport stream能够封装多个频道,所以transport stream应用范围更广,比如蓝光光碟就使用transport stream。Program stream和Transport stream都是封装一连串PES包,每个PES包封装一个音视频帧。

TS是由一连串188个字节的ts packet组成,因为TS中包含多个媒体流,所以我们需要知道这一连串ts packet应该如何划分到不同的媒体流中,这就需要依靠PSI表(Program Specific Information),PSI表包括PAT、PMT、CAT、NT。每个ts packet都带有PID字段,PAT(Program Association Table)列出了每个频道的PMT对应的PID值,每个频道都用不同的program id来标记,PAT本身也有PID,PAT的PID为0x000。PMT(Program Map Table)定义每个频道不同媒体流对应PID值。比如PAT表中记录program id为1的PMT对应pid为1000,找到pid为1000的ts packet就是频道1的PMT表,在PMT表中记录着不同媒体流的PID值,比如video的pid为501,audio的pid为502,这样pid值为501的ts packet和pid值为502的ts packet就是频道1的音频和视频流。

program id PMT pid
1 1000
2 1001

通过PAT表可以找到频道对应的PMT

PMT pid stream type elementory pid
1000 video 501
1000 audio 502
1001 video 601
1001 audio 602

通过PMT找到频道的音视频流PID
为了便于理解,从YouTube视频里面截了一张图出来 这样我们通过PAT和PMT能够在一连串188个字节的ts packet中能够找出每个频道对应音视频流

每个音视频帧都表示为一个PES包,一个PES包可以远大于一个ts packet的大小(188字节), 这样的PES包用多个ts packet来封装,其中payload_unit_start_indicator被标记为1的ts packet表示一个PES的起始包,如果一个PES包不满足整数倍的ts packet数量,PES的末尾使用0xff来填充。

PES包中携带的播放需要的DTSPTS,用33位来表示,由于ts流使用的系统时钟频率为27000000,所以ts中的DTS和PTS并不是毫秒为单位而是使用1/90ms为单位。

更多的细节还是需要看官方文档: google搜索ISO/IEC 13818-1