高通 Camera HAL3:CamX、Chi-CDK 详解

news2024/12/28 19:31:16

网上关于高通CameraHAL3的介绍文档不多,之前做高通CameraHAL3的一些收集、总结,杂乱了一点,将就着看吧。

一.初步认知

高通CameraHAL3的架构很庞大,代码量也很巨大。

先对CamX、Chi-CDK的关键术语、目录等有个初步认知

1.1 术语

  • ABF :Auto Bayer Filter,Bayer 域的降噪算法
  • ACE :Advanced Chroma Enhancement 高级色度增强
  • ADRC:automatic dynamic range compression 自动动态范围压缩
  • AFD :Auto Flicker Detection,频闪自动检测
  • ASD :Auto Scene Detection
  • ASF :Adaptive Spatial Filter,自适应空间滤波
  • BDS :Bayer Download Scaler
  • BPC :Bad Pixel Correction,坏点校准
  • BPS :Bayer processing segment(for snapshot)
  • CDS :Chroma DownSampler
  • CDK :Camera Development Kit 相机开发包
  • CHI :Camera Hardware Interface 相机硬件接口
  • CS :Chroma Suppression,色度抑制
  • CSID:Camera serial interface decoder module
  • CV :Chroma Enhancement 色度增强
  • DPU :Display processing unit
  • GTM :Global Tone Mapping, 全局色调映射
  • IFE :Image Front End,Sensor 输出的数据首先会到达IFE
  • IPE :Image processing engine
  • KMD :Kernal ModeDriver
  • LPM :low power manager(低功耗下运行)
  • LTM :Local Tone Mapping,局部色调映射
  • MCTF:Motion Compensation Temporal Filtering 录像时的多帧降噪
  • MCE :Memory Color Enhancement
  • MFNR:Multi Frame Noise Reduction 拍照时的多帧降噪
  • OPE :Offline Processing Engine
  • PDAF:phase difference auto focus,相位对焦
  • QCFA:Quad (Bayer Coding) Color Filter Arrangement/Array
  • RDI :Raw Dump Interface
  • RTB :Real Time Bokeh
  • SCE :Skin Color Enhancement, 肤色增强
  • TNR :temporal noise reduction,时域降噪
  • TFE :Thin Front End
  • UMD :User Mode Driver
  • VPU :Video processing unit(codec)
  • WNR :Wavelet Noise Reduction,小波降噪,Yuv域的降噪算法

1.2 主要目录

1.2.1 CamX 中有如下几个主要目录:

  • core/ : 用于存放camx的核心实现模块,其中还包含了主要用于实现hal3接口的hal/目录,以及负责与CHI进行交互的chi/目录
  • csl/: 用于存放主要负责camx与camera driver的通讯模块,为camx提供了统一的Camera driver控制接口
  • hwl/: 用于存放自身具有独立运算能力的硬件node,该部分node受csl管理
  • swl/: 用于存放自身并不具有独立运算能力,必须依靠CPU才能实现的node

1.2.2 Chi-Cdk 中有如下几个主要目录:

  • chioverride/: 用于存放CHI实现的核心模块,负责与camx进行交互并且实现了CHI的总体框架以及具体的业务处理。
  • bin/: 用于存放平台相关的配置项
  • topology/: 用于存放用户自定的Usecase xml配置文件
  • node/: 用于存放用户自定义功能的node
  • module/: 用于存放不同sensor的配置文件,该部分在初始化sensor的时候需要用到
  • tuning/: 用于存放不同场景下的效果参数的配置文件
  • sensor/: 用于存放不同sensor的私有信息以及寄存器配置参数
  • actuator/: 用于存放不同对焦模块的配置信息
  • ois/: 用于存放防抖模块的配置信息
  • flash/: 存放着闪光灯模块的配置信息
  • eeprom/: 存放着eeprom外部存储模块的配置信息
  • fd/: 存放了人脸识别模块的配置信息

二.Camx整体架构

2.1 Camx整体的架构图:

2.2 CamX-CHI通信机制

CamX 与 Chi-Cdk 通过互相dlopen对方的So库,获取了对方的入口方法:

2.3 CameraHAL3数据流向

CamraHAL3数据流向图:

Camera数据从sensor出来,首先会经过IFE,然后分预览/视频和拍照2种情况。

