V4L2驅動的移植與應用 二

2021-08-26 14:32:58 字數 2633 閱讀 2665

v4l2驅動的移植與應用(二)

2023年05月12日

二、v4l2的應用 下面簡單介紹一下v4l2驅動的應用流程。

// 用非阻塞模式開啟攝像頭裝置

int camerafd;

camerafd = open("/dev/video0", o_rdwr | o_nonblock, 0);

// 如果用阻塞模式開啟攝像頭裝置,上述**變為:

//camerafd = open("/dev/video0", o_rdwr, 0);

3、 設定屬性及採集方式

extern int ioctl (int __fd, unsigned long int __request, ...) __throw;

__request:具體的命令標誌符。

在進行v4l2開發中,一般會用到以下的命令標誌符:

vidioc_reqbufs:分配記憶體

vidioc_querycap:查詢驅動功能

vidioc_s_fmt:設定當前驅動的頻捕獲格式

vidioc_g_fmt:讀取當前驅動的頻捕獲格式

vidioc_try_fmt:驗證當前驅動的顯示格式

vidioc_cropcap:查詢驅動的修剪能力

vidioc_dqbuf:把資料從快取中讀取出來

vidioc_qbuf:把資料放回快取佇列

這些io呼叫,有些是必須的,有些是可選擇的。

在亞洲,一般使用pal(720x576)制式的攝像頭,而歐洲一般使用ntsc(720x480),使用vidioc_querystd來檢測:

v4l2_std_id std;

do while (ret == -1 && errno == eagain);

switch (std)

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)

v4l2_format結構體定義如下:

struct v4l2_format

fmt;

};struct v4l2_pix_format

;6、 分配記憶體

struct v4l2_requestbuffers req;

if (ioctl(fd, vidioc_reqbufs, &req) == -1)

v4l2_requestbuffers定義如下:

struct v4l2_requestbuffers

;7、 獲取並記錄快取的物理空間

使用vidioc_reqbufs,我們獲取了req.count個快取,下一步通過呼叫vidioc_querybuf命令來獲取這些快取的位址,然後使用mmap函式轉換成應用程式中的絕對位址,最後把這段快取放入快取佇列:

typedef struct videobuffer videobuffer;

videobuffer* buffers = calloc( req.count, sizeof(*buffers) );

struct v4l2_buffer buf;

for (numbufs = 0; numbufs 記憶體劃分成使用者空間和核心空間,分別由應用程式管理和作業系統管理。應用程式可以直接訪問記憶體的位址,而核心空間存放的是 供核心訪問的**和資料,使用者不能直接訪問。v4l2捕獲的資料,最初是存放在核心空間的,這意味著使用者不能直接訪問該段記憶體,必須通過某些手段來轉換位址。

1)使用read、write方式:直接使用 read 和 write 函式進行讀寫。這種方式最簡單,但是這種方式會在 使用者空間和核心空間不斷拷貝資料 ,同時在使用者空間和核心空間占用 了 大量記憶體,效率不高。

2)記憶體對映方式(mmap):把裝置裡的記憶體對映到應用程式中的記憶體控制項,直接處理裝置記憶體,這是一種有效的方式。上面的mmap函式就是使用這種方式。

3)使用者指標模式:記憶體由使用者空間的應用程式分配,並把位址傳遞到核心中的驅動程式,然後由 v4l2 驅動程式直接將資料填充到使用者空間的記憶體中。這點需要在v4l2_requestbuffers裡將memory欄位設定成v4l2_memory_userptr。

9、 處理採集資料

struct v4l2_buffer buf;

memset(&buf,0,sizeof(buf));

buf.type=v4l2_buf_type_video_capture;

buf.memory=v4l2_memory_mmap;

buf.index=0;

//讀取快取

if (ioctl(camerafd, vidioc_dqbuf, &buf) == -1)

//重新放入快取佇列

if (ioctl(camerafd, vidioc_qbuf, &buf) == -1)

close(camerafd)

(待續)

V4L2驅動框架

v4l2驅動框架 主裝置號 81 次裝置號 0 63 64 67 192 223 224 255 dev videox 應用層 char驅動 v4l2 具體的驅動 硬體應用層的操作都需要有底層v4l2驅動的支援。核心中有一些非常完善的例子。比如 linux 2.6.26核心目錄drivers med...

V4L2程式設計

include include include include include include include include include include typedef struct buftype buftype user buf int n buffer 0 開啟攝像頭裝置 int ope...

V4L2 程式設計

v4l2程式設計 1.定義 2.工作流程 開啟裝置 檢查和設定裝置屬性 設定幀格式 設定一種輸入輸出方法 緩衝區管理 迴圈獲取資料 關閉裝置。3.裝置的開啟和關閉 include int open const char device name,int flags include int close ...