糾刪碼在實(shí)時(shí)視頻流中的應(yīng)用丨Dev for Dev 專欄

本文為「Dev for Dev 專欄」系列內(nèi)容,作者為聲網(wǎng)網(wǎng)絡(luò)體驗(yàn)團(tuán)隊(duì) 王瑞。
01背景
在實(shí)時(shí)音視頻通話中,音視頻質(zhì)量受網(wǎng)絡(luò)丟包影響較大,特別是對于視頻。
為什么視頻對丟包更敏感呢?通常來說,音頻的原始碼率相對視頻來說比較小,因此音頻編碼器的壓縮率比視頻編碼器要小很多。音頻幀通常都是獨(dú)立編碼和解碼的,因此任何一幀數(shù)據(jù)的丟失,都不會影響其他幀的解碼。
而對于視頻來說,為了達(dá)到較高的壓縮率,通常會采用殘差編碼的方法來去除大量的空間和時(shí)間冗余信息,這就導(dǎo)致了在解碼時(shí),需要依賴參考幀才能正確解碼,任何一幀數(shù)據(jù)的丟失,都會導(dǎo)致后續(xù)互相關(guān)聯(lián)的一些幀無法解碼。由于視頻幀之間的這種相關(guān)性就導(dǎo)致了視頻對傳輸丟包更加敏感。
常見的丟包包括 IP 傳輸網(wǎng)絡(luò)的擁塞丟包,以及靠近用戶側(cè)的無線丟包。擁塞丟包一般是由于網(wǎng)絡(luò)中處理能力比較小的瓶頸節(jié)點(diǎn)導(dǎo)致的,可能表現(xiàn)為隨機(jī)或連續(xù)丟包,無線丟包一般是由于信道干擾導(dǎo)致的,經(jīng)常表現(xiàn)為連續(xù)丟包。當(dāng)然,在實(shí)際網(wǎng)絡(luò)的丟包原因很多,表現(xiàn)也都不一樣。
通過擁塞控制算法可以一定程度避免擁塞丟包的產(chǎn)生,但無法解決所有場景的丟包問題。
丟包發(fā)生后,通常會采用以下兩種補(bǔ)救方法:
(1)重傳(Automatic Repeat-reQuest, ARQ)
重傳是一種高效的補(bǔ)救手段,但它依賴反饋信道,同時(shí)重傳效率對網(wǎng)絡(luò)RTT非常敏感。在高丟包下可能需要多次重傳。
(2)糾錯編碼(Forward Error Correction, FEC)
糾錯編碼無需反饋信道,同時(shí)網(wǎng)絡(luò)RTT的大小也不會影響它的效率。
在一對一的互聯(lián)場景中,如果網(wǎng)絡(luò)RTT較低,重傳是一種合適的選擇。但在RTT較大的時(shí)候,重傳的效率會明顯降低。另外在大規(guī)模的多播和廣播應(yīng)用中,過多的重傳請求可能會加劇網(wǎng)絡(luò)擁塞和丟包。
在這些情況下,采用FEC技術(shù)是更合適的選擇。FEC在編碼端進(jìn)行冗余編碼,在接收端通過冗余數(shù)據(jù)自動恢復(fù)出丟失的數(shù)據(jù)包,其優(yōu)勢在于不依賴反饋信道,且糾錯效率不受RTT影響。因此,在高RTT環(huán)境中,可以有效避免重傳導(dǎo)致的高延遲。本文主要對實(shí)時(shí)視頻傳輸中的FEC技術(shù)做簡要介紹,并介紹聲網(wǎng)的最佳實(shí)踐。

02基本概念介紹
1、刪除信道
如果發(fā)送端發(fā)送的一組數(shù)據(jù),經(jīng)過特定信道傳輸,其丟失數(shù)據(jù)的位置對接收端是已知的,那么這種信道模型就稱之為刪除信道?;诨ヂ?lián)網(wǎng)的包交換網(wǎng)絡(luò)是一種典型的刪除信道,在這種信道模型下,所有已接收到的數(shù)據(jù)都被認(rèn)為是正確的。

2、檢錯碼,糾錯碼與糾刪碼
在信道編碼中,差錯控制編碼根據(jù)編碼用途不同,可以分為檢錯碼、糾錯碼和糾刪碼三種。
檢錯碼是為了校驗(yàn)數(shù)據(jù)經(jīng)過信道傳輸后是否出現(xiàn)了錯誤,常用的檢錯碼包括簡單奇偶校驗(yàn)碼、循環(huán)冗余校驗(yàn)碼等。糾錯碼不僅可以識別到信道傳輸是否出現(xiàn)了錯誤,還能糾正傳輸錯誤。在糾錯碼看來,經(jīng)過差錯信道傳輸后,接收端收到的數(shù)據(jù)都是不可靠的,需要通過解碼來發(fā)現(xiàn)和糾正錯誤。常見的糾錯碼包括漢明碼、BCH碼等(見參考資料5)。
糾刪碼可以認(rèn)為是一種特殊的糾錯碼,對于糾刪碼來說,其差錯信道是一種刪除信道,對接收者來說錯誤的位置是已知的,并且收到的數(shù)據(jù)都認(rèn)為是正確的,因此其編譯碼會比糾錯碼更容易一些。
傳統(tǒng)糾錯碼技術(shù)的發(fā)展已經(jīng)非常成熟,通常用在網(wǎng)絡(luò)協(xié)議的物理層和數(shù)據(jù)鏈路層,用于保障可靠的鏈路級信道。而糾刪碼大部分是基于糾錯碼的理論發(fā)展而來,常用于應(yīng)用層的FEC編碼。
3、RS碼
在視頻傳輸?shù)膽?yīng)用層FEC編碼算法中,RS碼是一種常見的算法。RS碼是一類重要的線性分組碼,也是一種性能優(yōu)異的短碼,工作在有限域上。線性分組碼通常用(n,k)碼來表示,對于位編碼來說,k和n表示比特?cái)?shù),其中k為信息位個(gè)數(shù),n為碼長;而在應(yīng)用層FEC領(lǐng)域,F(xiàn)EC編碼采用包編碼方式,在包編碼中,k和n都表示包數(shù)。對于碼長為n的RS糾刪碼來說,只要收到任意k個(gè)信息位,就可以解碼出所有n個(gè)數(shù)據(jù)。
對于一個(gè)(n,k)線性糾刪碼,可以表示為如下的矩陣運(yùn)算:?Y = x * G
其中,x是信息位向量,y是碼字向量,G是生成矩陣。
在RS碼中,常見的生成矩陣有范德蒙矩陣和柯西矩陣,分別如下圖所示,這兩種矩陣的特點(diǎn)是任意子矩陣均可逆,因此總能利用任意k個(gè)接收碼字來解碼出剩余n-k個(gè)碼字。
??■范德蒙矩陣?■柯西矩陣
4、有限域運(yùn)算
域是一個(gè)可以在其上進(jìn)行加、減、乘、除運(yùn)算而結(jié)果不會超出域的集合,如果域中的元素個(gè)數(shù)是有限的,就稱為有限域,或伽羅華域。有限域在密碼學(xué)、編碼理論中有著廣泛的應(yīng)用。
RS碼是一種工作在有限域GF(2^q)上的多進(jìn)制糾刪碼,RS碼的全部碼元取自有限域GF(2^q)上。通常,我們可以用以下兩種方法來構(gòu)造有限域:
定理一:對于集合Zp={0,1,…,p-1},如果p為素?cái)?shù),那么在Zp上進(jìn)行模p的加法和乘法運(yùn)算就構(gòu)成一個(gè)有限域。
即Z2,Z3,Z5都是有限域,但是Z8不是,因?yàn)?不是素?cái)?shù)。為了能夠在非素?cái)?shù)上構(gòu)造有限域,就需要借助于本原多項(xiàng)式。
定理二:如果p為素?cái)?shù),m為正整數(shù),那么在GF(p^m)上模一個(gè)m階本原多項(xiàng)式也構(gòu)成有限域。
本源多項(xiàng)式就是首項(xiàng)系數(shù)為1的不可約多項(xiàng)式,在實(shí)際算法實(shí)現(xiàn)中,考慮到性能與算法復(fù)雜性,RS算法常實(shí)現(xiàn)在GF(2^8)域上,本原多項(xiàng)式可以有多個(gè),如下就是一個(gè)8階本源多項(xiàng)式的例子:
P(x) = x8?+ x4?+ x3?+ x2?+ 1
03實(shí)時(shí)視頻流的FEC編碼方案
1、卷積碼與分組碼
所謂分組碼是指編碼器需要預(yù)先把輸入數(shù)據(jù)分組,達(dá)到分組長度才能編碼。而卷積碼的輸入是連續(xù)的,輸出也是連續(xù)的,不需要進(jìn)行預(yù)分組。
分組碼的輸出只與當(dāng)前編碼的分組數(shù)據(jù)有關(guān),例如(n,k)分組碼以k個(gè)輸入為一組,編碼出n個(gè)輸出,輸出僅與k個(gè)輸入有關(guān)。而(n,k,L)卷積碼的編碼輸出不僅與k個(gè)輸入有關(guān),還與歷史的L個(gè)輸入有關(guān)。L為約束長度,或記憶深度。
為了增強(qiáng)對抗連續(xù)丟包的能力,通常會增加分組碼的分組長度(即k),但是由于分組碼的解碼延遲是線性的,k值的增加會導(dǎo)致解碼延遲的增加。這就帶來了分組長度的選擇問題,較長的分組長度能提供更好的糾錯能力,但同時(shí)增大了系統(tǒng)延遲。而卷積碼不需要考慮分組長度問題,可以實(shí)現(xiàn)on-the-fly coding,更適合實(shí)時(shí)流傳輸場景使用。
2、常見的幾種編碼方案
對實(shí)時(shí)視頻流來說,常見有以下幾種編碼方案,幀級編碼、GOP級編碼、擴(kuò)窗編碼、滑窗編碼。其中前兩種是分組碼,后兩種是卷積碼的應(yīng)用。
幀級FEC編碼以單幀為分組單位(如下圖),在這種編碼方案中,F(xiàn)EC可以實(shí)現(xiàn)最小解碼延遲,但在低碼率下由于分組太小,導(dǎo)致在連續(xù)丟包時(shí)很容易出現(xiàn)無法解碼的情況。GOP級編碼以GOP為分組單位,這種編碼方案的好處是大幅提高了連續(xù)丟包下的解碼穩(wěn)定性,但是也帶來了較大的解碼延遲,在實(shí)時(shí)場景中難以應(yīng)用。

擴(kuò)窗和滑窗編碼是卷積碼的具體應(yīng)用,由于不存在分組問題,所以理論上可以在視頻流的任意位置進(jìn)行編碼。兩者的區(qū)別是,對幀X進(jìn)行編碼時(shí),擴(kuò)窗編碼會編碼所在GOP范圍內(nèi)的第1至第X幀,而滑窗編碼只會編碼第X-T到X幀,其中T為最大窗口長度。這兩種編碼方式都能很好的提高連續(xù)丟包場景下的解碼概率,同時(shí)不會額外增加解碼延遲。但由于擴(kuò)窗編碼在大GOP下存在性能問題,因此滑窗編碼是一個(gè)更為實(shí)際的方案。下圖是一個(gè)T=3的滑窗FEC編碼的例子。
3、信源與信道聯(lián)合卷積編碼
在聲網(wǎng)的實(shí)踐中,我們不僅大規(guī)模應(yīng)用了卷積碼方案,驗(yàn)證了卷積碼在實(shí)時(shí)視頻流傳輸中的優(yōu)勢,同時(shí),我們將信源編碼與信道編碼結(jié)合,創(chuàng)造了一種新的編碼方案,并命名為DMEC(Dense Matrix Erasure Coding),DMEC真正發(fā)揮了卷積碼的最大性能優(yōu)勢,能夠?qū)崿F(xiàn)在不同場景下的最優(yōu)視頻QoE。
在信息論中,對信息的編碼分為信源編碼和信道編碼,信源編碼是為了去除冗余信息,提高通信效率,例如常用的視頻編碼器H.264就是一種信源編碼器。而信道編碼是為了對抗信道中的噪聲和衰減,通過增加冗余,來提高抗干擾和糾錯能力,例如上面講到的RS碼就是一種信道編碼算法。
對于視頻信源編碼器來說,以H264為例,通常視頻幀是逐幀參考的,即后一幀總是參考同GOP內(nèi)的前一幀。但在分層編碼的情況下則不然,在分層編碼時(shí),視頻幀會分為基礎(chǔ)層和一個(gè)或多個(gè)增強(qiáng)層。在多下行的場景中,分層編碼可以為不同設(shè)備和不同網(wǎng)絡(luò)情況的終端提供不同等級的自適應(yīng)視頻流。但與此同時(shí),分層編碼使得視頻幀的依賴關(guān)系變得復(fù)雜,如果仍然套用簡單的滑窗FEC編碼,視頻質(zhì)量將無法達(dá)到最優(yōu)。
相比于傳統(tǒng)的滑窗方案,DMEC將信源編碼器輸出的視頻幀參考關(guān)系作為卷積編碼器的編碼約束,排除了非參考幀對于解碼概率的影響,使得視頻可播放幀率(Playable Frame Rate, PFR)達(dá)到最優(yōu)(該方案的理論依據(jù)見參考文獻(xiàn)1)。
在DMEC編碼時(shí),當(dāng)前幀的編碼窗口僅包含當(dāng)前幀以及其參考幀,越重要的幀被參考的概率就越大,那么在FEC編碼時(shí)被編碼次數(shù)就越多,在解碼側(cè)被恢復(fù)的概率就越高,通過這種機(jī)制,DMEC自動實(shí)現(xiàn)了非對等保護(hù)(UEP),而不需要為高優(yōu)先級的幀分配更多的FEC碼率。
僅以下圖所示的兩層時(shí)域、兩層空域SVC為例說明,當(dāng)T=6時(shí),幀P31的編碼窗口中包含了I00 , I01 , P20 , P21 , P30 ,和 P31 。

