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图像编程接口深度学习]的更多相关文章

  1. 阶段2-新手上路\项目-移动物体监控系统\Sprint2-摄像头子系统开发\第2节-V4L2图像编程接口深度学习

    参考资料: http://www.cnblogs.com/emouse/archive/2013/03/04/2943243.htmlhttp://blog.csdn.net/eastmoon5021 ...

  2. [国嵌攻略][090][linux网络编程模型]

    编程模型 Socket的实质就是一个接口,利用该接口,用户在使用不同的网络协议时,操作函数得以统一.而针对不同协议的差异性操作,则交给了Socket去自行解决. TCP编程模型 UDP编程模型

  3. [国嵌攻略][077][Linux时间编程]

    时间类型 Coordinated Universal Time(UTC):世界标准时间,也就是格林威治时间(Greenwich Mean Time, GMT). Calendar Time:日历时间, ...

  4. [国嵌攻略][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 所属头文件 ...

  5. [国嵌攻略][137][DM9000网卡驱动编程]

    DM9000数据发送 DM9000数据发送函数是在/drivers/net/dm9000.c中的dm9000_start_xmit函数 static int dm9000_start_xmit(str ...

  6. [国嵌攻略][045-046][一跃进入C大门]

    [一跃进入C大门] 跳转方式 1.相对跳转:b或bl指令,通过计算两个地址之间的差值来给pc赋值相对跳转 2.绝对跳转:ldr指令,通过给pc直接赋值,完成绝对跳转 代码编写 1.在汇编代码中直接使用 ...

  7. [国嵌攻略][153][I2C裸机驱动设计]

    eeprom简介 eeprom电可擦除可编程只读存储器,是一种类似于flash的固态存储器,但是与flash相比又存在一些区别: 1.eeprom可以按位擦写,而flash只能大片擦除. 2.eepr ...

  8. [国嵌攻略][142][LCD驱动程序架构]

    LCD裸机驱动回顾 1.LCD初始化 1.1.控制器初始化 1.2.端口初始化 1.3.指明了帧缓冲 2.LCD图形显示 2.1.将图形数据写入帧缓冲 Linux帧缓冲体验 把图片转换成开发板屏对应的 ...

  9. [国嵌攻略][061][2440LCD驱动设计]

    LCD初始化 1.引脚初始化 2.时序初始化 VBPD(vertical back porch):表示在一帧图像开始时,垂直同步信号以后的无效的行数 VFBD(vertical front porch ...

随机推荐

  1. bzoj 1835: [ZJOI2010]base 基站选址

    Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...

  2. 转 - .net/c# 使用RabbitMQ

    背景 最近需要用C#写一个Adapter来做数据传输,合作方使用的是RabbitMQ,所以我这边也要跟着写写... 在网上搜索了一些,发现园子里的这篇写的还是非常好的.虽然有点老了,我自己用的是最新的 ...

  3. Linux(CentOS6.5_X86.64)编译libjpeg出现“checking host system type... Invalid configuration `x86_64-unknown-linux-gnu': machine `x86_64-unknown' not recognized”的解决

    本文地址http://comexchan.cnblogs.com/,作者Comex Chan,尊重知识产权,转载请注明出处,谢谢!   今天在编译libjpeg 的时候,遇到下面的报错: checki ...

  4. .bashrc:16: command not found: shopt配置环境变量时出错

    source .bashrc ------------------------------------------------------- .bashrc:: command not found: ...

  5. MySQL数据库学习: 02 —— 数据库的安装与配置

                             MySQL安装图解 一.MYSQL的安装 1.打开下载的mysql安装文件mysql-5.0.27-win32.zip,双击解压缩,运行“setup. ...

  6. alpha rarefaction using qiime

    shannon菌群多样性指数 H=-∑(Pi)(㏑Pi) Pi=样品中属于第i种的个体的比例,如样品总个体数为N,第i种个体数为ni,则Pi=ni/N: 各种之间,个体分配越均匀,H值就越大.如果每一 ...

  7. Nginx 限制连接的实践 (DDOS)

    参考:  运维人员的日常 关于限制用户连接,Nginx 提供的模块: ngx_http_limit_req_module , ngx_http_limit_conn_module  , 还有 stre ...

  8. Sqlserver如何递归查询层级数据将父级字段和本级某个字段合并?如何自定义用户函数并调用?

    开门见山,首先说下遇到的问题:前期系统地区字典表中,每个省市县只存了本级名称,没存完整的字段.如:肥西县隶属安徽省合肥市,表中就存了一个肥西县.现有需求需要将完整字段显示,由于系统已在线上运营,无法做 ...

  9. C#高级编程学习一-----------------第五章泛型

    三层架构之泛型应用 概述 1.命名约定 泛型类型以T开头或就是T. 2.泛型类 2.1.创建泛型类

  10. 如何在 iOS 真机运行 Appium

    使用 gui 启动的 appium 1.2.2 也会有这个问题,所以你要把 deviceconsole 复制到 /Applications/Appium.app/Contents/Resources/ ...