WebRTC 系列之視頻輔流


作者:網易雲信資深客戶端開發工程師 陶金亮

近幾年,實時音視頻領域越來越熱,業界很多音視頻引擎都是基於 WebRTC 進行實現的。本文主要介紹 WebRTC 在視頻輔流上的需求背景以及相關技術實現。

WebRTC 中的 SDP 支持兩種方案: PlanB 方案 和 Unified Plan 方案。早期我們使用多PeerConnection的 Plan B 方案中只支持一條視頻流發送,這條視頻流,我們稱之為”主流”。目前我們使用單 PeerConnection 的 Unified Plan 方案,新增一條視頻輔流,何為視頻”輔流”?視頻輔流是指第二條視頻流,一般用於屏幕共享。

需求背景

隨着業務的發展,一路視頻流滿足不了更多實際業務場景的需求,例如在多人視頻聊天、網易會議以及其他在線教育場景下,需要同時發送兩路視頻流:一路是攝像頭流,另一路是屏幕共享流。

但是,目前使用 SDK 分享屏幕時,采用的是從攝像頭采集通道進行屏幕分享。在該方案下,分享者只有一路上行視頻流,該場景中要么上行攝像頭畫面,要么上行屏幕畫面,兩者是互斥的。

除非實例一個新的 SDK 專門采集並發送屏幕畫面,但實例兩個 SDK 的方案在業務層處理起來十分麻煩且會存在許多問題,例如如何處理兩個流間的關系等。

在 WebRTC 場景中,還存在一種可以單獨為屏幕分享開啟一路上行視頻流的方案,並稱之為“輔流(Substream)”。輔流分享即共享者同時發布攝像頭畫面和屏幕畫面兩路畫面。

另外,有了這個輔流的通道,當設備為新版本 iPhone(新版本 iPhone 具有同時開啟前后攝像頭的能力)時,也為支持前后2路攝像頭發送視頻數據奠定了基礎。

技術背景

前期 SDK 的架構設計是一個多 PeerConnection 的模型,即:一個 PeerConnection 對應一路音視頻流。隨着新的 SDP(Session Description Protocol)格式(UnifyPlan)的推出和支持,一個 PeerConnection 可以對應多路音視頻流,即單 PeerConnection 模型,即基於單 PC 的架構,允許創建多個 Transceiver,用於發送多條視頻流

技術實現

目前視頻流主要分為三類:Camera 流、屏幕共享流、自定義輸入視頻流,分別有不同屬性:

  1. 將 Camera 流作為主流,支持 Simulcast;

  2. 將自定義視頻輸入(非屏幕共享)作為主流,不支持 Simulcast;

  3. 將屏幕共享作為輔流,不支持 Simulcast,有單獨的屏幕共享編碼策略;

由於 iOS 屏幕共享的特殊性,其需要通過自定義視頻輸入的方式來獲取視頻數據,因此存在如下圖所示的流程圖:

綜上所述:iOS 的自定義輸入既可以使用主流的通道發送視頻(非屏幕共享),也可以使用輔流的通道發送視頻(屏幕共享)。

如果是其他平台,例如 Mac、Win、Aos 等,則會相對簡單,攝像頭數據和屏幕共享的數據都來自於 SDK 內部,外部自定義視頻輸入的數據才來自於外部。

關鍵類圖

上述提到的單 PC 架構,目前會有2個 RtpTransceiver,一個是 AudioTransceiver,一個是 VideoTransceiver,而輔流的屏幕共享會在新增一個 RtpTransceiver。一個 VideoRtpSender 會包含一個 VideoMediaChannel。

輔流改動

實現輔流需要對不同層面都做一些調整以及重構,具體如下:

  1. 信令層面需要支持多路視頻流,使用 mediaType 用於區分上述的 Camera 流(Video)、屏幕共享流(ScreenShare)、自定義視頻輸入流(externalVideo);

  2. 重構跨平台層的 Capture 和 Source 的管理;

  3. 重構用戶和渲染畫布的管理,從一個 UID 對應一個 render,過渡到一個 UID 的 sourceId 對應一個 render,每個 UID 可能會包含2個 sourceId;

  4. 互動直播的服務器推流和錄制需要支持主流和輔流的合流錄制;

  5. 主流和輔流的擁塞控制方案的落地;

  6. 主流和輔流的碼率分配方案的落地;

  7. 主流和輔流的編碼器性能優化;

  8. PacedSender 發送策略、音畫同步等方案的調整;

  9. 服務器 Qos 下行碼率的分配方案的調整;

  10. 輔流相關的統計數據的匯總;

下面介紹在整個過程中,比較重要的幾個技術點的實現。

帶寬分配

在弱網情況下,需要視頻輔流的時候,我們會優先把碼率分配給音頻流,其次是輔流,最后再分配給主流,整體策略為保輔流

