?? rfc2508.txt
字號:
個RTP頭及其負載)。不過,FULL_HEADER也可以攜帶IP封裝的包,其中可能有兩個IP頭
及其相應的UDP和RTP。對于IPv6,該包還可能是IPv6和IPv4頭的組合。通常每個后續頭都
由前一個頭的類型字段來指示。
FULL_HEADER包與IPv4或IPv6包的區別在于它必須攜帶壓縮環境ID和4位的順序號。為了
避免頭變大,這些值被插入到IP和UDP頭的長度字段中,因為實際的長度可以根據鏈路層提
供的長度推算出來。這里需要2個16位長的字段:它們來自包中的頭兩個可用頭。對于
IPv4/UDP包,第一個長度字段是IP頭總長度字段,第二個字段是UDP頭長度字段。對于IPv4
封裝包,第一個長度字段為第一個IP頭的總長度字段,第二個字段是第二個IP頭的總長度字
段。
如5.3.2節所規定,環境ID(CID)和4位順序號的位置取決于是采用8位還是16位環境ID,
如下圖所示(16位寬,左邊為最高位):
對于8位環境ID:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|1| Generation| CID | 第一長度字段
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0 | seq | 第二長度字段
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
對于16位環境ID:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1|1| Generation| 0 | seq | 第一長度字段
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| CID | 第二長度字段
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
第一長度字段的起始位表示CID的長度。CID的長度要么對于所有環境均相同,要么必須
提供兩個額外包類型來分別指示COMPRESSED_UDP和COMPRESSED_RTP包格式采用8位還是16位
CID。 對于IP/UDP/RTP壓縮方案,第一長度字段的第二位為1表示當前為4位順序號。
在IPv6的COMPRESSED_NON_TCP包中使用Generation字段方法如[3]所述。IPv4實現不使用
COMPRESSED_NON_TCP包,壓縮器應該將generation字段設置為0。為了使IPv4和IPv6操作一
致,當解壓器接收到Generation值后就將它存在環境中,并在CONTEXT_STATE包中返回最近
的值。
當接收到一個FULL_HEADER時,接收方將整個頭存在由環境ID選擇的環境中。4位順序號
也存在環境中,從而可實現解壓器和壓縮器的同步。在使用COMPRESSED_NON_TCP包時,順序
號插入到該包的“Data字段”中,并且D位設置參照[3]的第6節所述。在接收到
COMPRESSED_NON_TCP包后,接收方將Generation號和存在環境中的值進行比較。如果不同,
則環境已經過期,需要用該FULL_HEADER包來進行刷新。如果一致,則壓縮的IP和UDP頭信息,
順序號,以及RTP頭都存入已保存的環境中。
保存環境所需要的內存數量取決于FULL_HEADER中到底封裝了多少個頭。最大頭的大小可
通過壓縮/解壓縮雙方協商得到。
3.3.2. COMPRESSED_RTP包格式
如果包中RTP頭的二次差分值為0,則解壓器只需在前一個包的未壓縮頭上加上存儲的一
次差分值就可以重建該包。雙方之間只需傳輸會話環境標識符和順序號就可以維持同步和檢
測出丟失包。
如果包中RTP頭某些字段的二次差分值不為0,則要在雙方要傳輸這些字段的新的一次差
分結果的壓縮編碼。除了要把新的一次差分值加到解壓器會話環境的未壓縮頭上,也要加到
那些二次差分為0的后續包的相應字段上并顯式地存儲到環境里。每當一次差分改變時,都
要對其進行傳輸和存儲。在實際應用中,唯一需要用到一次差分的字段就是IPv4 ID字段和
RTP時間戳字段。
RTP順序號字段的增量為1。如果順序號變化不是1,則必須進行通信以報告該區別,但并
不因此為下一個包重新設置期望的變化值。期望的一次差分值仍然為1,這樣如果下一個包
按順序來到就不用再為變化進行通信。
對于RTP時間戳,當發送FULL_HEADER, COMPRESSED_NON_TCP和COMPRESSED_UDP包刷新RTP
狀態時,存儲的一次差分初始化為0。如果下一個包的時間戳一樣(如相同的視頻幀),則二
次差分值為0。否則必須將兩個包時間戳的差別作為新的一次差分傳輸并存入環境中,該值
將被加到解壓器環境存儲的未壓縮頭時間戳上。每當后續包的一次差分改變時,都要用該變
化來更新環境。
類似地,由于IPv4 ID字段每次遞增1,當用FULL_HEADER刷新狀態或以非壓縮形式發送攜
帶ID字段的COMPRESSED_NON_TCP包時,該字段的一次差分初始化為1。然后,每當一次差分
改變其變化都會重傳并存到環境中。
這里還用了一個掩蔽碼來表示哪個字段發生了非預期變化。除了小鏈路順序號外,要在
壓縮的IP/UDP/RTP頭中進行傳輸的項列表如下:
I = IPv4包ID (非IPv4頭為常數0)
U = UDP校驗和
M = RTP標志位
S = RTP順序號
T = RTP時間戳
L = RTP CSRC記數和列表
如果用4位作為鏈路順序號來進行丟失檢測,包頭中就沒有足夠的位逐一分配給上面的幾
項并填充到一個單字節中隨環境ID發送。
因為發送源要么在會話中所有的包里包括UDP校驗和,要么就根本不用校驗和,所以沒必
要顯式地攜帶U位表示UDP校驗和的存在。如果以未壓縮包頭初始化會話狀態時其校驗和非0,
就說明在所有的后續壓縮包中都將插入16位的未編碼校驗和,直到發送了另一個未壓縮包改
變該設置。對于剩余的幾項,用于CSRC記數和列表的L位可能是使用頻率最低的。與其專門
在掩蔽碼中用一位來表示CSRC改變,還不如采用另外一種不常用的位組合。該位組合稱為
MSTI。如果IP包ID,RTP標志位,RTP順序號和RTP時間戳的位都已經被使用,這種特殊情況
表示其后可能有一種擴展形式的壓縮RTP包頭。該包頭將包括一個額外字節,其中含有4位加
上CC記數的實際值。當CSRC列表(長度由CC記數表示)出現在未壓縮RTP頭中時也將被包含
其中。
假設RTP頭中的其余字段(版本, P位, X位, 負載類型和SSRC標識符)都保持相對恒定。
特別地,對于給定的環境SSRC標識符定義為常量,因為SSRC標識符是選擇環境的一個因素。
如果任何其它字段發生變化,都必須按照3.3.3節要求發送未壓縮RTP包。
下圖中,帶點劃線的壓縮IP/UDP/RTP頭表示可選字段。最高位為0。多字節字段按照網絡
字節順序發送(最高字節在先)。Delta字段通常如圖所示為單字節,但根據具體delta值也可
能為2或3字節,如3.3.4節所解釋。
0 1 2 3 4 5 6 7
+...............................+
: 會話環境 ID 的msb : (如果使用16位CID)
+-------------------------------+
| 會話環境 ID 的lsb |
+---+---+---+---+---+---+---+---+
| M | S | T | I | 鏈路順序號 |
+---+---+---+---+---+---+---+---+
: :
+ UDP 校驗和 + (如果環境中校驗和為非0)
: :
+...............................+
: :
+ "RANDOM" fields + (如果被封裝)
: :
+...............................+
: M'| S'| T'| I'| CC : (如果MSTI = 1111)
+...............................+
: delta IPv4 ID : (如果I或I' = 1)
+...............................+
: delta RTP 順序號 : (如果S或S' = 1)
+...............................+
: delta RTP 時間戳 : (如果T或T' = 1)
+...............................+
: :
: CSRC list : (如果MSTI = 1111
: : 并且CC非0)
: :
+...............................+
: :
: RTP 頭擴展 : (如果環境中設置了X位)
: :
: :
+-------------------------------+
| |
| RTP 數據 |
/ /
/ /
| |
+-------------------------------+
: 填充 : (如果環境中設置了P位)
+...............................+
如果FULL_HEADER初始化的環境中IPv4頭數目多余1,則封裝頭的IP ID字段必須如[3]所
述按照絕對值形式發送。這些字段標識為"RANDOM"字段。它們按照與原始包中相同的順序被
插入COMPRESSED_RTP包,如圖所示,其后緊接著是UDP校驗和或MSTI字節。除非IPv4包正好
在UDP頭之前,該頭的IP ID才會被區別發送,例如,如果二次差分為0,或者二次差分不為0
但該字段是作為delta IPv4 ID字段它就不占任何位。如果沒有IPv4頭正好位于UDP頭之前,
則I位必須為0且不應存在delta IPv4 ID字段。
3.3.3. COMPRESSED_UDP包格式
如果RTP頭中任何一般情況下應為常量的字段(如負載類型字段)發生了變化,則必須發
送一個非壓縮RTP頭。如果IP和UDP頭不需要更新,則該RTP頭可以用COMPRESSED_UDP包攜帶,
而不必用FULL_HEADER包。除了M,S和T為為常數0以及沒有相應的delta字段以外,
COMPRESSED_UDP包同COMPRESSED_RTP格式相同:
0 1 2 3 4 5 6 7
+...............................+
: 會話環境ID的msb : (如果使用16位CID)
+-------------------------------+
| 會話環境ID的lsb |
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | I | 鏈路順序號 |
+---+---+---+---+---+---+---+---+
: :
+ UDP 校驗和 + (如果環境中校驗和非0)
: :
+...............................+
: :
+ "RANDOM" 字段 + (如果被封裝)
: :
+...............................+
: delta IPv4 ID : (如果I = 1)
+-------------------------------+
| UDP 數據 |
: (非壓縮RTP ) :
請注意,這里IP/UDP頭的壓縮形式和[3]中定義的COMPRESSED_NON_TCP包類型不同。其目
的是象IPv4所允許的那樣,當禁用UDP校驗和時使壓縮目標達到2字節。[3]中定義的協議沒
有使用UDP包的差分編碼,所以在用于IPv4時,除了前面的兩個壓縮字節,還有兩個字節的
IP ID和兩個字節的非0 UDP校驗和都要進行傳輸。對于IPv6,可使用COMPRESSED_NON_TCP包
類型來替代。
3.3.4.差分編碼Encoding of differences
COMPRESSED_RTP和COMPRESSED_UDP包的delta字段為變長編碼,可將壓縮數據映射到更多
的通常使用值。下面規定了一種優化的哈夫曼編碼作為缺省編碼,推薦在實現表驅動delta
編/解碼器來為會話進行面向表協商時使用。針對一定范圍內數據的測試表明,在合理的表
規模下基于對位流進行順序解釋的編碼執行速度比非表驅動的實現要快,這種缺省表和哈夫
曼編碼就是例子。缺省delta編碼規范見下表。該編碼在IP ID和RTP順序號變化很小的情況
下可高效編碼,此時壓縮器發出的包丟失,但仍能將大多數音視頻deltas保持為2字節。左
邊的列是要編碼的10進制數,右邊的列是16進制顯示的編碼后按發送順序排列(網絡字節順
序)的字節序列。其中顯示了相臨范圍的首尾值,其余均省略:
十進制 16進制
-16384 C0 00 00
: :
-129 C0 3F 7F
-128 80 00
: :
-1 80 7F
0 00
: :
127 7F
128 80 80
: :
16383 BF FF
16384 C0 40 00
: :
4194303 FF FF FF
對于正數,在一個字節內直接以0到127表示。如果該字節的最高兩位是10或者11,則表示
分別表示要擴展到2或3個字節。低6位按照降序同后面緊跟的1到2個字節聯合表示一個14或
22位值。
當包出現亂序或者在MPEG視頻的RTP時間戳故意被打亂時可能會出現負數的delta值。這
種情況很少見,所以負數值編碼范圍更小,僅使用表中正數值剩余的部分。
RTP時間戳值中小于-16384或大于4194303的改變都會導致強制發送未壓縮的
FULL_HEADER, COMPRESSED_NON_TCP或COMPRESSED_UDP類型RTP頭。IP ID和RTP順序號字段都
只有16位,所以這些字段的負數delta都掩蔽為16位再進行編碼(作為16位正數)。
3.3.5.錯誤恢復
除了由FULL_HEADER和COMPRESSED_NON_TCP包設置外,當特定環境的4位順序號增量不為1
時,解壓器必須將環境置為無效并發送CONTEXT_STATE包回壓縮器表示環境已經無效。無效
環境的所有當前包都必須丟棄,直到收到一個FULL_HEADER或COMPRESSED_NON_TCP重建穩定
狀態為止(除非使用了本節后面將描述的"twice"算法。)。由于在這一過渡時期可能會有
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -