对流媒体相关协议的认识(二) ——ES,PES,TS

来源:互联网 发布:外国人评论中国知乎 编辑:程序博客网 时间:2024/06/05 16:57

  在了解了流媒体的大概内容之后,下面将具体描述数据由数据源方发送给服务器方的封装过程。
  es->pes->ts流程作用是将采集到的裸数据一步一步通过在头部加包头的方式封装起来,使最后接收方接收到有该数据的相关描述信息,并由其中的信息进行数据的忽略,调整以及数据传输机制的调整。之后数据包头中的数据会有所反映(也希望后续能对为什么加这些数据能有更具体的了解)

首先引用下http://blog.chinaunix.net/uid-9688646-id-1998407.html这篇博客的TS解码过程,以便后续的理解中可以方便参考和理解:

TS 流解码过程:
1. 获取TS中的PAT
2. 获取TS中的PMT
3. 根据PMT可以知道当前网络中传输的视频(音频)类型(H264),相应的PID,PCR的PID等信息。
4. 设置demux 模块的视频Filter 为相应视频的PID和stream type等。
5. 从视频Demux Filter 后得到的TS数据包中的payload 数据就是 one piece of PES,在TS header中有一些关于此 payload属于哪个 PES的 第多少个数据包。
因此软件中应该将此payload中的数据copy到PES的buffer中,用于拼接一个PES包。
6. 拼接好的PES包的包头会有 PTS,DTS信息,去掉PES的header就是 ES。
7. 直接将 被被拔掉 PES包头的ES包送给decoder就可以进行解码。解码出来的数据就是一帧一帧的视频数据,这些数据至少应当与PES中的PTS关联一下,以便进行视音频同步。
8. I,B,B,P 信息是在ES中的。

ES(Elementary Streams)–原始流

  ES(原始流)是指直接从编码器采集过来的数据流,包括视频流(H264,MJPEG…), 音频流(AAC), 以及其他的一些编码数据流。
  ES(原始流)顾名思义是最初的数据流,裸数据。后续的协议可以在原始流上添加各自的包头数据。
  因为是原始流,所以这里不详细介绍其用法,同时有一个VBV_delay(视频流延时值)存在于视频ES的头部,长度为16bit,在后面介绍PTS和DTS时会稍加解释。但还是有几点需要注意,入下所示。

ES(原始流)单位专一性

  每个ES(原始流)只能包含一种数据类型,同时ES打包后的PES也同样只能包含一种数据类型,即如果ES中的一部分填充了H264数据,那么其他部分也只能填H264数据,就不能再填充音频数据及其他的一些数据。

ES(原始流)的组成

  一个ES流中存在了许多个AU,AU即存储单位。
  每个AU由头部和编码数据组成,其中1个AU容量相当于一幅视频图像或1个音频帧。

PES(Packetized Elementrary Stream)–被分组的原始流

  PES(被分组的原始流)是一种用来传递ES(原始流)的一种布局,而ES分组被称为PES分组。
ES>PES描述
  ES至PES的流程如上图所示,而其中的第三步骤“参加包头信息”中参加的包头内容含有PTS和DTS,下面将针对这两个内容进行详细叙述。
  至此可以知道,一个PES中含有多个ES,而PES包为PES流的单位,PES包中包含:包头和payload。

http://wenku.baidu.com/link?url=CU9-uT-m6MqN3HUyMu1CZvCpzTIPddDj_AJt7wH3EYm17FfGy8LZXDKeFYw70Tpp7JnBwAL7neRo4jCQkCfmThI8yPGOXBjiBTQrRUNMPr7
  上图中的包头又含有如下信息:

(以后会对这其中的每一位信息进行详细的记录和说明)

PTS(Presentation Time Stamp),DTS(Decoding Time Stamp)

  PTS(Presentation Time Stamp)–显示时间标记,表示的是显示单元出现在目标解码器的时间;
  DST(Decoding Time Stamp)–解码时间标记,表示存取单元从解码缓存器取出的时间;
  存在这两个值的目的是解决音视频同步,以及防止解码器上溢或者下溢的关键。在视频帧中I帧(关键帧)和P帧(预测帧)都存在PTS和DTS,而B帧(双向预测帧)只存在PTS,因为对于B帧PTS和DTS是相等的,所以没必要标出DTS。
  但这里为什么PTS和DTS能解决音视频的同步问题,因为I帧和P帧经过复用之后,数据之间的顺序会混乱,所以在显示前一定要存储于解码器的排序缓冲器中进行显示前的重新排序,重新插入PTS和DTS作为新顺序的依据。
  其实音视频同步的处理在es, pes和ts中都存在。在es层的AU(存取单元)中存在视频缓冲验证VBV(Video Buffer Verifier),作用是防止解码缓冲器的上溢或下溢;在pes层存在PTS(显示时间标签)和DTS(解码时间标签);在TS中存在节目时钟参考PCR,在同步中的作用是用来恢复与解码端一致的系统时序时钟STC。
  下面通过解码器实现音视频同步的步骤来进一步认识同步的原理:

同步准备

