王超 王昊京
(中國科學院長春光學精密機械與物理研究所 吉林省長春市 130033)
在傳統的望遠鏡觀測系統中,圖像數據通過JPEG 格式進行傳送。由于壓縮技術的限制,圖像的壓縮比例低,占用的存儲空間和帶寬都比較大。隨著望遠鏡觀測系統獲取圖像數量的增加和實時性傳輸需求的增強,使用JPEG 壓縮技術已經無法滿足系統需求,因此將流媒體實時傳輸技術應用到望遠鏡的圖像傳輸系統中具有很好的實用性。
本文設計了一種用于實時觀測相機圖像的流媒體數據傳輸系統。系統利用OpenCV 進行視頻采集,將采集到的數據進行Н.264壓縮編碼,最后將編碼數據通過RTSP 服務器進行實時流媒體推送。
實時流媒體協議RTSP(real time stream protocol)是一種應用廣泛的實時流媒體傳輸協議,主要負責處理服務器和客戶端之間的數據通信,能夠建立和控制媒體的時間同步流。RTSP 協議主要由兩部分構成,分別是RTP和RTCP。其中RTP協議用來傳輸媒體數據,RTCP 則是負責在RTP 傳輸過程中提供傳輸控制信息[1]。RTSP 協議本身不具有流媒體推送的能力,主要依靠其中的RTP 和RTCP 來進行數據的傳輸。在網絡結構中,RTSP 屬于應用層協議,需要相應的鏈路層協議配合才能進行數據的推送。
Н.264 編碼技術是一種高效視頻壓縮編碼技術,能夠支持流媒體數據進行分組傳輸[2]。Н.264 技術具有較高的編碼壓縮率,在相同帶寬下,用其進行壓縮編碼能夠傳輸更多的數據。同時Н.264 技術具有較強的抗干擾性,能夠適應不同的網絡環境,常用于數據流的傳輸過程,尤為適合圖像的傳輸。經壓縮編碼后,圖像的幀結構由NALU 組成。每個NALU 中都分為兩部分,一部分是NAL 頭文件信息,用以儲存數據傳輸的相關信息。另一部分是原始圖像編碼后的數據信息。
流媒體實時傳輸系統采用客戶端-服務器工作模式。系統中的Н.264 編碼模塊選用FFmpeg 中的Н.264 編碼庫。網絡傳輸協議選用TCP 協議。流媒體傳輸系統的整體結構如圖1 所示,主要包括三部分:視頻采集編碼模塊、流媒體服務器模塊和流媒體客戶端模塊。
前端模塊主要負責圖像的獲取和處理,在功能上分為兩部分,分別是圖像采集和Н.264 編碼器。兩部分各占用一個線程單獨進行處理,這樣可以保證在獲得圖像信息后,能夠實時的進行Н.264 編碼。圖像獲取過程使用OpenCV 對相機的原始圖像信息進行采集,采集到的每一幀圖像都會被轉存為cv::Mat 格式,便于接下來編碼器的編碼操作。幀數據在進入編碼器之前會經過數據格式轉換,該過程將每一幀的圖像信息提取出來,通過色度空間轉換轉變為YUV420 格式,之后再進入編碼器進行Н.264 編碼。編碼器通過調用編碼函數,對圖像進行壓縮編碼,然后將數據存儲到內存中等待RTSP 服務器調用。

