基于V4L2視頻采集緩存機制應用與實現
這些函數原型一般定義在include/linux/videodev2.h或者videodev.h中。
視頻采集的具體過程描述如下:
(1)打開設備。通過open()函數打開設備文件,返回文件描述符。
(2)初始化設備。首先通過VIDIOC_QUERYCAP查詢設備屬性,判斷該設備是否為一個合法的視頻采集設備,并確定其支持的功能有哪些;然后通過 VIDIOC_S_FMT設置圖像的格式,例如圖像的大小等;通過VIDIOC_REQBUFS和malloc()分別在內核空間和用戶空間分配內存緩沖區(qū);最后通過mmap()函數進行內存映射。
(3)圖像采集循環(huán)。首先通過VIDIOC_QBUF將空緩沖區(qū)移入待處理隊列,準備接收圖像數據;然后通過VIDIOC_QBUF將滿緩沖區(qū)移出已處理隊列,進行圖像的顯示和處理;最后通過VIDIOC_STREAMON和VIDIOC_STREAMOFF啟動和停止采集。
(4)關閉設備。通過close()函數關閉設備文件。
2 雙幀緩存數據傳輸
在視頻采集中,首先在內核空間建立2個圖像緩沖區(qū),不斷將采集到的圖像存放到緩沖區(qū)中。當應用程序需要圖像時,驅動程序并不做拷貝操作,而是建立內核緩沖區(qū)到用戶空間的映射,也就是利用mmap()函數,存取其返回的指針,相當于存取內核中的圖像緩沖區(qū)。由于不需要做額外的復制操作,效率大大提高了,圖像采集流程如圖1所示。
具體說明如下:
(1)程序首先使用VIDIOC_REQBUFS向驅動程序請求圖像緩沖區(qū),v412_requestbuffers結構體包含了所要求緩沖區(qū)的類型及數量,但驅動程序有權決定最后返回的數量,因此程序仍需要使用系統(tǒng)返回的緩沖區(qū)數量,在這里程序返回2個緩沖區(qū)。
(2)由于緩沖區(qū)數量有2個,調用2次mmap()建立起用戶空間和內核空間緩沖區(qū)的對應關系,然后讀取mmap()所返回的指針就相當于讀取圖像緩沖區(qū)。
(3)此時驅動程序仍然不能對圖像緩沖區(qū)做讀取,調用2次VIDIOC_QBUF ioctl將緩沖區(qū)加入到驅動程序內部的采集序列,之后采集的圖像就會被儲存到這些緩沖區(qū)內。
(4)調用VIDIOC_STREAM ioctl后,驅動程序開始采集圖像,并將圖像放置到緩沖區(qū)內。
(5)雖然緩沖區(qū)內已經存放有圖像了,但直接去讀取某個緩沖區(qū)還是需要非常小心的,因為緩沖區(qū)仍然在驅動程序的圖像采集序列中,有可能讀取到一半,驅動程序又使用該緩沖區(qū)儲存新的圖像,而圖1中的(5)是最后調用VIDIOC_STREAMOFF,以停止圖像采集,此時驅動程序會自動將所有緩沖區(qū)從圖像采集序列中移除,所以不需要手動調用VIDIOC_DQBUF,接著使用munmap()清除所有的存儲區(qū)映射導致圖像前后不一致。因此要在讀取緩沖區(qū)前,先調用VIDIOC_DQBUG ioctl,通知驅動程序不要使用此緩沖區(qū),在這個階段中,通常是以如圖2所示的順序來讀取每個緩沖區(qū)的。
評論