基于V4L2視頻采集緩存機制應用與實(shí)現
這些函數原型一般定義在include/linux/videodev2.h或者videodev.h中。
視頻采集的具體過(guò)程描述如下:
(1)打開(kāi)設備。通過(guò)open()函數打開(kāi)設備文件,返回文件描述符。
(2)初始化設備。首先通過(guò)VIDIOC_QUERYCAP查詢(xún)設備屬性,判斷該設備是否為一個(gè)合法的視頻采集設備,并確定其支持的功能有哪些;然后通過(guò) VIDIOC_S_FMT設置圖像的格式,例如圖像的大小等;通過(guò)VIDIOC_REQBUFS和malloc()分別在內核空間和用戶(hù)空間分配內存緩沖區;最后通過(guò)mmap()函數進(jìn)行內存映射。
(3)圖像采集循環(huán)。首先通過(guò)VIDIOC_QBUF將空緩沖區移入待處理隊列,準備接收圖像數據;然后通過(guò)VIDIOC_QBUF將滿(mǎn)緩沖區移出已處理隊列,進(jìn)行圖像的顯示和處理;最后通過(guò)VIDIOC_STREAMON和VIDIOC_STREAMOFF啟動(dòng)和停止采集。
(4)關(guān)閉設備。通過(guò)close()函數關(guān)閉設備文件。
2 雙幀緩存數據傳輸
在視頻采集中,首先在內核空間建立2個(gè)圖像緩沖區,不斷將采集到的圖像存放到緩沖區中。當應用程序需要圖像時(shí),驅動(dòng)程序并不做拷貝操作,而是建立內核緩沖區到用戶(hù)空間的映射,也就是利用mmap()函數,存取其返回的指針,相當于存取內核中的圖像緩沖區。由于不需要做額外的復制操作,效率大大提高了,圖像采集流程如圖1所示。

具體說(shuō)明如下:
(1)程序首先使用VIDIOC_REQBUFS向驅動(dòng)程序請求圖像緩沖區,v412_requestbuffers結構體包含了所要求緩沖區的類(lèi)型及數量,但驅動(dòng)程序有權決定最后返回的數量,因此程序仍需要使用系統返回的緩沖區數量,在這里程序返回2個(gè)緩沖區。
(2)由于緩沖區數量有2個(gè),調用2次mmap()建立起用戶(hù)空間和內核空間緩沖區的對應關(guān)系,然后讀取mmap()所返回的指針就相當于讀取圖像緩沖區。
(3)此時(shí)驅動(dòng)程序仍然不能對圖像緩沖區做讀取,調用2次VIDIOC_QBUF ioctl將緩沖區加入到驅動(dòng)程序內部的采集序列,之后采集的圖像就會(huì )被儲存到這些緩沖區內。
(4)調用VIDIOC_STREAM ioctl后,驅動(dòng)程序開(kāi)始采集圖像,并將圖像放置到緩沖區內。
(5)雖然緩沖區內已經(jīng)存放有圖像了,但直接去讀取某個(gè)緩沖區還是需要非常小心的,因為緩沖區仍然在驅動(dòng)程序的圖像采集序列中,有可能讀取到一半,驅動(dòng)程序又使用該緩沖區儲存新的圖像,而圖1中的(5)是最后調用VIDIOC_STREAMOFF,以停止圖像采集,此時(shí)驅動(dòng)程序會(huì )自動(dòng)將所有緩沖區從圖像采集序列中移除,所以不需要手動(dòng)調用VIDIOC_DQBUF,接著(zhù)使用munmap()清除所有的存儲區映射導致圖像前后不一致。因此要在讀取緩沖區前,先調用VIDIOC_DQBUG ioctl,通知驅動(dòng)程序不要使用此緩沖區,在這個(gè)階段中,通常是以如圖2所示的順序來(lái)讀取每個(gè)緩沖區的。
評論