馬希超,魏志強(qiáng),葛 珊
(中國電子科技集團(tuán)公司第三研究所,北京 100015)
隨著無人機(jī)在偵察監(jiān)視、安防保衛(wèi)、森林消防及航拍攝影等眾多領(lǐng)域的推廣應(yīng)用,作為其核心載荷的光電吊艙得到了人們越來越多的關(guān)注[1-2]。在執(zhí)行飛行任務(wù)時(shí),光電吊艙作為無人機(jī)的“眼睛”,通過有線或無線傳輸鏈路將采集的可見光視頻和紅外視頻實(shí)時(shí)傳輸至地面,由地面操控臺上運(yùn)行的顯控軟件接收并顯示。目前,主流的光電吊艙采集的可見光視頻分辨率基本都可達(dá)到1 920×1 080 像素,幀率為25 f/s 或30 f/s。通過計(jì)算可知,如果直接傳輸原始視頻數(shù)據(jù),數(shù)據(jù)量會達(dá)到Gb/s 的量級,對于遠(yuǎn)距離無線傳輸來說極難實(shí)現(xiàn)。因此,通常對視頻進(jìn)行編碼,如采用H.264 或H.265 格式,將數(shù)據(jù)量壓縮至Mb/s 的量級,再經(jīng)無線鏈路傳輸后由地面顯控軟件解碼后顯示[3-4]。
視頻編解碼的引入對顯控軟件提出了更高的要求[5],主要體現(xiàn)在實(shí)時(shí)性和平穩(wěn)性兩個方面。一方面,顯控軟件從接收視頻流到解碼再到顯示需經(jīng)過多個環(huán)節(jié),若簡單地順序執(zhí)行,必然會導(dǎo)致較大的滯后,對操控設(shè)備和觀察視頻造成明顯的影響。為保證較好的實(shí)時(shí)性,需要設(shè)計(jì)合理的多線程架構(gòu),盡量減小視頻顯示的延遲滯后。另一方面,在H.264或H.265 格式的視頻碼流中,視頻幀分為關(guān)鍵幀(I幀)、前向參考幀(P幀)和雙向參考幀(B幀)3類[6]。其中,I 幀每隔一定時(shí)間出現(xiàn)一次,包含一幀圖像的完整信息,因此數(shù)據(jù)量較大;其余的P 幀和B 幀只包含幀差信息,數(shù)據(jù)量小。因此,傳輸、接收及解碼I 幀時(shí)所需的時(shí)間較長,導(dǎo)致視頻在顯示時(shí)出現(xiàn)周期性卡頓現(xiàn)象。此時(shí),需要采取適當(dāng)?shù)姆椒▉肀WC視頻顯示的平穩(wěn)性。
本文描述一種針對機(jī)載光電吊艙的視頻流實(shí)時(shí)解碼顯示技術(shù)。通過設(shè)計(jì)合理的多線程架構(gòu),采用動態(tài)圖像緩存技術(shù),實(shí)現(xiàn)了視頻解碼顯示的低延遲和無卡頓,提高了顯控軟件的實(shí)時(shí)性和平穩(wěn)性。
整個流程分為3 個線程,即接收線程、解碼線程及顯示線程。3 個線程并行運(yùn)行,通過視頻流緩存和圖像緩存兩個存儲區(qū)進(jìn)行數(shù)據(jù)交換。處理流程和線程結(jié)構(gòu)如圖1 所示。
圖1 流程圖
在接收線程中,程序以循環(huán)的方式不斷接收視頻流數(shù)據(jù)并存入視頻流緩存;解碼線程同樣以循環(huán)的方式不斷檢查視頻流緩存中的數(shù)據(jù)量,當(dāng)數(shù)據(jù)量超過一定的閾值,提取數(shù)據(jù)進(jìn)行解碼,并將解碼后的圖像存入圖像緩存;顯示線程以定時(shí)器方式周期性地從圖像緩存中提取圖像進(jìn)行顯示。3 個線程在各自獨(dú)立運(yùn)行的同時(shí)緊密配合,以保證數(shù)據(jù)的快速傳遞,最大限度降低延遲,同時(shí)數(shù)據(jù)流向清晰,避免產(chǎn)生線程沖突。
接收線程用于完成光電吊艙下傳視頻流的接收。光電吊艙通常采用UDP 通信協(xié)議,通過網(wǎng)絡(luò)下傳視頻流,可能帶有加密幀頭。接收線程通過循環(huán)的方式不斷讀取網(wǎng)絡(luò)數(shù)據(jù),根據(jù)通信協(xié)議從加密數(shù)據(jù)包中提取有效的視頻流數(shù)據(jù),并立即將數(shù)據(jù)存入視頻流緩存。視頻流緩存為全局存儲區(qū),需具備大量數(shù)據(jù)快速寫入寫出的能力。同時(shí),它對內(nèi)存空間的控制十分重要,一旦發(fā)生接收線程和解碼線程配合失常的情況,如接收線程正常運(yùn)行而解碼線程由于初始化問題未能運(yùn)行時(shí),視頻流緩存將出現(xiàn)只存入不取出的情況,最終導(dǎo)致內(nèi)存溢出,程序崩潰。為避免這種情況的發(fā)生,采用環(huán)形存儲器作為視頻流緩存。環(huán)形存儲器采用先進(jìn)先出原則,當(dāng)存儲空間用盡后會從尾部回到頭部,用新的數(shù)據(jù)覆蓋最早的數(shù)據(jù)。這樣既可以免去不斷申請新內(nèi)存空間的開銷,又可避免出現(xiàn)內(nèi)存溢出的情況。在程序運(yùn)行過程中,接收線程控制存儲器的寫入指針不斷存入視頻流數(shù)據(jù),到達(dá)末端后便回到起點(diǎn)繼續(xù)寫入;解碼線程控制存儲器的讀取指針以追趕的方式不斷取出數(shù)據(jù),使存儲器內(nèi)的數(shù)據(jù)量始終保持在一定長度之內(nèi),實(shí)現(xiàn)動態(tài)平衡。
解碼線程同樣采用循環(huán)方式不斷獲取視頻流緩存中的數(shù)據(jù)量。當(dāng)數(shù)據(jù)量大于設(shè)定的閾值N(如1 024 Bytes)時(shí),則提取N個字節(jié)的數(shù)據(jù)移交至解碼器處理。解碼器調(diào)用FFmpeg 程序庫對H.264 或H.265 碼流解碼,并轉(zhuǎn)換為RGB 格式圖像存入圖像緩存。
在H.264 或H.265 碼流中,大部分幀都是只包含幀差信息的參考幀(P 幀和B 幀),數(shù)據(jù)量較小。每隔固定時(shí)間(如1 s)會有一個關(guān)鍵幀I 幀,包含完整的圖像信息,數(shù)據(jù)量大,使得傳輸和解碼都較為耗時(shí)。因此,解碼得到各幀圖像的時(shí)間間隔是不均勻的。若不加處理地將每一幀解碼圖像立即顯示,則會每隔一段時(shí)間出現(xiàn)一次卡頓現(xiàn)象,影響視頻顯示的連貫性和平穩(wěn)性。
為解決這一問題,本文引入了圖像緩存。圖像緩存的總體思路是將解碼圖像依次存入緩存,由顯示線程定時(shí)提取圖像進(jìn)行顯示,使顯示的周期與解碼的周期隔離開來并保持均勻。圖像緩存采用隊(duì)列形式,以先入先出原則進(jìn)行存取。采用圖像緩存需要解決的一個重要問題是保證輸入輸出的平衡。雖然根據(jù)相機(jī)的幀率可以計(jì)算各幀的平均間隔,但并不十分精確。此外,為定時(shí)器設(shè)定的響應(yīng)周期也無法做到與真實(shí)的幀間隔完全一致,會導(dǎo)致輸入輸出的不平衡。若輸出快于輸入,則會耗盡緩存內(nèi)的圖像,存入一幀則立即顯示一幀,導(dǎo)致緩存失去作用,視頻依然發(fā)生卡頓;若輸出慢于輸入,則緩存數(shù)量不斷增加,若不加限制會導(dǎo)致內(nèi)存溢出,程序崩潰,若設(shè)置限幅則會丟失圖像。
本文采用動態(tài)圖像緩存的方法實(shí)現(xiàn)輸入輸出的平衡,流程如圖2 所示。每隔一段時(shí)間判斷一次緩存內(nèi)的圖像數(shù)量,若數(shù)量較多,則減小定時(shí)器的間隔,加快顯示;若數(shù)量較少,則增大定時(shí)器的間隔,減慢顯示;若數(shù)量適中,則保持初始間隔。以30 f/s的可見光視頻為例,設(shè)初始顯示間隔T=33 ms。每解碼30 幀判斷一次緩存數(shù)量N,若N>5,則令T=30 ms,加速顯示,消耗緩存數(shù)量,減小視頻滯后;若N<3,則令T=34 ms,稍稍減慢顯示,積累緩存數(shù)量,避免出現(xiàn)卡頓;若3 ≤N≤5,則令T=33 ms,保持穩(wěn)定顯示。
經(jīng)過對提取頻率的動態(tài)調(diào)整,可以使圖像緩存長期維持在數(shù)量較少的狀態(tài),保持輸入與輸出的平衡和穩(wěn)定。
測試所用的光電吊艙顯控軟件采用C++語言和Qt 框架編寫,實(shí)現(xiàn)了本文所述的多線程架構(gòu)和動態(tài)圖像緩存技術(shù)。在解碼線程和顯示線程中分別記錄每幀圖像解碼和顯示的時(shí)間戳,計(jì)算解碼時(shí)間間隔和經(jīng)動態(tài)調(diào)整后的顯示時(shí)間間隔,最后繪制如圖3 所示的曲線圖。
從圖3 可知,解碼間隔極不穩(wěn)定,約30 幀(大概1 s)會出現(xiàn)一次120 ms 以上的長間隔,即處理I幀所需的時(shí)間。而經(jīng)動態(tài)調(diào)整后,顯示間隔平穩(wěn)程度顯著提高,絕大多數(shù)數(shù)據(jù)穩(wěn)定在33 ms 左右,其中一小段在30 ms 左右,這是緩存數(shù)量較多、加快顯示的結(jié)果。這一結(jié)果表明,采用動態(tài)圖像緩存技術(shù)可以有效提高視頻顯示的平穩(wěn)性,避免出現(xiàn)卡頓現(xiàn)象。
圖2 動態(tài)圖像緩存流程
圖3 幀間隔統(tǒng)計(jì)
此外,合理的多線程架構(gòu)設(shè)計(jì)也使顯控軟件具有較好的實(shí)時(shí)性。本文用簡易方法測試了從相機(jī)成像到視頻編碼、傳輸再到接收、解碼及顯示全過程的總延遲時(shí)間約為0.4 s,如圖4 所示。在這一較低的延遲下,控制光電吊艙和觀察視頻時(shí)基本不會產(chǎn)生明顯的滯后現(xiàn)象。
圖4 延遲時(shí)間測試
本文介紹了一種針對機(jī)載光電吊艙的視頻流實(shí)時(shí)解碼技術(shù),通過設(shè)計(jì)合理的多線程架構(gòu)和數(shù)據(jù)交換方式,采用動態(tài)圖像緩存技術(shù),實(shí)現(xiàn)了低延遲和無卡頓的視頻解碼顯示效果,對于充分發(fā)揮光電吊艙的性能和提高地面顯控軟件的運(yùn)行效率與使用體驗(yàn)具有重要意義。