4、性能對比
下圖是不同F(xiàn)EC方案在實(shí)驗(yàn)室采用標(biāo)準(zhǔn)序列的PFR測試結(jié)果,PFR即可播放幀率,是評估FEC算法對最終視頻體驗(yàn)的直觀指標(biāo)。其中紅色是幀內(nèi)FEC,藍(lán)色是滑窗FEC,紫色是聲網(wǎng)的DMEC??梢钥闯鯠MEC相較于另外兩種方案的明顯優(yōu)勢。

除了實(shí)驗(yàn)室數(shù)據(jù),我們還通過對線上進(jìn)行大規(guī)模的A/B Test,并通過數(shù)據(jù)挖掘獲取了大量的對比數(shù)據(jù)(下表為部分客戶的A/B Test對比數(shù)據(jù)),同樣驗(yàn)證了聲網(wǎng)自研的DMEC相比傳統(tǒng)FEC方案對于降低視頻卡頓率的效果。
場景灰度分鐘數(shù)卡頓率降幅客戶A1v11.3?百萬22.22%客戶B會議5.6百萬10.94%客戶C直播0.4?百萬12.73%
參考文獻(xiàn)
1,R. Wang, L. Si and B. He, "Sliding-Window Forward Error Correction Based on Reference Order for Real-Time Video Streaming," in?IEEE Access, vol. 10, pp. 34288-34295, 2022, doi: 10.1109/ACCESS.2022.3162217.<https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=9741773>2,?[RFC8680]??Roca, V. and A. Begen, "Forward Error Correction (FEC)?Framework Extension to Sliding Window Codes", RFC 8680,?DOI 10.17487/RFC8680, January 2020,<?https://www.rfc-editor.org/info/rfc8680?>.3, Vincent Roca, Belkacem Teibi, Christophe Burdinat, Tuan Tran-Thai, Cédric Thienot. Block or Convolutional AL-FEC Codes? A Performance Comparison for Robust Low-Latency Communications.?2017. ffhal-01395937v2<?https://hal.inria.fr/hal-01395937v2/document?>4,?Sliding Window Selective Linear Code (SLC) Forward Error Correction(FEC) Scheme for FECFRAME?draft-wang-tsvwg-sw-slc-fec-scheme-03<?https://datatracker.ietf.org/doc/html/draft-wang-tsvwg-sw-slc-fec-scheme-03?>5,Department of Electrical and Computer Engineering - University of New Brunswick, Fredericton, NB, Canada
(正文完)
關(guān)于 Dev for Dev
Dev for Dev 專欄全稱為 Developer for Developer,該專欄是聲網(wǎng)與 RTC 開發(fā)者社區(qū)共同發(fā)起的開發(fā)者互動創(chuàng)新實(shí)踐活動。
透過工程師視角的技術(shù)分享、交流碰撞、項(xiàng)目共建等多種形式,匯聚開發(fā)者的力量,挖掘和傳遞最具價(jià)值的技術(shù)內(nèi)容和項(xiàng)目,全面釋放技術(shù)的創(chuàng)造力。
關(guān)注「聲網(wǎng)開發(fā)者」公眾號,關(guān)注實(shí)時(shí)互動領(lǐng)域的技術(shù)實(shí)踐、行業(yè)洞察、人物觀點(diǎn)。