楊明極,陳 楠
(哈爾濱理工大學測控技術與通信工程學院,黑龍江 哈爾濱 150080)
數字視頻技術正在逐步進入人們的工作和生活中,各種嵌入式應用和電子產品由于增加了視頻功能而提高了價值。例如,用戶可以使用移動視頻服務器方便地看到交通路口的實時情況,可以看到家中需要照顧的老人和小孩,家長還可以隨時看到孩子在幼兒園的情況等。為了應對這種需求,2005 年,TI推出了 DaVinci技術[1],將可編程器件的靈活性和固定功能器件的高效率結合在一起,支持各種數字視頻的設計要求。在軟件方面,由于系統較大并且應用線程較多,因此有必要使用嵌入式操作系統。Linux操作系統具有開放源代碼、易于移植、資源豐富、免費等優點,在嵌入式領域得到廣泛應用。
設計的主要目標是對視頻圖像進行采集,然后將采集到的視頻圖像經過壓縮編碼處理,最后通過網絡傳輸到服務器上,允許手機客戶端進行實時監控。DaVinci平臺的特點是基于DSP+ARM的SoC芯片。提供了軟件、開發工具、技術支持等系統組件,可以高效地開發數字多媒體系統,Linux操作系統可以提供多種進程間的通信機制,能夠統一管理系統資源,為用戶提供訪問硬件的接口[2],均可使設計達到要求。
DaVinci的TMS320DM6467處理器是為了滿足嵌入式設備的圖像編/解碼的應用而設計,集成了一個ARM926EJ-S核與一個C64x+DSP核。其中ARM處理器主頻為297 MHz,內核可嵌入Linux操作系統,主要起控制和管理作用;DSP處理器主頻為594 MHz,其內核相當于一個“黑匣子”,用DSP/BIOS來處理編解碼算法。DSP與ARM之間通過引擎和服務器完成通信和交互[3]。系統以TMS320DM6467處理器為核心,同時包括視頻采集模塊、用于上傳視頻到互聯網的以太網模塊、用于存儲用戶信息的I2C接口E2PROM以及可用于系統升級的RS-232接口和用于存儲視頻的硬盤接口[4],系統的功能框圖如圖1所示。

圖1 系統的功能框圖
系統采用的是Monta Vista軟件公司的Monta Vista Linux操作系統,它的可搶占內核技術可以顯著降低內核抖動和延遲,以保證系統的實時響應。Monta Vista公司提供了100多種板級硬件平臺支持和30多種處理器的通用代碼體系,有利于Linux中U-Boot移植、內核移植及根文件系統的構建[5]。軟件架構如圖2所示。

圖2 軟件架構圖
Video4Linux是Linux內核中支持視頻設備驅動的編程接口。視頻圖像的采集是通過Video4Linux提供的上層API來控制視頻設備的驅動程序,然后完成圖像實時采集。當攝像頭驅動程序加載后,系統把攝像頭映射為/dev/video設備文件,開始采集視頻信息。視頻圖像的采集用Video4Linux的API接口配合mmap()函數實現,其流程如圖3所示。