如果是预览或者录像,是先经过IPE处理,最后输出到显示。

如果是拍照,则是先经过BSP处理,然后再经过JPEG编码器,最后保存为图片输出。

IFE、IPE、BPS、JPEG,它们分别表示芯片内部的硬件处理单元,

数据在这些单元内部的处理还是比较复杂的,在不同的处理单元里面,会进行一些复杂的算法处理,这里先有个认识,有个基本概念。

三.CamX CHI-CDK基本组件

3.1 UseCase

UseCase,字面意思:用例

官方注解:

A set of streams configured by the client combined with a set of static properties specifying the processing of those streams

由客户端配置的一组流,这组流是有着一系列静态属性相结合描述的流


See createCaptureSession in the Android CameraDevice documentation

那就结合下面这段代码来好好理解下:

//UseCase: 预览+录像
List<Surface> surfaces = new ArrayList<>();

if(previewSurface != null && previewSurface.isValid()){
  surfaces.add(previewSurface);
  mPreviewBuilder.addTarget(previewSurface);
}

if(mMediaRecorder != null && mMediaRecorderSurface != null 
      && mMediaRecorderSurface.isValid()){
  surfaces.add(mMediaRecorderSurface);
  mPreviewBuilder.addTarget(mMediaRecorderSurface);
}

mCameraDevice.createCaptureSession(surfaces,...,...);

这段代码,是把预览的surface和录像的surface都设进去,然后去创建session

就是表示我预览和录像都需要拿到camera数据。

假设我预览设置的size是1080 x 720,录像是1080p的,那这个1080 x 720预览+1080p录像

就是一个usecase(用例)

其它类推。

UseCase在camx中很有很多衍生类,这是camx针对不同的stream来建立不同的usecase对象,用来管理选择feature,并且创建 pipeline以及session。

3.2 Feature

Feature 代表一个特定的功能。

高通CameraHAL3的 feature 有HDR(高动态范围)、SuperNight(超级夜景)、MFNR(多帧降噪)等等。

Usecase选择相应的feature,然后关联一组pipeline,上层下发request请求,hal层会根据request去选择对应的feature。

3.3 Node

Node是单个具有独立处理功能的抽象模块,可以是软件单元也可以是硬件单元。

Node是camx中非常重要的一个父类,是处理camera 请求的一个中间节点,用于处理pipeline下发的请求。

Node 节点在camx chi架构中至关重要,数据的处理都是通过封装好的Node节点来进行的。

Node初始化流程: 

3.4 Pipeline

一连串node的集合。pipeline提供单一特定功能的所有资源集合,维护着所有硬件资源以及数据的流转。

3.5 Session

若干个有关联的pipeline的集合,用于管理pipeline的抽象控制单元,其中至少包含一个pipeline,并控制着所有的硬件资源,管控着每个pipeline内部的request流转以及数据的输入输出。

3.6 Link

定义不同的Port的连接端口(输入端口和输出端口)

3.7 Port

作为Node的输入输出端口,使用SrcPort以及DstPort结构定义XML文件。

3.8 Topologies

3.9 常用Usecase、Pipeline及其对应关系

Camx、Chi-Cdk做成组件化的目的在于:

不同机型、产品性能及定位不同,即使基线一样usecase等也有可能不一样

给了手机厂商极大的自定义空间,UseCase可以场景复用,对应的pipeline也可以不用或复用

常用Usecase、Pipeline的对应关系:

 

四.组件之间的关系

4.1 基本组件之间的关系:

  • 上层根据需求,config对应的stream下来
  • 下面会根据申请的stream来选择对应的usecase
  • usecase选择完成后,又会去选择需要的feature
  • 不同的feature会去关联对应的pipeline
  • pipeline是由一系列node组成的
  • 最终上层config的stream,就会交由各个node去处理

组件关系图: 

目前高通Camera HAL3的架构已逐步改为以Feature为中心,摒弃之前Usecase为中心的架构模式

五.基础组件与上层交互

5.1 Camera App整体渲染流程以及与CamX交互流程图:

5.2 Request流转

上层由Session下发的每一个Request对应了三个Result:

  • partial metadata
  • metadata
  • image data

对于每一个Result,上传过程可以大致分为以下两个阶段:

  • Session内部完成图像数据的处理,将结果发送至Usecase中
  • Usecase接收到来自Session的数据,并将其上传至Provider

