light-rtc: 理念與實踐

VideoCloudTech發表於2021-01-04

在與同行交流過程中,發現很多同行對 WebRTC 改動太多,導致無法升級 WebRTC 版本。而 WebRTC 開源社群的快速迭代,讓他們感到欣喜又焦慮:開源社群的迭代效果,是不是超過了他們對 WebRTC 的優化效果?我們針對特定場景優化 WebRTC 時,怎麼緊跟 WebRTC 開源社群通用的優化?

作者:阿里雲智慧技術專家 熊金水

理念

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

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

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

架構

模組拆解

file
WebRTC 的核心模組,包括:

音訊

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

視訊

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

通用

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

WebRTC 在長期的演進中,API 已經具備了作為 Framework 的大部分能力。紅色的核心模組,已經基本可以外掛化,如下面的 API:
file

倉庫管理

file
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 硬解卡死等問題;
  • 新的音訊編碼器,適配商用接收端;
    ……
    file

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

ADM

很可惜,ADM(Audio Device Module)沒有提供檢測裝置插拔的功能,需要增加 Callback 介面。

另外,雖然 WebRTC 支援樣本數量的監控,但是當前只用於列印日誌,如果想在此基礎上做更多事情(如:發現採集樣本為 0 時,重啟採集),則單獨做一個 AudioSampleMoniter 的類,比較有利於擴充套件。
file
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 內部模組的資料流程圖:
file
從圖中可以看出,APM 其實也為外掛化做了準備,但是隻在近端訊號的尾部、遠端訊號的頭部。從 APM 建構函式上也可以看出來:
file
濾波/均衡,可以方便的實現一個 CustomProcessing 的 render_pre_processor。

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

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

AM

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

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

FEC

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

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

CC

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

演算法本身,可以用不同的演算法實現,如 WebRTC 預設的 goog_cc,也可以是 BBR,甚至是滿足 WebRTC::NetworkControllerFactoryInterface 介面的外部外掛。

關聯模組:

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

file

  • 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 倉庫裡實現。
file
讓 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

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

相關文章