前言
好记性不如烂笔头,学过的东西没有用的话过了几个月就忘得差不多了,所以写写博客记录一下学习过程中的一些“线索”,便于日后自己再“复习”的时候勾起我的回忆。
正文
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包中携带的播放需要的DTS
和PTS
,用33位来表示,由于ts流使用的系统时钟频率为27000000,所以ts中的DTS和PTS并不是毫秒为单位而是使用1/90ms为单位。
更多的细节还是需要看官方文档: google搜索ISO/IEC 13818-1