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