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. JPA的基本使用

    前提: 创建一个springboot项目 创建一个名为springboottest的MySQL数据库 1 jar包准备 jpa的jar包 mysql驱动的jar包 druid数据库连接池的jar包 l ...

  2. nginx搭建rtmp协议流媒体服务器总结

    最近在 ubuntu12.04+wdlinux(centos)上搭建了一个rtmp服务器,感觉还挺麻烦的,所以记录下. 大部分都是参考网络上的资料. 前提: 在linux下某个目录中新建一个nginx ...

  3. ES6 let和const命令(3)

    const 用来声明常量.一旦声明,就不能改变. const在声明必须初始化,只声明不赋值会出错 const的作用域与let一样,只在声明的块级作用域有效. const命令声明的常量也不提升,同样存在 ...

  4. 第九章 BootstrapTable的使用

    一.简介 BootstrapTable是一个Bootstrap 3 的表格插件,支持单选, 复选框, 排序, 分页等功能 官网:http://bootstrap-table.wenzhixin.net ...

  5. Shell脚本实现文件遍历和删除操作

    本文需要实现的功能如下:某文件夹下具有由按数字编号命名的文件夹,需要删除除最大编码外的文件. 具体实现 大致思路:循环遍历该文件夹下所有文件,正则匹配出最大编码文件:然后循环文件,删除除最大编码外的文 ...

  6. 三栏布局之 css3 calc和 flex

    圣杯布局的实现,有很多种. 大致都是借助 padding, margin, float之类的,当然这是传统的实现方式.更多的参考方式圣杯布局小结. 这里说的是用css3 cal 和flex来实现,因为 ...

  7. 使用ui-route实现多层嵌套路由

    一.预期实现效果: https://liyuan-meng.github.io/uiRouter-app/index.html (项目地址:https://github.com/liyuan-meng ...

  8. mimtproxy和arpspoof实现局域网MITM

    本地环境 环境:kali系统 目标机器:192.168.0.101 局域网网关:192.168.0.1 当前网络网卡端口:wlan0 arp欺骗流程 命令行开启本地数据转发: echo > /p ...

  9. php 抽象类和接口类

    PHP中抽象类和接口类都是特殊类,通常配合面向对象的多态性一起使用. 相同: ①两者都是抽象类,都不能实例化. ②只有接口类的实现类和抽象类的子类实现了 已经声明的 抽象方法才能被实例化. 不同: ① ...

  10. 【jQuery】(6)---jQuery validate插件

    jQuery  validate插件 一.导入js库                                      先导入jQuery库,然后导入Validate插件,如果是中文提示还需要 ...