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