開發與維運

light-rtc: 理念與實踐

作者:熊金水
來源:light-rtc: 理念與實踐

理念

簡言之,把 WebRTC 作為 Framework 使用,而不是 Library,即:WebRTC 倉庫輕量化,核心模塊插件化。

詳細的,WebRTC 作為 Framework 串聯核心模塊;核心模塊既可以以插件形式使用我們的實現,也可以 Fallback 到 WebRTC 的默認實現。目的是減少 WebRTC 衝突的可能性,提高升級 WebRTC 的敏捷性。

目標:一年升級一次 WebRTC,一次花費一個人月。

架構

模塊拆解

image.png

WebRTC 的核心模塊,包括:
音頻

  • ADM 採集、APM、ACM 編碼;
  • NetEQ 與解碼、AM、ADM 渲染;

視頻

  • 採集、編碼;
  • JB、解碼、渲染;

通用

  • RTP 打包與解包、FEC 生成與恢復、CC 與 Pacer、ICE、SDP 信令等。

WebRTC 在長期的演進中,API 已經具備了作為 Framework 的大部分能力。紅色的核心模塊,已經基本可以插件化,如下面的 API:
image.png

倉庫管理

image.png

light-rtc 作為 WebRTC 倉庫,我們需要保留兩個 Remote,一個是 Alibaba,一個是 Google。升級 WebRTC 時,我們從 Google 上 Pull 最新代碼, 解決衝突,然後 Push 到 Alibaba。

對插件化的模塊,我們需要放到單獨的倉庫 lrtc-plugin 裡,這樣有兩個好處:

  1. 對 light-rtc 倉庫改動少,減少與 Google 衝突的可能性;
  2. 更重要的,讓每個開發同學,在每次改動前,更主動、更有意識的思考,放到哪個倉庫更合適,否則容易慣性思維,直接改動 light-rtc。

對 lrtc-plugin 依賴的第三方庫,也應該以單獨的倉庫存在,並保留兩個 Remote,比如 Opus,這樣,即使修改了 Opus 源碼,仍然可以像升級 light-rtc 一樣,方便的單獨升級 Opus 版本。

模塊

Codec

  • 音頻編解碼器、視頻編解碼器,是我們最常優化的部分之一:
  • 新的編碼工(AV1/SCC/ROI 等)優化視頻質量和帶寬;
  • 分辨率自適應,使不同能力(編碼能力、發送帶寬等)的發送端,發送不同分辨率的碼流;
  • Simulcast,為不同能力(解碼能力、顯示能力、接收帶寬等)的接收端,提供不同分辨率碼流;
  • SVC,提供時域 / 空域分層;
  • 新的視頻解碼實現,規避 Mac 硬解卡死等問題;
  • 新的音頻編碼器,適配商用接收端;
  • ……

image.png

這部分插件化是相對簡單的,只需要實現自己的 [Video|Audio][Encoder|Decoder] Factory 即可。以 Simulcast 為例,在自己實現的 VideoEncoderFactory 裡,先用 WebRTC 原始的 VideoEncoderFactory,創建多個 Encoder 對象,然後封裝到一個 Simulcast Encoder 裡。

ADM

很可惜,ADM (Audio Device Module) 沒有提供檢測設備插拔的功能,需要增加 Callback 接口。

另外,雖然 WebRTC 支持樣本數量的監控,但是當前只用於打印日誌,如果想在此基礎上做更多事情(如:發現採集樣本為 0 時,重啟採集),則單獨做一個 AudioSampleMoniter 的類,比較有利於擴展。
image.png

ADM 是一個適配難點,相信是困擾 RTC 同行的共同難題。不同操作系統、不同機型,都可能有不一樣的問題。例如:

  • Mac 3.5mm 耳機插拔時,偶爾崩潰;
  • Mac 獲取的設備 ID 在插拔後發生變化,不能做持久化;
  • 聯想 X1 電腦,多次插拔後,整個 Audio 後臺服務失效;
  • 某些 Windows 機型採集不到聲音;
  • 某些手機採音權限問題;
  • ……

這些修改大部分屬於 Bugfix,參考 “Bugfix” 章節。

APM

APM (Audio Processing Module) 可能是 light-rtc 相對難處理的部分。

APM 與 NetEQ 一起,可能是 WebRTC 核心模塊中,開源價值最大的部分。在我對 APM 有限的認知裡,對 APM 常見的優化可能有:

  • 混音後的遠端信號,做濾波 / 均衡處理。這是業界不少音頻算法的必要條件;
  • 利用 Android 手機特性,優化 AECM,尤其是 Double Talk 時的效果;
  • 嘯叫檢測與抑制;
  • 利用機型特性,優化 AGC,提高語音音量;
  • ……

