WebRTC在PlanB方案下,只支持一條視頻流發(fā)送,這條視頻流,我們稱之為”主流”。何為視頻”輔流”?視頻輔流是指第二條視頻流,一般用于屏幕共享。
項目背景介紹
目前的SDK分享屏幕過程中,需要用攝像頭采集的通道分享屏幕,該方案下,分享者只有一路上行視頻流,該場景中要么上行攝像頭畫面,要么上行屏幕畫面,兩者是互斥的。
除非實例一個新的SDK專門采集并發(fā)送屏幕畫面,但實例兩個SDK的方案在業(yè)務層處理起來十分麻煩且會存在許多問題,例如如何處理兩個流間的關系等。
在RTC場景中,還存在一種可以單獨為屏幕分享開啟一路上行視頻流的方案,并稱之為“輔流(subStream)”,輔流分享即共享者同時發(fā)布攝像頭畫面和屏幕畫面兩路畫面。有了這個輔流的通道,同時也可以為新版本的iPhone支持前后2路攝像頭發(fā)送視頻數(shù)據(jù)奠定基礎。
技術背景介紹
前期SDK的架構設計是一個多PeerConnection的模型,即:一個PeerConnection對應一路音視頻流。隨著新的SDP格式(UnifyPlan)的推出和支持,一個PeerConnection可以對應多路音視頻流,即單PeerConnection模型。
基于單PC的架構,允許創(chuàng)建多個Transceiver,用于發(fā)送多條視頻流。

概要介紹
目前視頻流主要分為3類:Camera流、屏幕共享流、自定義輸入視頻流。
1.將Camera流作為主流,支持Simulcast
2.將自定義視頻輸入(非屏幕共享)作為主流,不支持Simulcast
3.將屏幕共享作為輔流,不支持Simulcast,有單獨的屏幕共享編碼策略
由于iOS屏幕共享的特殊性,其通過自定義視頻輸入的方式獲取視頻數(shù)據(jù),因此存在如下圖所示的流程圖:

綜上所述:iOS的自定義輸入既可以使用主流的通道發(fā)送視頻(非屏幕共享),也可以使用輔流的通道發(fā)送視頻(屏幕共享)。
關鍵類圖
上述提到的單PC架構,目前會有2個RtpTransceiver,一個是AudioTransceiver,一個是VideoTransceiver,而輔流的屏幕共享會在新增一個RtpTransceiver。一個VideoRtpSender會包含一個VideoMediaChannel。


1.信令層面需要支持多路視頻流,使用mediaType用于區(qū)分上述的Camera流(Video)、屏幕共享流(ScreenShare)、自定義視頻輸入流(externalVideo)。
2.重構跨平臺層的Capture和Source的管理。
3.重構用戶和渲染畫布的管理,從一個uid對應一個render,過渡到一個uid的sourceId對應一個render,每個uid可能會包含2個sourceId。
4.互動直播的服務器推流和錄制需要支持主流和輔流的合流錄制。
5.主流和輔流的擁塞控制方案的落地。
6.主流和輔流的碼率分配方案的落地。
7.主流和輔流的編碼器性能優(yōu)化。
8.PacedSender發(fā)送策略、音畫同步等方案的調整。
9.服務器Qos下行碼率的分配方案的調整。
10.?輔流相關的統(tǒng)計數(shù)據(jù)的匯總。
11.?產(chǎn)品的計費問題。
碼率分配
帶寬分配的主要流程:
1.CC評估出來的總帶寬分配會分給音頻流、主流、輔流
2.主流內部再由Simulcast模塊分配大小流的碼率,不開Simulcast時就直接給大流

輔流會在上圖的基礎上再新增一個VideoSendStream。
目前關于碼率分配的流程如下圖所示,概括起來有一下幾步:
1.cc的碼率通過 transport controller 傳遞到 call 中
2.然后經(jīng)過 BitrateAllocator 分配到各個注冊的流中 (目前就是視頻模塊)
3.視頻模塊拿到分配的碼率,分配給 fec 和重傳,剩下來的分配給 video encoder bitrate
4.視頻編碼器模塊拿到 video encoder bitrate,按照我們的策略,分配給大流、小流使用

擁塞控制
1、按照rfc2327(https://tools.ietf.org/html/rfc2327),使用"b=<modifier>:<bandwidth-value>"的方式來指定建議帶寬,有兩種modifier(修飾符):
AS:單一媒體帶寬
CT:會話總帶寬,表示所有媒體的總帶寬
目前SDK使用b=AS:的方式指定攝像頭碼流或屏幕共享碼流的建議帶寬,并把這個值作為CC模塊的估計值上限。
2、新的需求要求在同一會話中,可同時發(fā)送攝像頭碼流和屏幕共享碼流,因此應把兩路媒體的建議帶寬值相加得到整個會話的建議帶寬值,作為CC模塊的估計值上限
3、WebRTC支持b=AS:方式(單路媒體),在WebRTC內部對多路媒體進行相加處理即可滿足需求,而WebRTC目前不支持b=CT:方式。所以建議使用b=AS:方式,改動相對較少。
處理流程
pub碼流能力更新,通過sdp方式(b=AS:)的同步設置"最大帶寬"到CC模塊,當新增一路媒體流時,通過啟動probe快速探測的方式,迅速上探到可用帶寬:

快速帶寬評估
突然增加一路媒體流時,需要能夠很快上探到真實帶寬值,使用probe快速探測算法實現(xiàn)這一目標:
1.如果探測成功,CC估計值迅速收斂,在帶寬充足場景中收斂為CC上限,帶寬受限場景中為真實帶寬;
2.如果探測失敗(如高丟包率場景),CC估計值緩慢收斂,在帶寬充足場景中最終收斂為CC上限, 帶寬受限場景中為真實帶寬。
Paced?Sender處理
1.輔流與主流的視頻大小流的發(fā)送優(yōu)先級一致,所有視頻媒體數(shù)據(jù),使用預算和pacing multiplier的方式做平滑發(fā)送處理。
2.增加一個視頻碼流類型,kVideoSubStream?= 3,與主流的大小流視頻數(shù)據(jù)區(qū)分開來。
3.probe快速探測期間,當編碼數(shù)據(jù)不足的情況下,發(fā)送padding數(shù)據(jù)彌補,以保證發(fā)送碼率滿足要求。

統(tǒng)計上報
1、發(fā)送端和接收端MediaInfo獲取
當前SDK的MediaInfo獲取邏輯為:a)遍歷當前所有transceiver,獲取每個transceiver的video_channel和voice_channel,從而獲取到video_media_channel和voice_media_channel;b)根據(jù)media_channel 的getstats獲取當前channel的MediaInfo;c)將獲取的MediaInfo放在vertor media_infos中,便于上報;
主流和輔流同時發(fā)送場景,只是增加了一個transceiver,因此此邏輯適用于主流和輔流同時發(fā)送的場景,如下圖:

2、帶寬估計信息獲取
當前SDK的帶寬估計bweinfo獲取邏輯:
1、獲取gcc、probe探測等表示總體帶寬信息;
2、獲取每個transceiver的voiceChanel和videoChannel相關的帶寬估計信息(類似于mediaInfo的獲取)。
主流和輔流同時發(fā)送的場景只是增加了transceiver,因此此邏輯適用主流加輔流同時發(fā)送場景,如下圖:
