先給自己打個廣告,本人的微信公衆號正式上線了,搜索:張笑生的地盤,主要關注嵌入式軟件開發,股票基金定投,足球等等,希望大家多多關注,有問題可以直接留言給我,一定盡心盡力回答大家的問題
一 what
一個rtp碼流是由rtp header和stream組成的,如下:
- rtp固定header
rtp header的定義在ortp開源庫中的定義如下:
typedef struct rtp_header
{
#ifdef ORTP_BIGENDIAN
uint16_t version:2; //定義RTP版本,此協議定義的版本是2(值1被RTP草案版本使用,值0用在最初"vat"語音工具使用的協議中)
uint16_t padbit:1; //=1: 則此包包含1~n個附加在末端的填充比特,填充比特不算作負載的一部分。填充的最後一個字節指明可以忽略多少個填充比特。填充可能用於某些具有固定長度的加密算法,或者用於在底層數據單元中傳輸多個RTP包
uint16_t extbit:1; //=1: 固定頭(僅)後面跟隨一個頭擴展
uint16_t cc:4; //CSRC 計數包含了跟在固定頭後面CSRC識別符的數目
uint16_t markbit:1; //=1:表示該幀結束,=0:表示仍然是音視頻數據
uint16_t paytype:7; //此域定義了負載的格式,由具體應用決定其解釋,協議可以規定負載類型碼和負載格式之間一個默認的匹配。其他的負載類型碼可以通過非 RTP 方法動態定義。RTP發送端在任意給定時間發出一個單獨的 RTP 負載類型;此域不用來複用不同的媒體流
#else
uint16_t cc:4; //CSRC 計數包含了跟在固定頭後面CSRC識別符的數目
uint16_t extbit:1; //=1: 固定頭(僅)後面跟隨一個頭擴展
uint16_t padbit:1; //=1: 則此包包含1~n個附加在末端的填充比特,填充比特不算作負載的一部分。填充的最後一個字節指明可以忽略多少個填充比特。填充可能用於某些具有固定長度的加密算法,或者用於在底層數據單元中傳輸多個RTP包
uint16_t version:2; //定義RTP版本,此協議定義的版本是2(值1被RTP草案版本使用,值0用在最初"vat"語音工具使用的協議中)
uint16_t paytype:7; //此域定義了負載的格式,由具體應用決定其解釋,協議可以規定負載類型碼和負載格式之間一個默認的匹配。其他的負載類型碼可以通過非 RTP 方法動態定義。RTP發送端在任意給定時間發出一個單獨的 RTP 負載類型;此域不用來複用不同的媒體流
uint16_t markbit:1; //=1:表示該幀結束,=0:表示仍然是音視頻數據
#endif
uint16_t seq_number; //RTP包順序,比如一幀K幀,200K,順序可能是0-199,最後一個包Marker位爲1
uint32_t timestamp; //這個值並非每幀的時間戳,但是一個音頻或視頻包此項是相同的,因爲MTU的限制,一幀數據的長度可能大於1400,一幀數據會被拆分爲多個包發送
uint32_t ssrc; //爲流標識,實際可以多個流往一個端口上發,通過此位標識
uint32_t csrc[16];
} rtp_header_t;
- rtp擴展header
根據rtp固定header中extbit定義可知,當此位域=1時,rtp流中存在一個rtp擴展header,我們肯定會想問:爲何添加擴展頭部header?
它允許實現實現個性化:某些新的與負載格式獨立的功能要求的附加信息在RTP 數據包頭中傳輸。設計此方法可以使其它沒有擴展的交互忽略此頭擴展。RTP擴展頭格式如下所示。
RTP 固定頭之後只允許有一個頭擴展,爲允許多個互操作實現,獨立生成不同的頭擴展,或某種特定實現有多種不同的頭擴展,擴展項的前16比特用以識別標識符或參數。這 16 比特的格式由具體實現的上層協議定義。接下來16bit是指示長度域,指示擴展項中 32 比特字的個數,不包括 4 個字節擴展頭(因此零是有效值)。
基本的 RTP 說明並不定義任何頭擴展本身。
二 why
三 how