網易雲信 NERTC 高清畫質體驗之 H.265的工程實踐 | 體驗共享技術專題

導讀:H.265是 ITU-T VCEG 繼 H.264之後制定的新一代視頻編碼標準,相比於 H.264,H.265能夠進一步提高壓縮效率,提升畫質,在當前的很多音視頻場景中,得到了越來越廣泛的應用,我們在網易雲信 NERTC 中對 H.265做了大量的工程實踐,本文爲體驗共享系列第三篇—視頻篇,文章將從四個方面做具體介紹。

 

能力協商

 

一個客戶端能否發送指定的特徵的碼流,不僅由本端是否支持編碼決定,也由房間裏其他接收端能否解碼決定。即發送端和接收端共同決定了本端能發送什麼樣的碼流。對於 H.265,可能會出現下面的情況:

 

圖片

 

那麼他們之間將如何通信?客戶端 B 如果發 H.265的流,客戶端 A 和客戶端 D 由於只支持 H.264解碼,它們接收到客戶端 B 發送的 H.265的碼流,是無法解碼的,所以我們需要設計一套能力協商機制,來保證支持不同編解碼能力的客戶端之間可以正常的通信。

 

下圖爲能力協商的整體設計圖:

 

圖片

 

下面詳細介紹一下我們能力協商的設計方案。

 

能力集設計 

 

能力集定義爲 { uint32 key : [ uint8 value1, uint8 value2 ... ] },使用1位掩碼

 

sdk 的 key 範圍是 [ 0, 2^8  ) 

video 的 key 範圍是 [ 2^8, 2^16 )

audio 的 key 的範圍是 [ 2^16, 2^24 )

 

字節示意如下:

 

圖片

 

舉例說明如下:

 

圖片

 

能力協商流程(客戶端) 

1. 客戶端本地定義能力集

2. 客戶端本地實現能力集上報,能力集下發配置的機制

3. 服務端提供頻道內能力集的生成、綜合以及下發功能

 

舉例說明:

  • 定義:能力字段 VideoCodec : 256 (2^8)能力值 H.264 : 0H.265 : 1

  •  客戶端 A 和客戶端 B 進入同一個頻道時客戶端 A 上報能力集{ 256 : [0, 1]},客戶端 B 上報能力{ 256 : [0]}

  • 服務端收到客戶端 A 和客戶端 B 的能力集上報之後,知道 A 支持 H.264和 H.265,B 支持 H.264,綜合 A 和 B 的能力集,得到頻道內支持 H.264的結論,下發能力集 {256: [0]}

  • 客戶端 A 收到能力集後,主動關閉自己的 H.265能力;客戶端 B 收到能力集後,和自己的能力集一致,不做改變。

 

能力協商流程(服務器)

1. 房間創建時,生成默認能力集,默認能力集由引擎提供,服務器用作一個全局配置

2. 第一個 edge_login 請求如果有能力集字段,則使用這個能力集覆蓋默認能力集,作爲房間的能力集;如果沒有能力集字段,則使用默認能力集作爲房間的能力集。由於是第一個,不需要廣播。

3. 後續每個用戶進來,如果能力集大於房間的能力集,則返回房間的能力集給這個用戶,房間的能力集不變。舉例說明如下圖:

 

圖片

 

4. 後續每個用戶進來,如果能力集小於房間的能力集,則取交集,縮小房間的能力集,並把結果廣播給所有的用戶。舉例說明如下圖:

 

圖片

 

 

H.265編解碼器實踐

 

各個平臺有自己特有的硬件265編解碼器,同時還有各種開源的軟件265編解碼器那麼我們將如何選擇,才能實現最佳的使用效果?

 

下面我們將分 Android,iOS,Mac 和 Windows 四個平臺分別介紹各平臺265編解碼器的實踐情況。其中軟件編碼器選用 x265做測評,軟解選用 ffmpeg,libhevc 做測評。

 

Android 端 

首先我們看一下 android 端硬件編解碼器的功耗和碼率情況(測試機型 Mi 10 : Qualcomm Technologies, Inc SM8250,測試 Profile:720P 30fps 1.7M)

 

