一、RTP協議分析
第1章. RTP概述
1.1. RTP是什么
RTP全名是Real-time Transport Protocol(實時傳輸協議)。它是IETF提出的一個標准,對應的RFC文檔為RFC3550(RFC1889為其過期版本)。RFC3550不僅定義了RTP,而且定義了配套的相關協議RTCP(Real-time Transport Control Protocol,即實時傳輸控制協議)。RTP用來為IP網上的語音、圖像、傳真等多種需要實時傳輸的多媒體數據提供端到端的實時傳輸服務。RTP為Internet上端到端的實時傳輸提供時間信息和流同步,但並不保證服務質量,服務質量由RTCP來提供。
1.2. RTP的應用環境
RTP用於在單播或多播網絡中傳送實時數據。它們典型的應用場合有如下幾個。
簡單的多播音頻會議。語音通信通過一個多播地址和一對端口來實現。一個用於音頻數據(RTP),另一個用於控制包(RTCP)。
音頻和視頻會議。如果在一次會議中同時使用了音頻和視頻會議,這兩種媒體將分別在不同的RTP會話中傳送,每一個會話使用不同的傳輸地址(IP地址+端口)。如果一個用戶同時使用了兩個會話,則每個會話對應的RTCP包都使用規范化名字CNAME(Canonical Name)。與會者可以根據RTCP包中的CNAME來獲取相關聯的音頻和視頻,然后根據RTCP包中的計時信息(Network time protocol)來實現音頻和視頻的同步。
翻譯器和混合器。翻譯器和混合器都是RTP級的中繼系統。翻譯器用在通過IP多 播不能直接到達的用戶區,例如發送者和接收者之間存在防火牆。當與會者能接收的音頻編碼格式不一樣,比如有一個與會者通過一條低速鏈路接入到高速會議,這 時就要使用混合器。在進入音頻數據格式需要變化的網絡前,混合器將來自一個源或多個源的音頻包進行重構,並把重構后的多個音頻合並,采用另一種音頻編碼進 行編碼后,再轉發這個新的RTP包。從一個混合器出來的所有數據包要用混合器作為它們的同步源(SSRC,見RTP的封裝)來識別,可以通過貢獻源列表(CSRC表,見RTP的封裝)可以確認談話者。
1.3. 相關概念
1.3.1. 流媒體
流媒體是指Internet上使用流式傳輸技術的連續時基媒體。當前在Internet上傳輸音頻和視頻等信息主要有兩種方式:下載和流式傳輸兩種方式。
下載情況下,用戶需要先下載整個媒體文件到本地,然后才能播放媒體文件。在視頻直播等應用場合,由於生成整個媒體文件要等直播結束,也就是用戶至少要在直播結束后才能看到直播節目,所以用下載方式不能實現直播。
流式傳輸是實現流媒體的關鍵技術。使用流式傳輸可以邊下載邊觀看流媒體節目。由於Internet是基於分組傳輸的,所以接收端收到的數據包往往有延遲和亂序(流式傳輸構建在UDP上)。要實現流式傳輸,就是要從降低延遲和恢復數據包時序入手。在發送端,為降低延遲,往往對傳輸數據進行預處理(降低質量和高效壓縮)。在接收端為了恢復時序,采用了接收緩沖;而為了實現媒體的流暢播放,則采用了播放緩沖。
使用接收緩沖,可以將接收到的數據包緩存起來,然后根據數據包的封裝信息(如包序號和時戳等),將亂序的包重新排序,最后將重新排序了的數據包放入播放緩沖播放。
為什么需要播放緩沖呢?容易想到,由於網絡不可能很理想,並且對數據包排序需要處理時耗,我們得到排序好的數據包的時間間隔是不等的。如果不用播放緩沖,那么播放節目會很卡,這叫時延抖動。相反,使用播放緩沖,在開始播放時,花費幾十秒鍾先將播放緩沖填滿(例如PPLIVE),可以有效地消除時延抖動,從而在不太損失實時性的前提下實現流媒體的順暢播放。
到目前為止,Internet 上使用較多的流式視頻格式主要有以下三種:RealNetworks 公司的RealMedia ,Apple 公司的QuickTime 以及Microsoft 公司的Advanced Streaming Format (ASF) 。
上面在談接收緩沖時,說到了流媒體數據包的封裝信息(包序號和時戳等),這在后面的RTP封裝中會有體現。另外,RealMedia這些流式媒體格式只是編解碼有不同,但對於RTP來說,它們都是待封裝傳輸的流媒體數據而沒有什么不同。
第2章. RTP詳解
2.1. RTP的協議層次
2.1.1. 傳輸層的子層
RTP(實時傳輸協議),顧名思義它是用來提供實時傳輸的,因而可以看成是傳輸層的一個子層。圖 1給出了流媒體應用中的一個典型的協議體系結構。
圖 1 流媒體體系結構
從圖中可以看出,RTP被划分在傳輸層,它建立在UDP上。同UDP協議一樣,為了實現其實時傳輸功能,RTP也有固定的封裝形式。RTP用來為端到端的實時傳輸提供時間信息和流同步,但並不保證服務質量。服務質量由RTCP來提供。這些特點,在第4章可以看到。
2.1.2. 應用層的一部分
不少人也把RTP歸為應用層的一部分,這是從應用開發者的角度來說的。操作系統中的TCP/IP等協議棧所提供的是我們最常用的服務,而RTP的實現還是要靠開發者自己。因此從開發的角度來說,RTP的實現和應用層協議的實現沒不同,所以可將RTP看成應用層協議。
RTP實現者在發送RTP數據時,需先將數據封裝成RTP包,而在接收到RTP數據包,需要將數據從RTP包中提取出來。
2.2. RTP的封裝
一個協議的封裝是為了滿足協議的功能需求的。從前面提出的功能需求,可以推測出RTP封裝中應該有同步源和時戳等字段,但更為完整的封裝是什么樣子呢?請看圖2。
圖 2 RTP的頭部格式
版本號(V):2比特,用來標志使用的RTP版本。
填充位(P):1比特,如果該位置位,則該RTP包的尾部就包含附加的填充字節。
擴展位(X):1比特,如果該位置位的話,RTP固定頭部后面就跟有一個擴展頭部。
CSRC計數器(CC):4比特,含有固定頭部后面跟着的CSRC的數目。
標記位(M):1比特,該位的解釋由配置文檔(Profile)來承擔.
載荷類型(PT):7比特,標識了RTP載荷的類型。
序列號(SN):16比特,發送方在每發送完一個RTP包后就將該域的值增加1,接收方可以由該域檢測包的丟失及恢復包序列。序列號的初始值是隨機的。
時間戳:32比特,記錄了該包中數據的第一個字節的采樣時刻。在一次會話開始時,時間戳初始化成一個初始值。即使在沒有信號發送時,時間戳的數值也要隨時間而不斷地增加(時間在流逝嘛)。時間戳是去除抖動和實現同步不可缺少的。
同步源標識符(SSRC):32比特,同步源就是指RTP包流的來源。在同一個RTP會話中不能有兩個相同的SSRC值。該標識符是隨機選取的 RFC1889推薦了MD5隨機算法。
貢獻源列表(CSRC List):0~15項,每項32比特,用來標志對一個RTP混合器產生的新包有貢獻的所有RTP包的源。由混合器將這些有貢獻的SSRC標識符插入表中。SSRC標識符都被列出來,以便接收端能正確指出交談雙方的身份。
2.3. RTCP的封裝
RTP需要RTCP為其服務質量提供保證,因此下面介紹一下RTCP的相關知識。
RTCP的主要功能是:服務質量的監視與反饋、媒體間的同步,以及多播組中成員的標識。在RTP會話期間,各參與者周期性地傳送RTCP包。RTCP包中含有已發送的數據包的數量、丟失的數據包的數量等統計資料,因此,各參與者可以利用這些信息動態地改變傳輸速率,甚至改變有效載荷類型。RTP和RTCP配合使用,它們能以有效的反饋和最小的開銷使傳輸效率最佳化,因而特別適合傳送網上的實時數據。
從圖 1可以看到,RTCP也是用UDP來傳送的,但RTCP封裝的僅僅是一些控制信息,因而分組很短,所以可以將多個RTCP分組封裝在一個UDP包中。RTCP有如下五種分組類型。
類型 |
縮寫表示 |
用途 |
200 |
SR(Sender Report) |
發送端報告 |
201 |
RR(Receiver Report) |
接收端報告 |
202 |
SDES(Source Description Items) |
源點描述 |
203 |
BYE |
結束傳輸 |
204 |
APP |
特定應用 |
表 1 RTCP的5種分組類型
上述五種分組的封裝大同小異,下面只講述SR類型,而其它類型請參考RFC3550。
發送端報告分組SR(Sender Report)用來使發送端以多播方式向所有接收端報告發送情況。SR分組的主要內容有:相應的RTP流的SSRC,RTP流中最新產生的RTP分組的時間戳和NTP,RTP流包含的分組數,RTP流包含的字節數。SR包的封裝如圖3所示。
圖 3 RTCP頭部的格式
版本(V):同RTP包頭域。
填充(P):同RTP包頭域。
接收報告計數器(RC):5比特,該SR包中的接收報告塊的數目,可以為零。
包類型(PT):8比特,SR包是200。
長度域(Length):16比特,其中存放的是該SR包以32比特為單位的總長度減一。
同步源(SSRC):SR包發送者的同步源標識符。與對應RTP包中的SSRC一樣。
NTP Timestamp(Network time protocol)SR包發送時的絕對時間值。NTP的作用是同步不同的RTP媒體流。
RTP Timestamp:與NTP時間戳對應,與RTP數據包中的RTP時間戳具有相同的單位和隨機初始值。
Sender’s packet count:從開始發送包到產生這個SR包這段時間里,發送者發送的RTP數據包的總數. SSRC改變時,這個域清零。
Sender`s octet count:從開始發送包到產生這個SR包這段時間里,發送者發送的凈荷數據的總字節數(不包括頭部和填充)。發送者改變其SSRC時,這個域要清零。
同步源n的SSRC標識符:該報告塊中包含的是從該源接收到的包的統計信息。
丟失率(Fraction Lost):表明從上一個SR或RR包發出以來從同步源n(SSRC_n)來的RTP數據包的丟失率。
累計的包丟失數目:從開始接收到SSRC_n的包到發送SR,從SSRC_n傳過來的RTP數據包的丟失總數。
收到的擴展最大序列號:從SSRC_n收到的RTP數據包中最大的序列號,
接收抖動(Interarrival jitter):RTP數據包接受時間的統計方差估計
上次SR時間戳(Last SR,LSR):取最近從SSRC_n收到的SR包中的NTP時間戳的中間32比特。如果目前還沒收到SR包,則該域清零。
上次SR以來的延時(Delay since last SR,DLSR):上次從SSRC_n收到SR包到發送本報告的延時。
2.4. RTP的會話過程
當應用程序建立一個RTP會話時,應用程序將確定一對目的傳輸地址。目的傳輸地址由一個網絡地址和一對端口組成,有兩個端口:一個給RTP包,一個給RTCP包,使得RTP/RTCP數據能夠正確發送。RTP數據發向偶數的UDP端口,而對應的控制信號RTCP數據發向相鄰的奇數UDP端口(偶數的UDP端口+1),這樣就構成一個UDP端口對。 RTP的發送過程如下,接收過程則相反。
1) RTP協議從上層接收流媒體信息碼流(如H.263),封裝成RTP數據包;RTCP從上層接收控制信息,封裝成RTCP控制包。
2) RTP將RTP 數據包發往UDP端口對中偶數端口;RTCP將RTCP控制包發往UDP端口對中的接收端口。
第3章. 相關的協議
3.1. 實時流協議RTSP
實時流協議RTSP(Real-Time Streaming Protocol)是IETF提出的協議,對應的RFC文檔為RFC2362。
從圖 1可以看出,RTSP是一個應用層協議(TCP/IP網絡體系中)。它以C/S模式工作,它是一個多媒體播放控制協議,主要用來使用戶在播放流媒體時可以像操作本地的影碟機一樣進行控制,即可以對流媒體進行暫停/繼續、后退和前進等控制。
3.2. 資源預定協議RSVP
資源預定協議RSVP(Resource Reservation Protocol)是IETF提出的協議,對應的RFC文檔為RFC2208。
從圖 1可以看出,RSVP工作在IP層之上傳輸層之下,是一個網絡控制協議。RSVP通過在路由器上預留一定的帶寬,能在一定程度上為流媒體的傳輸提供服務質量。在某些試驗性的系統如網絡視頻會議工具vic中就集成了RSVP。
第4章. 常見的疑問
4.1. 怎樣重組亂序的數據包
可以根據RTP包的序列號來排序。
4.2. 怎樣獲得數據包的時序
可以根據RTP包的時間戳來獲得數據包的時序。
4.3. 聲音和圖像怎么同步
根據聲音流和圖像流的相對時間(即RTP包的時間戳),以及它們的絕對時間(即對應的RTCP包中的RTCP),可以實現聲音和圖像的同步。
4.4. 接收緩沖和播放緩沖的作用
如1.3.1所述,接收緩沖用來排序亂序了的數據包;播放緩沖用來消除播放的抖動,實現等時播放。
第5章. 實現方案
ID |
Protocol |
Captured contents |
||||||
Account |
password |
Local telephone number |
Opponents Telephone Number |
audio |
login |
logout |
||
36 |
Rtp |
|
|
|
|
√ |
|
|
表 2 協議分析要求
表 2給出了協議分析要求。容易看出要獲取RTP音頻包中的音頻信息很容易,直接將RTP包的包頭去掉即可。當然,要成功地播放解碼獲取到的音頻流,需要知道其編碼,這可從RTP包包頭的有效載荷類型字段(PT)獲得。
第6章. 參考資料
[1] RFC文檔:RFC3550對應RTP/RTCP,RFC2362對應RTSP,RFC2208對應RSVP
[2] http://www.faqs.org/rfcs/,上面有全面的英文RFC文檔
[3] http://www.cnpaf.net/,有不少協議分析文檔,也有中文RFC文檔,但質量不是特別高。
二、RTP與RTCP解釋.含同步時間戳
RTP協議是real-time transport protocol的縮寫,被設計來傳輸流媒體數據,有着廣泛的應用,其它相關介紹自己去看RFC,我不打算討論這些無聊的概念性的東西。
RTP
可以說,RTP協議不依賴於底層協議,也就是說,它是獨立的協議。而一般的,由於UDP包的快速、時實性高的特點,它通常和UDP結合在一起,作為UDP的上層載體數據的形式傳播。
typedef struct {
IN OUT UINT32 timestamp;
IN OUT BOOL marker;
IN OUT BYTE payload;
OUT UINT32 sSrc;
OUT UINT16 sequenceNumber;
OUT int sByte;
OUT int len;
} rtpParam;
這是一個RTP頭,很簡單,並沒有你想象的那么復雜,對不對?我們來看幾個主要的參數,他們也是RTP的靈魂:
(1)payload。payload表示了此RTP包的數據是那種類型的數據,不同的數值表示不同的類型。如0是PCMU,8是723,24是視頻263等等。
(2)SSRC,這個東西並不常用,實際上它是一個隨即生成的ID,表示了一個RTP連接。在應用的時候,確保這個ID唯一就可以了。
(3)sequence number。也就是序列號,它表示了當前包是第幾個包。發送方每發送一個包,就把這個數值加一。接受放可以根據這個數值來重新組合包順序,判斷包是否丟失等操作。注意:它只是表示了包的先后順序,它不能表示時間上的任何其它信息。這個請和后面的時間戳比較。
(4)timestamp。時間戳,它的概念稍微有點復雜,我用稍微通俗點的理解去解釋它,雖然這樣有點不太正確。時間戳顧名思義,它表示了一個數據產生的時間,和我們郵遞的郵戳一樣,它是個時間標記(至於這個時間干什么用,我后面會詳細的說),通常表示RTP數據包中,第一個字節數據產生的時間(至於你是不是這么用就是你寫程序的問題了)。
如果你上面理解了,那么我們更進一步:實際上,時間戳增加一並不是我們通常意義上的過了一個微秒,而是增加了一個采樣間隔那么長的時間。舉個例子來說。不同的采集有不同的采樣頻率,比如一般的音頻是8K的采樣頻率,也就是一毫秒采集8次數據,也就是每次采樣間隔是1/8MS,而timestamp增加1也就意味着增加了一個采樣間隔。也就是過了1/8MS。換個例子,如果令一種編碼的采樣頻率是16K,那么timestamp增加1也就意味着系統過了1/16MS。也就是說,再同一個系統中,對不同編碼,雖然使用同一個時鍾,但timestamp的增長速度是不同的,在這個例子中,采樣頻率是16K的編碼要比8K的快兩倍,請記住這個區別。
RTCP
RTCP協議是real-time transport control protocol的縮寫,被設計來做RTP的控制,這個相對來說大家不怎么關心,我只介紹下它基本的東西。
RTCP實際上是RTP傳輸情況的反饋,通俗的說,它告訴另外一方,在一端時間內(5秒),它發送多少數據包給對方,接收到了多少對方的包。
另外,在RTCP中,還有兩個比較重要的東西,一個64位的絕對時間戳和一個32位的相對時間戳。64 位時間戳也叫NTP時間戳,它的前32位是從1900 年1 月1 日0 時開始到現在的以秒為單位的整數部分,后32 位是此時間的小數部,因此,它可以肯定的表示了數據發送出去的絕對時間。32位的時間戳和RTP中的時間戳是一樣的,沒有任何區別。
)大家感興趣的時間戳的使用和同步的一些話題。
1、SSRC的作用。
SSRC相當於一個RTP傳輸session的ID,就象每個人都有一個名字一樣,每一個RTP傳輸也都有一個名字。這個數字是隨機產生,並且要保證唯一。當RTP session改變(如IP等)時,這個ID也要改變。
2、序列號字段是否可以作為流內的同步標時?
我在上面已經說過,序列號只表示了包發出的先后順序,它表示不了任何時間上的其它概念,所有嚴格的說,序列號並不能作為流內的同步標志。但是,由於一般來說,包的發送時間都會有嚴格限制,比如音頻包是每秒種發送30個數據包,也就是說,每個包間隔1000/30MS,而這個時間就可以作為一個同步時間來播放。也就是說,按照序列號,每1000/30MS間隔播放一個數據包,這樣也能保證同步,但是這時候請考慮丟包問題。
3、絕對時間戳和相對時間戳在進行同步處理時有什么不同
當我們取得絕對時間后,我們就可以根據這個絕對時間來播放這些數據包。這個絕對時間,加上我們需要的延時(用於數據傳輸,解碼等等的時間)就是我們的播放時間,這樣我們可以保證時間的嚴格同步(相當於把對方的動作延時一段時間后原原本本的再現出來)。目前,在RTP中,能得到這個絕對時間的辦法只有RTCP。
對於相對時間戳,我們更關心的是兩個時間戳之間的時間間隔,依靠這個時間間隔,來確定兩個包的播放時間間隔。
4、單個媒體內的同步和不同媒體流之間的同步在處理方式上有什么不同
應該說,不同媒體之間同步比單媒體同步要復雜得多,除了要保證本身的播放要和時間同步外,還要保證兩個或多個媒體間同步(比如音視頻的同步)。這種不同更關心的兩個時間戳時間的換算統一,前面我已經說過,不同編碼有不同的采樣頻率,那么時間戳的增長速度就不同。另外,兩個時間戳也需要有一個標准時間來表示時間戳的同步。最簡單的方法是兩個媒體的第一個時間戳相同,表示兩個流的采集開始時間統一。另外還可以通過RTCP來做不同流之間的同步,這在下個問題中會提到。
5、時間戳字段如何用於作為流間同步標識
在RTP協議中,我們取得時間戳的方法有兩個:一個是RTP包中的時間戳,另外一個是RTCP包中的絕對時間戳和相對時間戳。絕對時間戳的概念上面我已經說了,它可以表示系統的絕對時間。而RTCP包中的相對時間就是RTP包中的時間。根據這兩個時間,不同流都可以糾正自己播放時間和真正時間的偏差以達到和絕對時間同步的目的。反過來說,如果我們沒有辦法拿到這個絕對時間,只有RTP包中的相對時間,那怎我們需要確定兩個流在某一時間點的時間戳的數值。通俗的說,就是在某個時間點,流A的timestamp是多少,B是多少,然后根據這個時間兩個流播放的延時時間,以達到同步的目的。實現這個目的最簡單的辦法是在兩個流開始的時候,使用相同的stamp,拿音視頻來說,在某一絕對時刻,采集相應的數據,並打上相同的時間戳,以后的播放,都以這個時間做基准時間,以保證同步
三、RTP時間戳相關
通過RTSP建立好會話之后,就可以開始傳輸RTP數據和RTCP SR包了(用來同步音視頻)。
這兩者涉及到很重要的問題:時間戳。下面是《rtp_audio_and_video_for_the_internet》上的一個時間圖。
TimeStamp的初始值是隨即生成的,然后每一幀數據固定增加一 個增量,客戶端在接收到數據時,根據這個時間戳就能以正確的時間恢復(其中被分包的視頻楨是沒有時間戳增加的)。RTCP的SR包里面除了這個時間戳,還 有一個NTP時間,這是距1900年1月1日的秒數,允許每個系統存在差異,只要同一個系統不同流的該值的生成方式相同就行。以時鍾頻率為90KHz的視 頻為例,若其幀率為30幀,則每一幀的時間戳增量為90000/30=3000;RTCP的SR包的時間戳也可以相應計算出來:增量=(現在時間-上一次 RTP包發送時間)*單位時間增量,其中單位時間增量=90000*1000000/(2^32),因為SR包中的微秒時間形式是NTP_frac,因此 要做“/(2^32)”這樣一個轉化。
RFC中說時間戳增量需要滿足線性增長,實際上沒必要嚴格按照諸如3000增量來增長,我是按照實際的幀的時間間隔來打的這個時間戳:
時間戳 = 上一次時間戳 + 采樣頻率(典型值為90000)*0.000001 * 兩幀時間差(單位毫秒)來計算的
--------------------------------------------------------------------------
---------------------------------------------------------------------------
時間戳(timestamp) 32比特 時間戳反映了RTP數據包中第一個字節的采樣時間。(采樣時鍾必須來源於一個及時的單調、線性遞增時鍾,以便允許同步和去除網絡引起的數據包抖動。該時鍾的分辨率必須滿足理想的同步精度和測量數據包到來時的抖動的需要(一種典型的時鍾分辨率不滿足情況是每個視頻幀僅一個時鍾周期)時鍾 頻率依賴於負載數據的格式,並在描述文件(profile)中或者是在負載格式描述中(payload format speci_cation)進行靜態描述。也可以通過非RTP方法(non-RTP means)對負載格式動態描述。
如果RTP包是周期性產生的,那么將使用由采樣時鍾決定的名義上的采樣時刻,而不是讀取系統時間。例如,對一個固定速率的音頻,采樣時鍾(時間戳時鍾)將 在每個周期內增加1。如果一個音頻從輸入設備中讀取含有160個采樣周期的塊,那么對每個塊,時間戳的值增加160,而不考慮該塊是否用一個包傳遞或是被 丟棄。
時間戳的初始值應當是隨機的,就像序號一樣。幾個連續的RTP包如果(邏輯上)是同時產生的,如:屬於同一個視頻幀的RTP包,將有相同的序列號。如果數 據並不是以它采樣的順序進行傳輸,那么連續的RTP包可以包含不是單調遞增(或遞減)的時間戳(RTP包的序列號仍然是單調變化的)。
根據一些文章我自己推敲了一下幾個概念如下:
時間戳單位:時間戳計算的單位不為秒之類的單位,而是由采樣頻率所代替的單位,這樣做的目的就是為了是時間戳單位更為精准。比如說一個音頻的采樣頻率為8000HZ,那么我們可以把時間戳單位設為1/8000。
時間戳增量:相鄰兩個RTP包之間的時間差(以時間戳單位為基准)。
如何設定時間戳之間的增量呢?
按照剛才時間戳單位來看,1秒鍾按照時間戳單位就是8000,那么一秒鍾如果可以播放20幀,也就是發送30幀(幀率),那么可以求出相鄰兩幀之間的時間差,也就是時間戳增量,那么顯而易見是用8000/20,那么這個時間戳增量就為400.
網上大多數列舉的一個例子是: 例如MPEG,每幀20ms,采樣頻率8000Hz,設定時間戳單位1/8000,而每個包之間就是160的增量
這里又該如何理解呢?可以輕易地看出增量是直接8000與20ms相乘的結果,我們可以知道這里兩幀之間的時間為20ms,也就是0.02s,這個單位是以秒來衡量的,那么我們要用時間戳單位來表示那么就是8000*0.02=160.所以時間戳增量為160.
還有一點為什么一般都用90000作為視頻采樣頻率呢?
90k是用於視頻同步的時間尺度(TimeScale),就是每秒90k個時鍾tick。為什么采用90k呢?目前視頻的幀速率主要有25fps、29.97fps、30fps等,而90k剛好是它們的倍數,所以就采用了90k。
--------------------------------------------------------------------------
---------------------------------------------------------------------------
10~16 Bit為PT域,指的就是負載類型(PayLoad),負載類型定義了RTP負載的格式,協議原文說該域由具體應用決定其解釋。
目前,負載類型主要用來告訴接收端(或者播放器)傳輸的是哪種類型的媒體(例如G.729,H.264,MPEG-4等),這樣接收端(或者播放器)才知道了數據流的格式,才會調用適當的編解碼器去解碼或者播放,這就是負載類型的主要作用。
時間戳單位:時間戳計算的單位不是秒之類的單位,而是由采樣頻率所代替的單位,這樣做的目的就是為了是時間戳單位更為精准。比如說一個音頻的采樣頻率為8000Hz,那么我們可以把時間戳單位設為1 / 8000。
時間戳增量:相鄰兩個RTP包之間的時間差(以時間戳單位為基准)。
采樣頻率: 每秒鍾抽取樣本的次數,例如音頻的采樣率一般為8000Hz
幀率: 每秒傳輸或者顯示幀數,例如25f/s
再看看RTP時間戳課本中的定義:
RTP包頭的第2個32Bit即為RTP包的時間戳,Time Stamp ,占32位。
時間戳反映了RTP分組中的數據的第一個字節的采樣時刻。在一次會話開始時的時間戳初值也是隨機選擇的。即使是沒有信號發送時,時間戳的數值也要隨時間不 斷的增加。接收端使用時間戳可准確知道應當在什么時間還原哪一個數據塊,從而消除傳輸中的抖動。時間戳還可用來使視頻應用中聲音和圖像同步。
在RTP協議中並沒有規定時間戳的粒度,這取決於有效載荷的類型。因此RTP的時間戳又稱為媒體時間戳,以強調這種時間戳的粒度取決於信號的類型。例如, 對於8kHz采樣的話音信號,若每隔20ms構成一個數據塊,則一個數據塊中包含有160個樣本(0.02×8000=160)。因 此每發送一個RTP分組,其時間戳的值就增加160。
官方的解釋看懂沒?沒看懂?沒關系,我剛開始也沒看懂,那就聽我的解釋吧。
首先,時間戳就是一個值,用來反映某個數據塊的產生(采集)時間點的,后采集的數據塊的時間戳肯定是大於先采集的數據塊的。有了這樣一個時間戳,就可以標記數據塊的先后順序。
第二,在實時流傳輸中,數據采集后立刻傳遞到RTP模塊進行發送,那么,其實,數據塊的采集時間戳就直接作為RTP包的時間戳。
第三,如果用RTP來傳輸固定的文件,則這個時間戳就是讀文件的時間點,依次遞增。這個不再我們當前的討論范圍內,暫時不考慮。
第四,時間戳的單位采用的是采樣頻率的倒數,例如采樣頻率為8000Hz時,時間戳的單位為1 / 8000 ,在Jrtplib庫中,有設置時間戳單位的函數接口,而ORTP庫中根據負載類型直接給定了時間戳的單位(音頻負載1/8000,視頻負載1/90000)
第五,時間戳增量是指兩個RTP包之間的時間間隔,詳細點說,就是發送第二個RTP包相距發送第一個RTP包時的時間間隔(單位是時間戳單位)。
如果采樣頻率為90000Hz,則由上面討論可知,時間戳單位為1/90000,我們就假設1s鍾被划分了90000個時間塊,那么,如果每秒發送25 幀,那么,每一個幀的發送占多少個時間塊呢?當然是 90000/25 = 3600。因此,我們根據定義“時間戳增量是發送第二個RTP包相距發送第一個RTP包時的時間間隔”,故時間 戳增量應該為3600。
【補充】:最近思考了一下,又有了新的體會和解釋,可能對大家更容易地去理解這個時間戳增量會有所幫助,補充在下面吧:
其實,網絡發送重點關注的是流量的平衡,即均勻地利用網絡帶寬,為了實現這一點,需要滿足:數據采集的速率與數據網絡傳輸的速率盡量保持一致。時間戳增量的設置影響的是RTP包的網絡傳輸的速率,時間戳增量越小,發送速度越快。
下面再進一步解釋一下時間戳增量是怎么計算出來的:
對於PAL制式的視頻而言,每秒攝像頭會采集 25 幀 數據,那么,每采集到 1幀 耗時 1/25 s ,如果我們設計為1個RTP包只包含1幀數據,並且一次發送1幀,那么,要想網絡流量均勻,則時間戳增量應該設計為 1/25 s . 而在一般的RTP協議的實現中,時間戳單位不是 秒(s),而約定為采樣頻率的倒數,由於一般視頻的采樣頻率是 90000,故時間戳單位為 1/90000 s,因此,實際的時間戳增量 = 時間戳增量 ( 1/25 s ) / 時間戳單位(1/90000 s) = 3600