淺析雲控平臺畫面傳輸的視訊流方案

高德技術發表於2020-11-04

背景

ARC(高德車機雲控平臺)是一個基於車載裝置業務深度定製的雲控平臺,通過該平臺我們能夠實現遠端使用不同型別的車載裝置。為了讓遠端使用者像在本地一樣使用車載裝置,需要將車載裝置的畫面及時的傳回給使用者。因此,畫面傳輸能力是ARC平臺的一個核心元件。

起初我們採用行業內普遍在用的畫面傳輸開源方案(minicap)。該方案獲取到螢幕資料後壓縮生成JPG影像,逐幀傳輸到Web端進行展示。由於車機效能比手機差很多,壓縮圖片消耗CPU效能大,在部分低端車機裝置上壓縮圖片能消耗80%左右的CPU,容易使裝置使用出現卡頓。同時影像壓縮率不算很高,傳輸消耗頻寬大,在低頻寬下造成使用者看到的畫面過度延遲。

因此,我們需要一個解決方案能夠平衡傳回的畫面質量和車機端的CPU資源消耗。本文將小結本次雲控平臺畫面傳輸的視訊流方案。

淺析雲控平臺畫面傳輸的視訊流方案

 思路方法

淺析雲控平臺畫面傳輸的視訊流方案

基於影像資料的基本傳輸鏈路,為了能夠不消耗裝置端CPU資源,首先想到了影像不進行壓縮,先傳輸到服務端進行處理。但是經過調研,車機的USB頻寬傳輸根本無法滿足高清影像不壓縮排行傳輸,高清原始資料非常大,基本1秒只能傳輸三幀左右的資料。

 

另一個思路是採用裝置端的硬體編碼器減少CPU資源的消耗。經過調研Android 4.1開始基本都自帶了H264視訊編碼器。因此,決定嘗試採用視訊流的方案,在裝置端通過硬體編碼器編碼成視訊流,通過服務端轉發到Web端進行解碼展示。

 

實現方案

淺析雲控平臺畫面傳輸的視訊流方案

 整個實現方案可以分為以下三個部分:

  • 裝置端:負責畫面的獲取和編碼。

  • 服務端:處理視訊流的傳輸和控制。

  • Web端:視訊流的解碼和展示。

畫面的獲取和編碼

影像畫面的獲取直接採用的是Android的Virtual Display。編碼方式有多種實現方法:

淺析雲控平臺畫面傳輸的視訊流方案

由於Java方案只能支援Android 5.0以上機器, 而目前車載市場Android 4.x的佔比還比較大,無法忽略。因此只能使用cpp的方案,最低可相容Android 4.3版本。

 視訊流的傳輸和控制

Web端最常見的直播方案是rtmp/hls/flvjs等。但是這些方案最低都有1-3s的延遲。對於一般直播平臺沒有影響,但是對於有實時互動場景的雲控平臺,要求達到毫秒級延遲。所以,最終決定採用H264裸流通過Socket傳輸的方案,裝置端編碼H264視訊流直接傳輸到Web端進行播放。

同時,為了提高使用體驗,對視訊流的傳輸增加了彈性控制。通過在服務端加入快取佇列用來監控前端頻寬負載情況,根據頻寬狀況自動調節幀率和位元速率,優先保證使用者的流暢感。

Web端展示和解碼

Web端展示使用media source extensiton(MSE) + fragment mp4的方案, 把H264裸流封裝成fragment mp4後,通過MSE api進行解碼播放, 具體實現是參考了開源的Jmuxer方案。 

丟幀和補幀

預設情況下Android Virtual Display產生的最大幀率是60fps,而我們肉眼30fps就能感覺流暢。為了能夠節省頻寬,我們定義了視訊流最大輸出幀率是30fps。在網路頻寬較差的情況下,我們還能夠降低幀率來最大限度的避免延遲。同時,Android MediaCodec不支援控制幀率,幀率是由每秒送入的幀數量決定的。因此,我們需要通過實現丟幀來進行幀率控制。

Win7硬體解碼器沒有低延遲模式,需要大概10幀左右資料才能開始播放,而VirtualDisplay是畫面有變化才會產生影像幀,因此需要實現補幀來消除解碼延遲。

淺析雲控平臺畫面傳輸的視訊流方案

我們通過建立一個EglSurface對丟幀補幀進行處理,通過時間間隔控制eglTexture繪入EglSurface的頻度進行丟幀,通過重複繪入最後一幀資料進行補幀。

總結

該方案在ARC平臺上的使用,在保證傳輸質量的同時,有效的提升了使用者操作的流暢感。該方案理論上也可以應用於其他類似的雲控平臺上,如果不需要支援Android 4.x裝置,採用Java層API來獲取視訊流資料,則可以降低開發和適配成本。

淺析雲控平臺畫面傳輸的視訊流方案

相關文章