圖片

 

再看一下 android 端各軟件編解碼器的性能情況(測試機型 Mi 10 : Qualcomm Technologies, Inc SM8250,測試 Profile:720P 30fps 1.7M)

 

圖片

 

圖片

 

最後看一下畫質對比(測試機型 Mi 10 : Qualcomm Technologies, Inc SM8250,測試 Profile:720P 30fps 858k),左爲 H.264,右爲 H.265

 

圖片

 

總結:

1. android 硬編265在功耗方面基本跟硬編264持平,同時 android 硬編265碼率比硬編264更穩一些

2. android 端軟編265的性能還是比較差的,不能滿足需求

3. android 端 ffmpeg 軟解265在 arm64上面性能比較差,CPU 佔用達15%,同樣條件下,使用 libhevc,CPU 佔用只有4.5%,性能上有很大提升空間

4. android 硬編265的畫質明顯要比硬編264的畫質更清晰,畫質收益很明顯

 

所以 android 我們265編解碼器的使用策略如下:

1. 優先使用265硬解。一些設備存在265硬解兼容問題的,高端機型選擇265軟解碼器,低端設備直接認爲不支持265解碼

2. 優先使用265硬編。一些設備存在265硬編兼容問題的,則認爲不支持265編碼,降級到264編碼

3. 由於 libhevc 軟解的性能明顯優於 ffmpeg 軟解265,所以265軟解碼器我們會優先選擇 libhevc

 

iOS 端 

首先我們看一下 iOS 端硬件編解碼器的功耗情況(測試機型 iPhone11,測試 Profile:720P 30fps 1.7M)

 

圖片

 

圖片

另外我們發現在某些機型上或者某些場景下,iOS 硬編265會出現明顯的碼率不足的問題測試機型 iPhoneXR,測試 Profile:720P 30fps 1.7M)

 

H.264:

圖片

 

H.265:

圖片

 

像這種出現碼率嚴重不足的情況,我們基於 iOS 硬編碼控,設計了一套碼率監控方法,如果監控到碼率出現嚴重不足,會從 H.265回退到 H.264

最後看一下在硬編碼率穩定的情況下的畫質對比(測試機型 iPhone11,測試 Profile:720P 30fps 858k)

 

左 H.264,右 H.265

圖片

 

總結:

1. 使用 iOS 硬編265功耗明顯比硬編264要大,同樣的使用 iOS 硬解265功耗也明顯比硬解264要大一些

2. iOS 硬編265偶現一些碼率不足的情況,導致畫質反而不如264

3. iOS 硬編265的畫質要比硬編264的畫質更清晰一些有一些畫質收益

 

所以最後 iOS 端我們265編解碼器的使用策略如下:

1. 優先使用硬編265,不支持軟編265

2. 優先使用硬解265只有在硬解265多次解碼失敗無法恢復後纔會回退到 ffmpeg 265軟解

3. 由於 iOS 265硬件編碼功耗比硬件264要大,監測 iOS 設備整體電量,在低電量情況下(比如到20%臨界點),我們把硬件265切回到了264硬件編碼器

4. 使用 iOS 硬編碼控模塊,監測實際編碼碼率情況,若出現明顯的碼率不足或者碼率超發,我們把硬編265切回到了硬編264

 

iOS 硬編碼控

下圖爲硬編碼控模塊設計圖:

 

圖片

 

碼控流程:

  • 首先硬編碼器將目標碼率 Target Bitrate 傳遞給碼控模塊 HWBitrateController

  • 每編碼完成一幀,將編碼後的幀大小更新給 HWBitrateController 估算出每秒的實際編碼碼率 Estimated Bitrate

  • 計算目標碼率與實際碼率直接的差值 Diff

  • 通過二分法取0.5倍的 Diff 加 Target Bitrate,作爲需要調整的碼率 Adjusted Bitrate

  • 將需要調整的碼率 Adjusted Bitrate 設置回硬編碼器 HWEncoder,作爲 HWEncoder 的目標碼率 Target Bitrate

  • 再回到第一步硬編碼器將當前目標碼率 Target Bitrate 傳遞給碼控模塊 HWBitrateController

  • 計算 Diff/Target Bitrate,如果持續大於30%,則認爲碼率出現明顯不足,需要觸發降級編碼器

 

