Linux v4l2框架分析

news/2024/5/20 12:06:27/文章来源:https://blog.csdn.net/lx123010/article/details/131471273

1. 概述

  • V4L2(Video for Linux 2):Linux内核中关于视频设备驱动的框架,对上向应用层提供统一的接口,对下支持各类复杂硬件的灵活扩展;

  • V4L2框架,主要包括v4l2-coremeida frameworkvideobuf2等模块,这也是本文将要展开的内容,仅提纲挈领;

2. v4l2-core

2.1 应用视角

先从应用的角度来看如何使用v4l2吧:

 

假如要进行视频数据采集,大体的步骤如上图左侧所示:

  1. 打开设备文件/dev/videoX

  2. 根据打开的设备,查询设备能力集;

  3. 设置视频数据的格式、参数等;

  4. 分配buffer,这个buffer可以是用户态分配的,也可以是从内核中获取的;

  5. 开始视频流采集工作;

  6. 将buffer enqueue到v4l2框架,底层负责将视频数据填充后,应用层再将buffer dequeue以便获取数据,然后再将buffer enqueue,如此循环往复;

上图右侧是v4l2-core的大体框架,右侧是对硬件的抽象,要想理解好它,可以先看一下较常见的硬件拓扑结构:

 

  • 通常一个camera的模组如图所示,通常包括Lens、Sensor、CSI接口等,其中CSI接口用于视频数据的传输;

  • SoC的Mipi接口对接Camera,并通过I2C/SPI控制camera模组;

  • Camera模组中也可以包含ISP模块,用于对图像进行处理,有的SoC中也集成了ISP的IP,接收camera的raw数据后,进行图像处理;

2.2 数据结构

如果以上图的硬件为例,对摄像头的硬件该怎么来抽象呢?没错,就是以v4l2_devicev4l2_subdev来进行抽象,以v4l2_device来代表整个输入设备,以v4l2_subdev来代表子模块,比如CSISensor等;

  • v4l2_device:对视频设备的整体进行抽象,可以看成是一个纽带,将各个子设备联系在一起,通常它会嵌入在其他结构体中以提供v4l2框架的功能,比如strcut isp_device

  • v4l2_subdev:对子设备进行抽象,该结构体中包含的struct v4l2_subdev_ops是一个完备的操作函数集,用于对接各种不同的子设备,比如video、audio、sensor等,同时还有一个核心的函数集struct v4l2_subdev_core_ops,提供更通用的功能。子设备驱动根据设备特点实现该函数集中的某些函数即可;

  • video_device:用于向系统注册字符设备节点,以便用户空间可以进行交互,包括各类设置以及数据buffer的获取等,在该结构体中也能看到struct v4l2_ioctl_opsstruct vb2_queue结构体字段,这些与上文中的应用层代码编写息息相关;

  • 如果子设备不需要与应用层交互,struct v4l2_subdev中内嵌的video_device也可以不向系统注册字符设备;

  • video_device结构体,可以内嵌在其他结构体中,以便提供用户层交互的功能,比如struct isp_video

  • 针对图中回调函数集,v4l2-core提供了一些实现,所以driver在实现时,非特殊情况下可以不用重复造轮子;

2.3 流程分析

来进一步看一下内部的注册,及调用流程吧:

 

  • 在驱动实现中,驱动结构体中内嵌struct video_device,同时实现struct v4l2_file_operations结构体中的函数,最终通过video_register_device向提供注册;

  • v4l2_register_device函数通过cdev_add向系统注册字符设备,并指定了file_operations,用户空间调用open/read/write/ioctl等接口,便可回调到驱动实现中;

  • v4l2_register_device函数中,通过device_register向系统注册设备,会在/sys文件系统下创建节点;

