V4L2應用程式框架

2021-09-01 01:14:11 字數 2632 閱讀 7208

四、細節

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

int

camerafd;

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

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

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

int 

ioctl (int

__fd, unsigned long int

__request, .../*args*/) ;

在進行v4l2開發中,常用的命令標誌符如下(some are optional):

在亞洲,一般使用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

;

2.3 分配記憶體

struct 

v4l2_requestbuffers req;

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

v4l2_requestbuffers 結構如下:

struct

v4l2_requestbuffers

;

使用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

< req.count; numbufs++)

buffers[numbufs].length = buf.length;

// 轉換成相對位址

buffers[numbufs].start = mmap(null, buf.length, prot_read | prot_write,

map_shared,fd, buf.m.offset);

if (buffers[numbufs].start == map_failed)

// 放入快取佇列

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

}

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

read、write方式,在使用者空間和核心空間不斷拷貝資料,占用了大量使用者記憶體空間,效率不高。

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

使用者指標模式:記憶體片段由應用程式自己分配。這點需要在v4l2_requestbuffers裡將memory欄位設定成v4l2_memory_userptr。

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)
如果使用mmap,最後還需要使用munmap方法。

V4L2應用程式框架

用非阻塞模式開啟攝像頭裝置 int camerafd camerafd open dev video0 o rdwr o nonblock,0 如果用阻塞模式開啟攝像頭裝置,上述 變為 camerafd open dev video0 o rdwr,0 int ioctl int fd,unsign...

V4L2應用程式框架

四 細節 int ioctl int fd,unsigned long int request,args 在進行v4l2開發中,常用的命令標誌符如下 some are optional struct v4l2 format fmt struct v4l2 requestbuffers req if ...

V4L2驅動框架

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