Linux多媒体子系统02:V4L2核心框架分析

news2024/12/28 8:53:27

1 V4L2框架结构概述

1.1 imx8视频输入通路硬件结构

软件框架是对硬件结构的映射与描述,所以在说明V4L2框架结构之前先说明一下硬件结构,此处以imx8视频输入通路为例(下图中红框部分)

1. MIPI-CSI2(Camera Serial Interface V2)

① MIPI-CSI是由MIPI联盟下的Camera工作组指定的接口标准,用于规范Camera和SoC的连接

② imx8支持2个4-lane的MIPI-CS2接口用于连接Camera

③ MIPI-CSI2的输出根据配置可传输给下一级的ISI或ISP模块处理

说明:在当前使用的imx8开发板中,从第2组MIPI-CSI2中引出2-lane的接口连接OV5645 camera,对camera的控制则是通过I2C接口实现

2. ISI(Image Sensing Interface,图像传感器接口)

① ISI是一个简单的camera接口,可以对camera输入的图像进行简单处理

② ISI支持的功能包括下采样(down scaling)、颜色空间转换(color space conversion)、去隔行(de-interlacing)、裁剪(cropping)和旋转(rotation)

经过ISI处理的图像将被存储在软件指定的内存中

说明:去隔行是指进行隔行扫描(interlaced)到逐行扫描(progressive)的转换

3. ISP(Image Signal Processor,图像信号处理器)

① ISP可以对camera输入的图像进行更为复杂的处理(e.g. 3A处理和降噪)

② 经过ISP处理的图像将被存储在软件指定的内存中

4. Dewarp Engine(广角鱼眼畸变矫正引擎)

① Dewarp Engine用于矫正广角鱼眼镜头产生的畸变

② Dewarp Engine从内存中获取待矫正的图像,之后再将矫正后的图像输出到内存

1.2 V4L2设备节点观察

在了解了imx8视频输入通路的硬件结构之后,我们再从V4L2设备节点的角度对其进行观察

1. 在当前实验环境中,生成的V4L2设备节点如下图所示

2. 在/sys/class/video4linux目录下查看每个V4L2设备节点的name字段,与imx8视频输入通路相关的设备节点如下图红框中所示

1.3 dts配置观察

1. arch/arm64/boot/dts/freescale/imx8mp.dtsi

可见在当前实验环境中,与视频通路相关的物理IP被组织在逻辑设备cameradev之中

2. arch/arm64/boot/dts/freescale/OK8MP-C.dts

可见在当前实验环境中,OV5645 sensor连接在mipi_csi_1

1.4 probe函数观察

1.4.1 函数功能简介

观察上述模块的probe函数,是为了理清V4L2设备节点是何时以及如何被创建的,为此先简单介绍相关函数的功能

函数

功能

v4l2_device_register

注册v4l2_device结构体

硬件设备可能包含多个子设备,v4l2_device结构体就是所有这些设备的根节点,负责管理所有子设备

v4l2_subdev_init

初始化v4l2_subdev结构体,设置子设备操作函数集

v4l2_device_register_subdev

注册子设备,将v4l2_subdev结构体注册到v4l2_device结构体中

v4l2_async_register_subdev

异步注册子设备,将v4l2_subdev结构体注册到V4L2异步框架(async framework)中。在完成匹配后,异步框架会调用v4l2_device_register_subdev函数将异步注册的v4l2_subdev结构体注册到匹配的v4l2_device结构体中

video_register_device

注册video_device结构体,一般用于创建/dev/video[x]设备节点

v4l2_device_register_subdev_nodes

根据配置,为v4l2_device结构体管理的所有v4l2_subdev结构体注册video_device结构体,创建/dev/v4l-subdev[x]设备节点

说明:创建/dev/video[x]/dev/v4l-subdev[x]设备节点的目的,就是为了让应用程序可以在用户态使用这些设备提供的功能

1.4.2 各模块probe函数分析

1.4.2.1 isi父设备

文件:drivers/staging/media/imx/imx8-isi-core.c

mxc_isi_probe函数中会分配并填充mxc_isi_dev结构体

1.4.2.2 isi子设备

文件:drivers/staging/media/imx/imx8-isi-cap.c

isi_cap_probe函数中会分配并填充mxc_isi_cap_dev结构体,并且初始化mxc_isi_cap_dev.sd子设备。需要注意的是,初始化过程中并没有设置V4L2_SUBDEV_FL_HAS_DEVNODE标志,那么在v4l2_device_register_subdev_nodes函数中将不会为其创建/dev/v4l-subdev[x]设备节点