圖1:流媒體傳輸系統整體架構
RTSP 服務器通過指針調用內存中的編碼數據。在接收到數據后,RTSP 服務器首先對數據格式進行判別處理,然后將Н.264 數據進行轉換操作,再將圖像數據封裝成RTP 數據包、將控制信息封裝成RTCP 協議支持的數據包,最后使用RTSP 服務器對外推流。
如圖2 所示為RTSP 客戶端和服務器的交互過程。客戶端首先向服務器發送Options 請求報文,等待服務器響應。待服務器對此進行響應后,客戶端會向服務器端發送Describe 請求報文、Setup請求報文,服務器通過接收這些報文,逐步建立與客戶端的連接[3]。在客戶端與服務器建立連接的過程中,客戶端會向服務器端發送Play 請求,即請求服務器進行RTSP 數據推送。在對該請求進行響應后,RTSP 服務器便會進行RTP 和RTCP 的推送。推送完成后,客戶端和服務器通過Turndown 報文結束連接[4]。
為了保障數據傳輸的可靠性,本系統在數據鏈路層使用TCP協議進行數據發送。客戶端和服務器在SETUP 過程中確定了使用TCP 協議進行后續的RTSP 數據推送工作。當流媒體數據進行傳輸時,服務器不會構建新的TCP 連接,而是直接使用此前通信過程中的TCP 通道。服務器會對RTP 數據包進行封裝處理,在原RTP包的基礎上添加辨識符、通道號和RTP 包的大小等信息,然后經由TCP 通道發送給客戶端,發送示意圖詳見圖3。
本系統的編碼器主要以FFmpeg 中提供的libx264 為基礎進行圖像信息的Н.264 壓縮編碼。前端視頻采集裝置在獲得圖像信息后,經過色度空間轉換,再通過指針傳入到Н.264 編碼器中。Н.264 編碼器對接收到的圖像數據進行判別和預處理,并將圖像數據存儲在AVFrame 結構體中,然后通過調用avcodec_encode_video()函數進行Н.264 編碼[5]。編碼后的數據存放在AVPacket 結構中,待RTSP服務器進行推送。
RTSP 服務器是流媒體實時傳輸系統的核心部分,其主要職能是對圖像數據進行RTSP 封裝處理及推流。RTSP 服務器的主要功能為客戶端和服務器之間的通信、構建流媒體數據、發送RTSP 流媒體數據。RTSP 服務器的基本設計流程如圖4 所示。
RTSP 服務器在運行時,首先會監聽當前狀態下的TCP 連接情況,當監聽到來自客戶端的連接請求時,服務器會建立新的socket,并綁定相應端口號。然后服務器進入RTSP 的事件循環中,待接收到客戶端發送的connection 信息后,與客戶端進行連接[6]。
在等待連接的同時,RTSP 服務器會開辟新的線程來構建流媒體傳輸數據。RTSP 服務器在接收到來自編碼器的數據后,自身會構造一個AVFrame 類型的幀結構,用來進行后續的流媒體推送。該幀結構主要包括圖像編碼數據、編碼器的頭文件信息、P 幀、I 幀、時間戳等。
在與客戶端連接成功后,RTSP 服務器通過解析接收到的信息,獲取流媒體ID,建立流媒體會話,通過會話傳遞流媒體數據。在會話建立后,系統會創建數據推送地址,建立TCP 連接,并構建動態監聽器,監聽來自客戶端的返回值。若返回值正確,便開始進行圖像數據的RTSP 推送。待推送結束后,服務器關閉RTSP 數據推送,移除流媒體會話。
實時性對于望遠鏡流媒體傳輸系統來說至關重要,其主要體現在編碼和推送兩方面。本系統通過使用多線程、環形緩存和時間同步等技術,使前端模塊和RTSP 服務器模塊的實時性都得到了提升,以達到減少傳輸時延的目的。
開源編碼庫中的Н.264 編碼程序是基于視頻文件進行編碼,這種編碼方式只能對內存中已有的圖像信息進行壓縮編碼,無法對從相機處實時獲取的原始數據進行軟編碼。基于這種情況,我們改進了Н.264 編碼器數據輸入部分的程序結構,以適應系統實時性的需求。
通過對Parse 函數的內部結構進行修改,使其不再將讀取文件信息作為獲取待編碼數據的來源,而是通過直接讀取系統內存中的數據流進行編碼。相機將采集的圖像信息直接存儲在共享內存中,Н.264 編碼器會從共享內存中逐幀讀取數據,將內存中的數據進行壓縮編碼,并在每一幀圖像的編碼數據前添加相應的關鍵幀、SPS和PPS 等前綴[7],使得編碼后的數據流具備完整的Н.264 格式。
為使系統在編碼后能夠直接進行RTSP 推流,編碼器對輸出的數據不再保存成Н.264 的文件格式,而是直接將其存儲在緩存中。RTSP 服務器從該緩存中讀取編碼信息后,直接進行下一步的推流操作。這樣不僅能減少處理過程的時延,還可以節約內存空間,減少系統產生不必要的輸出。
本系統設計并實現了一個RTSP 類,用來完成從初始化參數配置到數據實時推送的完整過程。RTSP 推送類主要包括Н.264 數據調用、RTSP 服務器構建和圖像推送等操作。通過構建RTSP 對象,進而建立一個完整的RTSP 實時推流過程。
RTSP 推流過程依靠多線程處理來實現實時性推送。主線程中構建了一個RTSP 對象,用于初始化RTSP 推送類、Н.264 編碼器函數、推送函數、圖像參數以及存儲空間。推送函數中定義了一個子線程,用來進行數據的處理和推送。主線程中打開RTSPServer函數,完成服務器的構建。然后主線程進入獲取圖像數據的循環中,不斷的將獲取到的圖像數據存放到推送類的指針成員中。最后主線程中加入推送對象的停止和退出操作。這樣便完成了主線程中實時推送環境的搭建。

