WebRTC | 網絡傳輸協議 RTP 和 RTCP
- WebRTC | 網絡傳輸協議 RTP 和 RTCP
- 如何選擇 TCP 與 UDP
- RTP
- 概述
- 工作機制
- 報文結構
- RTP 的使用
- RTP 拓展頭
- RTP 中的填充數據
- 翻譯器和混合器
- 同步控制
- 報文大小
- wireshark 抓取 RTP 報文
- RTCP
- 概述
- 工作機制
- 分組類型
- 報文結構
- WebRTC 的反饋報文
- RTPFB
- PSFB
- wireshark 抓取 RTCP 報文
- RTP 會話過程
- RTSP 和 RTP 的關系
- jrtplib
- 總結
- 參考
WebRTC | 網絡傳輸協議 RTP 和 RTCP
流媒體協議棧如下圖所示:
RTP 標準定義了兩個子協議,RTP 和 RTCP。
- 數據傳輸協議 RTP,用于實時傳輸數據。該協議提供的信息包括:時間戳(用于同步)、序列號(用于丟包和重排序檢測)、以及負載格式(用于說明數據的編碼格式)。
- 控制協議 RTCP,用于 QoS 反饋和同步媒體流。相對于 RTP 來說,RTCP 所占的帶寬非常小,通常只有5%。
如何選擇 TCP 與 UDP
TCP為了實現數據傳輸的可靠性,采用的是“發送→確認→丟包→重傳”這樣一套機制。而且為了增加網絡的吞吐量,還采用了延遲確認和Nagle算法(Nagle算法,將多個小包組成一個大包發送,組合包的大小不超過網絡最大傳輸單元)。這套機制就是TCP產生延遲的根本原因。
為了增加網絡的吞吐量,接收端不必每收到一個包就確認一次,而是對一段時間內收到的所有數據集體確認一次即可。為了實現該功能,TCP通常會在接收端啟動一個定時器。定時器的時間間隔一般設置為200ms,即每隔200ms確認一次接收到的數據。這就是延遲確認機制。除此之外,TCP在發送端也啟動了一個定時器,不過該定時器的功能不是發送確認消息,而是用來判別是否有丟包的情況。發送端定時器的時長為一個RTO(Retransmission Timeout,重傳超時時長。其值約等于RTT的平均值,每次超時后以指數級增長。RTT表示一個數據包從發送端到接收端,然后再回到發送端所用的時長)。如果在定時器超時后仍然沒有收到包的確認消息,則認為包丟失了,需要發送端重發丟失的包。這就是TCP的丟包重傳機制。
UDP屬于不可靠傳輸協議。在傳輸數據時,它不保證數據能可靠到達,也不保證數據有序,但它最大的優點就是傳輸速度“快”。由于UDP沒有TCP那一套保證數據可靠、有序的控制邏輯,所以它不會被“人為”地變慢,因此它的實時性是最高的。
針對UDP丟包和抖動的問題,WebRTC給出了一套比較完美的解決方案,通過NACK、FEC、Jitter Bufer以及NetEQ技術既可以解決丟包和抖動問題,又不會產生影響服務質量的時延。通過上面的分析可以知道,由于TCP在極端網絡情況下無法控制傳輸的時延大小,所以在做實時通信傳輸時,應該首選UDP。
RTP
概述
實時傳輸協議(Real-time Transport Protocol,簡稱 RTP)是一個網絡傳輸協議,它是由IETF的多媒體傳輸工作小組1996年在RFC 1889中公布的。
RTP 是應用層協議,基于 UDP,分組傳輸,接收端數據包往往有延遲和亂序。在發送端,存在丟包;為降低延遲,往往對傳輸數據進行預處理(降低質量和高效壓縮)。在接收端為了恢復時序,采用了接收緩沖;而為了實現媒體的流暢播放,則采用了播放緩沖。使用接收緩沖,可以將接收到的數據包緩存起來,然后根據數據包的封裝信息(如包序號和時戳等),將亂序的包重新排序,最后將重新排序了的數據包放入播放緩沖播放。
RTP 為數據提供了具有實時特征的端對端傳送服務,如在組播或單播網絡服務下的交互式視頻音頻或模擬數據。RTP 不像 HTTP 和 FTP 可完整的下載整個影視文件,它是以固定的數據率在網絡上發送數據,客戶端也是按照這種速度觀看影視文件,當影視畫面播放過后,就不可以再重復播放,除非重新向服務器端要求數據。
RTP 本身只保證實時數據的傳輸,并不能為按順序傳送數據包提供可靠的傳送機制,也不提供流量控制或擁塞控制,它依靠 RTCP 提供這些服務。RTP 并不保證傳送或防止無序傳送,也不確定底層網絡的可靠性。 RTP 實行有序傳送, RTP 中的序列號允許接收方重組發送方的包序列,同時序列號也能用于決定適當的包位置。
工作機制
RTP 協議就是提供了時間標簽,序列號以及其它的結構用于控制適時數據的流放。在流的概念中,時間標簽是最重要的信息。發送端依照即時的采樣在數據包里隱蔽的設置了時間標簽。在接受端收到數據包后,就依照時間標簽按照正確的速率恢復成原始的適時的數據。不同的媒體格式調時屬性是不一樣的。
但是 RTP 本身并不負責同步,不提供任何機制來保證實時地傳輸數據,不支持資源預留,也不保證服務質量。RTP 報文甚至不包括長度和報文邊界的描述。同時 RTP 協議和 RTCP 協議使用相鄰的不同端口,這樣大大提高了協議的靈活性和處理的簡單性。
RTP 協議基于 UDP 實現。UDP 協議只是傳輸數據包,不管數據包傳輸的時間順序。RTP 的協議數據單元是用 UDP 分組來承載的。在承載 RTP 數據包的時候,有時候一幀數據被分割成幾個包具有相同的時間標簽,則可以知道時間標簽并不是必須的。而 UDP 的多路復用讓 RTP 協議利用支持顯式的多點投遞,可以滿足多媒體會話的需求。
報文結構
每一個 RTP 數據報都由頭部(Header)和負載(Payload)兩個部分組成,其中頭部前 12 個字節的含義是固定的,而負載則可以是音頻或者視頻數據。
RTP報頭格式為:
- 版本號(V):2 比特,用來標志使用的 RTP 版本。現在使用的都是第 2 個版本,所以該字段固定為 2。
- 填充位(P):1 比特,如果 P=1,則該 RTP 包的尾部就附加一個或多個額外的八位組,它們不是有效載荷的一部分。
- 擴展位(X):1 比特,如果 X=1,拓展頭部會放在 CSRC 之后,攜帶一些附加信息。
- CC:4 比特,CSRC 計數器,指示 CSRC 標識符的個數。
- 標記位(M):1 比特,該位的解釋由配置文檔(Profile)決定,一般情況下用于標識邊界(對于視頻,標記一幀的結束;對于音頻,標記會話的開始)。
- 載荷類型(PT):7 比特,標識了 RTP 載荷的類型。具體值和對應參見:RFC3551。
- 序列號(Sequence Number):16 比特,發送方在每發送完一個 RTP 包后就將該域的值增加 1,接收者通過序列號來檢測報文丟失情況,重新排序報文,恢復數據。序列號的初始值是隨機的。
- 時間戳(Timestamp):32 比特,時間戳反映了該 RTP 報文數據的第一個八位組的采樣時刻。在一次會話開始時,時間戳初始化成一個初始值。即使在沒有信號發送時,時間戳的數值也要隨時間而不斷地增加。接收者使用時間戳來計算延遲和延遲抖動,并進行同步控制。
- 同步源標識符(SSRC):32 比特,同步源就是指 RTP 包流的來源。RTP 要求不同源的數據流之間用 SSRC 字段區分,在同一個 RTP 會話中不能有兩個相同的 SSRC 值。該標識符由 MD5 隨機算法生成。
- 貢獻源列表(CSRC List):0~15 項,每項 32 比特,用來標志對一個 RTP 混合器產生的新包有貢獻的所有 RTP 包的源。由混合器將這些有貢獻的 SSRC 標識符插入表中。SSRC 標識符都被列出來,以便接收端能正確指出交談雙方的身份。
RTP 的使用
關于RTP的使用主要包括以下兩個方面:一是創建/解析RTP包;二是根據RTP包進行邏輯處理。
WebRTC 提供了一個 RTP 處理類:RtpPacket,定義一個該類的對象,就可以設置/提取 RTP 協議頭各個字段的內容。
接下來講一下邏輯處理,比如創建一個接收隊列來消除包抖動。某個包找不到有兩種情況:包丟失或者包亂序。如果緩沖隊列滿了,說明包丟失;否則,該包還處于待定狀態。
當接收到一個包的標記位(M)為 1,可以與前面的 RTP 包組成一個完整的幀。將這些包從接收隊列彈出,交給組幀模塊處理。
WebRTC中解決RTP包抖動的緩沖隊列就是我們通常所說的JitterBuffer。上面的例子就是JitterBuffer的基本原理。
RTP 拓展頭
RTP 頭部的擴展位(X)占 1 比特,如果 X=1,拓展頭部會放在 CSRC 之后,攜帶一些附加信息。
RTP擴展頭由三部分組成,分別為profile、length以及header extension。
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| defined by profile | length |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| header extension || .... |
其中:
- profile字段占2字節,用于區分不同的配置。在RFC5285中定義了兩種profile,分別是 {0xBE,0xDE} 和 {0x10,0x0X}。接收端解析RTP擴展頭時,通過profile來區分header extension中的內容該如何解析。
- length字段占2字節,表示擴展頭所攜帶的header extension的個數。如果length為4,表示有4個header extension;header extension字段是擴展頭信息,以4字節為單位,其具體含義由profile決定。
擴展頭中的兩個profile值 {0xBE,0xDE} 和 {0x10,0x0X} 分別代表存放在header extension中的兩種不同的數據格式,即one-byte-header和two-byte-header。
one-byte-header 的含義是單個header extension由1字節的Header和N字節的Body組成。而Header由前4位的ID和后4位的len組成。
- ID:拓展頭的值,見于 《WebRTC 中的 SDP》 中 [網絡描述:RTP 拓展頭] 一章。
- len:跟在Header后面的數據(以字節為單位)長度減 1。
one-byte-header 示例:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| 0xBE | 0xDE | length=3 |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| ID | L=0 | data | ID | L=1 | data...+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...data | ID | L=3 | data |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| data | 0(pad) | 0(pad) |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
RTP拓展頭后的第一個16為固定為0XBEDE標志,意味著這是一個one-byte擴展,length = 3 說明后面有三個擴展頭,每個擴展頭首先以一個byte開始,前4位是這個擴展頭的ID, 后四位是data的長度-1,譬如說L=0意味著后面有1個byte的data,同理第二個擴展頭的L=1說明后面還有2個byte的data。body結束后,為了讓整個 RTP 拓展頭是 4 字節的整數倍,后面填充了 2 字節的 0。
two-byte-header 的含義是單個header extension由2字節的Header和N字節的Body組成。而Header的第一個字節是ID,第二個字節 len 表示存放的實際長度。
當擴展頭中的profile值為 {0x10,0x0X} 時,解析 RTP 拓展頭會按照two-byte-header 的格式進行。其中的 X 占 4 bit,代表任意值由應用層自己定義它的含義。
two-byte-header 示例:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| 0x10 | 0x00 | length=3 |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| ID | L=0 | ID | L=1 |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| data | ID | L=4 | data...+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...data | 0 (pad) |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
可以看到開頭為 0x100 + 0x0, 接下來的為length=3表示接下來有3個頭,接下來的就是擴展頭和數據,擴展頭除了ID和L相對于one-byte header從4bits變成了8bits之后,其余都一樣。
RTP 中的填充數據
與RTP擴展頭類似,RTP頭中的P位用于標識RTP包中是否有填充數據。如果P位為1,說明RTP包中含有填充數據。
當RTP包中包含有填充數據時,其數據包的最后一個字節記錄著包中填充字節的個數,即圖中的Padding Size部分。如果Padding Size為5,說明RTP包中共有5個填充字節,其中包括它自己。這些填充數據不屬于RTP Payload的部分,因此在解析RTP Payload部分之前,應將填充部分去掉。
去除填充部分的算法:讀取 RTP 包的最后一字節,即 Padding Size。從最后一個字節算起,將 RTP 包末尾 Padding Size 個字節丟棄。
翻譯器和混合器
翻譯器和混合器都是 RTP 協議的中繼系統。翻譯器用在通過IP多播不能直接到達的用戶區,例如發送者和接收者之間存在防火墻。當與會者能接收的音頻編碼格式不一樣,比如有一個與會者通過一條低速鏈路接入到高速會議,這時就要使用混合器。在進入音頻數據格式需要變化的網絡前,混合器將來自一個源或多個源的音頻包進行重構,并把重構后的多個音頻合并,采用另一種音頻編碼進行編碼后,再轉發這個新的RTP包。從一個混合器出來的所有數據包要用混合器作為它們的同步源(SSRC,見RTP的封裝)來識別,可以通過貢獻源列表(CSRC表,見RTP的封裝)可以確認談話者。
同步控制
由上圖可知,如果只有序列號,并不能完整按照順序的將 data 播放出來,因為如果 data 中間有一段是沒有資料的,只有序列號的話會造成錯誤,需搭配上讓它知道在哪個時間將 data 正確播放出來,如此我們才能播放出正確無誤的信息。
報文大小
RTP 載荷封裝設計本文的網絡傳輸是基于 IP 協議,所以最大傳輸單元(MTU)最大為 1500 字節,在使用 IP/UDP/RTP 的協議層次結構的時候,這其中包括至少 20 字節的 IP 頭,8 字節的 UDP 頭,以及 12 字節的 RTP 頭。這樣,頭信息至少要占用 40 個字節,那么 RTP 載荷的最大尺寸為 1460 字節。如果一幀數據大于 1460 字節,則需要分片打包,然后到接收端再拆包,組合成一幀數據,進行解碼播放。
wireshark 抓取 RTP 報文
抓取方法參考:《RTSP協議抓包及講解》。
我們可以參考上面的 RTP 協議的報文結構對下面一條 RTP 報文進行分析:
RTCP
概述
實時傳輸控制協議(Real-time Transport Control Protocol,RTCP)是 RTP 的一個姐妹協議,它是應用層協議,基于 UDP 實現。
RTCP 的主要功能是:服務質量的監視與反饋、媒體間的同步,以及多播組中成員的標識。
工作機制
當應用程序開始一個 RTP 會話時將使用兩個端口:一個給 RTP,一個給 RTCP。RTP 本身并不能為按順序傳送數據包提供可靠的傳送機制,也不提供流量控制或擁塞控制,它依靠 RTCP 提供這些服務。
RTP和RTCP使用UDP端口1024 - 65535。RTP 使用偶數端口號接收發送數據,相應的RTCP則使用相鄰的下一位奇數端口號。
RTCP 負責管理傳輸質量在當前應用進程之間交換控制信息。
在 RTP 會話期間,各參與者周期性地傳送 RTCP 包,其中含有已發送的數據包的數量、丟失的數據包的數量等統計資料。因此,各參與者可以利用這些信息動態地改變傳輸速率,甚至改變有效載荷類型。
RTP 和 RTCP 配合使用,能以有效的反饋和最小的開銷使傳輸效率最佳化,故特別適合傳送網上的實時數據。根據用戶間的數據傳輸反饋信息,可以制定流量控制的策略,而會話用戶信息的交互,可以制定會話控制的策略。
RTCP 封裝的僅僅是一些控制信息,因而分組很短,所以可以將多個RTCP分組封裝在一個UDP包中。
分組類型
在 RTCP 通信控制中,RTCP 協議的功能是通過不同的 RTCP 數據報來實現的,主要有如下幾種類型:
- SR:發送端報告,所謂發送端是指發出 RTP 數據報的應用程序或者終端,發送端同時也可以是接收端。
- RR:接收端報告,所謂接收端是指僅接收但不發送 RTP 數據報的應用程序或者終端。
- SDES:源描述,主要功能是作為會話成員有關標識信息的載體,如用戶名、郵件地址、電話號碼等,此外還具有向會話成員傳達會話控制信息的功能。其中有價值的是 CNAME,其作用是將不同的源(SSEC)綁定到同一個 CNAME 上。當重傳流時,SSRC 會沖突,可以通過 CNAME 將舊的 SSRC 更換成新的 SSRC,從而保證通信的每一個 SSRC 都是唯一的。
- BYE:通知離開,主要功能是指示某一個或者幾個源不再有效,即通知會話中的其他成員自己將退出會話。當 WebRTC 收到該報文時,就會刪除該 SSRC 對應的通道。
- APP:由應用程序自己定義,解決了 RTCP 的擴展性問題,并且為協議的實現者提供了很大的靈活性。
- RTPFB:RTP 反饋報文,是指 RTP 傳輸層面的報文。該報文可以裝入不同類型的子報文。
- PSFB:RTP 中與負載相關的反饋報文。該報文可以裝入不同類型的子報文。
報文結構
每一個 RTCP 數據報都由頭部(Header)和負載(Payload)兩個部分組成,其中頭部前 1 個字節的含義是固定的。
RTCP 報頭格式為:
- 版本號(V):2 比特,用來標志使用的 RTCP 版本。現在使用的都是第 2 個版本,所以該字段固定為 2。
- 填充位(P):1 比特,填充位標識。如果 P=1,則該 RTCP 包的尾部就附加一個或多個額外的八位組,它們不是有效載荷的一部分。
- 接收報告計數器(RC):5 比特,其含義取決于報文類型。對于 RR/SR,它表示所攜帶接收報告的個數;對于 SDES,它表示報文中 item 的個數;對于 BYE,它表示 SSRC/CSRC 的個數。
- 包類型(PT):8 比特,標識 RTCP 的分組類型。
- 長度域(Length):16 比特,表示整個 RTCP 包的大小(包括 RTCP 頭、負載、填充字節),以 4 字節為單位。
- Data:負載。不同類型的 RTCP 報文其負載的內容千差萬別,相關內容請自行查閱 RFC3550。
WebRTC 的反饋報文
RTPFB
PT = 205 表示 RTPFB 報文,是 RTP 傳輸層面的反饋報文。該報文可以裝入不同類型的子報文。該報文中可以包含多個子報文,其中WebRTC使用到的報文只有4項。
- NACK:接收端用于通知發送方在上次包發送周期內有哪些包丟失了。在NACK報文中包含兩個字段:PID和BLP。PID(Package ID)字段用于標識從哪個包開始統計丟包;而BLP(16位)字段表示從PID包開始,接下來的16個RTP包的丟失情況。
- TMMBR和TMMBN是一對報文,TMMBR表示臨時最大碼流請求報文,TMMBN是對臨時最大碼流請求的應答報文。這兩個報文雖然在WebRTC中實現了,但已被WebRTC廢棄,其功能由TFB和REMB報文所代替。
- TFB是WebRTC中TCC算法的反饋報文,該報文會記錄包的延遲情況,然后交由發送端的TCC算法計算下行帶寬。
PSFB
PT = 206 表示 PSFB 報文,是 RTP 中與負載相關的反饋報文。該報文可以裝入不同類型的子報文。
PLI報文與FIR報文很類似,當發送端收到這兩個報文時,都會觸發生成關鍵幀(IDR幀),但兩者還是有一些區別的。PLI報文是在接收端解碼器無法解碼時發送的報文。FIR報文主要應用于多方通信時后加入房間的參與者向已加入房間的共享者申請關鍵幀。通過這種方式,可以保障后加入房間的參與者不會因收到的第一幀不是關鍵幀而引起花屏或黑屏的問題。
REMB報文是WebRTC增加的反饋報文,用于將接收端評估出的帶寬值發給發送端。不過,由于最新的WebRTC已全面啟用基于發送端的帶寬估算方法,即TCC,因此目前REMB僅用于向后兼容,不再做進一步更新。
wireshark 抓取 RTCP 報文
我們可以參考上面的 RTCP 數據報對下面一包 RTP 報文進行分析:
設置過濾 RTCP 報文,可以看到下面第 397、401 報文為接收端報告+源描述,第 473、475 包報文為發送端報告 + 源描述報文:
RTP 會話過程
當應用程序建立一個RTP會話時,應用程序將確定一對目的傳輸地址。目的傳輸地址由一個網絡地址和一對端口組成,有兩個端口:一個給RTP,一個給RTCP,使得RTP/RTCP數據能夠正確發送。RTP和RTCP使用UDP端口(范圍 1024 - 65535)。RTP 使用偶數端口號接收發送數據,相應的RTCP則使用相鄰的下一位奇數端口號,這樣就構成一個UDP端口對。
發送過程如下:
- RTP 協議從接收流媒體信息碼流(如H.264),封裝成RTP數據包;RTCP接收控制信息,封裝成 RTCP 控制包。
- RTP 將 RTP 數據包發往UDP端口對中偶數端口;RTCP 將 RTCP 控制包發往UDP端口對中的奇數端口。
接收者:
- 根據RTP包的序列號來排序。
- 根據聲音流和圖像流的相對時間(即RTP包的時間戳),以及它們的絕對時間(即對應的RTCP包中的RTCP),可以實現聲音和圖像的同步。
- 接收緩沖用來排序亂序了的數據包。
- 播放緩沖用來消除播放的抖動,實現等時播放。
RTSP 和 RTP 的關系
RTSP 與 RTP 最大的區別在于:RTSP 是一種雙向實時數據傳輸協議,它允許客戶端向服務器端發送請求,如回放、快進、倒退等操作。當然,RTSP 可基于 RTP 來傳送數據,還可以選擇 TCP、UDP、組播 UDP 等通道來發送數據,具有很好的擴展性,它是一種類似于 HTTP 協議的網絡應用層協議。作為一個應用層協議, RTSP 提供了一個可供擴展的框架,它的意義在于使得實時流媒體數據的受控和點播變得可能。
jrtplib
jrtplib 是實現 RTP 的 C++ 庫。
初始化:
RTPSession sess;sess.Create(5000);// 3.11版jrtplib庫的Create方法被修改為Create(sessparams,&transparams)
RTPUDPv4TransmissionParams transparams;
RTPSessionParams sessparams;
sessparams.SetOwnTimestampUnit(1.0 / 8000.0); /*設置時間戳,1/8000表示1秒鐘采樣8000次,即錄音時的8KHz*/
sessparams.SetAcceptOwnPackets(true);
transparams.SetPortbase(portbase); /*本地通訊端口*/
數據發送:
// RTP 協議允許同一會話存在多個目標地址unsigned long addr = ntohl(inet_addr("127.0.0.1"));
sess.AddDestination(addr, 6000);sess.SetDefaultPayloadType(0);
sess.SetDefaultMark(false);
sess.SetDefaultTimeStampIncrement(10);sess.SendPacket((void *)buffer, sizeof(buffer), 0, false, 8000);
數據接收:
sess_client.Poll(); // 接收發送過來的 RTP 或者RTCP 數據報sess_client.BeginDataAccess();if (sess.GotoFirstSourceWithData())
{ // 遍歷那些攜帶有數據的源do{sess.AddToAcceptList(remoteIP, allports, portbase);sess.SetReceiveMode(RECEIVEMODE_ACCEPTSOME);RTPPacket *pack;pack = sess.GetNextPacket(); // 處理接收到的數據delete pack;} while (sess.GotoNextSourceWithData());
}sess_client.EndDataAccess();
總結
RTP是一個非常輕量的傳輸協議,特別適合傳輸音視頻數據,或者說它就是專門為傳輸音視頻數據而開發的。RTP控制協議RTCP對于傳輸服務質量起著關鍵的作用,WebRTC的服務質量系統中的大量控制參數都是通過RTCP獲取的。
參考
- https://blog.csdn.net/weixin_39766005/article/details/132301075
- https://baike.baidu.com/item/%E5%AE%9E%E6%97%B6%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE
- https://baike.baidu.com/item/rtcp
- https://www.rfc-editor.org/rfc/rfc3551.html
- https://blog.csdn.net/leixiaohua1020/article/details/50535230
- https://blog.csdn.net/wangbuji/article/details/130781275
- https://blog.csdn.net/wangbuji/article/details/121285741
- https://blog.csdn.net/qq_41839588/article/details/133465671
- https://www.cnblogs.com/ishen/p/12050077.html