音视频同步

来源:互联网 发布:学plc编程需要什么基础 编辑:程序博客网 时间:2024/05/16 05:29

1. 音视频同步

(1)视音频同步简单介绍

  一般来说,视频同步指的是视频和音频同步,也就是说播放的声音要和当前显示的画面保持一致。在视频流和音频流中已包含了其以怎样的速度播放的相关数据,视频的帧率(Frame Rate)指示视频一秒显示的帧数(图像数);音频的采样率(Sample Rate)表示音频一秒播放的样本(Sample)的个数。可以使用以上数据通过简单的计算得到其在某一Frame(Sample)的播放时间,以这样的速度音频和视频各自播放互不影响,在理想条件下,其应该是同步的,不会出现偏差。但,理想条件是什么大家都懂得。如果用上面那种简单的计算方式,慢慢的就会出现音视频不同步的情况。要不是视频播放快了,要么是音频播放快了,很难准确的同步。这就需要一种随着时间会线性增长的量,视频和音频的播放速度都以该量为标准,播放快了就减慢播放速度;播放慢了就加快播放的速度。所以呢,视频和音频的同步实际上是一个动态的过程,同步是暂时的,不同步则是常态。以选择的播放速度量为标准,快的等待慢的,慢的则加快速度,是一个你等我赶的过程。
  播放速度标准量的选择一般来说有以下三种:
- 将视频同步到音频上,就是以音频的播放速度为基准来同步视频。视频比音频播放慢了,加快其播放速度;快了,则延迟播放。换句话说,也就是根据音频的PTS来控制视频的播放,在视频解码一帧后,是否显示以及显示多长时间是通过该帧的PTS与同时正在播放的音频的PTS比较而来的,如果音频的PTS较大,则视频显示完毕准备下一帧的解码显示,否则等待。
- 将音频同步到视频上,就是以视频的播放速度为基准来同步音频。
- 将视频和音频同步外部的时钟上,选择一个外部时钟为基准,视频和音频的播放速度都以该时钟为标准。

  ==注意:==一般情况下,音频不容易同步到视频,但视频比较容易同步到音频,因为音频输出的采样率等参数一般都是固定的,设定好以后消耗数据的速率基本是固定的,很难在播放过程当中动态调整,而视频显示的图像更新速率更容易调整些。通常可以通过加速刷新,跳帧等办法来调整。

(2)DTS和PTS

  上面提到,视频和音频的同步过程是一个你等我赶的过程,快了则等待,慢了就加快速度。这就需要一个量来判断(和选择基准比较),到底是播放的快了还是慢了,或者正以同步的速度播放。在视音频流中的包中都含有DTS和PTS,就是这样的量(准确来说是PTS)。DTS,Decoding Time Stamp,解码时间戳,告诉解码器packet的解码顺序;PTS,Presentation Time Stamp,显示时间戳,指示从packet中解码出来的数据的显示顺序。换句话说,DTS和PTS分别是解码器进行解码和显示帧时相对于SCR(系统参考)的时间戳。SCR可以理解为解码器应该开始从磁盘读取数据时的时间。
  视音频都是顺序播放的,其解码的顺序不应该就是其播放的顺序么,为啥还要有DTS和PTS之分呢。对于音频来说,DTS和PTS是相同的,也就是其解码的顺序和解码的顺序是相同的,但对于视频来说情况就有些不同了。
  视频的编码要比音频复杂一些,特别的是预测编码是视频编码的基本工具,这就会造成视频的DTS和PTS的不同。这样视频编码后会有三种不同类型的帧:
- I帧 关键帧,包含了一帧的完整数据,解码时只需要本帧的数据,不需要参考其他帧。
- P帧 P是向前搜索,该帧的数据不完全的,解码时需要参考其前一帧的数据。
- B帧 B是双向搜索,解码这种类型的帧是最复杂,不但需要参考其一帧的数据,还需要其后一帧的数据。

  I帧的解码是最简单的,只需要本帧的数据;P帧也不是很复杂,只需要缓存上一帧的数据即可,总体来说都是线性,其解码顺序和显示顺序是一致的。B帧就比较复杂了,需要前后两帧的顺序,并且不是线性的,也是造成了DTS和PTS的不同的“元凶”,也是在解码后有可能得不到完整Frame的原因。(更多I,B,P帧的信息可参考:I,P,B帧和PTS,DTS的关系)

背景知识:

(一)音视频同步-时间戳

  从技术上来说,解决音视频同步问题的最佳方案就是时间戳:首先选择一个参考时钟(要求参考时钟上的时间是线性递增的);生成数据流时依据参考时钟上的时间给每个数据块都打上时间戳(一般包括开始时间和结束时间);在播放时,读取数据块上的时间戳,同时参考当前参考时钟上的时间来安排播放(如果数据块的开始时间大于当前参考时钟上的时间,则不急于播放该数据块,直到参考时钟达到数据块的开始时间;如果数据块的开始时间小于当前参考时钟上的时间,则“尽快”播放这块数据或者索性将这块数据“丢弃”,以使播放进度追上参考时钟)。
  可见,避免音视频不同步现象有两个关键——一是在生成数据流时要打上正确的时间戳。如果数据块上打的时间戳本身就有问题,那么播放时再怎么调整也于事无补。假如,视频流内容是从0s开始的,假设10s时有人开始说话,要求配上音频流,那么音频流的起始时间应该是10s,如果时间戳从0s或其它时间开始打,则这个混合的音视频流在时间同步上本身就出了问题。打时间戳时,视频流和音频流都是参考参考时钟的时间,而数据流之间不会发生参考关系;也就是说,视频流和音频流是通过一个中立的第三方(也就是参考时钟)来实现同步的。第二个关键的地方,就是在播放时基于时间戳对数据流的控制,也就是对数据块早到或晚到采取不同的处理方法。如上例中,参考时钟时间在0-10s内播放视频流内容过程中,即使收到了音频流数据块也不能立即播放它,而必须等到参考时钟的时间达到10s之后才可以,否则就会引起音视频不同步问题。
  基于时间戳的播放过程中,仅仅对早到的或晚到的数据块进行等待或快速处理,有时候是不够的。如果想要更加主动并且有效地调节播放性能,需要引入一个反馈机制,也就是要将当前数据流速度太快或太慢的状态反馈给“源”,让源去放慢或加快数据流的速度。熟悉DirectShow的读者一定知道,DirectShow中的质量控制(Quality Control)就是这么一个反馈机制。DirectShow对于音视频同步的解决方案是相当出色的。

这里写图片描述

(二)I,P,B帧和PTS,DTS的关系

(1)基本概念:

  I frame:帧内编码帧,又称intra picture,I帧通常是每个GOP(MPEG所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象。I帧可以看成是一个图像经过压缩后的产物。
  P frame:前向预测编码帧,又称predictive-frame,通过充分将低于图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,也叫预测帧;
  B frame:双向预测内插编码帧,又称bi-directional interpolated prediction frame,既考虑与源图像序列前面已编码帧,也顾及源图像序列后面已编码帧之间的时间冗余信息来压缩传输数据量的编码图像,也叫双向预测帧;
  STC(System Time Clock):系统时序时钟,此时钟用来产生指示音视频的正确显示和解码的时间戳,同时可用来指示在采样过程中系统时钟本身的瞬时值。
  PTS(Presentation Time Stamp):指示音视频显示时间的时间戳称为显示时间戳(PTS),PTS主要用于度量解码后的视频帧什么时候被显示出来;
  DTS(Decoding Time Stamp):指示音视频的解码时间戳称为解码时间戳(DTS),DTS主要是标识读入内存中的bit流在什么时候开始送入解码器中进行解码。
  在没有B帧存在的情况下DTS的顺序和PTS的顺序应该是一样的。

(2)IPB帧的不同:

  I frame:自身可以通过视频解压算法解压成一张单独的完整的图片。
  P frame:需要参考其前面的一个I frame 或者B frame来生成一张完整的图片。
  B frame:则要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的图片。
  两个I frame之间形成一个GOP,在x264中同时可以通过参数来设定bf的大小,即:I和p或者两个P之间B的数量。
  通过上述基本可以说明如果有B frame存在的情况下一个GOP的最后一个frame一定是P。

(3)DTS和PTS的不同:

  DTS主要用于视频的解码,在解码阶段使用。PTS主要用于视频的同步和输出,在display的时候使用。在没有B frame的情况下,DTS和PTS的输出顺序是一样的。

例子:
下面给出一个GOP为15的例子,其解码的参照frame及其解码的顺序都在里面:

这里写图片描述

  如上图:I frame的解码不依赖于任何的其它的帧。而p frame的解码则依赖于其前面的I frame或者B frame。B frame的解码则依赖于其前的最近的一个I frame或者P frame 及其后的最近的一个P frame。

原创粉丝点击