帶寬分配的主要流程如下:

  1. WebRTC 的擁塞控制算法 GCC(下文簡稱 CC) 評估出來的總帶寬分配會分給音頻流、主流、輔流;

  2. 主流內部再由 Simulcast 模塊分配大小流的碼率,不開 Simulcast 時就直接給大流;

具體過程如圖所示:

輔流會在上圖的基礎上再新增一個 VideoSendStream。

碼率分配

目前關於碼率分配的流程如下圖所示,概括起來有一下幾步:

  1. CC 的碼率通過 transport controller 傳遞到 Call 中;

  2. 然后經過 BitrateAllocator 分配到各個注冊的流中 (目前就是視頻模塊);

  3. 視頻模塊拿到分配的碼率,分配給 fec 和重傳,剩下來的分配給 video encoder bitrate;

  4. 視頻編碼器模塊拿到 video encoder bitrate,按照我們的策略,分配給大流、小流使用;

擁塞控制

為了實現視頻輔流的功能,我們需要對擁塞控制進行相關的改動,主要通過以下四個方面的改動來實現:

SDP 信令改動

按照 RFC 2327,使用 "b=< modifier >:< bandwidth-value >" 的方式來指定建議帶寬,有兩種 modifier(修飾符):

  • AS:單一媒體帶寬;

  • CT:會話總帶寬,表示所有媒體的總帶寬;

目前 SDK 使用 b=AS: 的方式指定攝像頭碼流或屏幕共享碼流的建議帶寬,並把這個值作為 CC 模塊的估計值上限。

新的需求要求在同一會話中,可同時發送攝像頭碼流和屏幕共享碼流,因此應把兩路媒體的建議帶寬值相加得到整個會話的建議帶寬值,作為 CC 模塊的估計值上限。

WebRTC 支持 b=AS: 方式(單路媒體),在 WebRTC 內部對多路媒體進行相加處理即可滿足需求,而 WebRTC 目前不支持 b=CT: 方式,所以建議使用 b=AS: 方式,改動相對較少。

CC 總碼率更新策略

Pub 碼流能力更新,通過 SDP 方式 (b=AS:) 同步設置"最大帶寬"到 CC 模塊,當新增一路媒體流時,通過啟動 probe 快速探測的方式,迅速上探到可用帶寬:

快速帶寬評估

突然增加一路媒體流時,需要能夠很快上探到真實帶寬值,使用 probe 快速探測算法實現這一目標:

  • 如果探測成功,CC 估計值迅速收斂,在帶寬充足場景中收斂為 CC 上限,帶寬受限場景中為真實帶寬;

  • 如果探測失敗(如高丟包率場景),CC 估計值緩慢收斂,在帶寬充足場景中最終收斂為 CC 上限, 帶寬受限場景中為真實帶寬;

Paced Sender 處理

  • 輔流與主流的視頻大小流的發送優先級一致,所有視頻媒體數據,使用預算和 pacing multiplier 的方式做平滑發送處理;

  • 增加一個視頻碼流類型,kVideoSubStream = 3,與主流的大小流視頻數據區分開來;

  • Probe 快速探測期間,當編碼數據不足的情況下,發送 padding 數據彌補,以保證發送碼率滿足要求;

下圖為實際進行碼率分配測試的結果展示:

統計上報

帶寬的統計上報分為兩個部分,分別是從 MediaInfo 獲取以及 Bweinfo 獲取。

1、發送端和接收端 MediaInfo 獲取

當前 SDK 的帶寬估計從 MediaInfo 獲取邏輯為:

  • 遍歷當前所有 transceiver,獲取每個 transceiver 的 video_channel 和 voice_channel,從而獲取到 video_media_channel 和 voice_media_channel;

  • 根據 media_channel 的 getstats 獲取當前 channel 的 MediaInfo;

  • 將獲取的 MediaInfo 放在 vertor media_infos 中,便於上報;

主流和輔流同時發送場景,只是增加了一個 transceiver,因此此邏輯適用於主流和輔流同時發送的場景,如下圖:

2、帶寬估計信息獲取

當前 SDK 的帶寬估計從 Bweinfo 獲取邏輯:

  • 獲取 gcc、probe 探測等表示總體帶寬信息;

  • 獲取每個 transceiver 的 voiceChanel 和 videoChannel 相關的帶寬估計信息(類似於 MediaInfo 的獲取);

主流和輔流同時發送的場景只是增加了 transceiver,因此此邏輯適用主流加輔流同時發送場景,如下圖:

總結

以上就是關於 WebRTC 中視頻輔流的分享,主要從業務需求出發,通過技術背景以及關鍵技術類圖,詳細分享了關於視頻輔流的技術實現。也歡迎留言與我們交流關於 WebRTC 以及音視頻相關技術。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM