天天看點

攝像頭v4l2采集中的mmap

用法:

buffers[i].start = (unsigned char *)mmap(NULL,

cam->buf.length,

PROT_READ | PROT_WRITE,

MAP_SHARED,

cam->fd,

cam->buf.m.offset);

我的了解:将攝像頭看做一個大一點的傳感器,它能采集到值,那麼我們應用層通過攝像頭檔案描述符可以read核心驅動層的資料,資料從核心态轉為使用者态有一個copy_to_user過程,使用read這樣頻繁、大量的讀取圖像資料,就會進行大量的資料拷貝,如果使用mmap,即将核心空間一段記憶體區域映射到使用者空間,我們可以直接讀取這段空間的圖像資料而不必進行拷貝。

那麼這個過程是攝像頭是如何知道将采集的圖像放到映射區域的呢?

看mmap之前調用的函數:

—請求攝像頭驅動配置設定記憶體,是以記憶體位于核心空間

ioctl(cam->fd, VIDIOC_REQBUFS, &cam->reqbuf)

—查詢已經配置設定的視訊緩沖區的相關資訊,包括視訊緩沖區的使用狀态、在核心空間的偏移位址、緩沖區長度等。

ioctl(cam->fd, VIDIOC_QUERYBUF, &cam->buf)

看過這兩個函數的調用,一切就明朗了,先申請緩沖區,假設申請4個緩沖區,緩沖區處于核心空間,再利用4次循環,分别擷取每個緩沖區的相關資訊。利用擷取的每個緩沖區的長度、在核心空間(核心空間、使用者控件均是記憶體的一段)的偏移位址來進行映射到使用者空間。

攝像頭v4l2采集中的mmap

順便記錄一下VIDIOC_QBUF :

投放一個空的視訊緩沖區到視訊緩沖區輸入隊列中,成功,則指定的視訊緩沖區進入視訊輸入隊列,在啟動視訊裝置拍攝圖像時,相應的視訊資料被儲存到視訊輸入隊列相應的視訊緩沖區中。