1 引言編程
多媒體通訊技術的發展爲信息的獲取和傳輸提供了豐富的手段,視頻採集是其中不可缺乏的重要組成部分。視頻採集的手段多種多樣,隨着人們對下降系統成本和提升可靠性的迫切需求,基於嵌入式的視頻採集系統成爲新的研發熱點。本方案以S3C2410微控制器做爲硬件平臺,經過移植具備實現硬件功能的Linux操做系統,實現了對視頻數據的實時採集和存儲。網絡
2 系統數據結構
構成系統平臺採用三星公司的處理器S3C2410,該處理器內部集成了ARM920T處理器核,爲32位微控制器,帶獨立的16KB指令Cache和16KB數據Cache,LCD控制器,RAM控制器,NANDFlash控制器,並行I/O口,8路10位ADC,主頻最高可達203MHz。在處理器豐富資源的基礎上進行了相關的配置和擴展,平臺配置了64Mbytes8位的NAND閃存和64Mbytes32位的SDRAM,經過以太網控制器芯片CS8900A擴展了一個網口,另外引出一個串行接口和兩個HOST/DEVICEUSB接口。經過在USB接口上外接一個USB攝像頭,將採集到的視頻圖像數據放入存儲器緩衝區中,或者用JPEG壓縮處理程序處理緩衝區的圖像數據並保存,數據可存儲在NAND閃存中等待遠程主機的訪問,也可經過CS8900A擴展的網絡接口將視頻數據直接發送到遠程網中的控制主機上。圖1爲系統的硬件圖,其中USB口接數碼攝像頭,串口、網口做爲輸入輸出設備,NAND閃存和SDRAM做爲存儲設備,JTAG口用來把嵌入式Linux操做系統和應用程序燒寫進Flash存儲器。ide
圖1視頻採集系統硬件框圖模塊化
3 嵌入式Linux概述Linux具備內核小,效率高,源代碼開放,微內核直接提供網絡支持等優勢。在中低端嵌入式網絡設備的應用中,比起VxWorks等其餘操做系統有許多優點,逐漸成爲嵌入式操做系統的主流。但嵌入式系統的硬件資源畢竟有限,不能直接將其做爲嵌入式硬件平臺上的操做系統,須要針對具體的應用進行內核的配置和裁減,使整個系統可以存放到容量較小的Flash中。Linux的動態模塊加載方式使Linux的裁剪極爲方便,高度模塊化使得添加和刪減很是容易。函數
系統採用交叉編譯調試,PC機做爲宿主機,對應的嵌入式系統平臺叫作目標板。嵌入式Linux提供了一套完整的工具鏈(toolchain),它利用GNU的gCC作編譯器,用gdb、xgdb作調試工具,可以很方便地實現從操做系統內核到用戶態應用軟件各個級別的調試。嵌入式Linux的移植過程如圖2所示,在此不做具體闡述。工具
圖2Linux系統開發流程圖測試
4 軟件設計操作系統
4.1 攝像頭驅動在Linux環境下,全部的外設都被當作一類稱爲「設備文件」的特殊文件,系統中全部硬件均可以用一個特殊的設備文件來表示。在本系統中,USB攝像頭被做爲一種字符設備來對待,用/dev/video0來表示。相對於應用程序來說,硬件是不透明的,設備驅動程序屏蔽了硬件在實現上的細節,應用程序必須依靠相應驅動程序中定義的通訊接口實現對硬件的操做。設計
Video4Linux(簡稱V4L)是Linux系統關於視頻設備的內核驅動程序,它爲針對視頻設備的應用程序編程提供一系列接口函數。對於USB接口攝像頭,驅動程序中提供了基本的I/O操做接口函數open、read、write、close的實現,對中斷的處理實現,內存映射功能以及對I/O通道的控制接口函數ioctl的實現等,並在structfile_operations數據結構中定義了這些函數,當應用程序對設備文件進行例如read、write等操做時,嵌入式Linux內核經過strcutfile_operations數據結構訪問驅動程序提供的函數。
驅動程序基本結構以下:
1)驅動的註冊與註銷經過在驅動程序的初始化過程當中調用register_chrdev()或register_blkdev()函數來添加驅動程序並分配主設備號;經過調用unregister_chrdev()或unregister_blkdev()函數從內核中註銷設備,同時釋放其佔用的主設備號。
2)設備文件的打開與釋放調用file_operations結構體中的Open()函數打開設備;調用file_operations結構中的函數release()關閉設備。
3)設備的讀/寫操做使用函數read()和write()完成對設備的讀和寫。
4)設備的控制操做經過設備驅動程序中的函數ioctl()來完成。ioctl()的用法與具體設備密切關聯,所以須要根據設備的狀況進行具體分析。
5)設備的中斷和輪流查詢處理因爲有些硬件設備不支持中斷,那麼在對其讀寫時須要輪流查詢設備狀態,以便決定是否繼續進行數據傳輸。若是硬件設備支持中斷,則能夠按中斷方式進行操做。
4.2 視頻採集在USB攝像頭驅動被加載成功後,還要編寫視頻流採集應用程序。攝像頭中各類I/O口的控制依靠Video4Linux提供的應用程序接口函數實現,主要有Open、Read、Write等。V4L下的視頻採集工做原理如圖3。在本系統中,將有關攝像頭的各類數據和結構封裝成了一個類。
圖3V4L下視頻採集工做模型
4.2.1 Video4Linux定義的數據結構structvideo_capabilitycapability:包含攝像頭設備的基本信息(設備名稱、支持的最大最小分辨率、信號源信息等),分別對應着結構體中成員變量name[32],maxwidth,maxheight,minwidth,minheight,channels(信號源個數),type等。
structvideo_windowwindow:包含採集到圖像的各類屬性,如brightness(亮度)、hue(色調)、color(顏色)、contrast(對比度)、whiteness(色度)、depth(深度)等。
structvideo_channelchannel:關於各個信號源的屬性,如channel(信號源編號)、name(名稱)、tuners(信號源通道)、type(類型)、Norm(制式)等。
structvideo_picturepicture:包含關於capturearea的信息。
structvideo_mmapmmap:用於內存映射。
structvideo_mbuFMbuf:利用mmap進行映射的幀信息,即輸入到攝像頭存儲緩衝區中的幀信息,包括size(幀的大小)、frames(最多支持的幀數)、offsets(每幀相對基址的偏移)。
在本系統中,程序主要用到的一些系統調用函數以下:open(「/dev/video0」,O_RDWR):設備的打開。
close(fd):設備的關閉。
mmap(voidaddr,size_tlen,intprot,intflags,intfd,off_toffset):設備緩衝區到內存空間的映射。
munmap(voidaddr,size_tlen):採集工做結束後取消mmap和mbuf的綁定。
ioctl(intfd,iNTCmd,。。。):控制I/O通道。
4.2.2視頻採集程序的實現
1)打開攝像頭首先對上面提到的類進行初始化,接下來利用系統調用函數_fd=open(「devfile」,O_RDWR),該函數的功能是打開參數devfile指定的設備,對於攝像頭用設備文件名「/dev/video0」表示,_fd是設備打開後返回的文件描述符,之後能夠直接使用它來對設備文件進行操做。
2)獲取攝像頭參數經過ioctl(_fd,VIDIOCGCAP,&capability)函數來讀取structvideo_capability結構中有關攝像頭的信息。ioctl(int_fd,intcmd,。。。)主要是用來控制I/O通道,函數成功返回後使用printf函數獲得各成員份量信息,接着調用ioctl(_fd,VIDIOCGWIN,&window)和ioctl(_fd,VIDIOCGPICT,&picture)函數讀取structvideo_window信息和攝像頭緩衝區中的video_picture圖像信息。
3)設置攝像頭緩衝區中圖像參數在採集攝像頭視頻數據前,可根據需求修改圖像參數如分辨率等,具體方法爲先給份量賦新值,再調用函數ioctl(_fd,VIDIOCSPICT,&picture)。
4)視頻數據的讀取與read()方式相比,mmap()方式經過把設備文件映射到內存,繞過了內核緩衝區,加速了I/O訪問。完成內存映射以後,就能夠用mmap()方式實現對內存映射區域視頻數據的單幀採集。此方式下真正作視頻截取的爲VIDIOCMCAPTURE,調用函數ioctl(_fd,VIDIOCMCAPTURE,&mmap),激活設備並真正開始一幀圖像的截取,是非阻塞的,接着調用ioctl(_fd,VIDIOCSYNC,&frame)函數等待一幀圖像截取結束,成功返回表示一幀截取已完成,接着能夠作下一次的VIDIOCMCAPTURE操做。
通過上述的幾個過程,系統完成了對USB攝像頭的驅動、對視頻數據的採集工做,捕獲到的視頻幀被映射到內存區域,若是要對視頻數據進行壓縮等處理工做則可經過訪問內存映射區域進行。
5 結語
做爲網絡視頻監控系統的一部分,本方案基於目前市場上主流的ARM處理器與嵌入式Linux操做系統,實現了視頻數據的實時採集,整個系統數字化、網絡化程度高,與傳統的採集系統相比有較大優點。經辦公室局域網測試,該系統實時性好、穩定可靠、圖像質量也比較優越,可普遍應用在交通、銀行、工業監控及視頻會議等衆多領域。目前該項目產生的經濟效益約爲20萬元。
本文做者創新點:設計了一個基於嵌入式Linux的視頻採集系統,詳細介紹了Video4Linux下USB攝像頭驅動和視頻採集程序的實現過程。