隨著網絡技術和嵌入式技術的迅猛發展,通過網絡來實現視頻監控已經得到了廣泛的應用,3G網絡以其高帶寬使得傳輸流暢的視頻信息成為可能,本文在采用3G技術的基礎上設計了一款基于嵌入式Linux的無線終端,在數據處理部分采用了Linux的Netfilter架構,通過掛載鉤子函數來實現數據包在內核態的獲取及高效轉發,并且通過在Linux內核開辟一片緩沖區,解決了視頻服務器與3G模塊撥號延時而造成的速率不匹配的問題,減少了數據丟包。配合Netfilter用戶態管理工具iptables的使用,可實現包過濾防火墻,及NAT等功能,從而便于本系統對流經其數據包的管理。
另一方面對嵌入式Linux的視頻采集程序的設計進行了詳細的介紹,并將其實際應用到了本系統的數據采集模塊中去,完成了數據的采集工作,同時針對目前市場上對與3G模塊通常只提供Windows CE下的驅動這一情況,開發了嵌入式Linux系統下的3G模塊驅動程序,在軟件設計上充分發揮了開源軟件的優勢,采用高效的Xvidcore編解碼庫,來完成視頻的編碼,以及使用PPP源碼來編譯撥號上網工具,成本低廉并且縮短了系統的開發周期,使得本系統具有較強的工程實用價值。
1 、系統硬件結構
硬件上采用“ARM+3G模塊”系統架構。ARM與3G模塊采用分離模塊的設計方法,通過USB線相連,較整體設計而言具有更好的靈活性,使得一些現有的以ARM為主處理器的系統能夠很好地擴展3G功能,便于產品的過渡。本系統的核心處理器是S3C2440A,S3C2440A是一款由SamSu-ng半導體公司推出的基于ARM920T內核的16/32位RISC微處理器。內部帶有全性能的MMU(內存處理單元),主頻為400MHz最大可達到533MHz,提供了一個數字攝像頭接口(Camera Interface)。具有高性能、低功耗、接口豐富和體積小等優良特性。而3G模塊核心部件采用的是MC8630模塊,該模塊具有語音、短信和高速數據業務等功能,可以廣泛應用于高速數據傳輸、安防、無線媒體、直放站監控、鐵路終端和車載監控等領域。
系統硬件結構如圖1所示。
2 、系統軟件設計
系統主要由視頻采集模塊、數據處理模塊、網絡轉發模塊組成。
2.1 視頻采集模塊設計
根據項目的實際需要,在本系統中視頻數據來源主要有兩個方面:
1)系統與可提供主動上傳功能的視頻服務器通過RJ45網線直接相接 主要用于完成多路視頻圖像采集。視頻服務器的主要功能是將攝像頭采集的數據完成編碼壓縮,并且將壓縮的數據以IP包的形式發送給接收端,由于該類視頻服務器通常是在局域網內使用,目前還很少有對于3G網絡的支持,隨著3G技術在國內發展的不斷深入,將在很大程度上取代有線網絡。所以本系統可作為現有視頻服務器的3G功能擴展。針對在外接視頻服務器時只需對收到的數據包進行轉發而無需對IP數據本身做分析處理的問題,并且在系統啟動到3G模塊撥號成功獲得IP地址之間會有一定的延遲,在本系統中提出了采用Linux的Netfilter架構的方法以及緩沖機制,通過在數據流經TCP/IP協議棧時掛載鉤子函數,實現IP數據在內核態的獲取,并且通過在內核開辟一塊足夠大的環形緩沖區來存儲數據。由于系統需要頻繁對緩沖區進行讀寫,為避免產生內存碎片,在本系統中采用了環形隊列的數據結構。在3G模塊獲得IP地址后,再通過驅動讀取緩沖區中的數據,由3G網絡完成轉發,從而降低丟包率并且提高數據包的轉發效率。因為傳統的方法是采用socket API來進行網絡編程,其對數據的訪問通常發生在用戶態,對于Linux操作系統來說,用戶進程的優先級和所占用的CPU時間要遠遠小于內核線程,同時內核進程擁有較高的執行優先度,故在網絡布局允許獲得IP數據包的條件下,將用戶態的數據包獲取功能載入內核態,可進一步提高系統的處理能力,增加系統的有效帶寬,本方法還可用于其他對IP數據本身進行處理并且對處理效率有苛刻要求的系統中,例如:本方法在本實驗室與某航空院合作開發的IP-TS協議轉換器上也得到了成功的應用,具有一定的通用性。Netfilter是Linux 2.6.x系列內核提供的一套數據包過濾框架,基于該框架的軟件能夠實現如數據包過濾、網絡地址轉換(NAT)等功能。要使用Netfilter,在內核編譯時設置“Network Packet Fihering”選項。Netfilter提供了一個抽象、通用化的框架,作為中間件,為每種網絡協議(IPv4、IPv6等)定義一套鉤子函數。對于Ipv4協議定義了5個鉤子函數,這些鉤子函數在數據報流過協議棧的5個關鍵點被調用,Netfilter可以在通過TCP/IP協議棧的路徑中的幾個定義良好的點上捕獲數據包,IPv4中的一個數據包通過netfilter系統的過程如圖2所示。
NF_IP_PRE_ROUTING
在對數據包進行初始正確性檢查(校驗和等)后,截獲該數據包。
NF_IP_LOCAL_IN
如果數據包將要到達本地主機,則捕獲該數據包。
NF_IP_FORWARD
如果數據包將要到達某些其他主機,則捕獲該數據包。
NF_IP_LOCAL_OUT
在本地捕獲其目的地是外部的已創建的數據包。
NF_IP_POST_ROUTING
這是最后的鉤子,在此之后將傳輸數據包。
內核netfilter結構在/usr/src/inelude/linux/netfilter.h中定義,類似如下:
參數是:
list
Netfilter本身是一個鉤子鏈;它指向netfilter鉤子的頭部,通常設置為{NULL,NULL}。
hook
該函數在數據包碰到鉤子點時被調用。該函數與前面描述的函數相同,它必須返回NF_ACCEPT、NF_DROP或NF_QUEUE。如果返回NF_ACCEPT,則下一個鉤子將被附加到將要調用的點。如果返回NF_DROP,則數據包被丟棄。如果返回NF_QUEUE,則對數據包進行排隊。sK_buff指針被傳遞到該函數中,并用數據包信息如IP報頭、TCP報頭等進行填充,可以使用sk_buff結構指針來操作或刪除數據包(要刪除數據包,只需將skb指針設置為空即可)。
pf
協議簇;例如,適用于IPv4的PF_INET。
hooknum
鉤子的掛載點,由于本系統不需要在本地對數據包進行任何處理,因此選擇的掛在點為NF_IP_PRE_ROUTING,在對數據包進行正確性校驗后就調用鉤子函數處理數據包。Priority表明鉤子的優先級,在本系統中采用高優先級處理NF_IP_PRI_FIRST。
內核數據處理的關鍵是鉤子函數的編寫,此函數規定了數據包在到達時需要進行的處理過程。
鉤子函數框架如下:
可以將已經注冊入內核的鉤子函數取消,此時,接收到數據包將按照內核的默認規則來進行處理。流程如圖3所示。
2)直接采用CMOS攝像頭作為視頻采集裝置 該視頻采集模塊在硬件上S3C2440帶有CMOS攝像頭接口,在開發板上通過稱為CAMERA的接口引出,并且帶有camera控制器,在本系統中使用了OmniVision公司的OV9650攝像頭。S3C2440支持ITU-R BT601/656格式的數字圖像輸入,支持2個通道的DMA,Preview通道和Codec通道,參見圖4。
Preview通道可以將YCbCr4:2:2格式的圖像轉換為RGB(16bit或24bit)格式的數據,并存放于為PreviewDMA分配的內存中,最大分辨率為640×480。主要用于本地液晶屏顯示,Codec通道可以輸出YCbCr4:2:0或YCbCr4:2:2格式到為Codec DMA分配的內存中。最大分辨率為4 096x4 096,主要用于圖像的編解碼處理。在本系統中使用的是Codec通道。
視頻采集模塊的設計采用的是V4L2(Video for Linux Two)V4L2,它是Linux下開發視頻采集設備驅動程序的一套規范,該規范采用分層的方法給驅動程序的開發提供了清晰的模型和一致的接口,并且正對視頻設備的應用程序編程也提供了一系列接口函數。其中應用程序處于最上層,V4L2處于中間層,而實際的硬件設備則處于下層,其本身包括兩層驅動結構,上層是videodev模塊,下層為V4L2驅動程序。video-dev通過V4L2驅動程序的成員函數來調用V4L2驅動。在V4L2驅動的驅動程序初始化過程中,它首先枚舉它將要處理的系統中的設備,為每個設備填充struct v412_device結構,并且將指向該結構的指針傳遞給v412_register_device()函數,該函數調用v4L2_deviee結構體中的初始化函數對設備進行初始化。當v412驅動程序初始化完成后,v412通過傳遞一個包含驅動程序成員函數,次設備號以及相關信息的結構給videod-ev,從而完成它將要處理設備在videodev的注冊工作,當應用程序通過系統調用觸發了某個驅動程序時,控制權首先傳遞給videodev中的函數,videodev將應用程序傳遞的文件或i節點結構指針轉換為相應的v412結構指針,并調用v412中的處理函數。以本系統以OV9650攝像頭為例,其驅動框架如圖5所示。
視頻采集過程如下,應用程序首先打開視頻設備文件,攝像頭在系統中對應的設備文件為/dev/camera,通過系統調用“open(“/ dev/camera”,O_RDWR)”函數打開該設備,獲得一個文件描述符fd,利用ioctl(fd,VIDIOCGPICT,&capability)函數獲取攝像頭的相關信息,例如設備名稱、支持的最大最小分辨率、信號源信息等,填充在結構體video_capability中,通過調用ioctl(fd,VIDIOCGPICT,&pict-ure)獲取圖像的相關信息如采集圖像的對比度、亮度、調色板等屬性,并且填充在video_picture結構體中,在獲取這類信息后,可根據實際需要來對其重新賦值,具體做法是將需要設置的值賦給相應結構體,然后通過系統調用ioctl(fd,VIDIOCSPICT,&)函數寫入設備。在圖像獲取方式上使用mmap()系統調用來實現內存映射達到各進程共享內層的目的,利用共享內存通信的一個顯而易見的好處是效率高,因為進程可以直接讀寫內存,而不需要任何數據的拷貝。使用mmap方式獲取圖像數據,需要首先設置圖像幀的緩沖區結構,即struct video_mmap,如每次采集幀數,圖像高度、寬度,圖像調色板格式等等。然后調用ioctl(fd,VIDIOCMCAPTURE,&grab_buf)啟動捕獲過程。調用iotcl(fd,VI-DIOCSYNC,&frame)等待采集完成,若該函數成功返回則表示采集完畢,采集到的圖像將放在通過mmap()映射的內存區域內,讀取該內存數據即可獲得圖像數據,其中frame為當前截取的幀數,V4L2允許一次采集多幀數據,可通過設置grab buf.frame來實現。調用close(fd)函數關閉設備文件,終止圖像采集。
2.2 視頻數據處理模塊設計
由視頻采集模塊獲取的視頻圖像需要通過3G網絡來進行傳輸,而從攝像頭直接采集的未經壓縮的數據量非常大,為了在不影響圖像質量的前提下提高傳輸效率,本系統中對原始獲得的視頻圖像進行了壓縮編碼。由于MPEG-4是專門為播放流式媒體的高質量視頻而設計的,并且MPEG-4標準以其高壓縮比、高質量、低傳輸率已經成為目前網絡多媒體傳輸的主要格式和標準。它可利用很窄的帶寬,通過幀重建技術壓縮和傳輸數據,以求使得用最少的數據獲得最佳的圖像質量并且能夠保存接近于DVD畫質的小體積視頻文件。在本系統中選用開源的Xvidcore作為視頻壓縮模塊的核心算法。Xvidcore是一個高效而且便于移植的編碼軟件。它不僅支持Simple Profile和Advanced Profile,還支持I/P Frames B-Frames Interlacing和GMC,以鉆石和方塊模式來進行PMVFast和EPZS運行估計,是目前比較流行的MPEG-4編碼軟件。Xvidcore源碼可從網上下載免費獲得,目前最新版為xvidcore-1.2.2,它提供了一系列的庫函數及接口函數供應用程序使用。但針對嵌入式系統平臺,要使用該庫需要將其移植到嵌入式系統中。移植過程如下:
解壓源代碼:tar-zxvf xvidcore-1.2.2.tar.gz;在使用前需要對xvidcore-1.2.2進行交叉編譯,步驟如下:
1)設置環境變量:export=“xvidcore當前所在目錄”;
2)進入/build/generic目錄;
3)生成Makefrle:/configure-host=local hostbuild=arm-linux-gcc;//指定交叉編譯工具以便進行交叉編譯;
4)編譯源代碼:make。
將交叉編譯生成的庫文件libxvidcore.so.*拷貝到交叉編譯器工作目錄lib子目錄中。完成編碼庫的移植工作。
以上對個獨立模塊進行了介紹,在軟件實現上對系統進行了整體設計,將各個模塊有機的組合在一起,并充分考慮了系統的可擴展性。
主要結構體如下:
以視頻壓縮模塊為例,其軟件流程如圖6所示。
2.3 網絡轉發模塊設計
在完成對采集圖像的壓縮或者接收完視頻服務器后,需要將數據通過3G網進行轉發,完成網絡數據轉發通常采取的辦法是利用Linux提供的socket API進行,socket給用戶提供了統一的編程接口,網絡傳輸協議通常有TCP和UDP兩種,對于TCP每次要通過3次握手建立連接,在等待亂序及重傳丟失數據時會產生較大延時,而UDP又缺乏流量控制,所以都不太適用于實時數據傳輸,在這種情況下運行于UDP之上的RTP則具有很大的優勢,目前對于有實時要求的數據傳輸RTP是最好的協議,故在本系統中使用了RTP協議作為數據傳輸協議,流程如圖7所示。
2.4 3G模塊驅動設計及聯網
3G模塊與ARM是通過USB相連的。無線終端到3G網絡的連接是通過PPP協議實現的,PPP協議是一種點對點串行通信協議,為在點對點連接上傳輸多協議數據包提供了一個標準方法。由于目前嵌入式市場上的3G模塊基本上都是提供Windows CE操作系統下的驅動程序,但對于嵌入式Linux下面的目前還沒有驅動支持,所以為本系統開發了3G模塊的驅動程序。要完成3G模塊的撥號上網功能,需要3個層面的支持:1)是內核層面;2)驅動層面;3)應用程序層面的支持。內核層面主要是通過對內核的重新配置來完成,由于3G模塊與ARM通過USB線連接,而上層的PPP通信采用的是串行協議,所以要在內核中加入USB轉串口的支持,通過makemenuconfig命令進入內核配置界面,依次選擇Device Drivers-》USB support-》USB Serial Converter Support選擇USB Generic Serial Driver按兩次空格鍵使項目前加[*]將其編譯入內核,其中加*為編譯成內核模塊,加M為編譯為模塊。由于采用的是PPP協議,故要在內核中加入PPP的支持。進入內核配置界面以后,依次選擇DeviceDrivers-》Network device support-》PPP(point-to-point)protocol support選中,將PPP編譯入內核,同時選擇PPP展開項,將其全部編譯入內核,保存退出。對于驅動層面,3G模塊的驅動開發主要是通過修改兩個文件generic.c以及usb-serial.c,其中generic.c為USB通用程序,usb-serial.c為USB轉串口程序。通過在其中加入一些網絡層的hook函數來達到對上層協議的支持。將修改過后的文件復制到/linux2.6.29/drivers/usb/serial,重新編譯內核,生成zImage鏡像,然后下載到板子上。完成3G模塊驅動的設計以及內核對PPP協議的支持,對于撥號上網應用程序的支持,主要是通過PPP提供的兩個工具pppd和chat來實現的,其中PPP提供了一種點對串行線路上傳輸數據流的方法,chat主要用于撥號并等待提示。可從網上下載PPP源碼,在本系統中采用的版本為PPP-2.4.0,下載后要解壓并且根據目標板的類型來進行交叉編譯得到撥號程序。
3 、結束語
本文在一塊ARM開發板上實現了多種功能,包括無線數據視頻終端,通過外接視頻服務器實現了現有視頻服務器的3G功能擴展,通過采用了Netfilter與socket結合的方法,將數據包獲取功能從用戶態載入Linux內核態,避免了數據的內存拷貝,提高了處理效率,同時引入內核緩沖機制。解決了3G撥號延時而造成的視頻服務器丟包問題,配合Netfilter用戶工具iptables的使用,可以在本系統上實現NAT,包過濾防火墻等功能。方便對流經系統數據包的管理。
針對目前市場上的3G模塊大多只提供Windows CE下驅動這一問題,開發了3G模塊驅動,使得現有3G模塊可使用與嵌入式Linux系統下,用戶可直接在此基礎上通過socket進行編程,而無需考慮底層的硬件通信問題。在軟件設計上充分發揮開源軟件的優勢,采用Xvideore進行視頻編碼,以及PPP源碼編譯撥號軟件等,縮短了系統開發周期,系統在軟件的整體設計上提出了一套相對通用的軟件架構,可方便實現功能的擴展及升級。
責任編輯:gt
評論
查看更多