Linux之V4L2基础编程(5)

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

if (!buffers) {

// 映射

fprintf (stderr,
"Out of memory/n");

exit (EXIT_FAILURE);

}

for (unsigned int n_buffers = 0; n_buffers < req.count; ++n_buffers)

{

struct v4l2_buffer buf;

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

buf.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE;

buf.memory
= V4L2_MEMORY_MMAP;

buf.index
= n_buffers;

// 查询序号为n_buffers 的缓冲区,得到其起始物理地址和大小

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

exit(
-1);

buffers[n_buffers].length
= buf.length;

// 映射内存

buffers[n_buffers].start
=mmap (NULL,buf.length,PROT_READ | PROT_WRITE ,MAP_SHARED,fd, buf.m.offset);

if (MAP_FAILED == buffers[n_buffers].start)

exit(
-1);

}

10. 缓冲区处理好之后,就可以开始获取数据了 10.1 启动 或 停止数据流 VIDIOC_STREAMON, VIDIOC_STREAMOFF

int ioctl(int fd, int request, const int *argp);

//argp 为流类型指针,如V4L2_BUF_TYPE_VIDEO_CAPTURE.

10.2 在开始之前,还应当把缓冲帧放入缓冲队列:

VIDIOC_QBUF// 把帧放入队列

VIDIOC_DQBUF// 从队列中取出帧

int ioctl(int fd, int request, struct v4l2_buffer *argp);

例:把四个缓冲帧放入队列,并启动数据流

unsigned int i;

enum v4l2_buf_type type;

for (i = 0; i < 4; ++i) // 将缓冲帧放入队列

{

struct v4l2_buffer buf;

buf.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE;

buf.memory
= V4L2_MEMORY_MMAP;

buf.index
= i;

ioctl (fd, VIDIOC_QBUF,
&buf);

}

type
= V4L2_BUF_TYPE_VIDEO_CAPTURE;

ioctl (fd, VIDIOC_STREAMON,
&type);

// 这有个问题,这些buf 看起来和前面申请的buf 没什么关系,为什么呢?

例:获取一帧并处理

struct v4l2_buffer buf; CLEAR (buf);

buf.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory= V4L2_MEMORY_MMAP;

ioctl (fd, VIDIOC_DQBUF,
&buf); // 从缓冲区取出一个缓冲帧

process_image (buffers[buf.index.]start);
//

ioctl (fdVIDIOC_QBUF
&buf); //

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1f4f3df66f22f03bca0e632f69dcc6ce.html