在WebRTC的視頻處理流水線中啤覆,接收端緩沖區(qū)JitterBuffer是關鍵的組成部分:它負責RTP數(shù)據(jù)包亂序重排和組幀,RTP丟包重傳,請求重傳關鍵幀溅潜,估算緩沖區(qū)延遲等功能肋演。其中緩沖區(qū)延遲JitterDelay對視頻流的單向延遲有重要影響抑诸,很大程度上決定著應用的實時性。本文不打算全面分析接收端緩沖區(qū)的實現(xiàn)細節(jié)爹殊,只針對緩沖區(qū)延遲JitterDelay的計算這一議題進行深入分析蜕乡。</br>
1 接收端延遲的組成
</br>
WebRTC視頻接收端延遲包括三部分:緩沖區(qū)延遲JitterDelay,解碼延遲DecodeDelay和渲染延遲RenderDelay梗夸。其中DecodeDelay和RenderDelay相對比較穩(wěn)定层玲,而JitterDelay受發(fā)送端碼率和網(wǎng)絡狀況影響較大。JitterDelay也是造成接收端延遲的最大因素反症。</br>
緩沖區(qū)延遲由兩部分延遲構(gòu)成:傳輸大尺寸視頻幀造成碼率burst引起的延遲和網(wǎng)絡噪聲引起的延遲辛块。WebRTC采用卡爾曼濾波Kalman Filter估算網(wǎng)絡傳輸速率和網(wǎng)絡排隊延遲,進而確定緩沖區(qū)延遲惰帽。本文在理論學習卡爾曼濾波的基礎上憨降,結(jié)合WebRTC源代碼,詳細深入分析緩沖區(qū)延遲的計算和更新過程该酗。</br>
2 卡爾曼濾波理論學習
</br>
本節(jié)主要參考引用文獻[1][2][3]授药,以此為入門資料學習卡爾曼濾波的基本原理士嚎。簡單來說,卡爾曼濾波器是一個最優(yōu)化自回歸數(shù)據(jù)處理算法悔叽,文獻[2]概括卡爾曼濾波的基本思想:</br>
“本質(zhì)上來講莱衩,濾波就是一個信號處理與變換(去除或減弱不想要的成分,增強所需成分)的過程娇澎”恳希卡爾曼濾波屬于一種軟件濾波方法,其基本思想是:以最小均方誤差為最佳估計準則趟庄,采用信號與噪聲的狀態(tài)空間模型括细,利用前一時刻的估計值和當前時刻的觀測值來更新對狀態(tài)變量的估計,求出當前時刻的估計值戚啥。算法根據(jù)建立的系統(tǒng)方程和觀測方程對需要處理的信號做出滿足最小均方誤差的估計奋单。”</br>
下面以文獻[1]為基礎猫十,簡要分析卡爾曼濾波的基本過程览濒。</br>
2.1 建立系統(tǒng)數(shù)學模型
</br>
首先,我們先要引入一個離散控制過程的系統(tǒng)拖云。該系統(tǒng)可用一個線性隨機微分方程(Linear Stochastic Difference equation)來描述:</br>
X(K) = AX(K-1) + BU(k) + W(k) (2.1.1)
再加上系統(tǒng)的測量值:</br>
Z(k) = HX(k) + V(k) (2.1.2)
上兩式子中贷笛,X(k)是k時刻的系統(tǒng)狀態(tài),U(k)是k時刻對系統(tǒng)的控制量宙项。A和B是系統(tǒng)參數(shù)乏苦,對于多模型系統(tǒng),他們?yōu)榫仃嚿荚省(k)是k時刻的測量值邑贴,H是測量系統(tǒng)的參數(shù),對于多測量系統(tǒng)叔磷,H為矩陣拢驾。W(k)和V(k)分別表示過程噪聲和測量噪聲。他們被假設成高斯白噪聲改基,他們的協(xié)方差分別是Q繁疤,R。</br>
2.2 卡爾曼濾波過程
</br>
首先我們要利用系統(tǒng)的過程模型秕狰,來預測下一狀態(tài)的系統(tǒng)狀態(tài)稠腊。假設現(xiàn)在的系統(tǒng)狀態(tài)是k,根據(jù)系統(tǒng)的過程模型鸣哀,可以基于系統(tǒng)的上一狀態(tài)而預測出現(xiàn)在狀態(tài):</br>
X(k|k-1)=AX(k-1|k-1) + BU(k) (2.2.1)
式(2.2.1)中架忌,X(k|k-1)是利用上一狀態(tài)預測的結(jié)果,X(k-1|k-1)是上一狀態(tài)最優(yōu)的結(jié)果我衬,U(k)為現(xiàn)在狀態(tài)的控制量叹放。到現(xiàn)在為止饰恕,我們的系統(tǒng)結(jié)果已經(jīng)更新【觯可是埋嵌,對應于X(k|k-1)的誤差協(xié)方差還沒更新。我們用P表示誤差協(xié)方差:</br>
P(k|k-1)=AP(k-1|k-1)A’+ Q (2.2.2)
式(2.2.2)中俱恶,P(k|k-1)是X(k|k-1)對應的誤差協(xié)方差雹嗦,P(k-1|k-1)是X(k-1|k-1)對應的誤差協(xié)方差,A’表示A的轉(zhuǎn)置矩陣合是,Q是系統(tǒng)過程的過程噪聲協(xié)方差了罪。式子1,2就是卡爾曼濾波器5個公式當中的前兩個聪全,也就是對系統(tǒng)的預測捶惜。</br>
現(xiàn)在我們有現(xiàn)在狀態(tài)的預測值,然后我們再收集現(xiàn)在狀態(tài)的測量值荔烧。結(jié)合預測值和測量值,我們可以得到現(xiàn)在狀態(tài)(k)的最優(yōu)化估算值X(k|k):</br>
X(k|k) = X(k|k-1) + Kg(k)[Z(k) - HX(k|k-1)] (2.2.3)
其中Kg為卡爾曼增益(Kalman Gain):</br>
Kg(k)= P(k|k-1) H’/ (H P(k|k-1) H’+ R) (2.2.4)
到現(xiàn)在為止汽久,我們已經(jīng)得到了k狀態(tài)下最優(yōu)的估算值X(k|k)鹤竭。但是為使卡爾曼濾波器不斷的運行下去直到系統(tǒng)過程結(jié)束,我們還要更新k狀態(tài)下X(k|k)的誤差協(xié)方差:</br>
P(k|k)=(I-Kg(k) H) P(k|k-1) (2.2.5)
其中I 為單位矩陣景醇。當系統(tǒng)進入k+1狀態(tài)時臀稚,P(k|k)就是式子(2)的P(k-1|k-1)。這樣三痰,算法就可以自回歸的運算下去吧寺。</br>
上述式子1~5是卡爾曼濾波的核心算法所在,包括預測值計算散劫,誤差協(xié)方差計算稚机,最優(yōu)值估算,卡爾曼增益計算获搏,誤差協(xié)方差更新等五個重要步驟赖条。</br>
3 WebRTC中JitterDelay的計算過程
</br>
本節(jié)結(jié)合WebRTC源代碼,分析視頻接收端緩沖區(qū)延遲JitterDelay的計算過程常熙。</br>
3.1 JitterDelay的計算公式
</br>
由第一節(jié)分析可知纬乍,JitterDelay由兩部分延遲造成:傳輸大幀引起的延遲和網(wǎng)絡噪聲引起的延遲。其計算公式如下:</br>
JitterDelay = theta[0] * (MaxFS – AvgFS) + [noiseStdDevs * sqrt(varNoise) – noiseStdDevOffset] (3.1.1)
其中theta[0]是信道傳輸速率的倒數(shù)裸卫,MaxFS是自會話開始以來所收到的最大幀大小仿贬,AvgFS表示平均幀大小。noiseStdDevs表示噪聲系數(shù)2.33墓贿,varNoise表示噪聲方差茧泪,noiseStdDevOffset是噪聲扣除常數(shù)30蜓氨。</br>
解碼線程從緩沖區(qū)獲取一幀視頻數(shù)據(jù)進行解碼之前,會根據(jù)公式3.1.1計算當前幀的緩沖區(qū)延遲调炬,然后再加上解碼延遲和渲染延遲语盈,得到當前幀的預期渲染結(jié)束時間。然后根據(jù)當前時刻缰泡,確定當前幀在解碼之前需要等待的時間刀荒,以保證視頻渲染的平滑性。 </br>
3.2 JitterDelay的更新過程
</br>
解碼線程從緩沖區(qū)獲取一幀視頻數(shù)據(jù)進行解碼之前棘钞,會根據(jù)當前幀的大小缠借、時間戳和當前本地時刻,更新緩沖區(qū)本地狀態(tài)宜猜,包括最大幀大小泼返、平均幀大小、噪聲平均值姨拥、信道傳輸速率绅喉、網(wǎng)絡排隊延時等參數(shù)。 更新過程如圖1所示:</br>
首先叫乌,確定幀間相對延遲frameDelay和幀間大小差值deltaFS:</br>
frameDelay = t(i) – t(i-1) – (T(i) – T(i-1)) (3.2.1)
deltaFS = frameSize – prevFrameSize (3.2.2)
其中t(i)表示當前幀本地接收時刻柴罐,t(i-1)表示上一幀本地接收時刻;T(i)表示當前幀的時間戳憨奸,T(i-1)表示上一幀的時間戳革屠。frameDelay表示相鄰兩幀的相對延遲,frameDelay > 0表示幀i相對于幀i-1在路上花費的時間更長排宰。frameSize和prevFrameSize分別表示當前幀和上一幀的大小似芝。</br>
然后計算幀大小的平均值和方差:</br>
avgFrameSize = phi * avgFrameSize + (1-phi) * frameSize (3.2.3)
varFrameSize = phi * varFrameSize + (1-phi) * (frameSize – avgFramesize)^2 (3.2.4)
接下來計算延遲殘差(反映網(wǎng)絡噪聲的大小),并據(jù)此計算噪聲均值和方差:</br>
residual = frameDelay – (theta[0] * deltaFSBytes + theta[1]) (3.2.5)
avgNoise = alpha*avgNoise + (1-alpha)*residual (3.2.6)
varNoise = alpha*varNoise + (1 – alpha)*(residual – avgNoise)^2 (3.2.7)
alpha = pow(399/400, 30/fps) (3.2.8)
其中alpha表示概率系數(shù)板甘,受幀率fps影響:當fps變低時党瓮,alpha會變小,表示當前噪聲變大盐类,噪聲方差受當前噪聲影響更大一些麻诀。實時幀率越接近30 fps越好。avgNoise表示自開始以來的平均噪聲傲醉。theta[0]表示信道傳輸速率蝇闭,theta[1]表示網(wǎng)絡排隊延遲。</br>
最后一步硬毕,卡爾曼濾波器根據(jù)當前幀間延遲和幀間大小差值呻引,動態(tài)調(diào)整信道傳輸速率theta[0]和網(wǎng)絡排隊延遲theta[1],具體過程在下一節(jié)進行詳細討論吐咳。</br>
至此逻悠,JitterDelay的一次更新過程結(jié)束元践。當下一幀數(shù)據(jù)到來時,使用本次更新結(jié)果計算JitterDelay童谒,并再次執(zhí)行更新過程单旁。</br>
4 卡爾曼濾波更新緩沖區(qū)狀態(tài)
</br>
本節(jié)結(jié)合WebRTC源代碼,深入分析卡爾曼濾波更新更新信道傳輸速率theta[0]和網(wǎng)絡排隊時延theta[1]的過程饥伊,這也是緩沖區(qū)延遲估計的核心算法所在象浑。</br>
4.1 數(shù)學符號定義
</br>
X_bar: 向量X
X_hat: 向量X的估計值
X(i): 向量X的第i個分量
[x y z]:包含元素xyz的行向量
X_bar^T:向量X_bar的轉(zhuǎn)置向量
E{X}: 隨機變量X的期望
4.2 理論推導過程
</br>
d(i) = t(i) – t(i-1) – (T(i) – T(i-1)) (4.2.1)
t(i)表示當前幀本地接收時刻,t(i-1)表示上一幀本地接收時刻琅豆;T(i)表示當前幀的發(fā)送端采樣時刻即時間戳愉豺,T(i-1)表示上一幀的采樣時刻。d(i) > 0表示幀i相對于幀i-1在路上花費的時間更長茫因。式子4.2.1是系統(tǒng)的測量值蚪拦。</br>
d(i) = dL(i) / C(i) + m(i) + v(i) (4.2.2)
dL(i)表示幀i和幀i-1的長度之差,C(i)表示信道傳輸速率冻押,m(i)表示幀i的網(wǎng)絡排隊時延驰贷,v(i)表示測量噪聲,其協(xié)方差為R洛巢。其中[1/C(i) m(i)]是我們要求的目標值饱苟,即信道傳輸速率和網(wǎng)絡排隊時延。式子4.2.2是系統(tǒng)的預測值狼渊。</br>
theta_bar(i) = [1/C(i) m(i)]^T 為幀i狀態(tài)列向量;
h_bar(i) = [dL(i) 1]^T 為幀間長度差列向量类垦;
theta_bar(i+1) = theta_bar(i) + u_bar(i)狈邑; u_bar(i)表示過程噪聲;
Q(i) = E{u_bar(i) * u_bar(i)^T} 表示過程噪聲協(xié)方差矩陣蚤认;
diag(Q(i)) = [10^-13 10^-3]^T Q(i)是對角陣米苹;
估計過程:</br>
theta_hat(i) = [1/C_hat(i) m_hat(i)]^T; // 目標估計值
z(i) = d(i) – h_bar(i)^T * theta_hat(i-1)
= d(i) – (dL(i)/C_hat(i-1) + m_hat(i-1)) (4.2.3)
上述式子的意義是砰琢,用上一時刻估計值估算本時刻的時間消耗:</br>
dL(i)/C_hat(i-1) + m_hat(i-1)
然后用當前觀測值d(i)和估算值求出殘差z(i)蘸嘶。</br>
theta_hat(i) = theta_hat(i-1) + z(i) * k_bar(i) (4.2.4)
上述式子表示i時刻和i-1時刻的狀態(tài)迭代關系:i-1時刻的狀態(tài)加上i時刻的殘差z(i)和i時刻卡爾曼濾波的乘積,其中i時刻的kalman gain計算公式如下:</br>
k_bar(i)=[(E(i-1)+Q(i))*h_bar(i)]/[var_v_hat(i)+h_bar(i)^T*(E(i-1)+Q(i))*h_bar(i)] (4.2.5)
E(i) = (I–k_bar(i)*h_bar(i)^T)*[E(i-1)+Q(i)] (4.2.6)
var_noise(i) = max(alpha*var_noise(i-1)+(1–alpha)*z(i)^2, 1) (4.2.7)
alpha = pow(399 / 400, 30 / fps) (4.2.8)
var_v_hat(i)=(300*exp[-fabs(deltaFS)/maxFrameSize)+1]*sqrt(varNoise) (4.2.9)
其中I是2*2單位陣陪汽,E(i)是誤差協(xié)方差(它是卡爾曼濾波迭代的關鍵參數(shù))训唱。var_noise是噪聲方差,var_v_hat是噪聲標準差指數(shù)過濾平均后取值挚冤,其實就是幀i的測量噪聲協(xié)方差R况增,它對最終計算出的卡爾曼增益有較大影響:var_v_hat(i)較大時,卡爾曼增益較小训挡,表示本次測量中噪聲較大澳骤,最終估計值更靠近上次估計值而較少受本次殘差的影響歧强。</br>
4.3 WebRTC代碼實現(xiàn)
</br>
下面?zhèn)未a是對WebRTC中VCMJitterEstimator::KalmanEstimateChannel函數(shù)的精簡概括,描述了卡爾曼濾波的代碼實現(xiàn)为肮。</br>
void VCMJitterEstimator::KalmanEstimateChannel(frameDelayMS, deltaFSBytes) {
// 計算誤差協(xié)方差和過程噪聲協(xié)方差的和:E = E + Q摊册;
_thetaCov[0][0] += _Qcov[0][0];
_thetaCov[0][1] += _Qcov[0][1];
_thetaCov[1][0] += _Qcov[1][0];
_thetaCov[1][1] += _Qcov[1][1];
// 計算卡爾曼增益:
// K = E*h'/(sigma + h*E*h')
// h = [deltaFS 1], Eh = E*h'
// hEh_sigma = h*E*h' + sigma
Eh[0] = _thetaCov[0][0] * deltaFSBytes + _thetaCov[0][1];
Eh[1] = _thetaCov[1][0] * deltaFSBytes + _thetaCov[1][1];
// sigma為測量噪聲標準差的指數(shù)平均濾波結(jié)果,即測量噪聲協(xié)方差R颊艳。
double sigma = (300.0 * exp(-fabs(static_cast<double>(deltaFSBytes)) /
(1e0 * _maxFrameSize)) +1) * sqrt(varNoise);
hEh_sigma = deltaFSBytes * Eh[0] + Eh[1] + sigma;
kalmanGain[0] = Eh[0] / hEh_sigma;
kalmanGain[1] = Eh[1] / hEh_sigma;
// 計算殘差茅特,獲得最優(yōu)估計值
measureRes = frameDelayMS - (deltaFSBytes * _theta[0] + _theta[1]);
_theta[0] += kalmanGain[0] * measureRes;
_theta[1] += kalmanGain[1] * measureRes;
// 更新誤差協(xié)方差:E = (I - K*h)*E;
t00 = _thetaCov[0][0]; t01 = _thetaCov[0][1];
_thetaCov[0][0] = (1 - kalmanGain[0] * deltaFSBytes) * t00 -
kalmanGain[0] * _thetaCov[1][0];
_thetaCov[0][1] = (1 - kalmanGain[0] * deltaFSBytes) * t01 -
kalmanGain[0] * _thetaCov[1][1];
_thetaCov[1][0] = _thetaCov[1][0] * (1 - kalmanGain[1]) -
kalmanGain[1] * deltaFSBytes * t00;
_thetaCov[1][1] = _thetaCov[1][1] * (1 - kalmanGain[1]) -
kalmanGain[1] * deltaFSBytes * t01;
}
至此籽暇,卡爾曼濾波估計信道發(fā)送速率和網(wǎng)絡排隊時延的一次迭代完成温治。</br>
5 總結(jié)
</br>
本文在理論學習卡爾曼濾波基本原理的基礎上,結(jié)合WebRTC源代碼戒悠,深入分析了WebRTC視頻接收端緩沖區(qū)延遲的計算方法和更新過程熬荆。通過本文,更進一步加深對WebRTC的學習和了解绸狐。</br>
參考文獻
</br>
[1] 卡爾曼濾波的原理說明 http://blog.sciencenet.cn/blog-1009877-784428.html
[2] 卡爾曼濾波的基本原理及應用[J]. 軟件導刊, Vol.8 No.11, Nov. 2009.
[3] An Introduction to the Kalman Filter [J]. University of North Carolina at Chapel Hill Department of Computer Science
Chapel Hill, NC 27599-3175
[4] A Google Congestion Control Algorithm for Real-Time Communication
https://tools.ietf.org/html/draft-alvestrand-rmcat-congestion-03
[5] Analysis and Design of the Google Congestion Control for Web Real-time
Communication[J]. MMSys ’16 Article No.13