原文链接:http://www.rosoo.net/a/201101/10776.html
多媒体通信同步方法,主要有时间戳同步法、同步标记法、多路复用同步法三种。下面主要讨论时间戳同步法,特别是RTP时间戳同步。内容包括RTP媒体间同步的实现,为什么需要RTCP的NTP时间来实现媒体间同步?没有RTCP,能实现RTP媒体间的同步吗?DirectShow时间戳和RTP时间戳的区别,MPEG2-TS流的时间戳等。本文只简单讨论时间戳同步的原理,不涉及具体的实现方法,如音频帧和视频帧时间戳的计算方法,怎样根据时间戳去做音视频的呈现等。
根据RTP规范,不同的RTP媒体流是分开传输的,且使用各自独立的时间戳进行同步。假设在一次视频点播中,传输两路RTP媒体流,一路视频,一路音频。根据视频帧时间戳,可以实现视频流内同步,这很好理解,通过视频帧时间戳可以计算出相邻视频帧的时间间隔,也就是视频帧之间的相对时间关系很容易通过时间戳来确定,按照这个间隔去呈现视频,就可以获得较好的效果。同理,音频流也可以实现自身的同步。
那么音频和视频这两路媒体间如何实现同步呢?我们只使用音视频的RTP时间戳,看能否实现媒体间的同步。音视频的RTP时间戳的增长速率一般是不同的,但没关系,知道了具体的单位后,两者是可以通过单位换算联系起来的。如下图:
现在来看,这种方法好像可以实现同步,因为音视频被映射到同一个时间轴上了,音频和视频帧间的相对关系很清楚。慢着,RTP规范要求时间戳的初始值应该是一个随机值,那么假设音频帧时间戳的初始值是随机值1234,视频帧时间戳的初始值是随机值5678,看起来应该是下面这样:
这么做合适吗?我们把音频帧时间戳1234和视频帧时间戳5678对应到绝对时间轴的0上,我们这么做的理由是什么?你可能会说,因为那是第一个音频帧和第一个视频帧,所以可以对应到同一个点上,在第一幅图中我们就是这么做的,把音频帧时间戳0和视频帧时间戳0对应到绝对时间轴的0上。但是RTP规范并没有规定第一个视频帧的时间戳和第一个音频帧的时间戳必须或者应该对应到绝对时间轴的同一个点上,从整个RTP规范中不能直接得出这样的结论,也推导不出这样的结论。
我们上面两幅图所做的转换是不正确的,为什么呢?因为在做转换时,隐含了一个假设,我们想当然地认为这个假设是成立的,实际上它并不总是成立。这个假设就是第一个视频帧和第一个音频帧的时间戳应该对应到同一个点上,即无论它们时间戳是多少,都应该在同一时间播放。
仅仅使用RTP时间戳是无法实现媒体间同步的,根本的原因是音频时间轴和视频时间轴是完全独立的,通过音频帧和视频帧的时间戳,无法确定一个视频帧和一个音频帧的相对时间关系,也就是无法把它们都准确定位在绝对时间轴上,只能准确定位一个。
要实现RTP媒体间同步,需要借助于RTCP,在RTCP的SR包中,包含有<NTP时间,RTP时间戳>对,音频帧RTP时间戳和视频帧RTP时间戳通过<NTP时间,RTP时间戳>对,都可以准确定位到绝对时间轴NTP上,音频帧和视频帧的相对时间关系就可以确定下来了。
上面提到,我们的那个隐含的假设并不总是成立,那就是说它有成立的时候。那是不是说当它成立时,我们就可以不用RTCP来做媒体间同步了?答案是,基本上可以这么认为。
例如,对于RTP实时流,在发送端媒体间就同步的很好,在接收端只需做少许处理,不需要RTCP,就可以实现媒体间同步。当然,这只是少数例外。因为RTP规范并不包括这个假设,所以我们还是按照RTP规范来做吧。
下面说一下DirectShow和MPEG2-TS的时间戳。DirectShow中的时间戳和RTP中的时间戳,除了单位不一样,计算方法不一样外,本质的区别就是DirectShow中的音频帧和视频帧时间戳使用的是同一个时间轴,所以不需要借助其他的东西,仅仅使用音频帧时间戳和视频帧时间戳就可以实现媒体间同步。MPEG2-TS流中也有时间戳,它的时间戳和RTP及DirectShow的时间戳都不同,TS流中的音频帧和视频帧时间戳使用的也是同一个时间轴,TS流中的音频和视频是复用的,这在一定程度上就起到了同步的作用,所以它并不是在每个帧上都打时间戳,比如它的PTS时间戳就是每隔0.1秒一个,缺失的时间戳是通过其他时间戳插值计算出来的。