H.265在QRTC场景的落地运用
點擊上方“LiveVideoStack”關注我們
近年來,伴隨著采集渲染設備終端發展,人們對視頻質量的需求也在日益“膨脹”,更高的分辨率:4k/8k,更寬泛的亮度,色度動態范圍HDR/Dolby視界,更沉浸式感受:VR /AR 360全景體驗等;這也給網絡帶寬/設備計算能力等帶來了新的挑戰,怎么在有限的容量下傳輸最有價值的視頻信息始終是我們需要解決的核心問題;面向未來,七牛云作為領先的云服務廠商,全線產品支持更好的視頻編解碼成為必然選擇。本次LiveVideoStack 2021 北京站邀請到七牛云視頻編解碼負責人—朱玲,重點分享七牛云將H.265落地運用到QRTC場景的一些創新經驗和教訓。
文 | 朱玲
整理 | LiveVideoStack
我是朱玲,在視頻編解碼領域有10多年的工作經驗,目前就職于七牛云,負責視頻編解碼方面工作。
本次主要和大家分享七牛云RTC場景中落地H.265的實踐經驗。
本次分享從以下三方面展開:首先是為什么在QRTC支持H.265?其次是如何更好支持H.265?最后探討QRTC在視頻質量優化方面的規劃。
1.為什么支持H.265
很多同學可能會疑惑,2013年H.265就結題了,七牛云為什么在過了將近十年后的今天才來談在rtc場景落地H.265,似乎很不fashion。我也觀察到,國內音視頻行業對H.265的討論在2017年達到高峰,內容主要集中在點播、轉碼、窄帶高清領域,少部分關于RTC領域的討論也主要是桌面共享優化中提到的H.265 SCC Tools,甚至于,近兩年關于AV1的討論卻逐漸多起來,這次大會就有幾場分享主題是AV1的,其實這都很好理解,AV1作為Google家VPx的下一代,就像10年前的VP8 vs H264之爭一樣,不同的是,Google這次聯合了許多商家研發AV1,也可見AV1的復雜程度,難搞啊。
在選擇H.265之前七牛云進行了完備的市場調研,結果顯示經過八年的發展,H.265生態已經非常完善,基本所有OTT設備包括攝像頭、smartphone都能夠支持H.265,這是AV1所遠不能及的。當然,RTC領域的從業者更多關注Web端,我們也對Web端進行了調研,Safari和Edge均支持H.265,個人看來Chrome支持H.265可能只是時間問題。
而且,伴隨著HDR/4K、8K高清視頻的出現,H.264已無法滿足不斷提升的視頻質量需求了,即使帶寬充足了,H.264的壓縮成本也非常高,亟需更高壓縮率的編碼器來解決當下的痛點。
左圖中黃線代表H.265,預測從2020年開始一直處于穩步上升的態勢,到2029年完全超過H.264。我個人是非常認可這張圖,從我們的后臺監控流量觀察,2019年H.265的量并不大,大概占據10%,但從2020年開始,流量就一直在不斷增加了。
業內同學經常討論H.265的好處和優點,在WebRTC中的應用效果還是那么好嗎?目前沒有足夠的文獻、數據支持定論,但我相信已經有許多廠商嘗試甚至已經開始支持H.265,七牛云也不例外。
在測試H.265時,我們找了一大批數據集(Class B-E,標準組織的開放源碼)。我們沒有測試2K,是因為RTC場景主要是720p、1080p。Qiniu是我們自己的用戶數據測試集,大概有六十多個,包括游戲、直播等場景。在所有的測試系列上對比了X265(不是very fast或ultra fast,是七牛云自己定的檔次,這一檔次的速度類似于ultra fast,但性能更好)、X264及OpenH264(WebRTC默認集成)。數據顯示,相對于X264,X265壓縮率提升了36.3%,相對于Open H264更是提升了64.1%。簡而言之就是節省了許多帶寬成本。但問題在于編碼速度降低了2-5倍,表中列舉的是相對速度,在四核機器上跑1080p時,X265編碼的絕對速度大概~20fps。
左視頻由OpenH264編碼,右視頻由X265編碼。大家可以觀察兩個視頻中“數字19”及地面上綠色的線,可以明顯看到左邊比較模糊。
總之,由于AV1的生態不完善,而H.265落地就能為用戶帶來價值,所以七牛云優先選擇H.265。
2.如何支持H.265
圖中是X265的框架,做編碼器的同學應該非常熟悉。X264和X265在框架圖中的區別僅在于SAO和Split into CTUs,既然框架大致相同,那么為何前者相對后者能夠提升較大性能呢?
主要原因是X265的分塊更大更靈活,編碼單元最大是64x64,64x64可以繼續以四叉樹形式劃分為32x32, 16x16,到8x8的分割,塊劃分方式一共有85種可能性,比H.264更豐富。
X265的幀內、幀間預測模式也更豐富,這里截取的是Inter模式下的PU劃分方式,左側的對稱性分割兩者都有,但H.265還能進行4x16或12x16的非對稱性分割。
X265的TU也更大,從之前的4x4,8x8到現在的16x16,32x32,TU越大,去冗余也就越多,(當然計算量也會越大,下文會詳細討論)。
除此以外,X265也增加了新的coding tools,如SAO、AMVP,AMVP相較于H.264中的MVP加了時域MV預測,還有Merge模式等等。
以上是X265性能提升的主要原因。
既然H.265 這么好,那是否有現成的編碼器實現可以直接應用到我們的產品中呢?帶著這個疑問,我們重點測試了硬件實現的代表:Video TooLBox,學術界實現:HM,以及開源實現X265,從測試數據看來,VideoTooLBox并不樂觀,兩個指標甚至都不如X.264,所以大家在直接使用Apple硬件支持H.265時也許會發現,怎么性能可能還不如X264啊;而HM 的速度真的太慢了,完全不能產品化,但壓縮率確實好。至于X265,前面也介紹了在特定環境下絕對速度只有20fps,達不到實時高清要求,而且相對于HM,X265的壓縮也有很大提升空間。
我們的目標是產品化的H265的速度能達到或接近H264的水平,壓縮率達到HM水平。
七牛云對265編碼器的優化包括碼率控制優化、編碼工具優化、匯編優化。
2.1 碼率控制分析&優化
WEBRTC傳輸層為了能夠實時檢測帶寬,耗費了很大精力在帶寬估計上,比如推出了GCC、TCC等,光帶寬估計準確是不夠的,編碼器的碼率控制(尤其在WebRTC場景下)同樣重要。
碼率控制的主要內容是預估當前幀/宏塊的相對復雜度,結合可分配碼率,計算當前幀/宏塊的編碼QP,可以簡化為Bit->QP, ?碼率控制要注意以下問題:
1、控制粒度,控制到幀級還是宏塊級,如果控制到宏塊級,那么一幀里的每個宏塊的QP都是不同的。
2、幀/宏塊復雜度估計,如何計算復雜度。
3、如何建立Bit-QP之間的關系模型,使用R-Q還是R-λ模型。
4、實時反饋調整機制,估計不準確要盡快進行調整。
優秀的碼率控制首先要能控住,但這并不是最重要的,比如500k的帶寬控制到200k,視頻質量會非常差,這樣的控住沒有意義,所以應該是控制且最大化發揮帶寬能力。其次還需要平穩的視頻質量和最優的壓縮性能。
下面讓我們帶著這四個問題,分析下X265的碼控實現。
圖為one-pass的ABR算法下X265幀級碼控流程圖
X265在計算當前幀的復雜度時,不僅使用了當前幀的SATD,還使用了之前的SATD。所以X265碼控特征是波動小,新的一幀對整個系統影響和沖擊比較小,延續了X264作者說到的希望QP波動不大。雖然這個想法很好,但當某一個場景下的R-Q關系發生大的變化后,這時如果QP波動還很小,無法對系統造成沖擊,勢必不能較好地控制碼率。X265也打了一些補丁,當出現新的一幀或新場景的時候,就會重置整個系統的碼控。
針對RTC場景,我們對X265幀級碼控了個有趣的測試。
橫坐標是時間維度的幀數(25幀/s),在250幀(10s)這一點改變目標碼率,從1000k改為500k(碼率實時波動是RTC場景的一個顯著特征),可以看到,如果在ABR碼控中只修改Bit值,不進行其他操作,圖示藍線(代表實際碼率)和目標碼率的跟隨很不緊密,一直到350幀也就是14s左右才能接近目標碼率,而且碼率很快又降低很多,和目標碼率差距較大。如果在改變目標碼率的同時刷新碼控模型,就會像紅線(代表重置后的實際碼率)的表現一樣,緊緊跟隨目標碼控并且很快達到目標碼率水平。
測試說明如果在RTC場景使用X265的ABR,設置新的目標碼率同時需要刷新碼控模型,否則會像藍線一樣表現非常差。
宏塊級碼率控制不是X265默認選項,需要先設置VBV才會啟動宏塊級調控,更準確地說是編碼一行之后再調整QP。VBV對QP的調整區間為[-6,+6],當超過+6時,系統判斷為此時碼率明顯不夠,將使用新的QP重新編碼這一行。
我們將碼率控制在500kbps,對RTC場景下使用VBV算法的X265宏塊級碼控系統做了大量測驗,數據顯示如果不打開VBV,碼率是能控住的,打開之后,PSNR表現差不多。
圖示QP-Limit的意思是,我們限制了碼控輸出的QP范圍:WebRTC的代碼中經常會將量化范圍設置為24~37,認為這個區間的視頻質量是人眼能夠接受的,低于24會浪費bit,人眼也不太能主觀看出差別,大于37人眼則不能接受。所以我們也設置了24~37的碼控限制,試圖造一個“不打開宏快級別碼控,碼率控不住,打開之后就能控住的case”,結果顯示, 打不打開VBV都控制不住,宏塊級別碼控沒什么作用。我個人懷疑是復雜度計算出了問題,但沒有深究。至少在大量測試數據的佐證下,VBV在RTC場景發揮的空間較小。另外,QP限制是有一定作用的,PSNR提升很多,視頻質量也會更好。
在保證單幀質量的情況下,X265控不住碼率,那么如何解決這個問題呢?既然X265不是針對RTC場景優化的編碼器,那我們就找到了為RTC場景誕生的OpenH264來進行測試。
圖為OpenH264的碼率控制模型,和X265的碼控系統相同,它也有復雜度、不斷更新的模型、上溢下溢。它的特別之處在于skip,當碼率控不住的情況下,會選擇跳幀來控制碼率,否則對帶寬應用影響很大。當然,跳幀也需要聰明的邏輯加持:如果10幀給了300k冗余,結果3幀就用完了后面7幀的冗余,其它全部跳幀,會導致畫面不連續。
對OpenH264進行的測驗中,QP限制是必須的,因為需要保證單幀質量,否則出現馬賽克會嚴重影響用戶體驗。在已經進行QP限制的情況下,控不住碼率時就要打開skip,對比最后兩行數據,打開skip控住后的碼率是496.8,未打開skip控不住時碼率達到653.3,當然幀數也是從本來的1000幀到694幀,跳了300多幀。
分析了這么多算法后,七牛云也提出了自己的碼控算法QNRC。目前只做了幀級的碼率控制。
QNRC采用的是R-λ模型。右上圖是我們擬合的一條bpp(bits per pixel)和qs cale的關系,這樣就可以跳過幀復雜度的計算,因為在實時場景下復雜度計算也不準確。QNRC允許skip,同時設置QP調節范圍。
右下圖是測試結果,橫坐標每2s為一個點,可以看到500k時QN265表現非常平穩(1s為一點時會有一些波動),而藍線X265-ABR波動比較大。從碼控來看,QN265基本接近目標碼控500k,碼率大概浪費了0.04,PSNR高了0.5,質量高很多,這就是七牛云目前所做的碼控系統,還有一定的優化空間。
2.2 編碼工具分析&優化
編碼工具優化我們主要介紹廣義B幀、AMP、Adaptive QP、SAO、幀間模式選擇(整個編碼器中最耗時的部分)的優化。
2.2.1.廣義B幀
H.264或H.265的傳統B幀用到后向參考幀,實時系統中實現傳統B幀勢必會增加延時。廣義B幀的出現就解決了這個問題,它的預測編碼模式選擇都和B幀一樣,但只用了前向參考幀,這就是廣義B幀(Generalized P and B picture)。
目前蘋果硬件碼流支持GPB, HM也是支持的,X265不支持,所以我們在HM上測試了廣義B幀的功能,觀察GPB是否能在RTC場景中產生效益。
為HM配的參數適用于zero lantency場景,從數據來看,GPB是有效果的,1080p能帶來超過10%的壓縮率,這是非常可觀的數據。
我們也嘗試了在X265上集成支持并做了些測試,將X265的P幀全部改為了GPB幀,壓縮速率并沒有達到預期效果。分析碼流發現,左上圖是HM中第一個GPB幀中的第一個采用雙向預測的宏塊,L0和L1不同。按理說,參考幀相同 L0應該等于L1(第一個宏塊,后面的可能被AMVP影響就不列舉),這是因為B幀的雙向預測會固定L0的mv,再重新降低范圍,增大精度進行精確搜索,而X265尚不支持雙向預測運動估計。
于是,在支持GPB的同時QN265也只吃了了Bi- prediction motion search,右圖數據顯示支持BI search和GPB后能夠帶來8.36%的壓縮率。
所以大家如果想要實現RTC場景下的編碼器,最好能夠支持BI search和GPB。
2.2.2.AMP
上文也提到了X264都是對稱性分割,X265增加了不對稱性分割,結合視頻塊運動的復雜多樣性,增加不對稱PU劃分分時,往往能找到更精確的mv。
測試顯示:X265也支持AMP +RECT,整體帶來了9.5%的性能提升,速度也降低的比較多了,怎么降低復雜度呢?
我們做了些測試,設置一個QP值37,碼率不太高的平滑運動場景,發現打開和關閉AMP其實影響不大,選中AMP的沒有多少,可見,針對碼率比較低低,比較平緩運動的視頻序列,可以自適應關閉AMP。
另外,我們對打開AMP的碼流進行了仔細的分析,如圖所示左邊是前一幀,右邊是后一幀。紅色箭頭所指的幀選中了非對稱性的劃分方式,它的前一幀不是skip。總結得出一個結論:如果當前幀用AMP的劃分方式,它的前一幀中相應塊大概率不是skip的,我們將這個邏輯運用到快速算法 中,結果顯示:可以看到壓縮性能提升了7.7%,速度略有一點降低。
2.2.3.Adaptive QP
Adaptive QP是X264作者的拿手之作, 它的實際思想是人眼對視頻中平坦區的失真是非常敏感的,而對于快速變化的失真沒有那么敏感,所以應該把碼率主要用在平坦的地方。它會檢測幀的復雜度,如果是平坦的就降低QP,提升整體主觀質量。
我們也集成了Adaptive QP算法,進行了大量測試,但設計了很多case都沒有看到明顯的主觀質量提升,雖然壓縮率降低是符合預期,但是畫質沒有增強就有點意外了,QN265暫時沒有打開此功能選項。
2.2.4.SAO
SAO(Sample Adaptive Offset ,樣本自適應偏移),它的出發點是:在編碼端既有重建解碼圖像也有原始圖像,對二者像素進行比較,如果將這個像素值偏移offset寫到碼流里傳到解碼端,解碼端解碼重建時候加上這個offset,那么就更接近原始幀了。這個工具主要是用來提升編碼的PSNR,使解碼幀接近于原始幀。想法自然是很好的,但每個pixel都計算殘差寫入碼流是是非常浪費bits,無法達到視頻壓縮目的的。因此,SAO的研發者提出了對圖像進行分類傳輸,只對特定類別的像素offset進行傳遞,這樣即能節省碼流也能降低視頻壓縮失真。
SAO在X265的實現可以說是直接從HM拿來的,站在巨人的肩膀上,避免重復造輪子一點問題也沒有,同時也說明了這部分的優化空間非常大,因為HM的實現側重點不在產品化上。
X265里面又個SAO加速工具 “SAO-imited”挺好使的,建議大家支持SAO,畢竟能帶來可觀的視頻質量提升,同時也要研發更多的快速算法實現宏塊級別自適應SAO功能,整體提升效率和壓縮率。
2.2.5.幀間模式選擇
圖示是X265的幀間模式流程圖簡化版,相較于HM的流程有很大變化。前面也提到,X265和HM比較有30%的壓縮率差異,這一塊就占了較大比重。QN265的幀間模式選擇流程充分接近HM實現,同時集成了自己的快速算法(主要是early skip),從現階段的測試數據來看,QN265幀間預測部分相較于X265壓縮率提升了5%。建議大家在實現或優化自己的265編碼器的時候,嘗試打破X265的思路,也許會有意想不到的效果。
2.3 代碼分析&匯編優化
最后是代碼的匯編優化部分,我們首先使分析工具對代碼進行復雜度/cpu耗時分析,如圖所示,對耗時比較多的函數進行逐個分析優化來降低函數執行時間。
舉個例子:X265的“ ComlexityCheckCU”函數,實現的功能是:先求像素平均值,再用每個像素值減去平均值得出差值。編譯器自動解析需要12條機器指令外加兩個大循環來實現,復雜耗時。
對這個函數進行指令集優化,所謂指令集優化或匯編優化,它的底層邏輯即使是一條指令并行處理多個數據,增加指令處理的吞吐量。如圖所示,使用 AVX2的匯編指令集,用四條指令,每條指令并行處理八個像素,整體耗時是原先的1/5。
經過以上幾方面的優化,QN265編碼器速度和X265的ultra fast相當,在720p上能達到實時編碼,1080p大概在20多幀。壓縮率提升~20%。
當然了,光有好的算法還不夠,在RTC場景中還需要實現一整套的質量控制系統,將具體應用的場景特性,設備特性,利用大數據的手段整合起來作為我們編碼器使用的指導。QN265在保證實時性的前提下提供了三個檔次可供選用,大概的性能指標如圖所示。可編碼速度越快,壓縮率會隨之下降。一般而言,好的設備最好用最慢的檔次,壓縮率會節省更多,畢竟帶寬占據視頻應用的大部分成本。
3.未來規劃
未來,我們會持續優化H.265,雖然速度已超過ultra fast,但我們不滿足于此。其次會集成一些抗弱網工具,RTC場景最大的問題就是弱網。最后,我們擁抱所有的好技術,新標準。
講師招募
LiveVideoStackCon 2022 音視頻技術大會 上海站,正在面向社會公開招募講師,無論你所處的公司大小,title高低,老鳥還是菜鳥,只要你的內容對技術人有幫助,其他都是次要的。歡迎通過?speaker@livevideostack.com?提交個人資料及議題描述,我們將會在24小時內給予反饋。
喜歡我們的內容就點個“在看”吧!
總結
以上是生活随笔為你收集整理的H.265在QRTC场景的落地运用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【今晚7点半】:华为云在数字人领域的技术
- 下一篇: 【城市沙龙】LiveVideoStack