(六) 编写vivid
title: 编写vivid
date: 2019/4/23 19:40:00
toc: true
编写vivid
新内核对video_buf
的封装更好了,很多函数基本上套个名字就好了,这个可以参考
下面的分析是韦老师的2.x
版本的,基本流程如下
1.注册平台设备和驱动;
2.probe()函数:
a.分配video_device;
b.设置video_device,包括:release、fops、ioctl_ops、v4l2_dev;
c.注册设置video_device;
d.其它:定义/初始化自旋锁/定时器;
3.填充操作函数v4l2_file_operations:
a.open():初始buf化队列和设置定时器;
b.close():删除定时器和释放buf队列;
c.mmap():调用videobuf_mmap_mapper开辟虚拟内存;
d.poll():调用videobuf_poll_stream实现poll机制非阻塞访问;
4.填充操作函数v4l2_ioctl_ops:
前面介绍的11个必须ioctl,几乎都是调用内核提供的API;
5.填充操作函数videobuf_queue_ops:
对buf进行一些操作;
6.填充数据:
利用定时器,不断产生数据并唤醒进程,实现获取到图像采集数据;
细致流程如下
请求缓冲区 VIDIOC_QUERYBUF
v4l2_fops
v4l2_file_operations vivi_fops .unlocked_ioctl = video_ioctl2
__video_do_ioctl
ops->vidioc_querybuf(file, fh, p); //.vidioc_querybuf = vidioc_querybuf,
vidioc_querybuf
vb2_querybuf(&dev->vb_vidq, p)
查询缓冲区 VIDIOC_QUERYBUF
ops->vidioc_querybuf(file, fh, p)
vb2_querybuf(&dev->vb_vidq, p)
vb = q->bufs[b->index]
__fill_v4l2_buffer(vb, b) 填充 v4l2_buffer 获得缓冲区的格式大小等信息
vivi_mmap
v4l2_fops.v4l2_mmap > vdev->fops->mmap
vivi_mmap
vb2_mmap(&dev->vb_vidq, vma)
ret = call_memop(q, mmap, vb->planes[plane].mem_priv, vma);
// 搜索
#define call_memop(q, op, args...) \
(((q)->mem_ops->op) ? \
((q)->mem_ops->op(args)) : 0)
q->ops = &vivi_video_qops;
q->mem_ops = &vb2_vmalloc_memops;
也就是调用 vb2_vmalloc_memops.mmap
vb2_vmalloc_mmap
remap_vmalloc_range
放入队列 VIDIOC_QBUF
ops->vidioc_qbuf
vb2_qbuf(&dev->vb_vidq, p)
call_qop(q, wait_prepare, q);
down_read(mmap_sem);
call_qop(q, wait_finish, q);
list_add_tail(&vb->queued_entry, &q->queued_list);
__enqueue_in_driver(vb); 这里执行驱动自身可能需要的入队列后的初始化
__fill_v4l2_buffer(vb, b);
启动摄像头 VIDIOC_STREAMON
vb2_streamon
start_streaming
q->streaming = 1;
v4l2_poll
vdev->fops->poll
vivi_poll
搜索 wait
队列 DECLARE_WAITQUEUE(wait, current);
timeout = msecs_to_jiffies(frames_to_ms(1));
vivi_thread_tick(dev);
vb2_buffer_done
wake_up(&q->done_wq); //唤醒
//创建了一个线程
static int vivi_thread(void *data)
{
vivi_sleep(dev); //具体30ms唤醒一次
#define frames_to_ms(frames) \
((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR)
#define WAKE_NUMERATOR 30
}
VIDIOC_DQBUF 取出缓冲
ops->vidioc_dqbuf
vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK)
call_qop(q, buf_finish, vb)
list_del(&vb->queued_entry);
vb->state = VB2_BUF_STATE_DEQUEUED;
(六) 编写vivid的更多相关文章
- 简明python教程六----编写一个python脚本
备份程序: #!/usr/bin/python #Filename:backup_ver1.py import os import time source = ['/home/liuxj/python ...
- Apache thrift RPC 双向通信
在上一篇介绍Apache thrift 安装和使用,写了一个简单的demo,讲解thrift服务的发布和客户端调用,但只是单向的客户端发送消息,服务端接收消息.而客户端却得不到服务器的响应. 在不涉及 ...
- jquery常用语句总结
一.jquery中text val html attr的使用区别 html和innerHTMl是一样的,可以获得和设置指定元素如<p>中的html标签和文本如:设置值: $("p ...
- Delphi下DLL编程知识(转)
一. DLL和系统变量 在 System 单元声明的变量中,有几个对DLL编程有特殊影响.IsLibrary 可以检测代码是执行在应用程序中还是执行在DLL中,在应用程序中 IsLibrar ...
- Spring框架的第三天
## Spring框架的第三天 ## ---------- **课程回顾:Spring框架第二天** 1. IOC的注解方式 * @Value * @Resource(name="" ...
- spring配置和下载
步骤一:下载 Spring 的开发包: 官网:http://spring.io/ 下 载 地 址 : http://repo.springsource.org/libs-release-local/o ...
- 6.1 如何在spring中自定义xml标签
dubbo自定义了很多xml标签,例如<dubbo:application>,那么这些自定义标签是怎么与spring结合起来的呢?我们先看一个简单的例子. 一 编写模型类 package ...
- 与python的第一次邂逅
python简介 一.什么是python python是一种面向对象.直译式的计算机程序语言,所以有了武老师的那句名言:一切皆为对象 python的设计哲学是:“优雅”,“明确”,“简单” pytho ...
- gulp使用 实现文件修改实时刷新
gulp例子:https://github.com/Aquarius1993/gulpDemo 淘宝镜像:$ npm install -g cnpm --registry=https://regist ...
随机推荐
- JMeter 接口测试-if控制器
JMeter 接口测试-if控制器 使用场景: 当业务场景是用户登录才能支付操作, 不登录点击支付, 页面会跳转到登录页面. 对于接口也是这样, 一个接口需要执行前, 需要有前提条件, 比如0状态 ...
- DVWA 黑客攻防演练(十三)JS 攻击 JavaScript Attacks
新版本的 DVWA 有新东西,其中一个就是这个 JavaScript 模块了. 玩法也挺特别的,如果你能提交 success 这个词,成功是算你赢了.也看得我有点懵逼. 初级 如果你改成 " ...
- 从0开始的Python学习015输入与输出
简介 在之前的编程中,我们的信息打印,数据的展示都是在控制台(命令行)直接输出的,信息都是一次性的没有办法复用和保存以便下次查看,今天我们将学习Python的输入输出,解决以上问题. 复习 得到输入用 ...
- AngularJS学习之旅—AngularJS 事件(十四)
1.AngularJS 事件 ng-click ( 适用标签 :所有,触发事件:单击): ng-dblclick( 适用标签 :所有,触发事件:双击): ng-blur(适用标签 : a,input, ...
- c/c++ 模板 类型推断
模板类型的推断 下面的函数f是个模板函数,typename T.下表是,根据调用测的实参,推断出来的T的类型. 请注意下表的红字部分, f(T&& t)看起来是右值引用,但其实它会根据 ...
- oracle有三种类型的异常错误: 预定义 ( Predefined )错误里面的常见错误
oracle有三种类型的异常错误: 预定义 ( Predefined )错误, 非预定义 ( Predefined )错误, 用户定义(User_define) 错误 预定义 ( Predefined ...
- flutter 自定义主题切换
1. 定义local_srorage.dart文件 使用Flutter第三方插件shared_preferences实现存储键值对信息 相关shared_preferences插件可参考: flutt ...
- win 解压安装mysql步骤
5 安装成功之后,启动mysql时报错: 系统错误2,找不到指定的文件.原因:有的系统安装过MySQL没有卸载干净,或者系统自带精简版的MySQL导致注册表关于MySQL的配置与实际安装路径不一致. ...
- 封装LocalStorage.js
之前使用vue开发的项目频繁使用到localStorage,封装了一下 localStorage.js文件代码如下: let obj = {}; /** * putLocalStorage 把数据放到 ...
- 队列(FIFO)—循环队列、队列的链式存储
1 队列的定义 队列是只允许在一端(队尾)进行插入操作,而在另一端(队头)进行删除操作的线性表. 2 队列的特点 1)先进先出是队列最大的特点,是应用中非常常见的模型,例如排队: 2)队列也属于线性表 ...