視訊 QoE 的平衡之道—揭祕網易雲信 NERTC 視訊質量控制系統

語言: CN / TW / HK
本文根據網易雲信資深引擎工程師戚繼躍在《MCtalk Live#4:視訊 QoE 的平衡之道》線上直播分享整理,文末有直播視訊回顧以及 QA 整理。

導讀

網際網路發展迅猛,實時通訊(Real Time Communication,簡稱 RTC)需求與日俱增。如何在各種複雜網路服務質量 (Quality of Serverice,簡稱 QoS)下,以及參差不齊的硬體終端上取得最佳的視訊體驗質量 (Quality of Experience,簡稱 QoE) ,是 RTC 技術的重要一環。
 
本文從視訊質量控制系統 (Video Quality Controller,簡稱 VQC)模組出發,介紹網易雲信 NERTC 在提升視訊 QoE 方面做的一些工作。
 

VQC 在視訊 QoE 中的作用

 
視訊的 QoE 主要包含視訊的清晰度、視訊流暢度、視訊延時三個方面的指標,整體上由網路 QoS、視訊處理演算法、VQC 共同決定:
 
  • 網路 QoS:提供儘可能充分的可使用頻寬
  • 視訊處理演算法:在一定的位元速率下,輸出儘可能好的視訊質量
  • VQC:
    • 對 QoS 負責,控制碼率,保證流暢度和延時
    • 對視訊演算法負責,保證效能,平衡清晰度和流暢度
 
 
VQC 通過對視訊 QoS 狀態、視訊演算法狀態的監控,輸出控制訊號,達到場景化的最佳 QoE 表現,包括平衡清晰度、流暢度、延時這幾個指標。今天,我們主要分享網易雲信 NERTC 上的 VQC 實現以及 QoE 調優的相關工作。
 

網易雲信 VQC 實現

 
網易雲信的 VQC 模組部分參考了 WebRTC 的模組設計,整體結構如圖中所示,主要包含四個監控模組和一個策略模組。輸入的引數通過監控模組後得到當前的各種狀態結果,然後由 VQC 策略模組決定最終輸出的控制訊號,控制視訊 pipeline 的工作。下面,我們具體介紹每個模組。
 
 

QualityScaller

 
QualityScaller 模組的作用是監測當前的編碼質量,主要對清晰度和編碼器穩定性負責。
 
 
該模組輸入根據編碼器型別和編碼演算法型別而確定的 QP 閾值、當前輸出編碼幀的 QP 值、當前丟幀的統計資料,輸出視訊質量好壞的結果。
 
其中 QpSmoother 模組使用指數加權累加的方式來確定 QP 的統計值,如下:
 
 
我們詳細看一下這個公式的組成,公式中:
 
  • sample 為當前幀的 QP
  • 輸出 y 為 QP 統計值
  • alpha 是根據編碼器 QP 變化特性總結的一組係數值,根據上限和下限使用不同的係數值。比如我們測試下來針對 OpenH264 編碼器,QP 上限係數值可以使用 0.9995, QP 下限係數值可以使用 0.9999。通過這種差異性的上下限係數,達到視訊質量變差時(QP 增加)反應迅速,視訊質量變好時(QP 減小)反應稍微遲鈍的效果。
 
最終統計的上下限 QP 統計值,與輸入的 QP 閾值比較判斷,決定當前畫質的好壞。輸入的 QP 閾值也是根據編碼器不同而不同的,比如在 OpenH264 上我們測試下來使用閾值下限為 24,上限為 37;硬體 iOS 裝置上硬體編碼則使用其他值,Android 上硬體編碼則又不同,這都需要根據裝置的大量驗證來獲取。
 
MovingAverage 為一個滑動視窗函式,取這個視窗內的丟幀比例,超過一定閾值認為是質量變差。
 
最終內部週期性查詢模組會收集 QpSmoother 和 MovingAverage 的統計結果,輸出兩個結果(不輸出不計入結果):
  1. 視訊質量好
  • QpSmoother 的 QP 統計值下限小於等於 QP 下限閾值
  • MovingAverage 統計的丟包率超過閾值
  1. 視訊質量差
  • QpSmoother 的 QP 統計值上限大於 QP 上限閾值
 

OveruseFrameDetector

 
OveruseFrameDetector 模組主要作用是監測當前的效能能否支撐當下幀率的執行,對視訊的流暢度負責。
 
 
該模組輸入當前的目標幀率、解析度、CPU Usage 閾值,採集和傳送視訊幀時間,輸出當前效能好或者壞的結果。
 
ProcessingUsage 模組通過輸入的視訊幀採集和傳送的時間,統計整個視訊傳送鏈路即視訊採集到傳送的時長,用這個時長做一些平滑運算後得到一個統計值,用這個統計值和當前幀率下幀間隔的理論時長做比較,統計時長是否超過理論值,並記錄次數。然後週期性的收集次數,超過一定次數則輸出效能差 CPU bad 的結果,低於一定次數則輸出效能好 CPU good 的結果。
 
