【v4l2】应用程序获取一帧并处理
来源:互联网 发布:nba变态数据 编辑:程序博客网 时间:2024/06/05 23:07
参考 http://blog.chinaunix.net/uid-23424741-id-3977591.html
2.3 分配内存
接下来可以为视频捕获分配内存:
struct v4l2_requestbuffers req;
if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
return -1;
}
v4l2_requestbuffers 结构如下:
struct v4l2_requestbuffers
{
__u32 count; // 缓存数量
enum v4l2_buf_type type; // 数据流类型,必须永远是V4L2_BUF_TYPE_VIDEO_CAPTURE
enum v4l2_memory memory; // V4L2_MEMORY_MMAP 或 V4L2_MEMORY_USERPTR
__u32 reserved[2];
};
使用VIDIOC_REQBUFS,我们获取了req.count个缓存,下一步通过调用VIDIOC_QUERYBUF命令来获取这些缓存的地址,然后使用mmap函数转换成应用程序中的绝对地址,最后把这段缓存放入缓存队列:
typedef struct VideoBuffer {
void *start;
size_t length;
} VideoBuffer;
VideoBuffer* buffers = calloc( req.count, sizeof(*buffers) );
//作为一个与驱动程序交换数据的数据结构,用来辅助数据的导出,即v4l2_buf是作为中介,因为他可被驱动认识。在应用层,用一个指针数组来存储这许多帧。
//这里有个问题啊,我分配的内存,是给驱动设定缓冲的队列大小么?我每次都把数据全部出队?不是的,一次出队一个就好了。
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;
}
//导出驱动层的数据到用户空间
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) {
return -1;
}
// 放入缓存队列
if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
return -1;
}
}
这是官方的例子:
每次读取一帧,然后处理。
static intread_frame(void){ struct v4l2_buffer buf;unsigned int i;switch (io) {case IO_METHOD_READ: if (-1 == read (fd, buffers[0].start, buffers[0].length)) { switch (errno) { case EAGAIN: return 0;case EIO:/* Could ignore EIO, see spec. *//* fall through */default:errno_exit ("read");}} process_image (buffers[0].start);break;case IO_METHOD_MMAP://printf("###USE MMAP FOR CAPTURE ######\n"); //YESCLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) { switch (errno) { case EAGAIN: return 0;case EIO:/* Could ignore EIO, see spec. *//* fall through */default:errno_exit ("VIDIOC_DQBUF");}} assert (buf.index < n_buffers); process_image (buffers[buf.index].start);if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))errno_exit ("VIDIOC_QBUF");break;case IO_METHOD_USERPTR:CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_USERPTR;if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {switch (errno) {case EAGAIN:return 0;case EIO:/* Could ignore EIO, see spec. *//* fall through */default:errno_exit ("VIDIOC_DQBUF");}}for (i = 0; i < n_buffers; ++i)if (buf.m.userptr == (unsigned long) buffers[i].start && buf.length == buffers[i].length)break;assert (i < n_buffers); process_image ((void *) buf.m.userptr);if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))errno_exit ("VIDIOC_QBUF");break;}return 1;}
0 0
- 【v4l2】应用程序获取一帧并处理
- V4l2 获取一帧图片的实现
- v4l2获取raw图像数据并保存
- V4L2应用程序
- V4L2 (一)
- 利用v4l2获取一帧数据到文件
- V4L2应用程序框架
- V4L2应用程序框架
- V4L2应用程序框架
- V4L2应用程序框架
- V4L2应用程序框架
- V4L2应用程序框架介绍
- V4L2应用程序框架
- V4L2应用程序框架
- V4L2应用程序框架
- V4L2应用程序框架
- V4L2应用程序框架
- V4L2应用程序框架
- sicily 1014. Specialized Four-Dig
- linux下使用tar命令
- 关于offsetLeft与position:relative,margin:auto;的一些关系
- 对程序员最具影响的书籍
- 转载和积累系列 - LuCI简介
- 【v4l2】应用程序获取一帧并处理
- thinkphp的sql优化原则
- 网上邻居背后的秘密——NetBIOS与SMB协议概览
- 黑马程序员_nameSpace+string+部分webform
- jquery 简介
- 黑马程序员_05_while_for_break_continue_重载_数组_内存结构
- 仿百度动态查询
- C++面向对象类的实例题目十二
- js中遍历对象的属性和值