说明1:在为mxc_isi_cap_dev.sd子设备设置的internal_ops->registered回调函数中,会创建isi子设备所属的/dev/video[x]设备节点,该节点就是操作MIPI Camera进行图像采集时使用的设备节点,详情可参考Linux多媒体子系统01:从用户空间使用V4L2子系统 chapter 1.3

说明2:v4l2_subdev结构体中internal_ops->registered回调函数的调用时机是在子设备v4l2_subdev结构体被注册时(在isi_cap_probe函数中只是调用v4l2_subdev_init函数初始化了mxc_isi_cap_dev.sd子设备)

1.4.2.3 mipi-csi设备

文件:drivers/staging/media/imx/imx8-mipi-csi2-sam.c

mipi_csis_probe函数中会初始化csi_state.sd子设备,并且设置了V4L2_SUBDEV_FL_HAS_DEVNODE标志

1.4.2.4 ov5645 sensor

文件:drivers/media/i2c/ov5645.c

ov5645_probe函数中会初始化ov5645.sd子设备,并且设置了V4L2_SUBDEV_FL_HAS_DEVNODE标志,同时还将该子设备注册到异步框架中

1.4.2.5 cameradev逻辑设备

文件:drivers/staging/media/imx/imx8-media-dev.c

1. 经过上面的步骤,与isi子设备和mipi-csi子设备相关的v4l2_subdev结构体已经被初始化但是尚未注册,mxc_md_probe函数会进行汇总。该函数会先注册v4l2_device结构体,之后调用v4l2_device_register_subdev函数将isi子设备和mipi-csi子设备注册到v4l2_device结构体中

说明:在register_isi_entity函数调用v4l2_device_register_subdev函数的过程中,就会导致isi_cap_probe函数注册的internal_ops->registered回调函数被调用,从而为isi子设备创建/dev/video[x]设备节点

2. 在完成v4l2_subdev结构体的注册后,就需要为各子设备创建/dev/v4l_subdev[x]设备节点,该操作是在subdev_notifier_complete函数中完成。subdev_notifier_complete函数被注册为subdev_notifier的回调函数,将在异步注册的ov5645 sensor子设备匹配成功时调用

说明:根据上述分析,如果不连接ov5645 sensor就会导致相应的子设备无法匹配,那么subdev_notifier_complete函数就不会被调用到,这就会导致整个视频输入通路的设备节点都不会被注册。经过验证,确实如此

1.4.2.6 isp设备

文件:extra/vvcam/v4l2/isp_driver_of.c

isp_hw_probe函数中会初始化isp_device.sd子设备,并且设置了V4L2_SUBDEV_FL_HAS_DEVNODE标志,同时还将该子设备注册到异步框架中

1.4.2.7 dwe设备

文件:extra/vvcam/v4l2/dwe_driver_of.c

dwe_hw_probe函数中会初始化dwe_device.sd子设备,并且设置了V4L2_SUBDEV_FL_HAS_DEVNODE标志,同时还将该子设备注册到异步框架中

1.4.2.8 vvcam逻辑设备

文件:extra/vvcam/v4l2/video/video.c

vvcam逻辑设备的作用与cameradev逻辑设备类似,用于汇总实现isp设备和dwe设备对应的/dev/video[x]和/dev/v4l-subdev[x]设备节点的创建

说明1:isp和dwe设备对应的v4l2_subdev结构体均采用异步方式注册,因此也是在匹配之后创建/dev/v4l-subdev[x]设备节点

说明2:上述分析的probe函数在实验环境中的启动顺序如下

说明3:在当前实验环境中,视频输入通路中如下组件的驱动程序是以内核模块的方式加载的

1.5 V4L2框架结构图示

根据上述分析,描述imx8视频输入通路的V4L2框架结构如下图所示,

说明1:出于简化目的,图中仅画了一路mipi-csi通路

说明2:可见在当前实验环境中,默认使用的是sensor --> mipi-csi --> isi --> ddr的视频输入通路,并没有使用ispdwe

说明3:创建/dev/video[x]设备节点与创建/dev/v4l-subdev[x]设备节点的区别

① 在实验环境的默认视频输入通路中,sensor / mipi-csi / isi均有相应的v4l2_subdev结构体,但是sensor和mipi-csi创建的是/dev/v4l-subdev[x]设备节点,isi创建的是/dev/video[x]设备节点