Mac 端 

首先我們看一下 Mac 端265軟硬件編解碼器的 CPU 和碼率情況(測試機型 MacBook Pro (15-inch, 2016): Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz,測試 Profile:720P 30fps 1.7M)

 

圖片

 

圖片

 

硬編265碼率情況:

 

圖片

 

軟編265碼率情況:

 

圖片

 

同時,我們通過 dump Mac 硬編265的碼流,發現使用前向 B 幀取代了 P 幀

 

圖片

 

最後,我們看一下畫質對比(測試機型 MacBook Pro (15-inch, 2016): Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz,測試 Profile:720P 30fps 1M)

 

圖片

 

圖片

 

總結:

1. Mac 上面硬件265相對於軟件265,CPU 佔用更低,性能收益比較明顯

2. 編265碼率穩定性不如軟編265波動比較大,但都是圍繞目標碼率上下波動,經過長時間測試,發現整體碼率平均下來沒有明顯的超發或者不足情況出現

3. 編編碼碼流前向 B 幀取代了 P 幀,整體壓縮率會更高,同等碼率畫質更優

4. 硬編265畫質明顯優於264而軟編265與硬編265畫質差異不大

 

所以 Mac 端我們265編解碼器的使用策略如下:

1. 先使用265硬解。一些設備存在265硬解兼容問題或者不支持265硬解的,在 CPU 性能比較強的設備上面使用軟解265(ffmpeg),如果是 CPU 比較弱的設備,則認爲不支持265解碼

2. 優先使用265硬編。一些設備存在265硬編兼容問題或者不支持265硬編的,在 CPU 性能比較強的設備上面使用軟編265,如果是 CPU 比較弱的設備,則認爲不支持265編碼

 

Windows 端 

windows 上面由於硬編硬解碎片化比較嚴重,我們暫時沒有考慮使用硬編硬解,目前以使用軟編軟解爲主。

下圖爲 win 上面軟編軟解265的情況(測試機型 Dell Latitude 5290: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz,測試 Profile:720P 30fps 1.7M)

 

圖片

 

圖片

 

可以看到:

1. 軟編265和軟解265在 x86上面的性能表現不如 x86_64

2. 軟編265在 x86_64上面的 CPU 消耗也是遠遠高於軟編264的

 

所以最後 Win 端我們265編解碼器的使用策略如下:

1. 在使用 win x86的情況下,直接不支持265軟編軟解

2. 在使用 win x86_64的情況下,CPU 性能比較強的設備上開啓265軟編軟解;同時軟編265對 CPU 性能要求比軟解265更高,所以對設備的性能要求也會更加嚴格

 

 

工程策略

 

白名單策略 

前面有提到,我們在使用265硬編硬解的時候,需要考慮設備兼容性的問題;同時在使用265軟編軟解的時候,由於涉及大量的編解碼運算,也要考慮設備的性能問題。

爲了在整體工程層面提供最佳的用戶體驗,我們使用到了白名單策略。通過白名單配置下發,把是否支持265硬編硬解和軟編軟解的設備區分出來。

 

以下是我們的具體做法:

  • 通過大量的設備適配,把對265硬編硬解支持比較好的設備,配置到線上白名單裏面

  • 通過設備跑分,區分出設備 CPU 性能的高低,配置高性能的設備支持265軟編軟解,低性能設備不支持265軟編軟解,然後將配置更新到線上白名單裏面

  • 最後通過線上白名單配置下發,客戶端獲取到當前是否支持硬編硬解和是否支持軟編軟解的配置信息

 

H.265能力協商 

