大家好,欢迎来到IT知识分享网。
目录
下图是简单模型的pipeline (sensor –> IFE –> IPE –> SinkTarget)
IFE output port的buffer在Camx中申请
IPE output port使用的buffer来自上层传入, IPE input port使用IFE的output port的buffer.
枚举物理camera (ProbeImageSensorModules)
解析相机信息表, 创建各种Camera ID的映射关系, 向上层返回FwCameraNums
devicetree中的xxx_camera-sensor.dtsi文件
枚举物理camera的过程 (ProbeImageSensorModules)
为了方便操作, fwkCameraId和logicalCameraId的对应关系会记录在全局数组m_cameraIdxToFwkId中
疑问: 最终目的是操作物理camera, 通过fwkCameraId也可以找到物理camera, 为什么还需要logicalCameraId ?
Qcom Camera HAL使用了两套MetadataBuffer管理接口
Camx中的DRQ和Chi中的FeatureGraph管理模型的对比
相较于Qcom以前的Chi架构, Feature2有如下优势:
使用RTBayer2YUV这个FeatureGraph完成单帧拍照
背景
比较简单的整理一下Qcom Camera HAL中的主要模块和流程, 包括如下内容:
- Android相机软件框架 :Qcom HAL主要包括Camx和Chi.
- get_number_of_cameras :创建HAL的Environment, 枚举物理camera, 解析相机信息表. 建立cameraId映射关系。
- Open接口 :cameraId映射关系的使用,创建HAL Device
- configure_streams :根据场景, 配置stream. 创建pipeline, 申请ImageBuffer和metadataBuffer.
- ImageBuffer管理 :保存图像数据的buffer, 使用MemPoolMgr(内存池)和ImagebufferManger两部分管理.
- MetadataBuffer管理 :保存TAG的buffer, 使用ChiMetadataManager(相当于内存池)和camx中MetadataPool两部分管理
- request 过程 :Request在Camx中处理, Request在Chi中的处理
Android相机软件框架
Camera HAL3是个per-frame Request的模型, 用一个Request来描述上层希望底层如何处理某一帧, 基本的处理框架如下所示:
调用关系: APP –> Frameworks –> cameraservice –> provider–> OEM HAL –> Qcom HAL.
Qcom HAL主要包括Camx和Chi两部分
- Camx中完成一条pipeline的处理, 通过DRQ完成Request在Node中的调度.
- Chi中客制化一些Usecase, Feature, 使用Camx中的一条或者多条pipeline来实现.
Camx中Pipeline 和 node
- 高通将功能模块抽象成Node来管理. 将Node串联, 形成Pipeline. Pipeline 的输入是srcTarget, 输出是SinkTarget。
- Node有多个Port口, 使用Link, 通过Port口将Node与Node, Node与SrcTarget, Node与SinkTarget连接起来.
下图是简单模型的pipeline (sensor –> IFE –> IPE –> SinkTarget)
- 这条pipeline包括sensor, ife, ipe三个node, 没有3A node, 仅用于调试使用.
- Sensor输出Raw数据的信号, 经IFE处理转为YUV数据, 经IPE降噪裁剪输出到SinkTarget buffer.
Pipeline中的buffer管理
IFE output port的buffer在Camx中申请
- Node的non sink output port的buffer在Camx中申请.
IPE output port使用的buffer来自上层传入, IPE input port使用IFE的output port的buffer.
- Node的sink output port的buffer上层传入.
- Node的input port使用父node(上行) 的output port的buffer.
下面整理一些关键函数和模块的实现
get_number_of_cameras
获取当前设备中相机的总和, 包括单摄, 多摄, 虚拟Camera. 在provider启动的时候调用, 主要完成三件事, 流程如下:
创建HAL工作的Environment
- 在Camx中创建HAL3Module, HwEnvironment.
- 在Chi中创建ExtensionModule.
- 在这个过程中, 创建了一些线程, 创建了很多static类型的数据, 相机退出的时候不会销毁.
枚举物理camera (ProbeImageSensorModules)
通过CameraModuleData和SendorDriverData文件, 结合devicetree中的sensor信息, 枚举物理camera
解析相机信息表, 创建各种Camera ID的映射关系, 向上层返回FwCameraNums
- 每个设备都有相机信息表, 描述当前设备中的单摄, 多摄, 虚拟Camera等信息
- 将fwkCameraId和物理camera的对应关系保存到全局数据区中.
- HAL中为camera定义了RoleId, 创建RoleId和fwkCameraId的map关系, 返回给APP.
HAL中定义了多种CameraId, CameraId之间会有对应的映射关系, 先总结一下CameraId的最终使用。
cameraId的最终使用过程
App中通过RoleId, 找到对应fwkCameraId, open的时候下发给HAL.
HAL中通过fwkCameraId找到logicalCameraId, 然后通过logicalCameraId找到物理cameraId, 然后操作对应的物理设备.
四个文件的使用
在get_number_of_cameras流程中, 涉及四个文件, 下面分析四个文件的使用,
重点关注相机信息表和cameraID映射关系的建立.
devicetree中的xxx_camera-sensor.dtsi文件
代码路径: vendor/qcom/proprietary/devicetree/qcom/camera/renoir-sm7350-camera-sensor.dtsi
每个camera在dtsi文件中都有对应的配置信息.
在KMD中 probe sensor的driver时候解析, 其中用cell-index标识具体的物理camera. 假如手机有4个camera, cell-index依次为0, 1, 2, 3
// wide camera qcom,cam-sensor0 { cell-index = <0>; compatible = "qcom,cam-sensor"; csiphy-sd-index = <1>; sensor-position-roll = <90>; sensor-position-pitch = <0>; sensor-position-yaw = <180>; eeprom-src = <&eeprom_wide>; actuator-src = <&actuator_wide>; led-flash-src = <&led_flash_wide>; cam_vio-supply = <&L5I>; cam_vdig-supply = <&L1I>; cam_vana-supply = <&L6I>; cam_vaf-supply = <&L3I>; cam_clk-supply = <&cam_cc_titan_top_gdsc>; regulator-names = "cam_vio", "cam_vdig", "cam_vana", "cam_vaf", "cam_clk"; };
其中,cell-index = <0>; 是重点。
cameraModuleData文件
代码路径: vendor/qcom/proprietary/chi-cdk/oem/qcom/module/renoir_module/renoir_ofilm_s5kgw3_wide_module.xml
每个模组都有对应的cameraModuleData文件, 模组中包括sensor, eeprom, flash等模块的信息.
文件中的cameraId和dtsi文件中的cell-index一样, 标识具体的物理camera. 如果是同一camera, 这两个值必须一样.
通过sensorName可以找到对应的sensorDriverData.
<cameraModuleData <!--Module group can contain either 1 module or 2 modules Dual camera, stereo camera use cases contain 2 modules in the group --> <moduleGroup> <!--Module configuration --> <moduleConfiguration description="Module configuration"> <!--CameraId is the id to which DTSI node is mapped. Typically CameraId is the slot Id for non combo mode. --> <cameraId>0</cameraId> <!--Name of the sensor in the image sensor module --> <sensorName>renoir_ofilm_s5kgw3_wide</sensorName> <!--Name of the module integrator --> <moduleName>renoir</moduleName> <!--Actuator name in the image sensor module This is an optional element. Skip this element if actuator is not present --> <actuatorName>renoir_ofilm_s5kgw3_dw9800_wide</actuatorName> <!--EEPROM name in the image sensor module This is an optional element. Skip this element if EEPROM is not present --> <eepromName>renoir_ofilm_s5kgw3_gt24p128e_wide_eeprom</eepromName> <!--Flash name is used to used to open binary. Binary name is of form flashName_flash.bin Ex:- pmic_flash.bin --> <position>REAR</position> <!--CSI Information --> </moduleConfiguration> </moduleGroup> </cameraModuleData>
重点:
<cameraId>0</cameraId> <!--Name of the sensor in the image sensor module --> <sensorName>renoir_ofilm_s5kgw3_wide</sensorName>
sensorDriverData文件
代码目录: chi-cdk/oem/qcom/sensor/renoir_sensor/renoir_ofilm_s5kgw3_wide_sensor/gedit s5kgw3_sensor.xml
sensorDriverData文件中定义了camera sensor的I2C slaveAddress 和 sensorId等信息.
枚举物理camera的过程 (ProbeImageSensorModules)
- 传入slaveAddress, 通过I2C读取sensorId对应的寄存器,
- 读出的值与文件中的sensorId值匹配, 如果相同, 则probe sensor成功.
- probe成功的个数就是物理camera的个数.
<sensorDriverData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../api/sensor/camxsensordriver.xsd"> <module_version major_revision="1" minor_revision="0" incr_revision="0"/> <!--Sensor slave information --> <slaveInfo> <!--Name of the sensor --> <sensorName>renoir_ofilm_s5kgw3_wide</sensorName> <!--8-bit or 10-bit write slave address --> <slaveAddress>0x20</slaveAddress> <!--Register address / data size in bytes --> <regAddrType range="[1,4]">2</regAddrType> <!--Register address / data size in bytes --> <regDataType range="[1,4]">2</regDataType> <!--Register address for sensor Id --> <sensorIdRegAddr>0x0000</sensorIdRegAddr> <!--Sensor Id --> <sensorId>0x7309</sensorId> <!--Mask for sensor id. Sensor Id may only be few bits --> <sensorIdMask>0xFFFFFFFF</sensorIdMask> <!--I2C frequency mode of slave
logicalcamerainfo文件(相机信息表)
路径: vendor/qcom/proprietary/chi-cdk/oem/qcom/multicamera/logicalcamerainfo/renoir/renoir.xml
每个手机都有对应的logicalcamerainfo文件, 例如K9使用renoir.xml, 文件中定义了当前手机中相机情况,
- 包括有几个单摄, 几个多摄和VT camera, 各个相机的功能是什么, 使用的fwkCameraId是什么, 对应的物理camera是什么.
- 文件中的 slotId 和 ‘cameraModuleData文件中的cameraId’, 以及 ‘dtsi文件中的cell-index’ 一样, 标识具体的物理sensor.
- 文件中的cameraId其实是返回给APP的fwkCameraId.
- name=“RearPhysicalCam” slotId=”0″ cameraId=”0″, 表示后置摄像头, 物理cameraId是0, fwkCameraId是0
- “MultiCamera”用于SAT, 它fwkCameraId是4, 使用Ultra (slotId 为3) 和 Rear (slotId 为0)两个摄像头.
- 在BuildLogicalCameraInfo阶段, 会将文件中的信息整理保存到全局数据区m_logicalCameraInfo中.
- 文件中定义的相机的总数, 就是get_number_of_cameras返回给APP的FwkCameraNums.
<Devices <PhysicalDevice name="RearPhysicalCam" slotId="0" cameraId="0"/> <PhysicalDevice name="FrontPhysicalCam" slotId="1" cameraId="1"/> <PhysicalDevice name="MacroPhysicalCam" slotId="2" cameraId="2"/> <PhysicalDevice name="UltraPhysicalCam" slotId="3" cameraId="3"/> <LogicalDevice name="MultiCamera" cameraId="4" primaryCamName="RearPhysicalCam"> <PhysicalDeviceRef>UltraPhysicalCam</PhysicalDeviceRef> <PhysicalDeviceRef>RearPhysicalCam</PhysicalDeviceRef> </LogicalDevice> <LogicalDevice name="bokeh" cameraId="5" primaryCamName="RearPhysicalCam"> <PhysicalDeviceRef>UltraPhysicalCam</PhysicalDeviceRef> <PhysicalDeviceRef>RearPhysicalCam</PhysicalDeviceRef> </LogicalDevice> <LogicalDevice name="VTCamera" cameraId="6" primaryCamName="RearPhysicalCam"> <PhysicalDeviceRef>RearPhysicalCam</PhysicalDeviceRef> <PhysicalDeviceRef>UltraPhysicalCam</PhysicalDeviceRef> <PhysicalDeviceRef>MacroPhysicalCam</PhysicalDeviceRef> </LogicalDevice> <LogicalDevice name="VTCameraFront" cameraId="7" primaryCamName="FrontPhysicalCam"> <PhysicalDeviceRef>FrontPhysicalCam</PhysicalDeviceRef> <PhysicalDeviceRef>RearPhysicalCam</PhysicalDeviceRef> </LogicalDevice> </Devices>
生成 logicalCameraId
上述分析, 得到了fwkCameraId, 物理cameraId. 我们在HAL中实际使用的是logicalCameraId, 这个logicalCameraId怎么来?
把全局数组m_logicalCameraInfo的下标当做logicalcameraId.
为了统一管理, HAL中会根据camera的position的顺序, 对m_logicalCameraInfo数组进行排序.
/// @brief camera sensor role/type typedef enum ChiSensorPositionType { NONE = 0, /// not part of multicamera REAR = 1, /// Rear main camera FRONT = 2, /// Front main camera REAR_AUX = 3, /// Rear Aux Camera FRONT_AUX = 4, /// Front aux camera } CHISENSORPOSITIONTYPE;
根据position使用冒泡算法进行排序
SortSensorDataObjects() { for (UINT i = 0; i < m_numberOfDataObjs; i++) { for (UINT j = 0; j< m_numberOfDataObjs - i - 1; j++) { m_ppDataObjs[j]->GetCameraPosition(&tmpPosition0); m_ppDataObjs[j+1]->GetCameraPosition(&tmpPosition1); if (tmpPosition0 > tmpPosition1) { pTmpImageSensorModuleData = m_ppDataObjs[j]; m_ppDataObjs[j] = m_ppDataObjs[j + 1]; m_ppDataObjs[j + 1] = pTmpImageSensorModuleData; } } } }
logicalcameraId 最终顺序
- 多摄ID按照logicalcamerainfo文件中定义的顺序.
- 单摄ID顺序为: REAR (cameraId 0) — > FRONT (cameraId 1) –> REAR_AUX(cameraId 2) –> FRONT_AUX (cameraId 3)
多个 REAR_AUX camera情况, 比如有macro和ultra, 他们的position相同 , 他们的logicalcameraId怎么确定?
多个 REAR_AUX camera的排序
- 由HAL读取cameraModuleData的bin文件的顺序决定, 先被读到的排在前面.
- bin文件的读取顺序跟d_off的属性相关. 不同的rom版本中的bin文件的d_off属性不同, logicalCameraId的顺序也会不同.
排序只影响了logicalCameraId, 并不影响frameworkId和CameraId的对应关系.
RoleId和fwkcameraId的对应关系
HAL为相机定义了RoleId的概念, 并且建立了fwkcameraId 和 RoleId的对应关系, 如下所示:
然后将这个对应关系以TAG的形式传递给APP.
fwkcameraId RoleId std::map<UINT32, UINT32> CameraConfigFwr2RoleId = { {0, RoleIdRearWide }, {1, RoleIdFront }, {2, RoleIdRearMacro2x}, {3, RoleIdRearUltra }, {4, RoleIdRearSat }, {5, RoleIdRearBokeh }, {6, RoleIdRearVt }, {7, RoleIdFrontVt }, };
enum CameraRoleId { RoleIdTypeNone = -1, // used for diagcheck RoleIdRearWide = 0, RoleIdFront = 1, RoleIdRearTele = 20, RoleIdRearUltra = 21, RoleIdRearMacro = 22, RoleIdRearTele4x = 23, RoleIdRearMacro2x = 24, };
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/157586.html