在該模組中,需要防止一些假的 CPU good 或者 bad 結果,比如:
  • 樣本數量少時(比如幀率低),週期性收集資料的時間沒有變,這就容易導致結果誤差
  • 新的幀率解析度剛開始工作時,各個環節的處理時間還沒有問題,也需要特殊處理
 

RateAllocator

 
RateAllocator 模組負責決定當前位元速率的使用,在大小流場景下充當大小流使用的策略模組。
 
該模組有幾個關鍵性作用:
 
  1. 遠端有多個使用者,其中有使用者訂閱了小流也有使用者訂閱了大流,該模組會決定有限的位元速率按照什麼比例分配比較合適
  2. 同樣的場景,在位元速率十分不足的情況下,該模組會決策大小流合併成一條流使用,提升畫質
  3. 在下行的頻寬受限情況下,該模組會決策傳送端有沒有必要降低頻寬傳送
 

MediaOptimization

 
MediaOptimization 模組主要負責監測和修正實時的位元速率和幀率,防止位元速率超發導致網路擁堵,因為擁堵後網路會進一步惡化,導致畫質、流暢度、延時全面的降低。
 
該模組控制實時位元速率主要通過內部的 FrameDropper 模組,其使用漏斗演算法決策當前是否位元速率超發,是否需要丟幀來穩定位元速率。
 
在每一幀編碼之前,將該幀的目標位元速率作為輸入放入漏斗中,編碼之後將當前幀的實際位元速率作為漏斗的輸出,然後去檢視漏斗是否滿了,如果滿了就丟棄下一個編碼幀來控制碼率。漏斗的容量大小和可以容忍的延時相關,需要進行場景化定義。
 
丟幀與否的結果也會輸出給 QpScaller 模組,作為評價編碼質量的依據的一方面。
 
 

VQC 決策模組

 
VQC 決策模組根據 VQC 內部前述所有模組的結果,結合使用者的場景設定,決策當下的視訊策略。
 
 
其內部包含兩個狀態機以及一個決策模組。
 
兩個狀態機相互獨立,互不影響:
 
  • 視訊質量狀態機
  • 效能情況狀態機
 
一個決策模組,我們具體說明其中的一些重要功能:
 
  • 根據使用者設定的場景以及期望視訊引數,設定各種內部調整的閾值
  • 根據狀態機的結果,決策提高或者降低視訊的引數 (解析度、幀率),以及提高或者降低的策略
  • 根據其他資訊,決策當前幀編碼的其他引數,比如 simulcast 雙流場景下大流或者小流是否編碼
  • 根據其他資訊,決定演算法是否需要調整,比如編碼演算法,後處理演算法等
 

通過 VQC 進行視訊 QoE 調優

 
VQC 通過對視訊質量的全鏈路監控和調節來保證良好的視訊 QoE ,下面介紹下雲信 RTC 這邊在通過 VQC 調優 QoE 方面的一些工作。
 

正確判斷編碼質量

 
表徵編碼質量的引數有很多:PSNR、SSIM、QP、VMAF 等,因為硬體編碼器的特殊性以及引數獲取計算成本的考慮,選用了 QP 作為評判標準。
 
如果選擇使用 QP 作為正確反應編碼質量的指標,需要考慮如下幾點:
 
  • 常規的 Slice QP 在 H264/265 編碼中,一般編碼器中只能反應前面幾個編碼巨集塊的質量。在軟體編碼上可以使用更優的 average QP 來作為視訊幀的 QP,這樣判斷軟體編碼質量效果更優。
  • 不同編碼演算法的 QP 閾值是不同的,比如我們在 OpenH264 上可以使用 (24,37)作為 QP 好壞判斷的上下限,但是在不同的編碼器和不同的編碼演算法上就需要調整,比如我們的 NE264、NE265、NEVC 編碼演算法都需要做對應的適配調整。
  • 不同硬體加速平臺上編碼器的 QP 的閾值是不同的,比如 iOS 系統、Android 系統,甚至 Android 不同的晶片平臺也需要做對應的適配。
  • 不同編碼演算法,不同硬體平臺,QP 質量變化的曲線不同,為了提取特徵,需要調節統計方法的統計係數。
 

正確判斷效能問題

 
為了防止效能問題導致的視訊 QoE 降低,我們需要能準確的甄別出效能問題並作出正確有效的調整。當前我們的 VQC 中,使用視訊幀處理時間來表徵效能狀態,想要正確甄別效能狀態,需要考慮以下幾個方面:
 
  • 能判斷編碼和前處理的整個流程的效能
  • 一些硬體有 pipeline 延時需要考慮
  • 如果幀間隔不均勻,會導致誤判定效能問題,需要識別出這種特徵
 
為了進行有效的調整,我們主要需要考慮以下幾個方面內容:
 
  • 根據測試中效能消耗的優先順序來調整,比如我們測試下來部分模組的優先順序是:前處理 > 編碼演算法 > 幀率調整 > 解析度調整
  • 如果做了相應的調整,統計的效能狀態還是沒有變化,我們需要有相應的處理手段,反饋調整內容和結果給狀態機,讓狀態機報告給決策模組進行下一步決策
  • 如果效能狀態變化過大,需要拉大調整步長
 