完成注册后,用户空间便可通过文件描述符来进行访问,从应用层看,大部分都是通过ioctl接口来完成,流程如下:

  • 户层的ioctl回调到__video_do_ioctl中,该函数会对系统提供的struct v4l2_ioctl_info v4l2_ioctls[]表进行查询,找到对应的项后进行调用;

  • 驱动做的工作就是填空题,实现对应的回调,在合适的时候被调用;

下一个小节,让我们看看更复杂一点的情况。

3. media framework

3.1 问题引入

为了更好的描述,本节以omap3isp为例,先看一下它的硬件构成:

  • CSI:camera接口,接收图像数据,RGB/YUV/JPEG等;

  • CCDC:视频处理前端,CCDC为图像传感器和数字视频源提供接口,并处理图像数据;

  • Preview/Resizer:视频处理后端,Preview提供预览功能,可针对不同类型的传感器进行定制,Resizer提供将输入图像数据按所需的显示或视频编码分辨率调整大小的方法;

  • H3A/HIST:静态统计模块,H3A支持AF、AWB、AE的回路控制,HIST根据输入数据,提供各种3A算法所需的统计数据;

上述硬件模块,可以对应到驱动结构体struct isp_device中的各个字段。

omap3isp的硬件模块,支持多种数据流通路,它并不是唯一的,以RGB为例,如下图:

  • Raw RGB数据进入ISP模块后,可以在运行过程中,根据实际的需求进行通路设置;

  • 所以,重点是:它需要动态设置路径!

那么,软件该如何满足这种需求呢?

3.2 框架

没错,pipeline框架的引入可以解决这个问题。说来很巧,我曾经也实现过一个类似的框架,在阅读media framework时有一种似曾相识的感觉,核心的思想大体一致。

  • 模块之间相互独立,通过struct media_entity来进行抽象,通常会将struct media_entity嵌入到其他结构中,以支持media framework功能;

  • entity模块包含struct media_pad,pad可以认为是端口,与其他模块进行联系的媒介,针对特定模块来说它是确定的;

  • pad通过struct media_link来建立连接,指定source和sink,即可将通路建立起来;

  • 各个模块之间最终建立一条数据流,便是一条pipeline了,同一条pipeline中的模块,可以根据前一个模块查找到下一个模块,因此也可以很方便进行遍历,并做进一步的设置操作;

    因此,只需要将struct media_entity嵌入到特定子模块中,最终便可以将子模块串联起来,构成数据流。所以,omap3isp的驱动中,数据流就如下图所示: 

 

  • video devnode代表video device,也就是前文中提到的导出到用户空间的节点,用于与用户进行控制及数据交互;

  • 每个模块分别有source pad和sink pad,从连接图就可以看出,数据通路灵活多变;

  • 至于数据通路选择问题,可以在驱动初始化的时候进行链接创建,比如isp_create_links

还是看一下数据结构吧:

 

  • media_device:与v4l2_device类似,也是负责将各个子模块集中进行管理,同时在注册的时候,会向系统注册设备节点,方便用户层进行操作;

  • media_entitymedia_padmedia_link等结构体的功能在上文中描述过,注意,这几个结构体会添加到media_device的链表中,同时它们结构体的开始字段都需是struct media_gobj,该结构中的mdev将会指向它所属的media_device。这种设计方便结构之间的查找;

  • media_entity中包含多个media_pad,同时media_pad又会指向它所属的media_entity

  • media_graphmedia_pipelinemedia_entity的集合,直观来理解,就是由一些模块构成的一条数据通路,由一个统一的数据结构来组织管理;

罗列一下常见的几个接口吧,细节不表了:

/* 初始化entity的pads */
int media_entity_pads_init(struct media_entity *entity, u16 num_pads,struct media_pad *pads);/* 在两个entity之间创建link */
int media_create_pad_links(const struct media_device *mdev,const u32 source_function,struct media_entity *source,const u16 source_pad,const u32 sink_function,struct media_entity *sink,const u16 sink_pad,u32 flags,const bool allow_both_undefined);/* 开始graph的遍历,从指定的entity开始 */
void media_graph_walk_start(struct media_graph *graph,struct media_entity *entity);/* 启动pipeline */
__must_check int media_pipeline_start(struct media_entity *entity,struct media_pipeline *pipe);

 将media frameworkv4l2_devicev4l2_subdev结合起来,就可以将各个子设备构建pipeline,完美!

