基於嵌入式linux和s32410平台的視頻採集續

來源:互聯網
上載者:User
在USB網路攝影機被驅動後,只需要再編寫一個對視頻流採集的應用程式就可以了。根據嵌入式系統開發特徵,先在宿主機上編寫應用程式,再使用交叉編譯器進行編譯連結,產生在目標平台的可執行檔。宿主機與目標板通訊採用列印終端的方式進行交叉調試,成功後移植到目標平台。本文編寫採集程式是在安裝
Linux作業系統的宿主機PC機上進行的,下面是具體論述。
  (1)程式中定義的資料結構
  struct voide_capability grab_cap;
  struct voide_picture grab_pic;
  struct voide_mmap grab_buf;
  struct voide_mbuf grab_vm;
  這些資料結構都是由Video4Linux支援的,它們的用途如下:
  *video_capability包含網路攝影機的基本資料,例如裝置名稱、支援的最大最小解析度、訊號源資訊等,分別對應著結構體中成員變數
name[32]、maxwidth、maxheight、minwidth、minheight、channels(訊號源個數)、type等;
  *voide_picture包含裝置採集映像的各種屬性,如brightness(亮度)、hue(色調)、contrast(對比)、whiteness(色度)、depth(深度)等;
  *video_mmap用於記憶體映射;
  *voido_mbuf利用mmap進行映射的幀資訊,實際上是輸入到網路攝影機儲存空間緩衝 中的幀資訊,包括size(幀的大小)、frames(最多支援的幀數)、offsets(每幀相對基址的位移)。
  程式中用到的主要系統調用函數有:open("/dev/voideo0",int
flags)、close(fd)、mmap(void *start,size_t length,int prot,int flags,int
fd,off_t offset)、munmap(void *start,size_tlength)和ioctl(int fd,int
cmd,…)。
  前面提到Linux系統中把裝置看成裝置檔案,在使用者空間可以通過標準的I/O系統調用函數操作裝置檔案,從而達到與裝置通訊互動的目的。當然,在裝置驅動中要提供對這些函數的相應支援。這裡說明一下ioctl(int
fd,int
cmd,…)函數,它在使用者程式中用來控制I/O通道,其中,fd代表裝置檔案描述符,cmd代表使用者程式對裝置的控制命令,省略符號一般是一個表示類型長度的參數,也可沒有。
  (2)採集程式實現過程
  首先開啟視頻裝置,網路攝影機在系統中對應的裝置檔案為/dev/video0,採用系統調用函數grab_fd=open
("/dev/video0",O_RDWR),grab_fd是裝置開啟後返回的檔案描述符(開啟錯誤返回-1),以後的系統調用函數就可使用它來對裝置檔案進行操作了。接著,利用ioct1(grab_fd,VIDIOCGCAP,&grab_cap)函數讀取struct
video_capability中有關網路攝影機的資訊。該函數成功返回後,這些資訊從核心空間拷貝到使用者程式空間grab_cap各成員分量中,使用
printf函數就可得到各成員分量資訊,例如printf("maxheight=%d",grab_fd.maxheight)獲得最大垂直解析度的大小。不規則用ioct1(grab_fd,VIDIOCGPICT,&grab_pic)函數讀取網路攝影機緩衝中voideo_picture資訊。在使用者空間程式中可以改變這些資訊,具體方法為先給分量賦新值,再調用VIDIOCSPICT
ioct1函數,例如:
  grab_fd.depth=3;
  if(ioct1(grab_fd,VIDIOCSPICT,&grab_pic)<0)
  {perror("VIDIOCSPICT");return -1;};
  完成以上初始化裝置工作後,就可以對視頻映像截取了,有兩種方法:一種  是read()直接讀取;另外一種mmap()記憶體映射。Read
()通過核心緩衝區來讀取資料;而mmap()通過把裝置檔案對應到記憶體中,繞過了核心緩衝區,最快的磁碟訪問往往還是慢於最慢的記憶體訪問,所以mmap
()方式加速了I/O訪問。另外,mmap()系統調用使得進程之間通過映射同一檔案實現共用記憶體,各進程可以像訪問普通記憶體一樣對檔案進行訪問,訪問時只需要使用指標而不用調用檔案操作函數。因為mmap()的以上優點,所以在程式實現中採用了記憶體映射方式,即mmap()方式。
  利用mmap()方式視頻裁取具體進行操作如下。
  ①先使用ioct1(grab_fd,VIDIOCGMBUF,&grab_vm)函數獲得網路攝影機儲存緩衝區的幀資訊,之後修改voideo_mmap中的設定,例如重新設定映像幀的垂直及水平解析度、彩色顯示格式。可利用如下語句
  grab_buf.height=240;
  grab_buf.width=320;
  grab_buf.format=VIDEO_PALETTE_RGB24; 
  ②接著把網路攝影機對應的裝置檔案對應到記憶體區,具體使用grab_data=(unsigned
char*)mmap(0,grab_vm.size,PROT_READ|PROT_WRITE,MAP_SHARED,grad_fd,0)操作。這樣裝置檔案的內容就映射到記憶體區,該映射內容區可讀可寫並且不同進程間可共用。該函數成功時返回映像記憶體區的指標,挫敗時傳回值為-1。
  下面對單幀採集和連續幀採集進行說明:
  *單幀採集。在上面擷取的網路攝影機儲存緩衝區幀資訊中,最多可支援的幀數(frames的值)一般為兩幀。對於單幀採集只需設定
grab_buf.frame=0,即採集其中的第一幀,使用ioctl(grab_fd,VIDIOCMCAPTURE,&grab_buf)
函數,若調用成功,則啟用裝置真正開始一幀映像的截取,是非阻塞的。接著使用ioct1(grab_fd,VIDIOCSYNC,&frame)
函數判斷該幀映像是否截取完畢,成功返回表示截取完畢,之後就可把映像資料儲存成檔案的形式。
  *連續幀採集。在單幀的基礎上,利用grab_fd.frames值確定採集完畢網路攝影機框架緩衝區幀資料進行迴圈的次數。在迴圈語句中,也是使用
VIDIOCMCCAPTURE ioct1和VIDIOCSYNC
ioctl函數完成每幀截取,但要給採集到的每幀映像賦地址,利用語句buf=grab_data+grab_vm.offsets[frame],然後儲存檔案的形式。若要繼續採集可再加一個外迴圈,在外迴圈語句只要給原來的內迴圈再賦frame=0即可。
  4 小結
  筆者最後在宿主機PC上使用交叉編譯器編譯連結連續幀採集程式(以雙幀採集為例並儲存成bmp檔案檔案形式)使之產生可執行代碼,並完成了向目標平台的移植。為了進一步觀察採集的映像效果,筆者在目標平台帶網路支援的基礎上,編寫了一個簡單的網路通訊程式,把採集到並儲存為bmp的影像檔通過網路傳輸到PC機上進行顯示,把採集到並儲存為bmp的影像檔通過網路傳輸到PC機上進行顯示,通過對效果的分析,再回到採集程式中重新設定
video_picture中的資訊,如亮度、對比等和voide_mmap中的解析度,重新移植以達到最好效果為準。
  嵌入式系統平台上,應用本文所述方法完成視頻採集工作,再加上相關的視頻處理並接入網路,就構成了一個智能終端裝置,可用於工廠、銀行及小區等場合全天候的智能監控,具有廣闊的市場和應用前景.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.