最優化調整

 
有效的調整就是是調整後視訊 QoE 提升明顯,我們主要可以通過以下幾個方面進行調整:
 
  • 解析度調整
  • 幀率調整
  • Simulcast 流的調整
  • 前處理的一些演算法開關
  • Codec 調整
 
VQC 是如何進行最優化調整的呢,如下:
 
  • 支援使用者可配置多種場景和策略
    • 通訊模式,直播模式
    • 使用者高可定製化:特殊場景模式,解析度不變模式,幀率不變模式,最小幀率最小位元速率等設定
  • 內部自適應調整,根據大量測試試驗確定某個具體場景下的引數組合,調整步長以及最佳路徑,比如如下視訊解析度和幀率調整步長和路徑
 
 

結語

 
本文主要介紹了網易雲信 RTC 中視訊質量控制系統 VQC 的設計,以及在 QoE 調優方面的一些工作。沒有一種策略是完美無缺的,魚和熊掌不可兼得。我們在 QoE 調優中做的工作就是在一定的條件下,通過一些列手段平衡清晰度、流暢度、延時這些指標,趨利避害。通過互相配合的策略以及大量的資料測試驗證,尋找出最優的策略。
 

QA 整理

 
以下內容,根據線上直播群內 QA 記錄整理:
 
  1. @一葦以航 提問:
Q: 請問 ratecontroller 的時候,一般都是 SFU 轉發模式,這個時候的 simulcast 是從服務端考慮所有訂閱端反饋給傳送者去調整大小流的位元速率嗎?
A:我們服務端做了各種場景下的策略,預設是走可配置的 TopN 策略,部分頭部觀眾儘量使用高清高流暢的大流,少量網路質量不好的使用者使用小流,服務端會根據下行所有觀眾的網路情況,算出一個合適的反饋位元速率
Q: 恩,我的問題不是問服務端的 SFU 轉發策略,而是傳送端在大小流的位元速率調整策略,你們談 ratecontrol 這個模組的時候說到了一點,傳送端收到一個 cc 的頻寬反饋,同時傳送端提供了 simulcast,你們好像還能夠考慮到不同的接收端的網路狀態,進行大小流的位元速率調整 , 是有這個能力嗎?
A: 我們有下行的 cc,伺服器會根據下行 cc 輸出的估計頻寬,然後綜合出一個合適的頻寬反饋給傳送端。Simulcast 是端上根據總的位元速率,在我們模組裡面做決策,是發大流還是小流,還是雙流。服務端也會根據每個端的情況,決定給下行傳送大流還是小流。
 
Q:美顏跟超分會帶來多大的延遲?
A: 關於美顏跟超分會帶來多大的延遲的問題:小於幀間隔,不會 delay 我們 pipeline,我們做了動態適配,如果大於幀間隔,會動態關閉掉,對整個流水線的延時小於一個幀間隔,如果 30 fps 就是小於 33ms。
 
Q: 一般做這一塊的都是基於 WebRTC 去做的,好像中途要切換 codec 的話,要麼就重新建立 peerconnection 重新協商,你們支援是因為自研新增的嗎,還是 WebRTC 本身支援呀?
A: 我們有部分參考了 WebRTC,codec 切換這塊不需要重新協商,我們做了頻道內的能力協商,是私有協議,不需要像 WebRTC 那樣做 sdp 交換,我們有自己的能力協商協議,然後音視訊引擎內部做切換。
 
Q:還有一個問題,你們在 RTC 會議房間裡如何處理關鍵幀請求,每一個新加入的使用者如果都發關鍵幀請求,會導致房間的流量很大,但是不發的話等到下一個 GOP 會很久,你們採用了什麼樣的策略去均衡?
A: 1. 一般邏輯是每個新加入的使用者都會有 intra request 發出來,然後接收端有一個 key frame 傳送間隔的控制。這樣不會有太多 key frame,也不會導致出圖很慢。
2. 當然我們為快速出圖做了些優化,提前伺服器 intrarequest, 儲存近期的 key frame 等操作。
這些都是我們實際調整的一些細節,需要根據自己的場景去適配,我們也是分場景的。直播和通訊策略就不一樣。
 
  1. @galen 提問:
Q: 請教下怎麼檢測卡頓呢, 一般檢測卡頓幀間隔時間有講究嗎?
A:卡頓我們會統計 200ms 卡頓和 500ms 卡頓,檢測實際渲染的幀率間隔,超過 200ms 或者 500ms,統計小卡頓或者大卡頓。

作者介紹

 
戚繼躍,網易雲信資深引擎工程師,長期從事音視訊相關開發工作,對 WebRTC 引擎,音視訊會議系統,視訊編解碼等有深入研究。目前主要負責網易雲信 NERTC 引擎的視訊體驗。
 
視訊回顧地址:http://mctalk.yunxin.163.com/details-live/13