4. videobuf2

4.1 框架分析

  • 框架可以分成两个部分看:控制流+数据流,上文已经大概描述了控制流,数据流的部分就是video buffer了。

  • V4L2的buffer管理是通过videobuf2来完成的,它充当用户空间和驱动之间的中间层,并提供low-level,模块化的内存管理功能;

  • 上图大体包含了videobuf2的框架;

  • vb2_queue:核心的数据结构,用于描述buffer的队列,其中struct vb2_buffer *bufs[]是存放buffer节点的数组,该数组中的成员代表了vb2 buffer,并将在queued_listdone_list两个队列中进行流转;

  • struct vb2_buf_ops:buffer的操作函数集,由驱动来实现,并由框架通过call_bufop宏来对特定的函数进行调用;

  • struct vb2_mem_ops:内存buffer分配函数接口,buffer类型分为三种:1)虚拟地址和物理地址都分散,可以通过dma-sg来完成;2)物理地址分散,虚拟地址连续,可以通过vmalloc分配;3)物理地址连续,可以通过dma-contig来完成;三种类型也vb2框架中都有实现,框架可以通过call_memop来进行调用;

  • struct vb2_ops:vb2队列操作函数集,由驱动来实现对应的接口,并在框架中通过call_vb_qop宏被调用;

4.2 流程分析

本节以omap3isp为例进行简要分析,感觉直接看图就可以了:

  1. buffer申请

 

2.buffer enqueue

3.buffer dequeue

4.stream on

 行文至此,主体讲完了,相信看完本文应该有个大概的轮廓了,还有一些细节未进一步描述,就此打住。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_323778.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

攻防世界-Crypto-Normal_RSA

题目描述:下载附件后,附件中只有两个文件,一个是加密后的密钥,一个是公钥文件 背景知识:RSA加密算法 现在相当于给出了密文和公钥,需要我们去求解明文 1. 思路分析 既然要解密,那么必须要获取…

Facebook Insights分析工具解读,掌握关键数据指标

什么是Facebook Insights? Facebook Insights是Facebook平台上的一项内置分析工具,旨在帮助企业和品牌了解其在Facebook上的表现和受众互动情况。该工具提供了丰富的数据和指标,可以帮助用户洞察粉丝群体、了解发布内容的表现,并…

Hutool 30

Hutool是一个Java工具包,提供了丰富的工具类库和简化开发的工具方法。它的目标是提供一套丰富、实用、高效和易用的Java工具类,以提升开发者的开发效率和开发质量。以下是Hutool的一些主要特点和功能模块: 常用工具类:Hutool提供了…

百度智能车竞赛丝绸之路2——手柄控制

