[国嵌攻略][171][V4L2图像编程接口深度学习]
V4L2摄像编程模型
1.打开摄像头设备文件
2.获取驱动信息-VIDIOC_QUERYCAP
3.设置图像格式-VIDIOC_S_FMT
4.申请帧缓冲-VIDIOC_REQBUFS
5.获取帧缓冲的地址长度信息-VIDIOC_QUERYBUF
6.使用mmap把内核空间的帧缓冲映射到用户空间
7.帧缓冲入队列-VIDIOC_QBUF
8.开始采集图像-VIDIOC_STREAMON
9.取出帧缓冲(出队)-VIDIOC_DQBUF
10.访问帧缓冲
11.帧缓冲重新入队-VIDIOC_QBUF
USB摄像头驱动工作流程
摄像头驱动从输入队列中取出一个帧缓冲,放到输出队列中。
应用程序从输出队列中取出一个帧缓冲,读取数据后,再把帧缓冲放入输入缓存中。
camera.c
#include <stdio.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/videodev2.h> struct buffer{
void *start; //帧缓冲地址
int length; //帧缓冲长度
}; int main(int argc, char **argv){
//创建图片文件
int fd_img; fd_img = open("img.jpg", O_RDWR | O_CREAT, ); //打开设备文件
int fd_dev; fd_dev = open("/dev/video0", O_RDWR | O_NONBLOCK, ); //获取驱动信息
struct v4l2_capability cap; ioctl(fd_dev, VIDIOC_QUERYCAP, &cap); printf("Driver name:%s\nCard name:%s\nBus info:%s\n\n", cap.driver, cap.card, cap.bus_info); //设置图像格式
struct v4l2_format fmt; fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = ;
fmt.fmt.pix.height = ;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; ioctl(fd_dev, VIDIOC_S_FMT, &fmt); //申请图像缓冲
struct v4l2_requestbuffers req; req.count = ;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP; ioctl(fd_dev, VIDIOC_REQBUFS, &req); //映射用户空间
int i;
struct buffer *buffs;
struct v4l2_buffer buff; buffs = calloc(req.count, sizeof(*buffs)); for(i = ; i < req.count; i++){
//获取缓冲长度
buff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buff.memory = V4L2_MEMORY_MMAP;
buff.index = i; ioctl(fd_dev, VIDIOC_QUERYBUF, &buff); buffs[i].length = buff.length; //映射缓冲地址
buffs[i].start = mmap(NULL, buff.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd_dev, buff.m.offset);
} //图像缓冲入队
for(i = ; i < req.count; i++){
buff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buff.memory = V4L2_MEMORY_MMAP;
buff.index = i; ioctl(fd_dev, VIDIOC_QBUF, &buff);
} //捕获图像数据
enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl(fd_dev, VIDIOC_STREAMON, &type); //等待捕获完成
fd_set fds; FD_ZERO(&fds);
FD_SET(fd_dev, &fds); select(fd_dev + , &fds, NULL, NULL, NULL); //图像缓冲出队
buff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buff.memory = V4L2_MEMORY_MMAP; ioctl(fd_dev, VIDIOC_DQBUF, &buff); //读取图像数据
write(fd_img, buffs[buff.index].start, buffs[buff.index].length); //图像缓冲入队
ioctl(fd_dev, VIDIOC_QBUF, &buff); //释放用户空间
for(i = ; i < req.count; i++){
munmap(buffs[i].start, buffs[i].length);
} //关闭打开文件
close(fd_dev);
close(fd_img); printf("Camera done!\n"); return ;
}
[国嵌攻略][171][V4L2图像编程接口深度学习]的更多相关文章
- 阶段2-新手上路\项目-移动物体监控系统\Sprint2-摄像头子系统开发\第2节-V4L2图像编程接口深度学习
参考资料: http://www.cnblogs.com/emouse/archive/2013/03/04/2943243.htmlhttp://blog.csdn.net/eastmoon5021 ...
- [国嵌攻略][090][linux网络编程模型]
编程模型 Socket的实质就是一个接口,利用该接口,用户在使用不同的网络协议时,操作函数得以统一.而针对不同协议的差异性操作,则交给了Socket去自行解决. TCP编程模型 UDP编程模型
- [国嵌攻略][077][Linux时间编程]
时间类型 Coordinated Universal Time(UTC):世界标准时间,也就是格林威治时间(Greenwich Mean Time, GMT). Calendar Time:日历时间, ...
- [国嵌攻略][070-095][Linux编程函数手册]
第1类 时间编程类 1.1 获取日历时间 1.1.1 函数名 time 1.1.2 函数原形 time_t time(time_t *t) 1.1.3 函数功能 返回日历时间 1.1.4 所属头文件 ...
- [国嵌攻略][137][DM9000网卡驱动编程]
DM9000数据发送 DM9000数据发送函数是在/drivers/net/dm9000.c中的dm9000_start_xmit函数 static int dm9000_start_xmit(str ...
- [国嵌攻略][045-046][一跃进入C大门]
[一跃进入C大门] 跳转方式 1.相对跳转:b或bl指令,通过计算两个地址之间的差值来给pc赋值相对跳转 2.绝对跳转:ldr指令,通过给pc直接赋值,完成绝对跳转 代码编写 1.在汇编代码中直接使用 ...
- [国嵌攻略][153][I2C裸机驱动设计]
eeprom简介 eeprom电可擦除可编程只读存储器,是一种类似于flash的固态存储器,但是与flash相比又存在一些区别: 1.eeprom可以按位擦写,而flash只能大片擦除. 2.eepr ...
- [国嵌攻略][142][LCD驱动程序架构]
LCD裸机驱动回顾 1.LCD初始化 1.1.控制器初始化 1.2.端口初始化 1.3.指明了帧缓冲 2.LCD图形显示 2.1.将图形数据写入帧缓冲 Linux帧缓冲体验 把图片转换成开发板屏对应的 ...
- [国嵌攻略][061][2440LCD驱动设计]
LCD初始化 1.引脚初始化 2.时序初始化 VBPD(vertical back porch):表示在一帧图像开始时,垂直同步信号以后的无效的行数 VFBD(vertical front porch ...
随机推荐
- Search an Element in an array
Given an integer array and an element x, find if element is present in array or not. If element is p ...
- NP完整性| 集1(简介)
我们一直在写关于高效算法来解决复杂问题,如最短路径,欧拉图,最小生成树等.这些都是算法设计者的成功故事. 在这篇文章中,讨论了计算机科学的失败故事. 计算机可以解决所有的计算问题吗? 存在计算问题,即 ...
- ioutil包二
ioutil包二 (原创随笔,转载请注明出处 http://www.cnblogs.com/majianguo/p/8016426.html) ioutil包实现了一些I/O实用功能,导出了7个函数和 ...
- Linux目录结构详解
/: 根目录,一般根目录下只存放目录,不要存放文件,/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中/bin:/usr/bin: 可执行二进制文件的目录,如常用的命令ls ...
- springBoot系列教程04:mybatis及druid数据源的集成及查询缓存的使用
首先说下查询缓存:查询缓存就是相同的数据库查询请求在设定的时间间隔内仅查询一次数据库并保存到redis中,后续的请求只要在时间间隔内都直接从redis中获取,不再查询数据库,提高查询效率,降低服务器负 ...
- Linux系统使用-CentOS7 for Redis
Redis系列(一):CentOS系统安装与环境配置 1.为什么使用虚拟机和CentOS 最近Redis比较 热门而且易于使用 而 Redisd对window支持并不好. 引用官方说明:http:// ...
- Linux下查询进程PS或者杀死进程kill的小技巧
假设我们要kill掉tomcat: 那么我们首先需要tomcat的进程号pid: ps -aux | grep tomcat 记下tomcat的PID后,执行:kill PID(tomcat) 好了, ...
- Spring入门之IOC
IOC/DI: Spring最核心的灵魂,IOC/DI(控制反转/依赖注入)!,这里一定要理解他,理解这个思想.我会细说什么是IOC/DI.他的思想是什么.它带来了那些好处. 进入正题,先说说什么是i ...
- js 数组的常用方法
pop,push,reverse,shift,sort,splice,unshift 会改变原数组 join,concat,indexOf,lastIndexOf,slice,toString 不会改 ...
- JavaScript语法详解:JS简介&变量
本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. JavaScript简介 Web前端有三层: HTML:从语义的角度,描 ...