下圖是 WebRTC APM 內部模塊的數據流程圖:

image.png

從圖中可以看出,APM 其實也為插件化做了準備,但是隻在近端信號的尾部、遠端信號的頭部。從 APM 構造函數上也可以看出來:
image.png

濾波 / 均衡,可以方便的實現一個 CustomProcessing 的 render_pre_processor。

其他的優化,遵循輕量化 / 插件化的理念,沒有現成的插件接口,我們可以創造新的插件接口,如嘯叫抑制,以及 AECM 優化的部分算法。

但 APM 仍然會有很多沒辦法插件化的,只能修改 light-rtc 倉庫,如 AECM Double Talk 優化等。

AM

AM (Audio Mixer) 的插件化,可以在不修改 light-rtc 的基礎上,玩出很多花樣:

  • 播放本地文件;
  • 藉助語音檢測算法,優化語音排序,從而選出更準確的語音做混音;
  • Mono 變成 Stereo,藉助 HRTF,可以在多方同時說話時提高說話人辨識度和可懂度;
  • 對 RTP 方案的回放,倍速回放時變速不變調;
  • ……

image.png

FEC

FEC (Forward Error Correction),常見的修改:

  • 調參,如冗餘度、MaxFrames、Table 類型,包括固定參數和動態自適應調參兩類,已有的插件接口 WebRTC::FecControllerFactoryInterface 即可滿足;
  • RSFEC,需要創造新的插件接口;
  • Opus Inband FEC。WebRTC 動態配置的 Opus FEC 參數,不能很好的解決弱網時聲音卡頓問題。這時,一個辦法是把 Opus 獨立成倉庫,直接修改 Opus 編碼器。

image.png

CC

CC (Congestion Control),包含兩個方面,一個是 CC 算法本身,一個是 CC 關聯模塊。

算法本身,可以用不同的算法實現,如 WebRTC 默認的 goog_cc,也可以是 BBR,甚至是滿足 WebRTC::NetworkControllerFactoryInterface 接口的外部插件。

關聯模塊:

  • 帶寬分配:不同場景可能不一樣,如視頻會議裡,需要 “保音頻、保屏幕”。可以通過 rtc::BitrateAllocationStrategy 實現插件化。

image.png

  • Pacer 調優:對於屏幕內容,I 幀往往非常大,WebRTC 的 2.5 倍的發送帶寬,會導致巨大的首幀時間。具體解法見仁見智。
  • ……

VideoRender

Android、iOS、Mac,WebRTC 都提供了默認的實現,雖然有少量 Bug,但是基本滿足需求。

Windows 平臺,早期 WebRTC 提供了 D3D 的實現,最新版已經剔除,我們可以在 lrtc-plugin 倉庫實現自己的 D3D,或者其他的渲染,如 QT OpenGL。

VideoProcess

WebRTC 並沒有提供視頻前處理(如:美顏)、後處理(如:超分辨率)的接口,但是我們完全可以像 rtc::BitrateAllocationStrategy 一樣,創造 VideoProcessInterface 接口,並在 lrtc-plugin 倉庫裡實現。

image.png

讓 VideoProcessInterface 同時繼承 Sink 和 Source 接口,可以方便的把多個對象串聯起來。

其他 & Bugfix

其他核心模塊,如 JitterBuffer、ICE 等,目前接觸的主要是 Bugfix,還沒有發現自己定製重寫的必要。

Bugfix,往往只能修改 light-rtc 倉庫。一方面,是儘量把 Bugfix 內聚成函數,減少對已有代碼的修改;另一方面,儘量把 Bugfix 貢獻到開源社區(issue tracker),既為開源社區做了貢獻,也徹底避免了升級的衝突。

貢獻到開源社區,往往比想象的要複雜,但也更能鍛鍊人。在特定場景,往往只用了 WebRTC 一部分能力,如視頻 JitterBuffer,一個 Bugfix 可能只考慮到了 H264,貢獻到開源社區時,則需要同時兼顧 VP8/VP9,甚至是將來的 AV1。在這個過程中,Google 工程師會在 Code Review 中與你親密切磋,其實是非常好的鍛鍊機會,進一步提高對 WebRTC 的認識。

參考

WebRTC m74 源碼

RSFEC:

  • WebRTC RSFEC 詳解和剖析;
  • ARTP 技術探祕之:WebRTC 中支持 RS FEC。

CC

「視頻雲技術」你最值得關注的音視頻技術公眾號,每週推送來自阿里雲一線的實踐技術文章,在這裡與音視頻領域一流工程師交流切磋。

image.png

Leave a Reply

Your email address will not be published. Required fields are marked *