上一篇,我們分析了5種流媒體系統與音視頻延遲的關系。今天,我們將按照數據的流動步驟,分析每個環節是如何影響音視頻時延的,首先分享的是音視頻“采集、前處理、編解碼”這三個部分是如何引入時延,以及我們的優化方案。
媒體數據流動步驟:
采集:把模擬信號變成數字信號;
前處理:包括3A之類的,把它變成純凈的信號;
編碼:將信號送給編碼器做編碼編成碼流,做數據壓縮;
傳輸:把碼流通過網絡傳輸到對端;
抗抖動:對端在播放時要考慮流暢,卡頓的時候沒法用,因此要做緩沖;
解碼:當有一定數據積累后給解碼器解碼;
后處理:恢復信號后有的產品會需要做后處理(通常不需要);
渲染:最后交給設備做渲染,實現音頻播放視頻播放。
上面整套流程的每個環節都會引入時延,我們可以針對每一環節去做優化。
1)采集
音視頻采集環節的延遲,與硬件設備、采集的參數配置相關。在即構側來說,我們是和操作系統的接口打交道。在音頻采集時,我們需要考慮音頻采樣頻率,每一次API返回的采樣點數。比如:
如果我們以44.1K赫茲去采樣,系統 API 每次返回 1024 個點的數據,那么就有 23.2ms 的延遲,再加上一些設備的延遲,最終的延遲會大於23.2ms。如果以48K赫茲去采樣,系統 API 每次返回 192 個點的數據,延遲只有 4ms。
但也不是越短越好,這里需要針對應用場景做權衡,很多情況下減少采集幀長的意義不大,一方面編碼的幀長有要求,另一方面可能會增加 CPU 開銷。並且發送封包需要加包頭,幀越短,需要拼幀做編碼,payload 占比太小,意義沒那么明顯,甚至會增加額外開銷。
2)前處理
第二個是前處理。比如實時音頻的回聲消除、噪聲抑制、自動增益3A處理;語聊場景的變聲;實時視頻的美顏、掛件、磨皮、瘦臉等。這些都會產生時延,我們可以從兩個角度來看時延的產生:
第一個是算法的固有時延,在下面的圖片中,原始數據是藍色的曲線,我們想通過FIR低通濾波給它做平滑處理,可以看到這個效果是不錯的,它確實變平滑了而且它的波形沒有太大變化,但是我們也可以看到它整體向右移了,這其實就是算法的固有時延。
第二個就是計算時延,尤其是對視頻來說有更大的挑戰。通常我們會把這個計算交給GPU,那么GPU就有額外的負擔,這是一個異構的計算,我們要把數據給GPU,再把數據從GPU拉下來,這里是需要同步的,我們發現會有10%-20%的延遲。而為了得到這么大的吞吐量一定要依靠GPU,因而這個是避免不了的。
3)編解碼
這是比較重要的部分,這里主要指的是信源編碼。信源編碼的主要目的是壓縮,把傳輸所需要的字節數壓縮減少,它需要權衡幾個方面的東西:第一個是質量,第二個是碼率,第三個是時延,第四個是吞吐。在同等碼率下,一個編碼方案引入的時延越高,通常來說質量會越高。
我們可以看看常見的編碼方案對延遲的影響:
首先是音頻的編碼方案,以我們常用的HE AAC編碼方案和開源的OPUS方案為例,HE AAE系統設計會引入129ms的固有時延,而OPUS可以做到10ms內,通常我們在低延遲的時候會選擇OPUS。
在視頻編碼方面,H.264是目前廣泛應用的標准,它有多種編碼類別,像baseline profile、main profile等,這兩種編碼最大的區別是baseline profile只產生I幀和P幀,而main profile除了I幀和P幀外還會產生B幀,B幀是雙向參考幀,它會參考未來的數據,當編碼幀率是20幀每秒,一個B幀將引入50ms的額外延遲。因而在實時通信場景中,我們通常都是用baseline profile。
另一方面,不同的編碼實現對質量與延遲都會產生影響,以視頻編碼為例。我們要考慮是用軟件實現編碼還是硬件實現編碼,軟編通常效果會比硬編好,一方面軟編有非常多的策略去做提升優化,另一方面軟編的時延通常會比硬編的低。
當然也不是說軟編就能完爆硬編,硬編的吞吐量大,當分辨率很大、碼流很大的時候,軟編是hold不住的,所以還是要依賴硬編。而硬編又依賴於具體的芯片實現,在某些芯片的實現上,硬編可能會達到70ms的延遲,而硬解可能會達到130ms的延遲,這和芯片性能相關。
以上就是采集、前處理、編解碼環節,時延是如何形成的。第三篇我們將分享在傳輸、渲染環節,有哪些影響時延的因素。