下面將給出Hi3559AV100外接UVC/MJPEG相機實時采圖設計的整體流程,主要實作是通過V4L2介面將UVC/MJPEG相機采集的資料送入至MPP平臺,經過VDEC、VPSS、VO最后通過HDMI的輸出,給出(二)V4L2介面的實作,
可以先參照前面隨筆介紹(一)Linux USB攝像頭驅動加載與分析:https://www.cnblogs.com/iFrank/p/14399421.html
板載平臺:BOXER-8410AI
芯片型號:Hi3559AV100
相機型號:Logitch c270
開發環境:VM15.5+ubuntu16.04+Hilinux
1、V4L2介面說明
V4L2是Video for linux2的簡稱,為linux中關于視頻設備的內核驅動,在Linux中,視頻設備是設備檔案,可以像訪問普通檔案一樣對其進行讀寫,攝像頭在/dev/video*下,如果只有一個視頻設備,通常為/dev/video0,V4L2是內核提供給應用程式訪問音、視頻驅動的統一介面,V4L2 的相關定義包含在頭檔案<linux/videodev2.h> 中,
V4L2 支持兩種方式來采集影像:記憶體映射(mmap)和直接讀取方式(read),V4L2 在/usr/include/linux/videodev2.h 檔案下定義了一些重要的資料結構,在采集影像的程序中,就是通過對這些資料的操作來獲得最終的影像資料,Linux 系統 V4L2 使能可在內核編譯階段配置,默認情況下是在 make menuconfig 是打開的,應用程式可以通過 V4L2 進行視頻采集,V4L2 支持記憶體映射(mmap)方式和直接讀取方式(read)方式采集資料,前者 一般用于連續的視頻資料采集,后者常用靜態圖片資料采集,v4l2 中不僅定義了通用 API 元素,影像的格式,輸入/輸出方法,還定義了Linux 內核驅動處理視頻資訊的一系列介面,這些介面主要有: 視頻采集介面——Video Capture interface; 視頻輸出介面——Video Output Interface; 視頻覆寫/預覽介面——Video Overlay Interface; 視頻輸出覆寫介面——Video Output Overlay Interface; 編解碼介面——Codec InterfaceIOCTL的實作V4L2的控制
打開視頻設備后,可以設定該視頻設備的屬性,例如裁剪、縮放等,這一步是可選的,在Linux編程中,一般使用ioctl函式來對設備的I/O通道進行管理: extern int ioctl (int __fd, unsigned long int __request, …) __THROW; __fd:設備的ID,例如剛才用open函式打開視頻通道后回傳的cameraFd; __request:具體的命令標志符, 在進行V4L2開發中,一般會用到以下的命令標志符:1:分配記憶體 2 VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的資料快取轉換成物理地址 3 VIDIOC_QUERYCAP:查詢驅動功能 4 VIDIOC_ENUM_FMT:獲取當前驅動支持的視頻格式 5 VIDIOC_S_FMT:設定當前驅動的頻捕獲格式 6 VIDIOC_G_FMT:讀取當前驅動的頻捕獲格式 7 VIDIOC_TRY_FMT:驗證當前驅動的顯示格式 8 VIDIOC_CROPCAP:查詢驅動的修剪能力 9 VIDIOC_S_CROP:設定視頻信號的邊框 10 VIDIOC_G_CROP:讀取視頻信號的邊框 11 VIDIOC_QBUF:把資料放回快取佇列 12 VIDIOC_DQBUF:把資料從快取中讀取出來 13 VIDIOC_STREAMON:開始視頻顯示函式 14 VIDIOC_STREAMOFF:結束視頻顯示函式 15 VIDIOC_QUERYSTD:檢查當前視頻設備支持的標準,例如PAL或NTSC,
這些IO呼叫,有些是必須的,有些是可選擇的,其命令標志符在在頭檔案<linux/videodev2.h> 定義,具體如下:
1 #define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability) 2 #define VIDIOC_RESERVED _IO('V', 1) 3 #define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc) 4 #define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) 5 #define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format) 6 #define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers)
Logitch c270支持的像素格式有兩種:
1 YUYV 4:2:2 2 Motion-JPEG
2、V4L2的實作流程
一般來說V4L2 采集視頻資料分為五個步驟: 首先,打開視頻設備檔案,進行視頻采集的引數初始化,通過 V4L2 介面設定視頻影像的采集視窗、采集的點陣大小和格式; 其次,申請若干視頻采集的幀緩沖區,并將這些幀緩沖區從內核空間映射到用戶空間,便于應用程式讀取/處理視頻資料; 第三,將申請到的幀緩沖區在視頻采集輸入佇列排隊,并啟動視頻采集; 第四,驅動開始視頻資料的采集,應用程式從視頻采集輸出佇列取出幀緩沖區,處理完后,將幀緩沖區重新放入視頻采集輸入佇列,回圈往復采 集連續的視頻資料; 第五,停止視頻采集,在本次設計中,定義了幾個函式實作對攝像頭的配置和采集, 一幀圖片采集流程:
動態視頻采集流程:
部分代碼實作:
1 /*打開視頻*/ 2 if ((fd = open(FILE_VIDEO, O_RDWR)) == -1) 3 { 4 printf("Error opening V4L interface\n"); 5 return (FALSE); 6 } 7 8 /*讀video_capability中資訊, 9 通過呼叫IOCTL函式和介面命令VIDIOC_QUERYCAP查詢 10 攝像頭的資訊*/ 11 if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) 12 { 13 printf("Error opening device %s: unable to query device.\n",FILE_VIDEO); 14 return (FALSE); 15 } 16 else 17 { 18 printf("driver:\t\t%s\n",cap.driver); 19 printf("card:\t\t%s\n",cap.card); 20 printf("bus_info:\t%s\n",cap.bus_info); 21 printf("version:\t%d\n",cap.version); 22 printf("capabilities:\t%x\n",cap.capabilities); 23 24 /*其中capabilities: 4000001通過與各種宏位與, 25 可以獲得物理設備的功能屬性*/ 26 if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE) 27 { 28 printf("Device %s: supports capture.\n",FILE_VIDEO); 29 } 30 31 if ((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING) 32 { 33 printf("Device %s: supports streaming.\n",FILE_VIDEO); 34 } 35 } //VIDIOC_QUERYCAP對應唯一結構體
3、V4L2測驗(640×480像素一幀圖片輸出)
我板載上裝的是Logitch c270攝像頭,從攝像頭支持的影像像素輸出的資訊可以看出,在Hi3559板載上可以支持2種像素格式,這里選用的是V4L2_PIX_FMT_YUV422 格式,從生成image的大小可以判斷出是正確的(YUV422資料大小 = 長 * 寬 * 1.5 = 640 * 480 * 2 = 614400 bytes = 600k)可以將image檔案拷出來,使用pYUV 軟體查看YUV圖片,這里需要注意,使用pYUV 查看YUV圖片的時候,需要正確設定圖片格式,按我上面代碼采集的資料格式,最后一幀圖片輸出結果如下:

之后隨筆將推出結合MPP平臺實作視頻流的輸出,
問題:

在虛擬機上,腳本運行正常,但是會卡在視頻采集處,個人認為是虛擬機的快取問題,而板載快取比較充足,所以能夠很好實作,
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/259950.html
標籤:其他