② 无论是创建/dev/v4l-subdev[x]设备节点还是/dev/video[x]设备节点,目的都是让应用程序可以在用户态直接使用设备提供的功能

  • 从提供的ioctl功能来看,/dev/video[x]设备节点提供的功能更加完备,/dev/v4l-subdev[x]设备节点支持的ioctl操作为/dev/video[x]设备的子集(可参考subdev_do_ioctl函数)以及一组子设备专用操作

  • 从持有的资源来看,/dev/video[x]设备节点一般都持有缓冲区队列(也就是vb2_queue结构体),可以进行缓冲区操作

③ 缓冲区的核心是缓冲区内存,因此最终操作缓冲区内存的设备需要创建/dev/video[x]设备节点,这也是视频通路中isi设备需要创建/dev/video[x]设备节点的原因

说明4:关于bridge driver的概念

在Linux内核的V4L2文档中,会提到一个bridge driver的概念。在内核文档中并没有给出bridge driver的清晰定义,但是他具备如下特征,

① bridge driver会创建/dev/video[x]设备节点,而其他驱动可以创建/dev/v4l-subdev[x]设备节点

② 通过bridge driver可以间接操作v4l2_subdev子设备

③ bridge driver会将总线上的数据传送到内存中

因此可以将bridge driver理解为V4L2设备驱动中处于顶层的,用于进行汇总和统领的驱动,当前实验环境中的cameradev驱动就是bridge driver

2 设备管理机制

2.1 v4l2_device结构体相关

2.1.1 v4l2_device结构体

视频设备正变得越来越复杂,在此类设备中通常包含多个需要相互协作的硬件IP,这会导致复杂的V4L2驱动程序。如上文所示,如果imx8默认视频输入通路视为一个V4L2驱动程序,其中就包含了sensor、mipi-csi和isi等多个子设备。v4l2_device结构体就是这些子设备的根节点,负责管理所有子设备

说明1:关于dev字段

v4l2_device结构体中并不包含device结构体实例,只是包含了指向device结构体的指针(即dev字段)。由于不包含device结构体实例,v4l2_device结构体在Linux设备驱动模型中不会存在实体,而是依赖dev字段所指向的device结构体存在

② 在很多材料中,包括Linux内核的V4L2文档中,将dev字段指向的device结构体称作v4l2_device结构体的父设备(parent device)。但是根据上述分析,v4l2_device结构体本身不包含device结构体,在Linux设备驱动模型中自己并不是一个设备,所以个人觉得将dev字段指向的device结构体称作父设备不是非常合理

③ 在本文中,dev字段指向的device结构体称作与v4l2_device结构体关联的device结构体

说明2:关于notify字段

notify字段指向的回调函数通过v4l2_subdev_notify_event函数调用,供v4l2_subdev子设备向v4l2_device父设备通知有事件发生

说明3:本文不包含对V4L2子设备的详细说明

2.1.2 v4l2_device结构体相关操作

2.1.2.1 注册v4l2_device结构体

V4L2驱动程序可以通过v4l2_device_register函数完成v4l2_device结构体的注册,

说明1:关于与v4l2_device结构体关联的device结构体

v4l2_device结构体关联的device结构体通常是总线相关设备数据结构中的device结构体,e.g. platform_device、usb_device和pci_dev。在imx8视频输入通路的V4L2驱动程序中,就是将cameradev逻辑设备驱动所属platform_device中的device结构体设置为与v4l2_device结构体关联的device结构体

说明2:关于v4l2_device结构体中name字段的设置

① 如果V4L2驱动程序调用v4l2_device_register函数时传递的dev参数为NULL,则必须在调用该函数之前设置name字段

② 如果V4L2驱动程序调用v4l2_device_register函数时传递了有效的dev参数,则只有在驱动程序没有设置name字段的情况下,v4l2_device_register函数才会根据驱动程序名和设备名构造默认的V4L2设备名

2.1.2.2 注销v4l2_device结构体

V4L2驱动程序可以通过v4l2_device_unregister函数完成v4l2_device结构体的注销,

说明1:一般在platfrom驱动程序的probe函数中注册v4l2_device结构体,在remove函数中注销v4l2_device结构体

说明2:关于v4l2_device_disconnect函数

① v4l2_device_disconnect函数的作用是将V4L2设备(由一个v4l2_device结构体实例表示)的状态设置为断开连接

② 如果v4l2_device结构体关联的device设备支持热插拔(hot-pluggable),e.g. v4l2_device结构体关联的device结构体属于一个USB设备,那么当该设备断开连接时,需要标识v4l2_device结构体关联的device已经无效

2.1.2.3 维护v4l2_device结构体引用计数

可以通过v4l2_device_getv4l2_device_put函数维护v4l2_device结构体的引用计数,需要注意的是,因为v4l2_device结构体中并不包含device结构体实例,所以是通过内部包含的kref结构体维护引用计数

说明1:v4l2_device_unregister函数不减少v4l2_device结构体的引用计数

需要注意的是,v4l2_device_unregister函数在注销v4l2_device结构体时并不会减少v4l2_device结构体的引用计数。考虑到v4l2_device_register函数中设置的v4l2_device结构体引用计数初始值为1,可以在驱动程序的disconnectremove回调函数中调用v4l2_device_put函数减少引用计数,否则引用计数不会达到0

说明2:v4l2_device.release回调函数设置实例

文件:drivers/media/radio/dsbr100.c

① dsbr100.c驱动程序对应的设备是一个USB设备,在相应的probe回调函数中会注册v4l2_device结构体并创建/dev/radio[x]设备节点,在此过程中会设置v4l2_device.release回调函数

② 由于USB设备支持热插拔,当设备断开连接时会调用相应的disconnect回调函数。此处的disconnect回调函数的实现非常典型,其中v4l2_device_put操作会将v4l2_device结构体的引用计数减少到0

③ 当v4l2_device结构体引用计数减少到0时,会调用v4l2_device.release回调函数,也就是usb_dsbr100_release函数。该函数会注销v4l2_device结构体,并释放之前在probe函数中动态分配的内存

2.1.2.4 设置v4l2_device结构体name字段

可以通过v4l2_device_set_name函数设置v4l2_device结构体的name字段,

说明:v4l2_device_set_name函数调用实例

文件:drivers/media/radio/radio-si476x.c

此处通过ATOMIC_INIT定义初值为0的实例计数器(instance counter)并传递给v4l2_device_set_name函数,是该函数的典型用法

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

测试Ocr工具IronOCR(续:编写图片圈选程序)

上一篇文章学习了IronOCR的基本用法之后,计划做一个加载本地图片后,从图片中圈选某一位置的文字,然后调用IronOCR识别圈选区域文本的程序。本文实现从本地加载图片并完成圈选的功能。   主要的功能包括以下几点:   1&#xff…

提效降本应对无序竞争,采埃孚+东软睿驰的组合样本

降价与降本,就好似车企与供应商之间的“窗户纸”;如果是持续的无序竞争,势必一捅就破。而只有通过产业链的通力协作,才有机会维持一定的平衡。 多元化需求、车企降本、新车开发周期缩短等一系列因素,正在驱动智能化在中…

Spring Security实现JWT token验证

Spring Security实现JWT token验证 Spring Security是Spring提供的一个安全框架,提供认证和授权功能,最主要的是它提供了简单的使用方式,同时又有很高的灵活性,简单、灵活、强大 一般系统里关于角色方面通常有这么几张表&#xf…

【Dubbo核心 详解三】Dubbo服务接口的详解

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Dubbo专栏 文章目录 引言一、简介1. 介绍 Dubbo 服务接口的基本概念和特点1.1 Dubbo 服务接口的基础概念1.2 Dubbo 服务接口的特点2. 介绍 Dubbo 服务接口的…

机器学习——SVM的易错题型

问:支持向量机仅可以用于处理二分类任务 答:错误。支持向量机可以用于处理多分类任务,通过使用一对多或一对一的方法,将多个类别分别与其他类别做二分类。也可以使用多类支持向量机算法,直接将多个类别一起纳入训练和…

路侧激光雷达目标检测系统-篇1

说明:又到了毕业的季节,拿出来我之前做的小雷达识别项目,给学弟学妹们做毕设一点参考。这个主要是根据雷达采集的数据包进行聚类识别,看那些是汽车,更改数据的特征之后可以识别特定目标,比如路上新人等。  …

SpringCloud --- Nacos注册中心

一、认识和安装Nacos Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。 二、服务注册到nacos Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循SpringCloud中定义的服务注…

Stable Diffusion公司发布首个大语言模型StableLM,已开源公测!

文 | 智商掉了一地 20号凌晨,Stability AI 发布了一个新的开源语言模型—— StableLM,该公司曾开发了 Stable Diffusion 图像生成工具。这则新闻意味着它不再局限于图像与视频生成领域,将正式加入文本生成 AI 赛道。 StableLM 模型可以生成文…

企业号运营全攻略,让你的品牌更具竞争力

实体企业抖音矩阵运营主要包含以下五个方面:多平台帐号绑定、短视频制作、短视频发布、私信评论维护以及提供数据分析报表。   一、多平台帐号绑定   多平台帐号绑定是实体企业进行抖音矩阵运营的第一步。通过将企业的各种社交账号与抖音账号进行绑定&#xff0…

CoreMark 测试指南

1、coremark 简介 coremark 是由EEMBC提出的一个评价CPU性能指标的跑分软件。其主要目标是测试处理器核心性能。CoreMark程序使用C语言写成,包含如下四类运算法则:数学矩阵操作(普通矩阵运算)、列举(寻找并排序&#…

[2019.01.25]Android NDK Crash错误定位

Android NDK开发Crash错误定位: D:\Users\Android\Sdk ndk-stack.exe: D:\Users\Android\Sdk\ndk-bundle\prebuilt\windows-x86_64\bin aarch64-linux-android-addr2line.exe: D:\Users\Android\Sdk\ndk-bundle\toolchains\ aarch64-linux-android-4.9\prebuilt\windows-x86_64…

六、Golang的并发

Go语言的并发指的是能让某个函数独立于其他函数运行的能力。当一个函数创建为goroutine时,Go会将其视为一个独立的工作单元。这个单元会被调度到可用的逻辑处理器上执行。 Go语言运行时的调度器是一个复杂的软件,能管理被创建的所有goroutine并为其分配执…

对考研考公的过分执念,正在悄悄束缚你的职场选择!

随着近年来就业形势的严峻,越来越多的同学在找工作时碰壁,尤其是对于大部分应届生,这种现象尤为明显。 每年数百万的大学生进入到社会,却发现能选择的机会并不多。高等教育规模不断扩大的背景下,职场晋升的门槛越来越…

Hudi最流行数据湖框架介绍

目录 1. 第一章Hudi 框架概述1.1 数据湖Data Lake1.1.1 仓库和湖泊1.1.2 什么是数据湖1.1.3 数据湖的优点1.1.4 Data Lake vs Data warehouse1.1.5 数据湖框架1.1.5.1 Delta Lake1.1.5.2 Apache Iceberg1.1.5.3 Apache Hudi 1.1.6 湖仓一体(Data Lakehouse&#xff…

【1】从零开始学习目标检测:YOLO算法详解

从零开始学习目标检测:YOLO算法详解 文章目录 从零开始学习目标检测:YOLO算法详解1. 🌟什么是目标检测?2.🌟传统的目标检测与基于深度学习的目标检测3.🌟目标检测算法的工作流程4.🌟目标检测可以干什么&am…

拿到新的服务器必做的五件事(详细流程,开发必看)

目录 1. 配置免密登录 基本用法 远程登录服务器: 第一次登录时会提示: 配置文件 创建文件 然后在文件中输入: 密钥登录 创建密钥: 2.部署nginx 一、前提条件 二、安装 Nginx 3.配置python虚拟环境 1.安装虚拟环境 …

自习室管理系统的设计与实现(论文+源码)_kaic

摘要 近年来,随着高校规模的逐步扩大,学生对高校自习室座位的需求也在不断增加。然而,一些高校仍然采用人工管理学院自习室座位,这大大降低了管理效率。显然,开发一个成本低、占用资源少、能提高高校自习室座位管理效率…

WindowsHash简介及windows认证

Windows系统使用两种方法对用户的密码进行哈希处理,他们分别是LAN Manager(LM)哈希和NT LAN Manager(NTML)哈希。 现在已经有了更新的NTLMv2以及Kerberos验证体系。 Windows的系统密码hash默认情况下一般由两个部分组成:第一部分是LM-hash,…

Nginx中间件漏洞复现

Nginx 解析漏洞 该漏洞与nginx、php版本无关,属于用户配置不当造成的解析漏洞。 漏洞原理: 该解析漏洞是PHP fastcgi 的漏洞,在PHP的配置文件 php.ini 中有一个关键的选项 cgi.fix_pathinfo 默认值为1,表示开启。同时在 php-fp…

ASO优化之如何回复Google Play评论

应用的平均评分会影响 Google Play 商店优化 和应用的 Google Play 排名。应用的评分越高,我们在搜索结果中的排名就越靠前。因此,当应用处于 4 星评级范围内时,它会被更多 Google Play 商店的访问者看到和发现。我们可以使用应用雷达中的评级…