圖2:RTSP 服務器與客戶端之間的通信過程

圖3:基于TCP 協議的RTSP 數據推流
在推送函數中定義的子線程主要負責構造RTSP 推送的數據。子線程調用主線程中前端相機獲取的原始圖像數據,將圖像數據轉換成YUV420 格式,并進行Н.264 編碼。再將編碼后的數據通過主線程中的RTSP 服務器進行推送,使用TCP 協議傳輸到客戶端。

圖4:RTSP 服務器的基本設計流程
在對原始圖像數據進行Н.264 編碼時,由于前端模塊獲取圖像數據的速度和Н.264 編碼器的讀入速度并不相同,兩者數據直連會造成時延。因此圖像數據需要經過緩存區再進入到編碼器中。線性緩存區不能同時進行讀寫兩種操作,數據需寫滿緩沖區后,再進行讀出,這會造成在編碼器讀取數據時,圖像數據因等待寫入而丟失,無法保證系統的實時性。為此系統在前端輸入設備和編碼器之間設置一個環形緩沖區。環形緩沖區能夠同時進行讀寫操作,實現圖像數據的先入先出,這樣便解決了兩個線程同時處理的問題。并且緩沖區不需要再拷貝內存,對數據的解析率高。但環形緩沖區的大小也是有限的,如果讀寫數據的速率相差很大,可能會導致數據溢出,這時便需要分別計算圖像獲取操作和Н.264 編碼操作的耗時,通過主動延遲某一方面的單次耗時,配合系統的環形緩沖區來確保數據不會丟失。
流媒體實時傳輸系統使用Visual Studio 2015 作為開發工具,在Windows 平臺下進行運行。采用高清魚眼相機作為前端采集與編碼模塊的視頻輸入設備,使用VLC 播放器作為客戶端。
運行流媒體實時傳輸系統后,終端界面會顯示出當前流媒體系統的RTSP 推流地址和如圖5 所示的前端實時圖像窗口。使用VLC中的網絡串流功能,輸入實時傳輸系統的推送地址和預先設定好的端口號,即可完成視頻的實時播放。實驗結果如圖6 所示,VLC播放器的顯示畫面與前端輸入圖像一致,證明基于RTSP 服務器的流媒體實時傳輸系統中的數據采集、編碼、推送、播放等各個功能皆能正常運行,系統整體達到實時傳輸效果。
系統在使用的過程中,支持多個接收端并行觀看,使用不同的網絡串流客戶端,通過訪問相同的RTSP 播放地址,便能同時觀看前端流媒體實時數據。
本文討論了使用RTSP 技術實現流媒體數據實時傳輸的全過程,設計并實現了一種基于RTSP 服務器的流媒體實時傳輸系統。系統能夠對圖像數據進行Н.264 實時編碼和RTSP 實時推送。在兼顧傳輸實時性的同時,系統采用了TCP 協議對RTSP 數據進行傳輸,保證了數據傳輸的可靠性。因此本系統能夠為望遠鏡的觀測圖像提供實時、可靠的傳輸服務。

圖5:前端實時圖像窗口

圖6:流媒體實時傳輸系統客戶端測試結果