Blog From http://blog.csdn.net/kof98765/article/details/17733701
http://hongdow.com/rtp%E3%80%81rtcp%E5%8F%8A%E5%AA%92%E4%BD%93%E6%B5%81%E5%90%8C%E6%AD%A5.html
RTCP控制參數
由於音視頻流作爲不同的RTP會話傳送,它們在RTP層無直接關聯。儘管由一個數據源發出的不同的流具有不同的同步源標識(SSRC),爲能進行流同步,RTCP要求發送方給接收方傳送一個唯一的標識數據源的規範名(canonical name),應用層藉此關聯音視頻流,以便實現同步。RTP/ RTCP中有時間戳(相對和絕對)和序列號等信息,可以利用它實現基於時間戳的多媒體流同步。使用相對時間戳和序列號實現流內同步;使用相對和絕對時間戳的對應關係實現流間同步。獲得相對與絕對時間戳的算法如下:
while ((pack = GetNextPacket()) != NULL)
{
if(srcdat->SR_HasInfo() && srcdat->SR_GetRTPTimestamp() != app->mvideortcprtp)
{
app->mvideortcprtp = srcdat->SR_GetRTPTimestamp();
app->mvideortcpntp = srcdat->SR_GetNTPTimestamp().GetMSW();
srcdat->FlushPackets();
}
DeletePacket(pack);
}
音視頻流間同步實現發送端在發送音視頻數據時,同時也會發送SR包,這樣可以使接收方能夠正確使音視頻同步播放。具體實現方法是在接收方每次接收數據包後,再遍歷一次數據源,獲取所有源端的SS_RTPTime與SS_NTPTime這兩則數據,通過獲取音頻端與視頻端的數據,可以利用下面的公式進行計算。
表 2.1 變量描述表
類型 RTP數據 NTP數據 RTP時戳頻率
音頻 Audio_SRRTPTime Audio_SRNTPTime Audio_Fre
視頻 Video_SRRTPTime Video_SRNTPTime Video_Fre
從SR包中可以讀出音頻與視頻的RTP與NTP數據,而需要計算的是時戳頻率,利用下述公式:
Audio_Fre=( AudioSRRTPtime2- AudioSRRTPtime1)/( AudioSRNTPtime2- AudioSRNTPtime1)
Video_Fre=( VideoSRRTPtime2- VideoSRRTPtime1)/( VideoSRNTPtime2- Video SRNTPtime1)
然後計算視頻RTP的時間,即: Video_RTPTime=Video_SRRTPTime + (Audio_SRNTP-Video_SRNTP)×Video_Fre
最後即可計算出Video_TRUERTP時間,將其與從RTP包中讀出的時間進行比較,就可以進行同步播放了。 (Video_TRUERTP-Video_RTPTime)/Video_Fre=(Audio_TRUERTP-Audio_SRRTPTime)/Audio_Fre
下面採用臨時緩衝區的方法來同步音視頻。因爲要保證音頻優先正常傳輸,所以本系統以音頻爲主軸,視頻爲輔軸。
以最大延遲時間爲緩衝區大小,存放M個音頻幀數據。當接收端獲得M個音頻幀後開始播放音頻,每次獲得視頻幀時,就計算出當前視頻應當播放RTP時間與現有RTP時間進行比對,如若在120ms以內,迅速播放;延遲120ms以上,則扔掉,然後比對下一幀;還在120ms以內,放入視頻緩衝區內進行儲存,如果視頻緩衝區的大小超過了最大臨時緩衝區的數值,依舊開始播放。