在與同行交流程序中,發現很多同行對 WebRTC 改動太多,導致無法升級 WebRTC 版本,而 WebRTC 開源社區的快速迭代,讓他們感到欣喜又焦慮:開源社區的迭代效果,是不是超過了他們對 WebRTC 的優化效果?我們針對特定場景優化 WebRTC 時,怎么緊跟 WebRTC 開源社區通用的優化?
作者:阿里云智能技術專家 熊金水
理念
簡言之,把 WebRTC 作為 Framework 使用,而不是 Library,即:WebRTC 倉庫輕量化,核心模塊插件化,
詳細的,WebRTC 作為 Framework 串聯核心模塊;核心模塊既可以以插件形式使用我們的實作,也可以 Fallback 到 WebRTC 的默認實作,目的是減少 WebRTC 沖突的可能性,提高升級 WebRTC 的敏捷性,
目標:一年升級一次 WebRTC,一次花費一個人月,
架構
模塊拆解

WebRTC 的核心模塊,包括:
音頻
- ADM 采集、APM、ACM 編碼;
- NetEQ 與解碼、AM、ADM 渲染;
視頻
- 采集、編碼;
- JB、解碼、渲染;
通用
- RTP 打包與解包、FEC 生成與恢復、CC 與 Pacer、ICE、SDP 信令等,
WebRTC 在長期的演進中,API 已經具備了作為 Framework 的大部分能力,紅色的核心模塊,已經基本可以插件化,如下面的 API:

倉庫管理

light-rtc 作為 WebRTC 倉庫,我們需要保留兩個 Remote,一個是 Alibaba,一個是 Google,升級 WebRTC 時,我們從 Google 上 Pull 最新代碼, 解決沖突,然后 Push 到 Alibaba,
對插件化的模塊,我們需要放到單獨的倉庫 lrtc-plugin 里,這樣有兩個好處:
- 對 light-rtc 倉庫改動少,減少與 Google 沖突的可能性;
- 更重要的,讓每個開發同學,在每次改動前,更主動、更有意識的思考,放到哪個倉庫更合適,否則容易慣性思維,直接改動 light-rtc,
對 lrtc-plugin 依賴的第三方庫,也應該以單獨的倉庫存在,并保留兩個 Remote,比如 Opus,這樣,即使修改了 Opus 原始碼,仍然可以像升級 light-rtc 一樣,方便的單獨升級 Opus 版本,
模塊
Codec
音頻編解碼器、視頻編解碼器,是我們最常優化的部分之一:
- 新的編碼工(AV1/SCC/ROI 等)優化視頻質量和帶寬;
- 解析度自適應,使不同能力(編碼能力、發送帶寬等)的發送端,發送不同解析度的碼流;
- Simulcast,為不同能力(解碼能力、顯示能力、接收帶寬等)的接收端,提供不同解析度碼流;
- SVC,提供時域/空域分層;
- 新的視頻解碼實作,規避 Mac 硬解卡死等問題;
- 新的音頻編碼器,適配商用接收端;
……

這部分插件化是相對簡單的,只需要實作自己的 [Video|Audio][Encoder|Decoder]Factory 即可,以 Simulcast為例,在自己實作的 VideoEncoderFactory 里,先用 WebRTC 原始的 VideoEncoderFactory,創建多個 Encoder 物件,然后封裝到一個 Simulcast Encoder 里,
ADM
很可惜,ADM(Audio Device Module)沒有提供檢測設備插拔的功能,需要增加 Callback 介面,
另外,雖然 WebRTC 支持樣本數量的監控,但是當前只用于列印日志,如果想在此基礎上做更多事情(如:發現采集樣本為 0 時,重啟采集),則單獨做一個 AudioSampleMoniter 的類,比較有利于擴展,

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 內部模塊的資料流程圖:

從圖中可以看出,APM 其實也為插件化做了準備,但是只在近端信號的尾部、遠端信號的頭部,從 APM 建構式上也可以看出來:

濾波/均衡,可以方便的實作一個 CustomProcessing 的 render_pre_processor,
其他的優化,遵循輕量化/插件化的理念,沒有現成的插件介面,我們可以創造新的插件介面,如嘯叫抑制,以及 AECM 優化的部分演算法,
但 APM 仍然會有很多沒辦法插件化的,只能修改 light-rtc 倉庫,如 AECM Double Talk 優化等,
AM
AM(Audio Mixer)的插件化,可以在不修改 light-rtc 的基礎上,玩出很多花樣:
- 播放本地檔案;
- 借助語音檢測演算法,優化語音排序,從而選出更準確的語音做混音;
- Mono 變成 Stereo,借助 HRTF,可以在多方同時說話時提高說話人辨識度和可懂度;
- 對 RTP 方案的回放,倍速回放時變速不變調;
……

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

CC
CC(Congestion Control),包含兩個方面,一個是 CC 演算法本身,一個是 CC 關聯模塊,
演算法本身,可以用不同的演算法實作,如 WebRTC 默認的 goog_cc,也可以是 BBR,甚至是滿足 WebRTC::NetworkControllerFactoryInterface 介面的外部插件,
關聯模塊:
- 帶寬分配:不同場景可能不一樣,如視頻會議里,需要“保音頻、保螢屏”,可以通過 rtc::BitrateAllocationStrategy 實作插件化,

- 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 倉庫里實作,

讓 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
- Pantheon:GitHub;Paper;Summary of Results,
- NADA,GCC,SCReAM 性能比較:Blog;Paper;GitHub,
「視頻云技術」你最值得關注的音視頻技術公眾號,每周推送來自阿里云一線的實踐技術文章,在這里與音視頻領域一流工程師交流切磋,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/244612.html
標籤:其他