5.3 Session回调函数在CamX的体现

5.3.1 Session::StreamOn()

该方法主要用于开始硬件的数据输出

具体点儿就是进行配置Sensor寄存器,让其开始出图,并且将当前的Session的状态告知每一Node,让它们在自己内部也做好处理数据的准备,所以之后的相关Request的流转都是以该方法为前提进行的,所以该方法重要性可见一斑。

Session的StreamOn方法中主要做了如下两个工作:

  1. 调用FinalizeDeferPipeline()方法
    如果当前pipeline并未初始化,则会调用pipeline的FinalizePipeline()方法,这里方法里面会去针对每一个从属于当前pipeline的Node依次做FinalizeInitialization、CreateBufferManager、NotifyPipelineCreated以及PrepareNodeStreamOn操作

    FinalizeInitialization用于完成Node的初始化动作,NotifyPipelineCreated用于通知Node当前Pipeline的状态,此时Node内部可以根据自身的需要作相应的操作,

    PrepareNodeStreamOn()方法的主要是完成Sensor以及IFE等Node的控制硬件模块出图前的配置,其中包括了曝光的参数的设置

    CreateBufferManagers()方法涉及到CamX-CHI中的一个非常重要的Buffer管理机制,用于Node的ImageBufferManager的创建,而该类用于管理Node中的output port的buffer申请/流转/释放等操作。
     

  2. 调用Pipeline的StreamOn()方法
    这个方法里面会进一步通知CSL部分开启数据流,并且调用每一个Node的OnNodeStreamOn()方法,该方法会去调用ImageBufferManager的Activate(),该方法里面会去真正分配用于装载图像数据的buffer,之后会去调用CHI部分实现的用户自定义的Nod的pOnStreamOn()方法,用户可以在该方法中做一些自定义的操作。

5.3.2 Session::ProcessCaptureRequest()

针对每一次的Request的流转,都是以该方法为入口开始的,具体流程见下图:

Pipeline首次针对每一个Node通过调用AddDeferredNode方法加入到DRQ中

此时所有的Node都会加入到m_readyNodes中,然后通过调用dispatchReadyNodes方法,触发DRQ开始进行整个内部处理流程

基本流程可以参见下图:

Session内部完成图像数据的处理后是如何将结果发送至Usecase的:

Usecase接收到Session的数据,是如何发送至Provider的,

以常用的AdvancedCameraUsecase为例进行代码的梳理:

六.日志TAG:

6.1 摄像头驱动上电:

driver上电日志:cam_sensor_driver_cmd | Probe success

6.2 摄像头驱动下电:

driver下电日志:

cam_sensor_driver_cmd: CAM_STOP_DEV Success for productname_ofilm_s5khm2_wide sensor_id:0x1ad2,sensor_slave_addr:0x20

cam_sensor_driver_cmd:  CAM_RELEASE_DEV Success for productname_ofilm_s5khm2_wide sensor_id:0x1ad2, slave_addr:0x20

6.3 打开摄像头开始传第一帧之前:

CAM_START_DEV

6.4 底层遍历摄像头:

  • CHIUSECASE: [INFO ] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 4, set 54
  • CHIUSECASE: [INFO ] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 0, set 50
  • CHIUSECASE: [INFO ] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 1, set 50
  • CHIUSECASE: [INFO ] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 2, set 50
  • CHIUSECASE: [INFO ] chifeature2graphselector.cpp:11256 BuildCameraIdSet() cameraId 3, set 50

6.5 打开相机:

CameraService: CameraService::connect|first frame arrived|CameraService: disconnect: Disconnected|CAM_ACQUIRE_DEV|CAM_START_DEV|CAM_STOP_DEV|CAM_RELEASE_DEV

"configure_streams":配置流

"pipelineName":pipeline名称

CamX    :|CHIUSECASE:|STREAM_ONSelectFeatureGraphforRequestFromTable|Node::|CamX:|CHIUSECASE:|Camera3|CameraDevice

七.其他

7.1 定义pipeline中node的xml地址:

vendor/qcom/proprietary/chi-cdk/oem/qcom/topology/titan/usecase-components/usecases/UsecaseZSL/pipelines

7.2 Node链接方式定义:

Pipeline中的Node以及连接方式都在XML中被定义,其主要包含了以下几个标签定义:

  • PipelineName: 用来定义该条Pipeline的名称
  • NodeList: 该标签中定义了该条Pipeline的所有的Node
  • PortLinkages: 该标签定义了Node上不同端口之间的连接关系

7.3 vendortag定义文件:

/vendor/qcom/proprietary/chi-cdk/api/common/chioemvendortagdefines.h 

7.4 sensor驱动目录:

某项目名为productname,其一颗摄像头的驱动文件目录:

vendor\qcom\proprietary\chi-cdk\oem\qcom\sensor\productname_sensor\productname_ofilm_ov16a1q_front_sensor

八.结束

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

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

相关文章

Servlet与Mybatis-2

过滤器 过滤器是一种代码重用的技术&#xff0c;它可以改变 HTTP 请求的内容&#xff0c;响应&#xff0c;及 header 信息。过滤器通常不产生响应或像 servlet 那样对请求作出响应&#xff0c;而是修改或调整到资源的请求&#xff0c;修改或调整来自资源的响应。 作用&#x…

Linux基础篇 使用SSH远程Ubuntu-03

目录 1.安装ssh服务器 2.启用SSH服务器 3.查看SSH服务运行状态 4.在Windows的CMD下进行验证 在默认情况下&#xff0c;外部设备是无法通过SSH远程Ubuntu的&#xff0c;因为Ubuntu没有启用ssh服务。 说明&#xff1a;当前Ubuntu系统为20.04 1.安装ssh服务器 sudo apt-get …

chatgpt赋能python:Python在一组数据中抽取数的方法

Python在一组数据中抽取数的方法 Python是一种非常流行的编程语言&#xff0c;因为它简单易学&#xff0c;可读性高&#xff0c;功能强大&#xff0c;适用于各种不同的应用场景。在数据科学领域&#xff0c;Python也非常受欢迎&#xff0c;因为它拥有广泛的数据处理和分析库。…

【Go LeetDay】总目录(1~88)

Leetcode Golang Day1~10 Golang每日一练(leetDay0001) 1. 两数之和 Two Sum 2. 两数相加 Add Two Numbers 3. 无重复字符的最长子串 Longest-substring-without-repeating-characters Golang每日一练(leetDay0002) 4. 寻找两个正序数组的中位数 Median of two sorted arra…

使用RP2040自制的树莓派pico—— [1/100] 烧录micropython固件

目录 开发环境烧录模式简介固件下载固件烧录验证阶段micropython初步了解 开发环境 软件&#xff1a;Thonny 烧录固件&#xff1a;micropython 烧录模式简介 正常插上电就启动&#xff0c;这是树莓派pico开发板的正常启动模式。 如果按住 bootset 按键再插上数据线&#xf…

Vue 设计模式

一、什么是设计模式&#xff1f; 设计模式是一套被反复使用、多数人知晓、经过分类编目的、代码设计经验的总结。它是为了可重用代码&#xff0c;让代码更容易的被他人理解并保证代码的可靠性。 设计模式实际上是“拿来主义”在软件领域的贯彻实践&#xff0c;它是一套现成的工…

Linux下配置Qt6安装开发环境

安装JDK 选择自己定义JDK安装路径 点击如下图按钮 安装SDK 提示TLS初始化失败 由于HTTPS问题造成无法下载,暂用Android Studio来安装Android SDK 成功安装SDK 安装NDK与命令行工具 正在下载NDK及命令行工具 NDK与工具下载完成 配置QT的Android SDK路径 配置NDK路径 选择ND…

卡尔曼滤波与组合导航原理笔记(一)卡尔曼滤波方程的推导 第一部分

文章目录 一、滤波的基本概念1、传统数字滤波器2、现代控制中的状态观测器3、最优估计的含义4、温度估计的例子1.问题描述2.分析 二、递推最小二乘 课程链接&#xff1a;https://www.bilibili.com/video/BV11K411J7gp/?p1 参考书目&#xff1a;《捷联惯导算法与组合导航原理》…

日志框架 --- Log4j

文章目录 1. 什么是log4j2. log4j的日志级别3. 日志层级4. log4j使用实例4.1 添加log4j依赖4.2 添加配置文件4.3 编写代码4.4 测试代码4.5 运行结果 5. 配置文件5.1 Logger 日志记录器5.2 Appender 附加器5.3 Layout 日志格式化器 6. 整体演示6.1 配置文件6.2 运行结果 1. 什么…

