深入理解Android相机体系结构之七

该系列文章总目录链接: https://blog.csdn.net/u012596975/article/details/107135938
本篇是《深入理解Android相机体系结构》连载文章的第七篇。

相机驱动层–V4L2框架解析

一、概览

相机驱动层位于HAL Moudle与硬件层之间,借助linux内核驱动框架,以文件节点的方式暴露接口给用户空间,让HAL Module通过标准的文件访问接口,从而能够将请求顺利地下发到内核中,而在内核中,为了更好的支持视频流的操作,早先提出了v4l视频处理框架,但是由于操作复杂,并且代码无法进行较好的重构,难以维护等原因,之后便衍生出了v4l2框架。

按照v4l2标准,它将一个数据流设备抽象成一个videoX节点,从属的子设备都对应着各自的v4l2_subdev实现,并且通过media controller进行统一管理,整个流程复杂但高效,同时代码的扩展性也较高。

而对高通平台而言,高通整个内核相机驱动是建立在v4l2框架上的,并且对其进行了相应的扩展,创建了一个整体相机控制者的CRM,它以节点video0暴露给用户空间,主要用于管理内核中的Session、Request以及与子设备,同时各个子模块都实现了各自的v4l2_subdev设备,并且以v4l2_subdev节点暴露给用户空间,与此同时,高通还创建了另一个video1设备Camera SYNC,该设备主要用于同步数据流,保证用户空间和内核空间的buffer能够高效得进行传递。

再往下与相机驱动交互的便是整个相机框架的最底层Camera Hardware了,驱动部分控制着其上下电逻辑以及寄存器读取时序并按照I2C协议进行与硬件的通信,和根据MIPI CSI协议传递数据,从而达到控制各个硬件设备,并且获取图像数据的目的。

V4L2英文是Video for Linux 2,该框架是诞生于Linux系统,用于提供一个标准的视频控制框架,其中一般默认会嵌入media controller框架中进行统一管理,v4l2提供给用户空间操作节点,media controller控制对于每一个设备的枚举控制能力,于此同时,由于v4l2包含了一定数量的子设备,而这一系列的子设备都是处于平级关系,但是在实际的图像采集过程中,子设备之间往往还存在着包含于被包含的关系,所以为了维护并管理这种关系,media controller针对多个子设备建立了的一个拓扑图,数据流也就按照这个拓扑图进行流转。

二、流程简介

整个对于v4l2的操作主要包含了如下几个主要流程:

a) 打开video设备
在需要进行视频数据流的操作之前,首先要通过标准的字符设备操作接口open方法来打开一个video设备,并且将返回的字符句柄存在本地,之后的一系列操作都是基于该句柄,而在打开的过程中,会去给每一个子设备的上电,并完成各自的一系列初始化操作。

b) 查看并设置设备
在打开设备获取其文件句柄之后,就需要查询设备的属性,该动作主要通过ioctl传入VIDIOC_QUERYCAP参数来完成,其中该系列属性通过v4l2_capability结构体来表达,除此之外,还可以通过传入VIDIOC_ENUM_FMT来枚举支持的数据格式,通过传入VIDIOC_G_FMT/VIDIOC_S_FMT来分别获取和获取当前的数据格式,通过传入VIDIOC_G_PARM/VIDIOC_S_PARM来分别获取和设置参数。

c) 申请帧缓冲区
完成设备的配置之后,便可以开始向设备申请多个用于盛装图像数据的帧缓冲区,该动作通过调用ioctl并且传入VIDIOC_REQBUFS命令来完成,最后将缓冲区通过mmap方式映射到用户空间。

d) 将帧缓冲区入队
申请好帧缓冲区之后,通过调用ioctl方法传入VIDIOC_QBUF命令来将帧缓冲区加入到v4l2 框架中的缓冲区队列中,静等硬件模块将图像数据填充到缓冲区中。

e) 开启数据流
将所有的缓冲区都加入队列中之后便可以调用ioctl并且传入VIDIOC_STREAMON命令,来通知整个框架开始进行数据传输,其中大致包括了通知各个子设备开始进行工作,最终将数据填充到V4L2框架中的缓冲区队列中。