ES层
  从MPEG-2编码处获得ES基本数据流,该数据流包含视频的I,P,B帧,也可以包含音频帧或者是其他的一些数据流。pes打包器会在包头中包含PTS和DTS,并打包成一个长度可变的单位包。至此数据由流的形式转为以包分割的形式存在,如下图所示:
(这里pes的单位pes包是指一帧一个单位包?)

http://blog.chinaunix.net/uid-26000296-id-3478558.html

PES层
  视频编码图像帧次序为 I1,P4,B2,B3,P7,B5,B6,I10,B8,B9的ES,加入PTS/DTS后,打包成一个个视频PES包(其中一个PES包中的数据内容为一个视频帧或者一个音频帧)。每个PES包都有一个包头,用于定义PES内的数据内容,提供定时资料。对I帧和P帧,显示前一定要存储于视频解码器的重新排序缓存器中,经过延迟(重新排序)后再显示,一定要分别标明PTS和DTS(B帧PTS与DTS相同)。

例如,解码器输入的图像帧次序为I1,P4,B2,B3,P7,B5,B6,I10,B8,B9,依解码器输出的帧次序,应该P4比B2、B3在先,但显示时P4一定要比B2、B3在后,即P4要在提前插入数据流中的时间标志指引下,经过缓存器重新排序,以重建编码前视频帧次序I1,B2,B3,P4,B5,B6,P7,B8,B9,I10。显然,PTS/DTS标志表明对确定事件或确定信息解码的专用时标的存在,依靠专用时标解码器,可知道该确定事件或确定信息开始解码或显示的时刻。例如,PTS/DTS标志可用于确定编码、多路复用、解码、重建的时间。

  (当视频中无B帧时,DTS和PTS的输出顺序是一样的,也就是说在没有B frame的情况下.DTS和PTS的输出顺序是一样的.)
  而对于I帧,P帧,B帧的详细内容可以参考如下网站进行进一步的了解:http://blog.chinaunix.net/uid-26000296-id-3478558.html。这里贴出其中的一张图来大概地熟悉一下PTS与DTS对于I, P, B帧的解码和显示关系。
该图显示:I frame 的解码不依赖于任何的其它的帧.而p frame的解码则依赖于其前面的I frame或者P frame.B frame的解码则依赖于其前的最近的一个I frame或者P frame 及其后的最近的一个P frame.

  有时候PES包头里面也会有DTS,PTS,对于PTS来说,他代表了这个PES包得payload里面的第一个完整地audio access unit或者video access unit的PTS时间(并不是每个音/视频接入单元都带有PTS/DTS,因此,你可以在PES里面指定一个,作为开始)。
  PES包头的DTS也是这个原理,只不过注意的是:对于video来说他的DTS和PTS是可以不一样的,因为B帧的存在使其顺序可以倒置。而对于audio来说,audio没有双向的预测,他的DTS和PTS可以看成是一个顺序的,因此可一直采用一个,即可只采用PTS。

TS层
  TS层中对于时间同步含有PCR(Program Clock Reference),他是指示系统时钟本身的瞬时值的时间标签称为节目参考时钟标签。在TS packet的header里面可能会有,他用来指定所期望的该ts packet到达decoder的时间。

  而关于同步的相关具体内容觉得以下这篇文章给予了很详细的讲解:
  http://blog.chinaunix.net/uid-26000296-id-3478558.html

TS(TransPort Stream)–传输流

  TS(TransPort Stream)传输流,是pes连同pes包头信息的再一次封装,固定188的字节长度。至此,es已经过两层封装。
  这里的固定长度使他能在网络环境恶劣的情况下仍然能进行数据的同步,也就是说,就算在进行数据流传输是丢失了个别的TS包,接收机也能在该坏包后的固定长度来定位读取到一个正常的数据包,进而恢复同步,避免信息丢失。
  TS有两个特性,分别是单一性和混合性。
  单一性:一个TS包固定188个字节大小。
  混合型:TS不同于es与pes,TS可以有多种数据类型组成。一个TS包中的数据可以是视频数据,音频数据,填充数据,PSI/SI表格数据等(唯一PID表对应)。
TS中后续的PSI, PAT, PMT将在后续的各阶段数据包头封装时了解总结。

ES->PES->TS总结

  首先引用一张图片来系统的了解es,pes,ts的封装过程:
  引用自:
 http://www.360doc.com/content/13/0829/15/13084517_310733557.shtml

这里写图片描述

步骤一:
  首先将A/D编码器中的数据通过MPEG-2*(后续需要进一步了解)*来压缩编码得到ES流,这个ES流的特点是数据流的量很大,是一些I帧,P帧,B帧,音频帧,或者一些其他数据流。

步骤二:
  ES流通过PES打包器打包成由一个一个的以PES包(一个PES包一个视音频帧)为基本单位的PES流,每个PES包前有一个PES头,存放一些数据的描述信息。自此,数据由流的形式转变为以包分割的形式。

步骤三:
  PES流经过再次封装,即再次的增加包头信息,以及一些节目表组成TS流。因每路只包含一路的音视频编码数据流,所以每路PES也只包含相应的数据流。

0 0