在 RTC 2019 第五屆實時互聯網大會的編解碼技術專場上,聲網開源了自研抗丟包音頻編解碼器Agora SOLO。git
目前,編解碼器的源代碼已經開源在 Github 上:https://github.com/AgoraIO-Community/Sologithub
這個開源項目兼容 WebRTC,可集成於多種場景下的實時音視頻應用中,好比在線課堂、直播社交、遊戲語音開黑、IoT 等。在分析它的特性以前,首先要講一下它名字中的一個關鍵詞,丟包。web
儘管不少人開始使用 WebRTC 了,可是其中有很多人都對「丟包」的概念不是很熟悉。因此,首先咱們要解釋一下。因爲 SOLO 是音頻編解碼器,咱們接下來說的場景,主要是指其中的實時音頻部分。算法
咱們如今的互聯網生活中有各類各樣的實時音視頻互動場景,好比:微信
這些場景都須要經過網絡進行實時傳輸。若是咱們將互聯網看做爲高速公路,那麼音頻數據是一輛輛車。丟包就是有的車沒法在有效時間內沒法達到終點,甚至可能永遠也到不了終點。假如咱們的一百輛車裏有五輛車沒能到達終點,咱們此次車隊傳輸的「丟包率」就是5%。是的,互聯網傳輸也同樣,它並非百分百可靠的,總有數據沒法按時傳輸到目的地。網絡
若是丟包比較嚴重,微信電話、視頻聊天或語音連麥的時候,你聽到的對方的聲音可能音質不好,甚至是斷斷續續的,或者乾脆沒有聲音。而這種狀況在任何網絡下均可能出現。不論你是經過 Wi-Fi、4G 仍是 5G,均可能由於進入地下車庫、進入電梯、信號覆蓋不良、網絡帶寬受限等緣由,遇到這些實時音頻體驗問題。因此,這就須要抗丟包策略,來保障音頻體驗。架構
咱們曾在一篇內容中詳細講過傳統的抗丟包策略,在這裏咱們不贅述。然而,傳統的抗丟包策略不是會浪費帶寬,就是會影響音頻質量,因此咱們結合信源和信道編碼的特色,利用充分包交換網絡的特性,基於此,研發出了抗丟包音頻編解碼器——Agora SOLO(如下簡稱「SOLO」)。性能
SOLO 是由聲網Agora自主研發的一款抗丟包音頻編解碼器。在測試
更重要的是,SOLO 編解碼器兼容WebRTC。若是開發者正在基於 WebRTC 開發本身的應用,可將 SOLO 集成到其中。編碼
要知道,WebRTC 默認使用的是 Opus 做爲編解碼器,而 Silk 與 Opus 有千絲萬縷的聯繫,咱們曾經在RTC 專欄的一篇投稿中講過。而 SOLO 則是以 Silk 爲基礎,融合了帶寬擴展(BWE)和多描述編碼(MDC)等技術,使其能在較低複雜度下擁有弱網對抗能力。也就是說,在 SOLO 的幫助下, WebRTC 應用能夠更好地應對不穩定的網絡環境,對音頻質量與體驗帶來有效的保障與提高。
根據咱們此前的測試(以下圖),一箇中文的女聲序列在不一樣編解碼器下的 MOS 分比較。第一列是不一樣的丟包率,後面各列是不一樣編解碼器在不一樣丟包率下的分數。能夠看到在丟包率25%時,SOLO 的 MOS 分比其它編解碼器有所提升。固然,咱們還在此前的內容中公開過更多跑分的細節。
利用 SOLO,能夠再也不關心網絡丟包狀態,由於它會默認發兩個包。若是隻收到一個就是有限失真,收到兩個就是高質量的恢復。
下面,咱們看一下 SOLO 編解碼器的架構。
圖 1. SOLO 編碼器架構
圖 2. SOLO 解碼器架構
SOLO的抗丟包策略與傳統方法不一樣。從通訊原理來講,信源編碼是儘量去追求高壓縮比,去冗餘。而信道編碼是追求強糾錯,靠加冗餘來實現糾錯。SOLO 就是把加冗餘和減冗餘結合起來,不重要的地方減冗餘,重要的地方加冗餘。在傳輸過程當中,它會將一個包拆分爲兩個進行傳輸,若是對端收到其中一個,則解碼恢復出一個有限失真的信號;若是對端收到兩個包,則可解碼恢復出一個高質量的信號。即 SOLO 不須要等待對當前網絡丟包狀態的統計,只須要直接把抗丟包作到編解碼內部。好處有三點:1.可實現更低延時;2.可實現更高質量,當收到一個包時質量達到的普通編解碼器水平,收到兩個包達到高質量編解碼水平;3. 可面向多人環境。
SOLO 使用帶寬擴展的主要緣由是但願減小計算複雜度,在 Silk WB 模式中,16khz 的信號都會進入後續處理模塊,而對於語音來講,8khz 以上的信息是很是少的,這部分信息進入到後續處理模塊,會帶來必定的計算資源浪費。MDC 由於要引入額外分析模塊處理多條碼流,又會引入額外的複雜度,這是 MDC 在近些年來落地不暢的重要緣由之一。爲了減小複雜度,咱們在編碼寬帶信號前,將其分爲 0-8k 的窄帶信息和 8-16k 的高頻信息。只有窄帶信息會進入到後續正常分析、編碼流程中,這樣後續的計算量就減小了一半,同時得益於帶寬擴展算法,總體質量不會有明顯降低。高頻信息部分,SOLO 使用獨立的分析與編碼模塊,默認將高頻信息壓縮成 1.6kbps 的碼流。這部分高頻信息能夠在解碼器內結合低頻信號恢復出高頻信號。
在 Silk 中,delay-decision 模塊是一個滯後計算編碼偏差的模塊,它能夠從多個候選碼流中選擇偏差最小的碼流做爲編碼輸出,必定程度上來講,它使得標量量化擁有了矢量量化的性能。SOLO 利用 delay-decision 模塊,實現了多描述碼流的分析與構建。SOLO 的MDC主要做用於濾波器輸出的殘差信號, SOLO 會根據當前信號狀態,對殘差信號作多增益控制:計算出 MD 增益 a(0<a<1),將 a 做用於奇數子幀,並將(1-a)做用於偶數子幀以產生兩段互補的殘差信號,這裏記做 residual 1 和 residual 2。
圖 3. 多描述殘差信號產生
隨後,這兩段殘差信號會進入到新的 delay-decision 模塊中,每一個殘差信號使用不一樣的抖動和量化方法,一共能夠產生 8 種不一樣的備選狀態,兩兩組合起來共有 64 種備選合成狀態,新的 delay-decision 模塊會對每一個殘差信號的獨立偏差和兩個殘差信號的合成偏差進行加權求和,決定出最佳的兩個殘差信號進入到編碼模塊。
圖 4. 編碼器碼流整合及組包
SOLO 默認配置爲每次輸入 40ms(2 幀),輸出兩段互補的多描述碼流,解碼器接收到任一段碼流,便可解碼出 40ms 的信號。爲了方便接收端區分碼流的順序,碼流第一個字節的右數第 4 個 bit 是碼流順序標誌位,第一段碼流標誌位的值是 0,第二段碼流標誌位的值是 1。接收端在進行碼流處理時,可依據此標誌位進行碼流順序判斷。
SOLO 已在 Github 開源,請點擊這裏跳轉 Github。固然,若是你對於SOLO 還有任何疑問,歡迎 點擊這裏向工程師們提問。