f) 将帧缓冲区出队
一旦数据流开始进行流转了,我们就可以通过调用ioctl下发VIDIOC_DQBUF命令来获取帧缓冲区,并且将缓冲区的图像数据取出,进行预览、拍照或者录像的处理,处理完成之后,需要将此次缓冲区再次放入V4L2框架中的队列中等待下次的图像数据的填充。

整个采集图像数据的流程现在看来还是比较简单的,接口的控制逻辑很清晰,主要原因是为了提供给用户的接口简单而且抽象,这样方便用户进行集成开发,其中的大部分复杂的业务处理都被V4L2很好的封装了,接下来我们来详细了解下V4L2框架内部是如何表达以及如何运转的。

三、关键结构体

在这里插入图片描述
从上图不难看出,v4l2_device作为顶层管理者,一方面通过嵌入到一个video_device中,暴露video设备节点给用户空间进行控制,另一方面,video_device内部会创建一个media_entity作为在media controller中的抽象体,被加入到media_device中的entitie链表中,此外,为了保持对所从属子设备的控制,内部还维护了一个挂载了所有子设备的subdevs链表。

而对于其中每一个子设备而言,统一采用了v4l2_subdev结构体来进行描述,一方面通过嵌入到video_device,暴露v4l2_subdev子设备节点给用户空间进行控制,另一方面其内部也维护着在media controller中的对应的一个media_entity抽象体,而该抽象体也会链入到media_device中的entities链表中。

通过加入entities链表的方式,media_device保持了对所有的设备信息的查询和控制的能力,而该能力会通过media controller框架在用户空间创建meida设备节点,将这种能力暴露给用户进行控制。

由此可见,V4L2框架都是围绕着以上几个主要结构体来进行的,接下来我们依次简单介绍下:
v4l2_device 源码如下:

struct v4l2_device {
   
    struct device *dev;
#if defined(CONFIG_MEDIA_CONTROLLER)
    struct media_device *mdev;                                                                                                                         
#endif
    struct list_head subdevs;
    spinlock_t lock;
    char name[V4L2_DEVICE_NAME_SIZE];
    void (*notify)(struct v4l2_subdev *sd,
        unsigned int notification, void *arg);
    struct v4l2_ctrl_handler *ctrl_handler;
    struct v4l2_prio_state prio;
    struct kref ref;
    void (*release)(struct v4l2_device *v4l2_dev);
};

该结构体代表了一个整个V4L2设备,作为整个V4L2的顶层管理者,内部通过一个链表管理着整个从属的所有的子设备,并且如果将整个框架放入media conntroller进行管理,便在初始化的时候需要将创建成功的media_device赋值给内部变量 mdev,这样便建立了于与media_device的联系,驱动通过调用v4l2_device_reg

  • 19
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
深入理解Android相机体系结构的过程中,我们需要了解相机API的工作原理和结构。Android相机体系结构主要由应用程序、相机服务和相机驱动程序组成。应用程序通过调用相机API与相机服务进行交互,而相机服务则负责管理相机硬件和驱动程序的通信。 相机API提供了对相机硬件的访问接口,可以控制相机的各种参数,比如曝光时间、焦距、白平衡等。通过相机API,应用程序可以实现拍摄照片、录制视频等功能。在调用相机API时,应用程序会通过相机服务与相机硬件进行通信,相机服务会将应用程序的请求转发给相机驱动程序。 相机服务是Android系统中的一个核心组件,负责管理相机硬件和驱动程序。相机服务会监听应用程序的相机请求,然后通过相机驱动程序与相机硬件进行通信。相机服务还会处理各种相机相关的事件,比如相机的打开、关闭、错误等。在Android系统中,每个相机硬件都对应一个相机服务实例,通过相机服务可以方便地管理多个相机硬件。 相机驱动程序是相机硬件的驱动程序,负责与相机服务进行通信,并控制相机硬件的工作。相机驱动程序可以理解为相机硬件的操作系统,它和相机硬件紧密结合,负责处理来自相机服务的指令,并将相机硬件的输出数据传递给相机服务。对于不同的相机硬件,其对应的相机驱动程序也会有所不同。 通过深入理解Android相机体系结构,我们可以更好地理解相机API的工作原理和使用方法,为开发高质量的相机应用提供参考和指导。同时,对于理解Android系统中其他基础组件的工作原理也会有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值