圖3 采集模塊流程圖
首先系統函數fd=open(/dev/video,O_RDWR)打開采集設備,然后由函數ioctl(fd,VIDIOC_GCAP)來獲得采集設備信息,并且由函數ioctl(fd,VIDIOC_GPICT)設置圖像信息,并將獲得的信息存在各自的分量中。用系統調用函數ioctl(fd,VIDIOC_GMBUF)初始化video_mbuf得到buffer信息,包括幀數及幀的大小等信息。再用函數mmap()把設備文件信息映射到內存中。最后用ioctl(fd,VIDIOC_SYNC)函數判斷一幀圖像是否讀取完畢,若讀取完畢則關閉設備。采集到的視頻數據存放到data地址的內存區域內,然后交給應用程序進行處理。
移動視頻服務器要求視頻數據實時傳輸,其質量要求是端到端的時延、時延抖動和分組丟失率[6]。針對多媒體數據流的傳輸特性,本文采用RTP/RTCP實時數據傳輸方式。通過時間戳來保持采樣和播放之間的同步,同時保證視頻信號的還原性。因此在RTP的數據包中加入了時間戳和序列號等信息。RTP通常不作為獨立的網絡層,而把它看作應用層的一部分,在應用程序之下,UDP之上。發送端將采樣到的媒體數據封裝成RTP格式,然后通過RTP底層調用相關的UDP API函數把數據發送出去。RTP有兩個鏈接組成,其中RTP是傳送實時數據的;RTCP則監控傳送質量并且傳送正在進行的相關數據信息。RTP和RTCP配合使用,保證傳送和接收的可靠性并能有效提高傳輸效率。
oRTP是實現庫,具有包調度、自動發送RTCP包、自適應抖動補償等功能。首先要在Linux平臺上建立oRTP協議棧,把oRTP移植到達芬奇系統后展開RTP/RTCP模塊編程設計,本文采用全局結構指針prtpstat開始實現對RTP/RTCP模塊的訪問和控制。代碼如下:

其中,STREAMS_COUNT表示系統可支持的最多數據流的數目;PACKET_SIZE表示RTP的數據流的最大長度;TS_INC表示RTP的數據流時間戳的遞增量;runcond變量表示RTP線程的運行狀態;channels表示RTP當前的運行任務數量;SessionSet表示oRTP中控制多任務的數據結構類型;RtpSession表示控制RTP任務,包含一個RTP任務的所有必要的信息,一個RtpSession代表一個RTP任務,把網絡地址和負載類型配置好后就可以發送媒體流;STREAMS_COUNT表示最多可支持并發的RTP任務的數量;buffer指針為媒體流的數據緩沖區;user_ts表示任務時間戳的增值量;connected表示任務的連接狀態,當任務連接成功后,對connected置1,否則置0。RTP在執行過程有初始化階段、數據流的傳輸階段、任務結束階段3個階段:初始化階段就是完成prtpstat指針的初始化過程。數據流的傳輸包括RtpSession初始化,即網絡地址和負載的配置,還有對數據流的封裝和傳輸及RTCP信號的傳輸過程。數據包的發送是調用oRTP協議棧中的rtp_session_send_with_ts(RtpSession* session,const uint8_t* buffer,int len,uint32_t userts)函數來實現的,其中 Session為任務指針,buffer為數據流首地址,len為數據流的長度,userts為數據流時間戳。此函數執行后,依次把數據流加上RTP協議頭、UDP頭、IP頭。當各個頭部信息設置好后就會得到一個完整的IP包,然后通過網絡發送。任務結束階段是對相關的指針回收和變量設置等操作。待發送的數據流通過DSP編碼模塊的輸出得到,將數據用rtp_session_send_with_ts()函數發送即可。
本文的視頻算法選用的是H.264,并打包在一個Codec服務器里,由Codec Engine管理。DSP核運行DSP/BIOS實時操作系統,執行處理算法。
整體模塊設計包括3個部分:主模塊(main.c)、視頻模塊(video.c)和顯示模塊(display.c)。模塊的初始化均由公用模塊Rendezvous來同步,該模塊首先執行初始化,用POSIX條件來同步各部分模塊。每個模塊執行各自的初始化,然后向Rendezvous模塊發送信號。此時所有模塊完成初始化,然后各模塊開始執行其各自主循環[7]。
主模塊是執行必要的初始化任務,用戶可以通過應用程序所提供的命令行參數初始化編碼運行時間,并且根據這些參數創建視頻。主模塊流程如圖4所示。

