為應對愈發多樣化的音視訊互動場景下的挑戰,Agora 開始設計自己的下一代視訊處理引擎,在過程中關於引擎架構、效能調優、外掛系統設計等方面總結了很多經驗,希望與各位音視訊領域的愛好者、行業從業者分享。
5月26日下午,QCon全球軟體開發大會「實時音視訊專場」活動中,聲網Agora 架構師李雅琪帶來了以《聲網下一代視訊處理引擎》為主題的大量乾貨分享,本文是對分享內容的整理。
今天的分享主要會分三部分來進行:
一,為什麼我們要打造下一代視訊處理引擎,以及引擎的設計原則和目標是什麼;
二,我們是如何達到設計原則和目標的;
三,下一代視訊引擎的實際落地效果如何。
01 下一代視訊處理引擎的設計目標
隨著音視訊技術快速發展,實時音視訊互動在各種各樣的領域,如社交娛樂、線上直播、醫療中都得到了廣泛的應用和發展。疫情以來,越來越多的場景遷移到線上,不少讀者可能也都有觀看直播帶貨,或是陪小孩參加線上教育的經歷。
那麼這兩個場景中會有哪些痛點呢?在視訊直播場景中,處理多路視訊源的需求越來越廣泛。比如電商直播場景中,主播通常需要使用多個機位進行多角度拍攝,以達到更好的帶貨效果。這類直播可能還會同步搭配使用導播臺,在多個視訊源中進行多種實時直播組合和無縫切換。
而對於線上教育場景來說,比較傳統的方式是攝像頭拍攝老師,老師進行螢幕分享。為了豐富線上教育的手段,我們還可以增加一路視訊拍攝,拍攝老師在手寫板上的書寫,甚至額外增加一個功能,支援老師播放本地課件或者線上課件。
在多路視訊源的基礎上,還會衍生出來對多路視訊源的實時編輯和合圖的需求。在直播助手的應用場景中,主播可能需要對多路視訊源的採集進行實時合圖和編輯,再新增本地素材和動態表情包來豐富直播效果,同時降低上行頻寬壓力。在多人互動場景中,為了降低接收端的頻寬壓力和效能損耗,需要在雲端將多路主播視訊合成一路流再傳送給各個接收端。
隨著 AI 技術在影像處理的快速發展,融合 AI 演算法的高階視訊前處理功能也得到越來越多的應用,諸如一些高階美顏功能、背景分割、背景替換。結合這三個場景我們可以看到,下一代視訊引擎的靈活可擴充套件能力被提出了更高的要求。
另外,隨著我們公司業務和團隊規模的不斷增長,下一代視訊引擎的使用者體量也在劇增,不同使用者對整合開發的需求也各異。對於研發團隊規模較小的開發者或個人開發者,他們需要的是引擎的整合簡易度,低程式碼量,快速上線。而對於企業業務中臺的開發者,會要求引擎開放更多的基礎視訊處理功能,從而可以定製化的實現視訊處理業務。
面向各開發者群體的需求,聲網的下一代視訊處理引擎需要一個有彈性的設計來滿足差異化的整合需求。
不僅是彈性的設計,視訊直播體驗也是很重要的指標。隨著 5G 時代的到來,網路基礎設施足夠支援使用者對更清晰更流暢直播的體驗需求,下一代 SDK 必須在效能優化方面做到極致,支援更高的視訊解析度,更高的幀率。考慮到實時互動業務場景不斷擴充套件,使用者分佈也越來越廣,為了在網路基礎設施較弱的國家和地區、效能較差的低端機型上,引擎都可以提供比較好的視訊直播體驗,我們就要支撐更好的弱網抗性,並優化效能資源消耗。
結合上面提到的場景豐富性、使用者差異性,以及對視訊直播體驗的需求。我們將下一代視訊處理引擎設計原則和目標可以總結為四個方面:
1.滿足不同的使用者對整合的差異化需求;
2.靈活可擴充套件,可快速支撐各種新業務和新技術場景落地;
3.視訊處理引擎的核心繫統要提供豐富強大的功能,降低開發人員的心智負擔,做到快速可靠;
4.效能優越可監控,需要持續優化視訊直播處理引擎效能,同時提高監控手段,形成閉環並不斷迭代優化引擎的處理效能。
接下來我們進入第二部分,針對上面所提到的四個設計目標,聲網具體採用了哪些軟體設計的方法來進行實施落地。
02 下一代視訊處理引擎的架構設計
前面提到的第一個設計目標,我們要滿足不同使用者差異化的整合需求:引擎的使用者是天然分層的,一部分使用者追求低程式碼快速上線,需要引擎儘可能提供貼近他業務的功能;另外一部分使用者,需要我們提供更多的核心視訊基礎能力,在這之上客戶可以按照自己的需要定製視訊處理業務。
根據這個使用者形態我們的架構也採取分層業務設計,分成 High Level 和 Low Level。Low level 部分是面向視訊處理核心功能進行建模,抽象出了視訊源處理單元,前/後處理單元、渲染器單元、編解碼器單元、核心基礎設施單元等。通過這些基礎模組的組合和開發,在 Low level 的基礎上,我們又抽象出面向客戶業務的視訊源 Track 的概念,網路視訊流 Stream 的概念和場景的概念,在這上面封裝了更貼近使用者業務的 High Level API 。
我們來通過實際例子看一下 High Level 和 Low Level 兩者在使用上的差別:假設現在要實現一個非常簡單的場景,開啟本地攝像頭開啟預覽,釋出到遠端。
如果使用 High Level API,可以只通過 2 個簡單 API 的呼叫,完成這個實時互動業務場景的搭建。首先通過 StartPreview API 開啟本地攝像頭並預覽,然後通過 JoinChannel API 加入頻道併發布視訊流。若使用者想在這一簡單場景上實現更多定製業務功能,就可以使用 Low Level API。首先建立本地相機採集管線 CreateCameraTrack,這個 Track 提供了多種多樣進行形態組建和狀態控制的介面。同時我們將本地媒體處理和網路釋出節點進行了解耦,視訊流可以釋出到聲網自研的 RTC 系統中去或釋出到 CDN 網路。
通過上面的例子可以看出。為了滿足使用者差異化需求我們採用了分層設計,High Level 面向業務提供易用性,Low Level 提供核心功能和靈活性。
我們看第二個目標,靈活可擴充套件這一點我們是如何做到的呢?在這之前我簡單介紹一下關於視訊處理當中的基本概念,視訊處理的過程是以視訊幀作為視訊資料的載體。以本地傳送處理流程為例,視訊資料被採集之後會經過一系列的前處理單元,然後送到編碼器單元進行壓縮編碼,最後根據不同網路協議通過封裝之後傳送到遠端網路。接收的處理流程是從網路當中接收到視訊流後進行解封裝操作,送到解碼器當中,經過一系列後處理單元后,再到渲染器進行展示。
我們把以視訊幀為資料載體的序列化視訊處理 稱為視訊處理管線,每一個視訊處理單元我們把它稱為一個模組。每個具體的視訊處理單元可以有不同的實現,比如說視訊源模組,可以是自採集的視訊源,可以是攝像頭採集的視訊源或者螢幕共享的視訊源。不同編碼器根據編碼標準和編碼器實現也是可以有不同的擴充套件功能。網路傳送節點可以根據不同協議傳送到自研的 RTC 網路或者 CDN。不同的視訊業務其實是基礎視訊處理單元根據業務靈活編排形成的。我們希望可以把靈活編排的能力作為我們視訊處理引擎的基礎能力開放給到開發者,這樣開發者就可以通過靈活自由的 API 組合,搭建滿足自己業務需求的處理管線。
為了做到這一點,我們的視訊處理引擎核心架構是採用了 Microkernel Architecture 的架構,分離了整個引擎的變數和不變數。如圖所示分兩個部分,中間的 Core System 和外圍的 Pluggable modules。中間黃色的部分是整個的核心繫統部分,對應著整個下一代視訊處理引擎的不變數。在核心繫統中,我們抽象出來了各個基礎視訊處理單元的模組,以及提供了統一的控制面和資料面的介面。同時,引擎還提供了對這些基礎視訊模組進行組裝和靈活編排的控制介面。此外,核心系統還提供了一系列基礎設施功能,比如跟視訊處理相關的視訊資料格式轉換,基礎的視訊處理演算法,針對視訊處理特徵進行記憶體管理優化的記憶體池以及執行緒模型,日誌系統和訊息匯流排等。
利用核心系統底層能力,各個模組可以方便地進行業務擴充套件,比方說視訊源模組,可以有推流模式視訊源模組,也可以支援拉流模式的視訊源模組,甚至支援一種特殊的視訊源,即在轉碼的過程我們可以把遠端使用者的視訊解碼後的視訊幀作為新的視訊源加入到本地傳送的管線當中去。前處理模組和後處理模組也可以擴充套件出各種各樣的實現,如基礎的裁減縮放功能、美顏、水印功能等。編解碼模組更為複雜,一方面要支援多種編碼標準,還有相應多種實現,軟硬編等。同時,編解碼選擇還是一個比較複雜的動態決策過程,我們在編解碼基礎模組當中內建了根據能力協商、機型和實時視訊編碼質量進行動態選擇切換的編碼器選擇策略。
接下來,結合實際運用場景看我們如何靈活的搭建視訊處理管線滿足不同的業務組合場景。回到線上教育場景當中,假設現在在一個複雜的線上教育場景當中,需要一個攝像頭拍攝老師黑板書寫,再有一路攝像頭拍攝老師的人像,同時老師會通過螢幕共享進行課件分享,或者使用媒體播放器來播放本地或者線上的多媒體視訊檔案。一些高階場景當中,老師為了更好的直播效果,會開啟背景分割和背景替換模式,把老師的頭像和課件疊加在一起,達到更好的效果。老師還可以在本地開啟錄製功能,將自己直播上課的視訊錄製到本地。
針對複雜的組合應用都可以通過管線搭建來實現,上圖是一個本地處理管線的概念圖,對於剛才所說的拍攝黑板,老師人像和課件分享,我們可以通過動態替換採集源模組的具體實現來做。背景分割是特殊的前處理模組,可以將老師頭像實時分析出來,然後再疊加到螢幕共享的採集源上。本地錄製是一種特殊形態的渲染器模組,它是將本地視訊幀按照檔案格式封裝、儲存到本地路徑當中,我們將整個媒體處理和最後網路傳送進行解耦,它可以動態選擇是推送到我們的 RTC 網路中還是推送到 CDN。
接下來看一個接收管線組合應用的場景,我們後臺有一個後臺媒體處理中心,可以根據使用者業務處理器需求去進行實時的流媒體處理服務,其中包括雲錄製(對接收到的視訊進行轉儲)雲端進行視訊鑑黃,低碼高清處理,合圖轉碼服務等。還有 Cloud Player 功能,將遠端視訊拉取下來之後推到 RTC 頻道當中去。以及旁路推流,可以在我們 RTC 網路當中將接收到的視訊流轉推到 CDN 當中去。
那接下來我們看一下是如何通過搭建接收管線來滿足不同運用場景的。
首先是我們網路接收源的模組,它可以通過動態切換來接收來自 RTN 網路或者 CDN 的視訊流。通過解碼器模組之後送到一系列後處理模組當中去,包括剛才提到的鑑黃模組、低碼高清後處理模組等等。接收的渲染器模組的數量和位置都是可以靈活定製的,比如剛才雲錄製的功能,它實際上就是一個特殊的渲染器模組。
剛才介紹的是我們通過微核心式架構設計實現了靈活擴充套件目標,各個模組功能可以快速擴充套件的。視訊處理管線也可以通過搭積木式的組合來實現業務的靈活編排。接下來我們看一下快速可靠這個目標,我們是想說我們核心系統要提供豐富且穩定的功能,在這基礎上可以極大降低開發工作人員的心智負擔,提升研發效能。
介紹這個之前,我們先想一個問題,如果我們沒有一個穩定可靠的核心繫統,一個開發人員要從零開始在我們的管線上開發一個美顏外掛,需要思考哪些問題。
首先毫無疑問是要開發美顏本身的業務邏輯。除此之外,在跟管線整合的時候,首先要考慮模組在管線當中是否可以載入到正確的位置,前序處理模組對它有哪些影響,以及它的業務模組對後續功能產生哪些影響。
第二是資料格式問題,當管線上流轉的資料格式不是美顏模組需要用到的格式的時候,它要對資料格式進行轉換,這個資料轉換演算法實現的業務邏輯也需要模組的開發者來實現。
接下來是和管線整合過程當中,它需要了解整個管線的執行緒模型和記憶體管理模式。在配合管線的狀態切換當中,美顏模組自身也要實現相應的狀態控制的業務邏輯。同時,在一個管線當中,如果後續節點根據視訊質量對前序節點有反饋的話,譬如後續節點說你需要調節你的吞吐量,它也需要有一種機制來接收和處理後續模組反饋的訊息。同時,當美顏外掛執行的時候,有一些訊息通知要傳送給使用者的話,就需要設計一套訊息通知機制。
由於美顏外掛是整合到提供了核心功能的 SDK 當中,外掛的開發就會變得特別簡單,外掛作者只要按照核心系統的介面協議的約定去實現相關的介面即可,核心系統會自動根據它的功能以及從全域性效能優化的角度,把它載入到正確的位置,那我們 SDK 的使用者就可以使用這個外掛了。
總結一下,關於快速可靠這一塊實現了豐富強大的核心繫統功能,可以極大降低模組開發者的心智負擔,從而提升研發效能。
最後,我們來看一下效能優越可監控這一塊,首先我們對整個視訊處理管線在移動端上資料傳遞效率進行優化,實現了對移動端原生資料格式全鏈路支援,包括採集模組、渲染模組、前處理模組,使用硬體的情況下可以實現整個處理鏈路的零拷貝,同時根據各個模組處理特性協商,可以把相應模組在管線上的位置進行優化,減少 CPU 和 GPU 跨越,從而更好的提高資料傳輸效率。
另外,我們在剛才也提到了通過基礎視訊處理單元,將控制面和資料面進行了一定分離,這樣有一定的好處,比如使用者對模組控制可以得到及時的響應,對於攝像機這類裝置操作,是屬於比較重的操作。當使用者頻繁切換前置後置攝像頭時,這類操作會阻塞使用者 UI 造成較大延時。通過進行控制面和資料面的分離,我們可以在保證最後狀態正確性的前提下實現快速響應的相機操作。並讓控制路徑不再阻塞資料流轉。同時控制路徑可以不阻塞資料流轉,我們可以做到對本地圖源進行實時編輯和傳送。
降低系統資源消耗方面,我們構建了適用於視訊資料儲存格式的記憶體池,支援多種視訊格式的幀間記憶體複用,同時,可以根據系統記憶體使用情況和管線負載情況、動態調整達到動態平衡的狀態,這樣可以減少頻繁的記憶體分配和釋放,從而降低 CPU 使用率。
最後,為了形成一個效能優化閉環反饋的通路,我們實現了全鏈路的效能質量監控機制,對每一個基礎視訊處理單元,都會統計和上報入幀和出幀的解析度和和幀率,以及一些模組特有的資料。系統層面上對耗時較長的任務也有監控和上報,根據不同問題調查的需求,我們將這部分資料按需匯入使用者本地日誌,並將體驗相關的資料上報線上質量監控系統,達到對問題快速定位以及優化效能反饋的效果。
總結一下,在效能優越可監控方面,我們首先優化了移動端資料處理鏈路,分離了控制面和資料面,提升了整體視訊資料的傳輸效率。另外構建了視訊處理特性相關的記憶體池來降低系統資源消耗。最後,實現了全鏈路視訊質量監控機制,來對視訊優化效能達到閉環反饋的效果。
實際上,我們現在下一代視訊處理引擎已經進入到了落地和打磨階段。架構優越性在實踐中也得到了驗證,我們現在就來看一下實際應用案例。
下一代視訊引擎具有高度的靈活性和可擴充套件性。基於這個視訊引擎,通過業務組合方式搭建了前後端統一的合圖轉碼通用框架,基於這個框架基礎上,我們可以快速響應前端和後端的各類合圖需求。比如線上視訊相親場景,這是典型的多人互動實時場景,傳統一個嘉賓需要訂閱紅娘以及其他嘉賓視訊流,對下行頻寬和機器處理效能造成很大的壓力,為了解決這個問題,我們快速運用合圖轉碼通用框架上線雲端合圖專案,在雲端將各個嘉賓和紅娘視訊合成一路流再推送給觀眾。同時合圖佈局和背景圖、嘉賓視訊中斷顯示策略可以根據使用者業務進行定製: 比如顯示最後一幀、背景圖、佔點陣圖等等。
同樣的合圖轉碼框架應用在本地的話,我們實現了本地實時視訊編輯混流的功能,可以用在電商直播等等領域當中,主播可以在本地將各種各樣圖源,比如多路攝像頭,多路螢幕共享,媒體播放器和遠端使用者視訊以及不同的圖片素材進行實時合流推送。
我們分享就這些,謝謝大家!