百度智能车竞赛丝绸之路1——智能车设计与编程实现控制 百度智能车竞赛丝绸之路2——手柄控制 一、机器人设计 二、实现原理 本教程使用Python的Serial库和Struct二进制数据解析库去实现Xbox手柄百度大脑学习开发板(上位机)和机器人控制器(…

你的服务器还安全吗?用户数据是否面临泄露风险?

一系列严重的网络安全事件引起了广泛关注,多家知名公司的服务器遭到黑客挟持,用户的个人数据和敏感信息面临泄露的风险。这些事件揭示了网络安全的脆弱性和黑客攻击的威胁性,提醒着企业和个人加强对网络安全的重视。 一、入侵案例1.1 蔚来数据…

Pycharm中成功配置PyQt5(External Tools),设计好界面直接生成python代码

1、安装PyQt5和PyQt5-tools 在Pycharm中设置好Python环境,点击File-Settings-Project-Python Interpreter 设置好后退出,点击窗口下的Terminal,输入 # 直接安装输入pip install pyqt5,如果太慢可以用国内镜像源,若出…

PS扣签名

打开Photoshop CS6,依次点击“文件”-“打开”,把签名照导入进来。 在“选择”菜单下点击“色彩范围”。 此时鼠标形状变成了一支笔,点击签名上黑色的地方,适当调整颜色容差,点击“确定”完成选择。 按住CtrlJ组…

Postman设置断言

目录 前言: 一、断言的定义 二、Postman断言的语法 三、Postman中chai.js断言常用语法 前言: 在进行API测试时,断言是一项重要的功能。它能帮助我们验证接口的响应是否符合预期结果,从而确保API的正确性和可靠性。在Postman中…

【微服务】什么是微服务?-- 全面了解微服务架构

What is Microservices — Edureka 您有没有想过,什么是微服务以及扩展行业如何与它们集成,同时构建应用程序以满足客户的期望? 要了解什么是微服务,您必须了解如何将单体应用程序分解为独立打包和部署的小型微型应用程序。本文将…

Electron + ts + vue3 + vite 项目搭建

Electron 是一个基于 Chromium 和 Node.js 的桌面应用程序开发框架,而 Vue3 则是一种流行的前端框架。将两者结合使用可以快速地打造出跨平台的桌面应用程序。在这种组合中,Electron 提供了强大的桌面应用开发能力,而 Vue3 则提供了易用的 UI…

【2023年江西省研究生数学建模竞赛】题目一 蒸汽发生器倒U型管内液体流动 建模方案及参考文献

代码与结果如下:完整文档见文末 完整思路”请点击这里“到原文章获取 题目: PACTEL压水堆整体测试设备在2009年建造,用于带有垂直倒U型管蒸汽发生器的压水堆热液压相关的安全性研究,参见图1。 PACTEL压水堆设施包括一个反应堆压力容器模型…

机器学习技术(一)——python基础超详解

机器学习技术(一)——python基础超详解 文章目录 机器学习技术(一)——python基础超详解0、引言1、基础概念**:snake:变量****:snake:注释****:snake:输入 输出** 2、数据类型**:snake:数值类型****:snake:运算符****:snake:字符串…

Matlab论文插图绘制模板第106期—带误差棒的堆叠柱状图

在之前的文章中,分享了Matlab带误差棒的折线图绘制模板: 带误差棒的柱状图绘制模板: 进一步,再来分享一下带误差棒的堆叠柱状图的绘制模板。 先来看一下成品效果: 特别提示:本期内容『数据代码』已上传资源…

《移动互联网技术》第一章 概述: 掌握移动互联网的基本概念和组成

🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~&#x1f33…

基于Java+Swing+Mysql商品信息管理系统

基于JavaSwingMysql商品信息管理系统 一、系统介绍二、功能展示1.主页2.新增商品信息3.查询商品信息 三、数据库四、其他系统实现五、获取源码 一、系统介绍 该系统实现了查看商品列表、新增商品信息、查询商品信息 运行环境:eclipse、idea、jdk1.8 二、功能展示…

Android跨平台语言分析

跨平台技术发展的三个阶段 第一阶段是混合开发的web容器时代 为了解决原生开发的高成本、低效率,出现了Hybrid混合开发原生中嵌入依托于浏览器的WebViewWeb浏览器中可以实现的需求在WebView中基本都可以实现但是Web最大的问题是,它的性能和体验与原生开发…

ARM接口题目

1)说出ARM可以工作的模式名字。 ARM有8个基本工作模式: User :非特权模式,大部分任务执行在这种模式 FIQ :当一个高优先级(fast)中断产生时将会进入这种模式 IRQ :当一个低优先级(normal)中断产生时将会进入这种模式 Supervisor :当复位…

《Linux操作系统编程》 第十章 线程与线程控制: 线程的创建、终止和取消,detach以及线程属性

🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~&#x1f33…