Linux学习(四)Docker构建Python_Web环境

目录 Docker 安装Docker 使用Docker 启停Docker 换源Docker 镜像Docker 容器Docker 创建内部网段Docker Python 镜像创建Docker MySQL 镜像创建Docker 补充 Docker 是一个开源的应用容器引擎&#xff0c;Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器…

vulnhub靶场渗透之DC-4渗透教程(超级详细)

vulnhub靶场渗透之DC-4渗透教程目录 0x01靶机概述 0x02靶场环境搭建 0x03靶机信息发现 0x04靶机渗透过程 0x05靶机提权 0x06渗透实验总结 0x01靶机概述 靶机基本信息&#xff1a; 靶机下载链接https://download.vulnhub.com/dc/DC-4.zip作者DCAU发布日期2019年4月…

DINO代码学习笔记(二)

在DINO代码学习笔记&#xff08;一&#xff09;中已经将输入transformer之前的参数处理给捋了一遍&#xff0c;接下就是将这些参数传给transformer。 DINO的transformer使用了Deformable-DETR中的可变性transformer&#xff08;他们之前的工作也有用到&#xff09; 这里还是使用…

chatgpt赋能python:Python回滚-避免代码灾难的有效措施

Python回滚-避免代码灾难的有效措施 什么是Python回滚 Python回滚是一种避免代码灾难的有效措施&#xff0c;它可以让你在代码出现问题之后及时回退到之前的版本&#xff0c;保证系统不会受到影响。 回滚是一项非常重要的工作&#xff0c;越是复杂的项目越需要进行回滚。Pyt…

​【指针与数组的恩怨情仇】

指针和数组的关系 指针指的是指针变量&#xff0c;不是数组&#xff0c;指针变量的大小是4/8个字节&#xff0c;是专门来存放地址的。数组也不是指针&#xff0c;数组是一块连续的空间&#xff0c;存放一组相同类型的数据的。 没有关系&#xff0c;但是它们之间有比较相似的地方…

java String类型对象转换为自定义类型对象

问题 java String类型对象转换为自定义类型对象 详细问题 对于java自定义类型对象提供了toString()方法&#xff0c;实现自定义类型对象转换为String类型对象&#xff0c;如何将String类型对象转换为自定义类型对象&#xff0c;譬如对于如下代码所定义的Class类 package co…

Android:Selector + Layer-lists 实现 AppCompatCheckBox

最近做项目涉及到一些UI相关的东东&#xff0c;虽然比较简单&#xff0c;但是也很有趣&#xff0c;写两篇简短的博客记录一下。 一."Selector 两张图片"实现 AppCompatCheckBox AppCompatCheckBox 是 androidx的一个widget&#xff1a;androidx.appcompat.widget.…

chatgpt赋能python:Python图中打字的SEO文章:让你的图片说出更多的话

Python图中打字的SEO文章&#xff1a;让你的图片说出更多的话 图片是传达信息的有力工具。不过&#xff0c;当你在网站上发布图片的时候&#xff0c;这张图片就很可能会被浏览器、机器学习算法、甚至是一些视觉障碍用户忽略。为了弥补这个缺陷&#xff0c;我们可以使用Python来…

chatgpt赋能python:Python回退快捷键:让你的编程更迅速高效

Python回退快捷键&#xff1a;让你的编程更迅速高效 作为一名有10年Python编程经验的工程师&#xff0c;我深知Python回退快捷键对于编程的重要性。当你在编写代码时&#xff0c;可能会出现需要回退或者修改之前的代码的情况&#xff0c;在这种情况下&#xff0c;如果你没有使…

用代码认识整型提升与unsigned signed

&#x1f929;本文作者&#xff1a;大家好&#xff0c;我是paperjie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 &#x1f970;内容专栏&#xff1a;这里是《C语言》专栏&#xff0c;笔者用重金(时间和精力)打造&#xff0c;基础知识一网打尽&#xff0c;希望可以…

[架构之路-206]- 常见的需求分析技术:UML图概览

UML&#xff08;Unified Modeling Language&#xff09;是一种统一建模语言&#xff0c;为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言。下面将对UML的九种图包图的基本概念进行介绍以及各个图的使用场景。 一、基本概念   如下图所示&#xff0c;U…