V4L2驅(qū)動(dòng)的移植與應(yīng)用(二).doc_第1頁
V4L2驅(qū)動(dòng)的移植與應(yīng)用(二).doc_第2頁
V4L2驅(qū)動(dòng)的移植與應(yīng)用(二).doc_第3頁
V4L2驅(qū)動(dòng)的移植與應(yīng)用(二).doc_第4頁
V4L2驅(qū)動(dòng)的移植與應(yīng)用(二).doc_第5頁
已閱讀5頁,還剩1頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

二、V4L2的應(yīng)用下面簡單介紹一下V4L2驅(qū)動(dòng)的應(yīng)用流程。1、 視頻采集的基本流程一般的,視頻采集都有如下流程:2、 打開視頻設(shè)備在V4L2中,視頻設(shè)備被看做一個(gè)文件。使用open函數(shù)打開這個(gè)設(shè)備:/ 用非阻塞模式打開攝像頭設(shè)備int cameraFd;cameraFd = open(/dev/video0, O_RDWR | O_NONBLOCK, 0);/ 如果用阻塞模式打開攝像頭設(shè)備,上述代碼變?yōu)椋?cameraFd = open(/dev/video0, O_RDWR, 0);關(guān)于阻塞模式和非阻塞模式:應(yīng)用程序能夠使用阻塞模式或非阻塞模式打開視頻設(shè)備,如果使用非阻塞模式調(diào)用視頻設(shè)備,即使尚未捕獲到信息,驅(qū)動(dòng)依舊會(huì)把緩存(DQBUFF)里的東西返回給應(yīng)用程序。3、 設(shè)定屬性及采集方式打開視頻設(shè)備后,可以設(shè)置該視頻設(shè)備的屬性,例如裁剪、縮放等。這一步是可選的。在Linux編程中,一般使用ioctl函數(shù)來對(duì)設(shè)備的I/O通道進(jìn)行管理:extern int ioctl (int _fd, unsigned long int _request, .) _THROW;_fd:設(shè)備的ID,例如剛才用open函數(shù)打開視頻通道后返回的cameraFd;_request:具體的命令標(biāo)志符。在進(jìn)行V4L2開發(fā)中,一般會(huì)用到以下的命令標(biāo)志符:VIDIOC_REQBUFS:分配內(nèi)存 VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的數(shù)據(jù)緩存轉(zhuǎn)換成物理地址 VIDIOC_QUERYCAP:查詢驅(qū)動(dòng)功能 VIDIOC_ENUM_FMT:獲取當(dāng)前驅(qū)動(dòng)支持的視頻格式 VIDIOC_S_FMT:設(shè)置當(dāng)前驅(qū)動(dòng)的頻捕獲格式 VIDIOC_G_FMT:讀取當(dāng)前驅(qū)動(dòng)的頻捕獲格式 VIDIOC_TRY_FMT:驗(yàn)證當(dāng)前驅(qū)動(dòng)的顯示格式 VIDIOC_CROPCAP:查詢驅(qū)動(dòng)的修剪能力 VIDIOC_S_CROP:設(shè)置視頻信號(hào)的邊框 VIDIOC_G_CROP:讀取視頻信號(hào)的邊框 VIDIOC_QBUF:把數(shù)據(jù)從緩存中讀取出來 VIDIOC_DQBUF:把數(shù)據(jù)放回緩存隊(duì)列 VIDIOC_STREAMON:開始視頻顯示函數(shù) VIDIOC_STREAMOFF:結(jié)束視頻顯示函數(shù) VIDIOC_QUERYSTD:檢查當(dāng)前視頻設(shè)備支持的標(biāo)準(zhǔn),例如PAL或NTSC。 這些IO調(diào)用,有些是必須的,有些是可選擇的。4、 檢查當(dāng)前視頻設(shè)備支持的標(biāo)準(zhǔn)在亞洲,一般使用PAL(720X576)制式的攝像頭,而歐洲一般使用NTSC(720X480),使用VIDIOC_QUERYSTD來檢測(cè):v4l2_std_id std;do ret = ioctl(fd, VIDIOC_QUERYSTD, &std); while (ret = -1 & errno = EAGAIN);switch (std) case V4L2_STD_NTSC:/case V4L2_STD_PAL:/5、 設(shè)置視頻捕獲格式當(dāng)檢測(cè)完視頻設(shè)備支持的標(biāo)準(zhǔn)后,還需要設(shè)定視頻捕獲格式:struct v4l2_format fmt;memset ( &fmt, 0, sizeof(fmt) );fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt.fmt.pix.width = 720;fmt.fmt.pix.height = 576;fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;if (ioctl(fd, VIDIOC_S_FMT, &fmt) = -1) return -1;v4l2_format結(jié)構(gòu)體定義如下:struct v4l2_formatenum v4l2_buf_type type; / 數(shù)據(jù)流類型,必須永遠(yuǎn)是V4L2_BUF_TYPE_VIDEO_CAPTURE unionstruct v4l2_pix_format pix; struct v4l2_window win; struct v4l2_vbi_format vbi; _u8 raw_data200; fmt;struct v4l2_pix_format_u32 width; / 寬,必須是16的倍數(shù)_u32 height; / 高,必須是16的倍數(shù)_u32 pixelformat; / 視頻數(shù)據(jù)存儲(chǔ)類型,例如是YUV4:2:2還是RGBenum v4l2_field field;_u32 bytesperline; _u32 sizeimage;enum v4l2_colorspace colorspace;_u32 priv; ;6、 分配內(nèi)存接下來可以為視頻捕獲分配內(nèi)存:struct v4l2_requestbuffers req;if (ioctl(fd, VIDIOC_REQBUFS, &req) = -1) return -1;v4l2_requestbuffers定義如下:struct v4l2_requestbuffers_u32 count; / 緩存數(shù)量,也就是說在緩存隊(duì)列里保持多少張照片enum v4l2_buf_type type; / 數(shù)據(jù)流類型,必須永遠(yuǎn)是V4L2_BUF_TYPE_VIDEO_CAPTURE enum v4l2_memory memory; / V4L2_MEMORY_MMAP 或 V4L2_MEMORY_USERPTR_u32 reserved2;7、 獲取并記錄緩存的物理空間使用VIDIOC_REQBUFS,我們獲取了req.count個(gè)緩存,下一步通過調(diào)用VIDIOC_QUERYBUF命令來獲取這些緩存的地址,然后使用mmap函數(shù)轉(zhuǎn)換成應(yīng)用程序中的絕對(duì)地址,最后把這段緩存放入緩存隊(duì)列:typedef struct VideoBuffer void *start;size_t length; VideoBuffer;VideoBuffer* buffers = calloc( req.count, sizeof(*buffers) );struct v4l2_buffer buf;for (numBufs = 0; numBufs req.count; numBufs+) memset( &buf, 0, sizeof(buf) );buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;buf.index = numBufs;/ 讀取緩存if (ioctl(fd, VIDIOC_QUERYBUF, &buf) = -1) return -1;buffersnumBufs.length = buf.length;/ 轉(zhuǎn)換成相對(duì)地址buffersnumBufs.start = mmap(NULL, buf.length,PROT_READ | PROT_WRITE,MAP_SHARED,fd, buf.m.offset);if (buffersnumBufs.start = MAP_FAILED) return -1;/ 放入緩存隊(duì)列if (ioctl(fd, VIDIOC_QBUF, &buf) = -1) return -1;8、 關(guān)于視頻采集方式操作系統(tǒng)一般把系統(tǒng)使用的內(nèi)存劃分成用戶空間和內(nèi)核空間,分別由應(yīng)用程序管理和操作系統(tǒng)管理。應(yīng)用程序可以直接訪問內(nèi)存的地址,而內(nèi)核空間存放的是 供內(nèi)核訪問的代碼和數(shù)據(jù),用戶不能直接訪問。v4l2捕獲的數(shù)據(jù),最初是存放在內(nèi)核空間的,這意味著用戶不能直接訪問該段內(nèi)存,必須通過某些手段來轉(zhuǎn)換地址。一共有三種視頻采集方式:1)使用read、write方式:直接使用 read 和 write 函數(shù)進(jìn)行讀寫。這種方式最簡單,但是這種方式會(huì)在 用戶空間和內(nèi)核空間不斷拷貝數(shù)據(jù) ,同時(shí)在用戶空間和內(nèi)核空間占用 了 大量內(nèi)存,效率不高。2)內(nèi)存映射方式(mmap):把設(shè)備里的內(nèi)存映射到應(yīng)用程序中的內(nèi)存控件,直接處理設(shè)備內(nèi)存,這是一種有效的方式。上面的mmap函數(shù)就是使用這種方式。3)用戶指針模式:內(nèi)存由用戶空間的應(yīng)用程序分配,并把地址傳遞到內(nèi)核中的驅(qū)動(dòng)程序,然后由 v4l2 驅(qū)動(dòng)程序直接將數(shù)據(jù)填充到用戶空間的內(nèi)存中。這點(diǎn)需要在v4l2_requestbuffers里將memory字段設(shè)置成V4L2_MEMORY_USERPTR。第一種方式效率是最低的,后面兩種方法都能提高執(zhí)行的效率,但是對(duì)于mmap 方式,文檔中有這樣一句描述 -Remember the buffers are allocated in physical memory, as opposed to virtual memory which can be swapped out to disk. Applications should free the buffers as soon as possible with the munmap () function .(使用mmap方法的時(shí)候,buffers相當(dāng)于是在內(nèi)核空間中分配的,這種情況下,這些buffer是不能被交換到虛擬內(nèi)存中,雖然這種方法不怎么影響讀寫效率,但是它一直占用著內(nèi)核空間中的內(nèi)存,當(dāng)系統(tǒng)的內(nèi)存有限的時(shí)候,如果同時(shí)運(yùn)行有大量的進(jìn)程,則對(duì)系統(tǒng)的整體性能會(huì)有一定的影響。) 所以,對(duì)于三種視頻采集方式的選擇,推薦的順序是 userptr 、 mmap 、 read-write 。當(dāng)使用 mmap 或 userptr 方式的時(shí)候,有一個(gè)環(huán)形緩沖隊(duì)列的概念,這個(gè)隊(duì)列中,有 n 個(gè) buffer ,驅(qū)動(dòng)程序采集到的視頻幀數(shù)據(jù),就是存儲(chǔ)在每個(gè) buffer 中。在每次用 VIDIOC_DQBUF 取出一個(gè) buffer ,并且處理完數(shù)據(jù)后,一定要用 VIDIOC_QBUF 將這個(gè) buffer 再次放回到環(huán)形緩沖隊(duì)列中。環(huán)形緩沖隊(duì)列,也使得這兩種視頻采集方式的效率高于直接 read/write 。9、 處理采集數(shù)據(jù)V4L2有一個(gè)數(shù)據(jù)緩存,存放req.count數(shù)量的緩存數(shù)據(jù)。數(shù)據(jù)緩存采用FIFO的方式,當(dāng)應(yīng)用程序調(diào)用緩存數(shù)據(jù)時(shí),緩存隊(duì)列將最先采集到的 視頻數(shù)據(jù)緩存送出,并重新采集一張視頻數(shù)據(jù)。這個(gè)過程需要用到兩個(gè)ioctl命令,VIDIOC_DQBUF和VIDIOC_QBUF:struct v4l2_buffer buf;memset(&buf,0,sizeof(buf);buf.type=V4L2_BUF_TYPE_

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論