優酷移動端彈幕穿人架構設計與工程實戰總結
點選藍字 關注我們
文娛妹導讀
彈幕穿人方案主要分為兩類:“雲端離線人體分割+端側渲染”和“移動端端側實時人體分割+端側渲染”。在這裡我們分別簡稱為 雲端方案 和 端側方案 。
本系列文章主要聚焦在 優酷端側彈幕穿人的技術實戰 上,主要包括優酷跨平臺多媒體渲染引擎OPR簡介、優酷端側彈幕穿人架構設計與工程實戰、淘系端智慧PixelAI移動端實時人像分割技術、以及優酷彈幕渲染及彈幕穿人渲染技術的方方面面。
一、背景
1. 彈幕穿人的價值
彈幕是目前使用者觀影的一個標配,彈幕能使使用者在觀影過程中與其他使用者實時互動,提升了觀影體驗。但彈幕也會遮擋影片畫面,也會給使用者帶來一些困擾。彈幕穿人是影片內容與彈幕內容爭奪使用者視覺焦點的一種平衡,能夠讓使用者在消費彈幕的同時,依然可以觀看到影片中涉及人物等的關鍵畫面區域。在有彈幕穿人效果的時候,使用者有更強的意願開啟更多行彈幕,彈幕穿人對使用者彈幕開啟行數有一定促進作用,從而證明彈幕穿人能產生正向的價值。
2. 端側彈幕穿人的優勢
相較於雲端方案需要提前針對某個劇生產、部署、下發,在介質有變化時需要重新生產等等不利因素,以及動則上百萬的生產、儲存及頻寬成本,不適用於直播等實時場景。端側彈幕穿人則完全依賴於移動端自身的算力,最大優勢是實時、低成本,並且利於大規模鋪量。
3. 端側彈幕穿人的技術要求及難點
3.1)穿人效果要準確
無論是雲端還是端側,穿人效果都要求準確。否則如果不達標,mask與人物有錯位、彈幕渲染頻繁抖動等等現象,這些都是不可接受的。
3.2)效能要達標
我們要在端側保證彈幕穿人效果和效能,不能因為端側彈幕穿人而導致CPU/GPU/記憶體等資源佔用的飆升,或者導致彈幕本身渲染卡頓,更不能影響到影片或音訊渲染的效果和效能。否則就是本末倒置了。
相較於雲端方案,端側方案的挑戰更大,主要表現在如下幾個方面:
(1) 算力有限
端側方案只能利用移動端自身的CPU或GPU來完成鏈路上所有操作。相較於雲端方案,端側的算力非常有限。移動端、邊緣端和雲端的GPU算力的介紹可以參考這篇文章《GPU深度報告,三大巨頭,十四個國內玩家一文看懂》。
(2) 模型小
由於端側的限制,我們不可能用大模型,這給檢測的準確性也帶來更大的挑戰。
(3) 實時性
彈幕穿人需要跟影片畫面實時匹配。由於影片幀率一般在25~60之間,為了達到好的穿人效果,我們對整個端側彈幕穿人鏈路的實時性要求是非常高的。端側穿人鏈路上所有操作,包括影片畫面獲取、人像分割檢測、彈幕穿人效果的實現及渲染上屏,所有這些操作加起來要求在20ms以內時間完成(超過20ms就基本能感知到彈幕的卡頓了),這樣才能達到一個好的效果。否則穿人效果就會有滯後感、穿人效果與畫面不匹配,甚至會對彈幕本身渲染的流暢度和影片渲染的流暢度都產生嚴重影響。
以上這些因素都會給端側彈幕穿人專案帶來巨大的挑戰。
在淘系演算法同學的大力支援下,PixelAI很好地完成了移動端實時人像分割的任務,給優酷端側彈幕穿人功能的上線鋪量打下了堅實的基礎。另外,我們在工程側也做了大量的優化(優化手段後面會有介紹),使市面上機型的大規模覆蓋成為了現實。
二、整體架構設計
1. 架構圖
OPR(OPen Render的縮寫)作為優酷主客全端的渲染引擎,主要負責audio、video和彈幕的渲染。另外,我們也在OPR中引入了端智慧引擎。由於OPR天生離audio、video和彈幕的raw資料最近,我們可以直接在OPR裡就去消費這些資料,產生我們所需的端智慧結果,給業務帶來更大的價值。我們不需要把資料再一層層地回傳給更高的層次去做處理去做消費處理。所以我們在OPR裡融入一層端智慧層,直接拿資料就可以處理端側智慧相關操作,然後把結果在OPR層展示、上報或者傳給上層去消費,這樣做的效率是最高的!
我們首先看一下整個OPR的架構圖:
OPR從上到下分為4個層次:
(1) 接入層
OPR是跨平臺的,我們支援Android(Android手機和OTT裝置)、iOS(iPhone、iPad、Mac)和Windows(DX9、DX11、DX12)平臺。我們抽象出對應平臺的介面,供業務層呼叫,來完成相應資料元素的渲染。
(2) 引擎層
引擎層,按功能分為Video Engine,Audio Engine和Danmaku Engine,分別對應video、audio和彈幕的引擎。
(3.1) 渲染層
除了基本的Video、Audio和彈幕渲染功能之外,OPR也包括相應的後處理能力,比如影片的幀享相關後處理、特效廣告、色盲、zoom等等能力,音訊的倍速、均衡器等能力,彈幕的節奏彈幕、流光彈幕、心動彈幕等特效能力。
(3.2) 端智慧層
主要包括人臉相關能力、語音能力、超分能力等,下層是其對應的支撐庫。
(4) 平臺層
對各平臺渲染介面的封裝,包括2d/3d的opengl es、metal、directx和audio的opensl、audioqueue、directsound等。
2. 流程圖
端側彈幕穿人流程如下:
(1) video正常解碼、渲染流程中,我們去實時擷取當前影片畫面幀;
(2) 送給端智慧模組,去做人像分割,得到人體分割mask資料;
(3) mask作為單通道紋理上傳至GPU;
(4) mask資料上傳至GPU之後,我們做一次5x5的gaussian blur,這樣邊緣處邊緣處更加平滑;
(5) 把blur處理之後的紋理作為alpha去跟彈幕紋理做blend;
(6) 有穿透效果的彈幕surface疊加在影片surface之後,就能得到如上絲滑的彈幕穿人效果了。
三、工程實戰
1. 技術選型及實踐
人像分割能力,外部開源的opencv和集團內的mnn都有這個能力。但是我們在移動端實測之後得的結論是,效能和效果都達不到我們端側彈幕穿人的要求。後來我們瞭解到,集團內部已經有一個強大的端上引擎PixelAI,有強大的人臉等處理能力,已經在淘寶直播等場景上線。我們快速實測了一下,的確在效果和效能都能滿足我們的需求。所以我們最終定型PixelAI來作為我們端智慧的主引擎來針對端側彈幕穿人來實時做人體分割。
2. 效能優化
1.1)幀畫面高效獲取
(1)正常video渲染流程如下:
video正常上屏流程是這樣的,video解碼後的資料(硬解或軟解),通過aliplayer調到opr的介面。video_player->video_engine->video_layer->video_pipeline,後面對接一個個後處理filters去完成各個後處理功能,最後上屏。
(2)使用者截圖場景下,幀畫面的獲取流程如下:
針對使用者截圖場景,由於截圖場景不需要上屏,所以我們自然而然想到如下流程,在所有的filter之後加一個snapshot的filter,這個filter完成資料渲染到一個紋理,然後拷貝出來即可。
針對使用者截圖這種場景,上述流程沒問題任何問題。我們在加上snapshot filter之後重新走一遍渲染流程,截圖完成後解除安裝snapshot filter,整個流程耗時若干毫秒。針對使用者主動截圖這個場景,我們不會因為這若干毫秒感知到效能存在問題問題。但是,當我們把整個鏈路應用到端側彈幕穿人這個場景下,我們發現每一幀截圖的這個若干毫秒的時間,就是一個致命的效能問題了。如果不壓縮時間的話,留給演算法的處理時間就太少了,無法達到上線的標準。
(3) 端側彈幕穿人場景,幀畫面獲取流程如下
針對這種需要頻繁實時截幀的場景,我們設計瞭如上鍊路。
我們在所有filter的末端增加一路quick_snapshot filter,這個filter有兩路渲染command。一路command按正常流程去渲染、正常上屏,不做任何額外處理。同時,另一路command把資料渲染到紋理,然後再拷貝出來。這樣,兩路相當於並行起來。在每一幀渲染過程中,不會有任何多餘的建立和銷燬snapshot filter的過程,完全不會對正常渲染鏈路造成任何影響。同時,新加的一路command使截幀的效率最大化,很好地實時完成了頻繁截幀的任務。
經過實測,我們的截幀效能提升若干倍,為演算法去做實時人體分割節省了大量的時間。
1.2)避免在cpu中完成耗時操作
PixelAI有大模型和小模型,為了使底層的MNN不做頻繁的初始化操作,大小模型要求的幀資料尺寸是固定的。如果大於或小於演算法要求的尺寸,PixelAI會先使用OpenCV去做scale。瞭解到這些scale操作全部在CPU中完成,會造成大量的耗時,所以我們針對大小模型,直接在前面的截幀操作中,通過紋理大小的變化,我們就可以在GPU裡完成了幀畫面的scale,使截幀輸出的尺寸就是PixelAI大小模型所要求的尺寸。這樣就避免了使用OpenCV在CPU中做scale鎖消耗的大量時間了。
1.3)非同步呼叫模型
從演算法同學瞭解到,PixelAI人像分割過程是一個原子操作,對應的底層MNN tensor等運算不可中端。一般來說,在GPU和高階手機的移動端運算比較快,但也有那種耗時比較久的場景。演算法側我們保證在一個固定的時間內返回結果。
如果演算法耗時較久不返回資料,我們在這裡死等的話,就會導致彈幕渲染卡頓、穿人效果的錯位等異常case,這是不可接受的。為了達到最好的效能和效果,我們必須要實現一個非同步呼叫模型。在正常時間內返回結果的,直接使用mask資料上屏。在正常時間沒有返回的,我們丟棄掉當前幀的mask資料。如果是若干幀以內沒有返回,我們都使用上一次檢測的資料;為了避免這種場景下穿人效果的錯位,超過若干幀就直接上屏,沒有穿人效果了。這也是在工程上對彈幕穿人渲染效果做出的一個均衡處理了。
3. 效果優化
要做到好的穿人效果,我們在渲染層面也做了大量的優化,參見文章《優酷彈幕穿人渲染技術揭祕》。
4. 測試結論
(1) 演算法測試結果,參見文章《PixelAI移動端實時人像分割》
(2) 優酷整體測試結果
測試結論:我們並沒有因為引入端側彈幕穿人帶來大量的效能損耗。
四、展望
移動端端智慧是未來一個趨勢,移動端彈幕穿人是端智慧一個很好的應用場景。後續我們會在OPR裡衍生出更多的端智慧應用場景,給優酷使用者的觀影帶來更好的使用者體驗。
以下內容你可能感興趣