下面將給出Hi3559AV100外接UVC/MJPEG相機實時採圖設計的總體流程,主要實現是經過V4L2接口將UVC/MJPEG相機採集的數據送入至MPP平臺,通過VDEC、VPSS、VO最後經過HDMI的輸出,給出(二)V4L2接口的實現。html
能夠先參照前面隨筆介紹(一)Linux USB攝像頭驅動加載與分析:https://www.cnblogs.com/iFrank/p/14399421.htmllinux
板載平臺:BOXER-8410AIgit
芯片型號:Hi3559AV100編程
相機型號:Logitch c270ubuntu
開發環境:VM15.5+ubuntu16.04+Hilinux緩存
V4L2是Video for linux2的簡稱,爲linux中關於視頻設備的內核驅動。在Linux中,視頻設備是設備文件,能夠像訪問普通文件同樣對其進行讀寫,攝像頭在/dev/video*下,若是隻有一個視頻設備,一般爲/dev/video0。V4L2是內核提供給應用程序訪問音、視頻驅動的統一接口。V4L2 的相關定義包含在頭文件<linux/videodev2.h> 中。數據結構
IOCTL的實現V4L2的控制ide
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
動態視頻採集流程:
部分代碼實現:
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對應惟一結構體
我板載上裝的是Logitch c270攝像頭,從攝像頭支持的圖像像素輸出的信息能夠看出,在Hi3559板載上能夠支持2種像素格式,這裏選用的是V4L2_PIX_FMT_YUV422 格式。從生成image的大小能夠判斷出是正確的(YUV422數據大小 = 長 * 寬 * 1.5 = 640 * 480 * 2 = 614400 bytes = 600k)能夠將image文件拷出來,使用pYUV 軟件查看YUV圖片。這裏須要注意,使用pYUV 查看YUV圖片的時候,須要正確設置圖片格式,按我上面代碼採集的數據格式,最後一幀圖片輸出結果以下:
以後隨筆將推出結合MPP平臺實現視頻流的輸出。
問題:
在虛擬機上,腳本運行正常,可是會卡在視頻採集處,我的認爲是虛擬機的緩存問題,而板載緩存比較充足,因此可以很好實現。