圖4 主模塊流程圖
主模塊首先通過DaVinci上的檢測開關S3的上電默認狀態來檢測視頻標準,當為0時,表示PAL制式;當為1時,表示NTSC制式。之后解析命令行參數,設置環境變量,包括啟動方式、圖像大小、串口參數、Linux啟動參數、文件系統路徑、IP地址等。Codec Engine初始化,打開同步初始化Rendezvous的目錄,主模塊開始解析與視頻相關的命令,通過調用CERuntine_init()函數開啟編碼引擎,調用Rendezvous_open(),開始視頻的創建,并且進入控制線程。控制線程負責用戶界面上實現與用戶的交互接口。
視頻模塊主要是采用視頻編碼算法對視頻前端采集到的圖像數據進行編碼算法處理,在客戶端顯示之前對編碼處理過的數據進行解碼。視頻模塊流程如圖5所示。

圖5 視頻模塊流程圖
視頻模塊首先通過FifoUtil_open()函數建立目標,打開和顯示進程間的數據緩存并且用于建立兩進程之間的通信交流通道。之后調用pthread_create()函數創建視頻模塊。用initCaptureDevice()函數初始化視頻前端的采集設備,使視頻數據輸入通道完成初始化工作。然后用VIDIOC_S_INPUT設置用戶用所選擇的輸入信號,視頻標準(NTSC或PAL)由采集設備檢測,對照Linux內核命令行的視頻標準進行驗證,最后使用VIDIOC_STREAMON開始對采集器件驅動器里的視頻幀進行采集。Codec Engine_open()函數是建立一個Codec Engine。之后,VIDENC_Create()函數完成視頻的編碼任務,設計支持H.264編碼格式[8]。模塊最后調用Memory_contigAlloc()函數為編碼緩沖和顯示緩沖分配連續的內存空間。到此結束視頻模塊的初始化,然后使用Rendezvous公用模塊和其他模塊同步,此時視頻模塊進入主循環。
顯示模塊將視頻處理子系統前端采集到的視頻數據的原始幀復制到視頻子系統后端的幀緩存器里。在DSP進行處理的同時,復制一個獨立的顯示模塊。顯示模塊最先通過initDisplayDevice()函數來完成顯示設備的初始化,在此函數中,調用mmap()函數完成地址重映射。然后使用FBIOPUT_VSCREENINFO函數,將分辨力設置為320×240格式。當顯示模塊完成初始化以及其他模塊都完成初始化時,顯示模塊通過Rendezvous_open()函數進入主循環。
本文在DaVinci平臺上實現了移動視頻服務器的軟件設計,主要對視頻數據采集、數據傳輸和服務器整體進行軟件設計。所設計的移動視頻服務器在嵌入式Linux操作系統下和DM6467開發板上實現了數據采集和傳輸等功能,并且穩定運行達到設計要求。對嵌入式應用及視頻服務器的發展有一定的借鑒意義。
[1] Texas Instruments.DVEVM getting started guide[EB/OL].[2011-08-25].http://www.kanecomputing.co.uk/pdfs/tmdsevm6446%20getting%20started%20guide.pdf.
[2]韋東山.嵌入式Linux應用開發完全手冊[M].北京:人民郵電出版社,2008.
[3]常國柱,何維,田增山,等.基于達芬奇技術的視頻傳輸系統設計[J].電視技術,2010,34(10):39-41.
[4] Texas Instruments.TMS320DM6446 digital media system on chip[EB/OL].[2011-08-25].http://www.ti.com/lit/ds/sprs283h/sprs283h.pdf.
[5]馮國進.嵌入式Linux驅動程序設計[M].北京:清華大學出版社,2008.
[6]張起貴,張勝,張剛.最新DSP技術——“達芬奇”系統、框架和組件[M].北京:國防工業出版社,2009.
[7]彭啟琮.達芬奇技術——數字圖像/視頻信號處理新平臺[M].北京:電子工業出版社,2008.
[8]成嘉,張文雄,李善勁.基于達芬奇技術的H.264視頻編碼器的實現[J].電視技術,2007,31(12):34-36.