協商的是 H.265解碼能力,協商結果最後作用於編碼側,是否使用 H.265編碼

  • H.265解碼的配置下發,用戶設置以及當前設備支持能力,三者綜合得出當前 H.265的解碼能力

  • 能力協商模塊,根據當前 H.265的解碼能力,生成能力集,上報給能力協商服務器

  • 能力協商服務器綜合頻道內各客戶端的能力集,生成新的房間能力集,下發給各客戶端

  • 客戶端收到來自於服務器下發的能力集,解析出當前頻道內 H.265的能力集

  • 根據當前頻道內 H.265的能力集,H.265編碼的配置下發、用戶設置以及當前設備支持能力,服務器對 H.265的支持能力,三部分綜合得出當前是否支持 H.265編碼,最後作用於編碼側是否編 H.265的流

 

CPU OverUse 策略 

通過跑分,區分出不同設備 CPU 性能的高低,可能不是完全的準確。在實際場景中,有可能存在跑分數據很高,但是編碼性能不夠的情況,這時候我們需要通過實時監測統計當前視頻編碼耗時,來判斷當前是否 CPU 過載。

 

我們的做法是:

  • 硬編265考慮到可能存在 pipeline delay 的情況,目前我們暫不統計每幀編碼的編碼耗時

  • 在使用軟編265的時候,統計每幀編碼的編碼耗時,如果出現持續編碼耗時過長,那麼就認爲當前 CPU 過載,265軟編將會立即回退到264

 

QP 閾值調整 

我們的 QOE 模塊,會根據 QP 閾值調整幀率和分辨率,以達到主觀視頻質量最優,所以設定合理的編碼器 QP 閾值就顯得非常重要,那麼在實際工程實踐中,準對硬件265編碼器,我們如何探索出合理的 QP 上下限閾值?

 

我們的做法是:

  • 確保 H.264和 H.265在主觀畫質基本對齊的情況下,打出 QP 值,生成 QP 曲線,基於 QP 曲線得出 QP 上下限閾值基本的範圍

我們以這款機型爲例:(測試機型 Mi 10 : Qualcomm Technologies, Inc SM8250,測試 Profile:720P 30fps)

 

圖片

 

可以看到:

1. 在720p 30fps 這個 Profile 檔位,硬編265與硬編264在畫質基本對齊的情況下,硬件265碼率能夠節省40%,QP 波動基本相似,上下閾值也基本接近。所以如果當前 android 硬編264的 QP 上下閾值是[A, B],那麼建議 android 硬編265的 QP 上閾值範圍爲[A-1, A+1],QP 下閾值範圍爲[B-1,B+1]

2. 基於步驟1得出的 QP 上下閾值範圍,逐步網損逐步放開,觀測 QOE 模塊基於 QP 閾值的分辨率和幀率的調整情況,從 QP 閾值範圍中摸出最合理的一個 QP 閾值,以下面的數據爲例:

 

圖片

 

我們發現在 QP 閾值爲[A-1,B-1]的時候,整體 QOE 表現最好,所以選定[A-1,B-1]爲最後的硬編265的 QP 閾值

 

收益

 

目前第一階段的收益評測,我們是基於與 H.264分辨率碼率對齊,看畫質收益、端到端延遲、CPU 佔用、流暢度這四個指標。這裏先列舉了與硬編264對比,Android 硬編265和 iOS 硬編265的畫質收益情況,從我們評測下來的情況看,端到端延遲、CPU 佔用、流暢度這三個指標基本上差異不大,而畫質收益,可以參考以下圖表數據:

 

圖片

 

圖片

 

總體來看:

1. 相比於264,265在視頻畫質上是有明顯收益的

2. 在低碼率、弱網或者畫面變化比較劇烈的場景下,畫質收益會更加明顯

3. android 硬編265的畫質收益要明顯優於 iOS 硬編265

 

總結

 

不管是硬編265,還是軟編265,相比於264,視頻畫質都有明顯的收益;後續網易雲信將準對畫質對齊,節省碼率這個維度做進一步的探索。

 

作者介紹 

施靈凱,網易雲信音視頻引擎開發工程師,負責 NERTC 視頻引擎的開發與維護。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章