MTK HAL3 基本内容


HAL3 是一个总线型的设计结构,本文先对 HAL3 的控制流进行总体概述,理解整个 HAL3 的主干框架,便于后续深入研究各个细节。

主干流程

以下全部摘抄 Google 官方网站上面介绍的 Camera 流程。
https://source.android.google.cn/devices/camera/camera3?hl=en

枚举、打开相机设备并创建有效的会话(session)

在初始化完成之后(这个初始化我觉得是 framework 层的服务初始化完成),framework 就会监听现有的 camera provider,camera provider 是在 ICameraProvider 接口实现的(AIDL 类型的接口),如果发现系统里面有的话就会建立一个连接。
framework 通过ICameraProvider::getCameraIdList接口来进行设备的枚举,其实这里并没有调用到具体设备相关的 HAL3 内部,因为在 provider 初始化的时候就已经调用过了,这里只是把 provider 里面保存下来的 camera list 返回给上层的 framework。
framework 实例化一个新的 ICameraDevice,实例化过程是 ICameraProvider::getCameraDeviceInterface_VX_X() 来完成的。
framework 调用 ICameraDevice::open() 接口来打开并且创建一个新的 ICameraDeviceSession 来完成后续的控制过程。

使用刚才创建好的 session 进行具体的业务逻辑处理

framework 通过ICameraDeviceSession::configureStreams()接口来向设备相关的 HAL 层传递用户所需的 stream 配置,同时 HAL 内部会根据传递下来的 stream 来选择具体的业务进行配置。
framework 通过 ICameraDeviceSession::constructDefaultRequestSettings() 接口来获取一个默认的具体业务场景配置,这个操作可以在 ICameraDevice::open() 之后的任何时刻执行,后面说下这个 constructDefaultRequestSettings() 接口的内容。
framework 使用上面构建的默认 setting,再佐以自己需要的特殊配置,然后发送第一个 request 请求到 HAL 里面去。这个 request 里面必须包含至少一个之前配置好的 stream(没错,它们的地址必须相同,不能够使用 copy 的方式重新新建一个 stream,并且这个 stream 地址与使用由 framework&app 去维护),因为要输出 buffer 给 framework 那边。上面的 request 使用 ICameraDeviceSession::processCaptureRequest() 进行传递,HAL 内部需要阻塞本次 request 请求,直到准备好接受下一个 request 的时候才返回。
framework 持续调用 ICameraDeviceSession::processCaptureRequest() 进行 request 的下发,如果需要切换其它场景的话就再次调用ICameraDeviceSession::constructDefaultRequestSettings()进行具体场景的默认 setting 构建。
当本次 request 开始被 HAL 正式执行的时候,也就是 HAL 底下的硬件 sensor 开始曝光本帧的时候(sensor starts exposing for capture),HAL 需要调用 framework 实现的 ICameraDeviceCallback::notify() 函数进行 SHUTTER 消息回调,这个消息里面包含了时间戳数据和 frame number。这个是 HAL 层主动发起的回调,但是不需要再第一个 request 下发下去之前就开始回调,并且一个 request 的 notify 完成之前,不要返回任何 result 给到 framework。
经过几个 pipeline 延迟之后,HAL 开始向 framework 返回已经完成的结果,返回过程通过 ICameraDeviceCallback::processCaptureResult() 函数完成,返回的顺序得是按照提交的 request 请求的顺序来,request 也可以一次性下发多个,数量取决于 request 的队列深度,一般 6~8 个吧,也取决于具体的平台和其代码实现。
上面的过程会不断地进行循环,等到一定时刻,会发生以下事件
framework 停止下发 request 请求,然后等待所有的 buffer 被填充完毕并且所有的 result 全部返回,这个时候再次调用 ICameraDeviceSession::configureStreams() 接口重新配置业务流,这在 HAL 内部会导致整个的硬件被重置一遍,然后用新的 stream 重新配置,接下来继续上面的循环。这说白了就是场景的切换,比如从拍照切换到录像(不关闭 camera app)。
framework 可能会调用ICameraDeviceSession::close()接口来结束整个会话,该函数可以在任何时候进行调用,但是 framework 在调用该函数的时候不可以继续下发 request,并且所有其它的函数调用都不能够进行下去,在 close 函数返回之后,HAL 层不得再回调 framework 的函数。其实在 close 之前,通常会有 flush 函数调用,这个函数的调用要求与 close 差不多,close 可以认为就是个收尾动作,flush 会等待所有的 request 完成并且所有的 result 全部返回到 framework。
当发生错误或者其它异步事件的时候,HAL 必须调用 ICameraDeviceCallback::notify() 函数来返回错误消息给 framework。如果 HAL 内部发生了严重的设备错误,HAL 内部在回复完错误消息之后需要按照 close 函数被调用时候的动作来清理案发现场。同时,在调用 notify 之前,也应该停止所有的尚在队列中的 request 请求响应,严重错误传递给 framework 的时候,HAL 不再返回任何结果给到 framework,并且在 framework 尝试调用 close 的时候需要返回 -ENODEV 或者 NULL。
在这里插入图片描述
上面就是整体上站在 framework 角度上来描述一个 camera 业务逻辑的生命周期完整的过程,有以下几个关键步骤:

设备枚举
session 创建
stream 配置,request 构建与下发
result 返回和 notify 事件回调
清理现场

下面从这些关键点来稍微概述它们的工作以及基本的实现原理

设备枚举
设备的枚举有两个层面意义上的枚举,第一个是在 provider 初始化的时候向 HAL 层内部的枚举,另一个是 framework 向 provider 索要的设备枚举过程,两者是不太一样的,至少其发生的时间是不一样的。

在 provider 创建的时候,也就是 CameraProviderImpl,这里有一个点,就是旧的 Android P 的代码,只有一个 Provider 的实现,但是新代码里面扩展了两个,这个以后再说。创建的时候会去获取 HAL 内部定义的 camera_module_t 结构体,然后创建一个新的 Google HAL 层的 CameraModule 抽象,以后的很多配置获取相关的操作都是使用这个 CameraModule 进行中转。

在 CameraModule 创建之后,Provider 就会继续获取设备上面枚举出来的 Camera 数量,然后再遍历所有的 Camera,调用其 get_camera_info 回调函数把 camera 的信息给保存起来,注意这个时候 Camera 设备名的枚举还没有送往 framework 层,而是保存在了 Provider 的一个 map 数组里面,这里只是检查下时候 Camera 设备是否兼容,把兼容的设备放在 map 数组里面去。

然后在 framework 想去获取设备列表的时候,就调用 Provider 的 getCameraIdList 进行设备名列表的获取,这个调用过程依然是通过 HIDL 完成的,媒介就是 Binder 这个跨进程通信工具。

在枚举过程完成之后,就会调用 getCameraDeviceInterface_VX_X 进行设备的创建,这个函数的实现也是在 CameraProviderImpl 里面实现的,之后这个设备的构造函数被调用,正式创建一个与 Camera device id 相关联的 CameraDevice 实体类,最后 framework 会调用这个类的 open 接口,在 open 函数里面会调用到 HAL 底层实现的 open,并且会创建一个 Google HAL 层的 CameraDeviceSession

然后呢,这个 Session 就是后续进行各种操作的基础类了,非常重要,等于说是 framework 通过 Provider 搭建了一个平台,然后平台之上催生了 CameraDeviceSession 这个交通枢纽,所有后期与业务逻辑紧密相关的调用操作都是通过这个交通枢纽来完成的,比如 configure_streams,processCaptureRequest,flush,close 等。

session 的创建
session 附属于 device 下面,很多重要的操作全部都是使用 session 来完成的。

struct camera3_device_ops_t {
	  initialize
	  configure_streams
	  construct_default_request_settings
	  process_capture_request
	  dump
	  flush  
}

另外在 session 里面还附加了一些回调函数,比如 notify、processCaptureResult 这样的回调,这些回调函数的实现是从 HAL 内层往 Google HAL 以至于 framework 层进行回调的。session 里面还简单的对 request 进行了队列的创建与管理,还对 stream 与 buffer 进行了简单的构建与管理。

总之 ,session 的角色就是重要交通枢纽,很多的重要操作以及数据资源都需要从它这里经过。

另外,上面讨论的 Provider 是 2.4 版本,CameraModule 是 1.0 版本,CameraDevice、CameraDeviceSession 都是基于 3.2 这个版本进行的,其它的版本是有不少改变的,尤其是 3.4 版本的 Device 和 3.2 就有很多的不同,这个以后再说。

constructDefaultRequestSettings
在 Camera 的世界里面,有很多种模式,这个在 Google 的官方文档里面有去定义,比如下面的几种类型:

TEMPLATE_MANUAL
TEMPLATE_PREVIEW
TEMPLATE_RECORD

还有其它的多种模板枚举定义,从它们的名字就可以看出来其基本使用场景了,这里说下手机上面的经典使用模式吧,比如普通录像模式就对应的是 TEMPLATE_RECORD,还有一种模式是在录像的时候还可以实时地进行拍照操作。TEMPLATE_ZERO_SHUTTER_LAG 是零延时拍照,按下拍照键之后就立刻给你返回一个照片,而不是等待那么一会儿延迟,可以知道,这个时候的照片其实并不是你按下拍照键那一刻的照片,而是稍前面一点的,所谓零延时拍照。

底层要构建好这样一个以 CameraMetadata 为载体的默认设置集,该 CameraMetadata 由 CameraDeviceSession 和 HAL 底层各执一份,当然源头还是在 HAL 底层,上面的都是其拷贝体,里面包含的内容就是 Google 规定的 CameraMetadata 的内容项,当然,更加具体的还是取决于 HAL 底层的实现以及部分 Google 规定好的套路化的东西。

本操作在第一次真正的 request 下发之前就已经应该执行完了,在具体的业务逻辑场景开始的时候,framework 使用默认的 CameraMetadata 进行每一帧的 request 具体参数的构建操作,这样就省去了很多的麻烦并且也能够适配好底层 HAL 的实现。

以上就是 Android HAL 在一个具体的业务逻辑的大致流程,接下来介绍一下MTK HAL的流程。

open Camera 流程
测试版本:2074C
Open camera 流程涉及Android 架构中的四个层次:App 层,Framework 层,Runtime 层,HAL层。
其中,App 层直接调用 Framework 层所封装的方法,而 Framework 层需要通过 Binder 远程调用 Runtime 层中 CameraService 的函数。
CameraService(Runtime层)与HAL层之间,通过HIDL机制进行调用。
下面开始分析相关代码。
App层
在 APP 中最初的入口是 CameraManager 类中的 openCamera,该函数主要实例化了一个 CameraOpenCallback 对象,用于处理 open 过程中的异常错误,然后获取了当前需要打开的 cameraID,
紧接着调用到 OneCameraStateMachine 中的openCamera,下一步调用 openCameraDecision 函数对当前状态进行决策,如果该 cameraID 设备已经打开,则直接再 open 一下该设备,
否则先调用closeCameraDecision 来将以前的 cameraID 的 session 和 device 关闭后再重新打开新 cameraID 的设备,最终会调用到 OneCameraImpl 中的 openCameraDevice 函数,
该函数通过获取 SystemService 的方式连接到 framework 中的 CameraManager 对象,并调用其 openCamera 函数,创建 CameraDevice.StateCallback 回调,APP 可以根据 framework 回调上来的状态进行响应的操作,
比如,当收到 onOpened 回调之后,APP 就可以开启预览。至此,open 流程已经正式进入 framework 了。
mCameraManager 是 CameraManager 类的实例。
currentCameraId 则是需要打开的相机设备号。
stateCallback 是 CameraDevice.StateCallback,是关于相机打开情况的相关回调。
backgroundHandler 则是 StateCallback 需要调用的 Handler。
Framework层
CameraManager
文件路径:/frameworks/base/core/java/android/hardware/camera2/CameraManager.java
最初的入口就是 CameraManager 的 openCamera 方法。
但通过代码可以看到,它仅仅是调用了 openCameraForUid 方法。

下面的代码忽略掉了一些参数检查相关操作,最终主要调用了 openCameraDeviceUserAsync 方法。
分析openCameraDeviceUserAsync ()代码:
首先实例化一个 CameraDeviceImpl,值得注意的是,构造时传入了 CameraDevice.StateCallback 。
然后获取 CameraDeviceCallback 实例,这是提供给远端连接到 CameraDeviceImpl 的接口。
之后,(据参考文档,HAL3 中走的是这一部分逻辑)从 CameraManagerGlobal 中获取 CameraService 的接口到本地,通过它远端调用(采用 Binder 机制) connectDevice 方法连接到相机设备。注意返回的 cameraUser 实际上指向的是远端 CameraDeviceClient 在本地接口。
为了缩短篇幅,省略了捕获异常的相关代码。
最后,将 CameraDeviceClient 设置到 CameraDeviceImpl 中进行管理。

CameraDeviceImpl
文件路径:/frameworks/base/core/java/android/hardware/camera2/Impl/CameraDeviceImpl.java
在继续向下分析打开相机流程之前,先简单看看调用到的 CameraDeviceImpl 中的方法。个人逻辑更倾向于时间上的先后有序,实际上setRemoteDevice 的调用要等到很后面去了,因为connectDevice方法会一直延申到HAL层甚至kernel层;不过对于分层编码规范来说,约定好层与层之间的接口,可以很好的解耦以及不用关心其他层的实现。setRemoteDevice 方法主要是将获取到的远端设备保存起来:
第 7 行,通过 ICameraDeviceUserWrapper 给远端设备实例加上一层封装。
第 9~21 行,是使用 Binder 机制的一些基本设置。
第 23、24 行,需要注意这个时间节点,此处触发 onOpened 与 onUnconfigured 这两个回调。
Runtime层
通过 Binder 机制,远端调用 connectDevice 函数,这个函数实现在 CameraService 类中。
CameraService
文件路径:/frameworks/av/services/camera/libcameraservice/CameraService.cpp
观察 connectDevice() 的实现:
第 22~25 行,此处调用的 connectHelper() 函数才真正实现了连接逻辑(HAL1 最终也调用到这个方法)。需要注意的是,设定的模板类型是 ICameraDeviceCallbacks 以及 CameraDeviceClient。
第 25 行,注意 client 指向的类型是 CameraDeviceClient,其实例则是最终的返回结果。
HAL层
CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT中,InterfaceT被定义为device::V3_2::ICameraDevice,而
CameraDevice3Impl.cpp是MTK对HAL接口ICameraDevice的实现,所以会调用到CameraDevice3Impl::open();
CameraDevice3Impl.cpp
source\vendor\mediatek\proprietary\hardware\mtkcam3\main\hal\device\3.x\device\CameraDevice3Impl.cpp
从log来看,确实先执行了CameraDevice3Impl::open(),但之后执行的是HidlCameraDevice3.cpp 中的HidlCameraDevice3::open() 在HidlCameraDevice3::open(),调用了HidlCameraDeviceSession::create(),HidlCameraDeviceSession::create()中就是创建了一个HidlCameraDeviceSession对象。
mSession的open函数,mSession是ICameraDevice3Session的对象,实现在CameraDevice3SessionImpl.cpp中。
CameraDevice3SessionImpl.cpp
source\vendor\mediatek\proprietary\hardware\mtkcam3\main\hal\device\3.x\device\CameraDevice3SessionImpl.cpp
ICameraDevice3Session::open()先后执行了mpCpuCtrl->enterCameraPerf(mCpuPerfTime)、status = pDeviceManager->startOpenDevice(instanceName)、,启动了CommandHandler线程,执行关键函数onOpenLocked(callback)以及
最终的pDeviceManager->finishOpenDevice(instanceName, true/cancel/)。
CameraDeviceManagerBase.cpp
source\vendor\mediatek\proprietary\hardware\mtkcam3\main\hal\devicemgr\base\CameraDeviceManagerBase.cpp
status = pDeviceManager→startOpenDevice(instanceName),在这个函数中首先调用了status = getVirtualDeviceLocked(deviceName, nullptr, &pVirtualDevice)位于CameraDeviceManagerBase_utils.cpp,大意就是根据deviceName,在mVirtEnumDeviceMap中查找出对应的IVirtualDevice类的实例,最后赋值给pVirtualDevice
第二个调用的是status = mActiveOperation.lock(pVirtualDevice, ActiveOperation::OPEN),根据注释理解:
save the caller’s information, which will be validated in future
第三个调用了status = validateOpenLocked(pVirtualDevice),如下所示:
第四个调用了status = attachOpenDeviceLocked(pVirtualDevice),其中onAttachOpenDeviceLocked()大意是判断MTKCAM_HAVE_CAM_MANAGER是否定义,是的话就将CameraId记录到CamManager.cpp的成员变量mvOpenId中;

再回到ICameraDevice3Session::open(),startOpenDevice函数调用完成后,创建了线程——CommandHandler,在这个线程里执行了整个open camera流程最关键的一个函数——onOpenLocked(callback)。
此函数大意为先根据callback和metadata创建appStreamManager,再根据从config和设备读取的内容创建pipelineModelManager,接下来让我们具体看一看:
CameraDevice3SessionImpl.cpp-》onOpenLocked()
在这个函数中首先调用了mAppStreamManager = IAppStreamManager::create(creationInfo),这一步创建了AppStreamManager,具体的实现在AppStreamMgr.cpp中,主要做的也只是构造和初始化。
关键函数onOpenLocked()中调用的关键函数是err = pPipelineModel->open(getInstanceName(), this),在这之前先创建了PipelineModelManager,再通过PipelineModelManager获取了PipelineModel。
调用pPipelineModel->open()实际调用的是PipelineModelImpl.cpp中的PipelineModelImpl::open()。
PipelineModelImpl.cpp
source\vendor\mediatek\proprietary\hardware\mtkcam3\pipeline\model\PipelineModelImpl.cpp
在这个函数中调用了两个重要函数:第一个函数是mHalDeviceAdapter->open(),对应HalDeviceAdapter.cpp中的open函数。
先通过auto pHalSensorList = MAKE_HalSensorList()获取sensor list,再调用pHalSensorList->createSensor(),如下:
pHalSensorList→createSensor()的实现在source\vendor\mediatek\proprietary\hardware\mtkcam\drv\src\sensor\common\v1\HalSensorList.openList.cpp,这里drv\在HAL1和HAL3是共用的。
HalSensorList::createSensor()主要调用了openSensor(vSensorIndex, szCallerName)。
在HalSensorList::openSensor()中,先判断此次sensor是否在已打开的sensor list中,如果已经存在,那么仅需要返回此实例并对引用计数加一;否则就创建新的实例,并加入到open list中,如下所示:
pHalSensor = new HalSensor(),HalSensor继承于IHalSensor,定义在IHalSensor.h中,这个类包含了sensor的所有信息:
pHalSensor→onCreate(vSensorIndex)的实现在HalSensor.cpp中。

接下来就是第二个重要函数mHalDeviceAdapter->powerOn(),此函数实现于HalDeviceAdapter.cpp中,在这个函数中主要做了三件事:
首先enable secure sensor,如下所示:
第二是创建线程去power on sensor,这是关键一步,如下所示:
这里mvHalSensor保存了刚才open函数中创建的sensor实例:
mvHalSensor[i]->powerOn()的实现位于HalSensor.cpp,HalSensor::powerOn()会循环调用三次mpSensorDrv->open(sensorIdx),最终调用到ImgSensorDrv::featureControl():
从这里开始进入kernel。
调用完成后,会回到CameraDevice3SessionImpl.cpp中,将创建的pPipelineModel保存到CameraDevice3SessionImpl的成员变量mPipelineModel中。
关键函数onOpenLocked()到此执行完毕,回到ICameraDevice3Session::open(),在这里执行了pDeviceManager->finishOpenDevice(),解除了在startOpenDevice()中加的锁。
最后,回到CameraDevice3Impl.cpp,将CameraDevice3SessionImpl实例传递给framework层的ICameraDeviceSession,至此整个HAL层流程结束。

文章链接

android mtk8.1上api1录相流程,从app到hal
https://blog.csdn.net/xuhui_7810/article/details/107605482
Android Camera HAL3中拍照Capture模式下多模块间的交互与帧Result与帧数据回调
https://blog.csdn.net/gzzaigcnforever/article/details/49094107

十问

结合mtk官网的文档学习一下大体的架构,任务目标如下:
1.ICameraDeviceSession里面定义了Android的哪一些camera3的接口,每一个接口都起到什么作用?
2.MTK hal3的APPstreamMgr的代码在哪一个目录,这部分的功能有哪一些?
3.在hal层的角度如何去理解pipeline?pipeline主要是做什么的?MTK hal3有哪一些常用的pipeline,每一种pipeline用在哪些模式?
4.IpipelineMode里定义了哪一些接口,每一个接口的作用是什么?
5.常用的PipelineModelSession有哪一些?尝试着去探索各自的区别?
6.SettingPolicy是什么?列举config阶段和request阶段的SettingPolicy有哪些?思考为什么不同的PipelineModelSession各自的SettingPolicy不同?决定这些SettingPolicy的差异有哪些因素?
7.如何去理解pipeline中node的作用?常见的hwnode有哪些?学习P1node p2Streamingnode p2Capturenode JpegNode Raw16node的具体作用?
8.以HidlCameraDeviceSession为入口并结合自己用手机抓取的log追踪代码流程(open,configureStreams,processCaptureRequest)
9.从config阶段和request阶段对P1node做出深入学习,搞清楚P1node和hal3a的协同关系
10.从config阶段和request阶段对p2Streamingnode,p2Capturenode做深入学习,理解FeaturePipe的概念以及作用?理解pipelinePlugin作用以及和FeaturePipe的关系
学习参考链接:https://online.mediatek.com/QuickStart/QS00137

ApsPreviewDecisionxxx.cpp、 OCamHdrVx.cpp,大概思路流程:
1.通过预览决策,判断当前场景触发HDR算法
2.决策当前拍照帧数,拍照设置的EV 亮度值
3.执行拍照动作,将参数设置到HAL层
4.HAL层跟App 设置下来的参数,产生对应的buffer
5.Aps 接收 HAL 传回的buffer,按照需要传入算法内部处理
6.算法处理成功之后,查看输出的buffer 是否有HDR效果
7.HDR处理完成之后,图片可以正常保存
【点评】
Ev如何传入到hal,EV如何生效?这一块的核心侧重在Sensordrv P1以及hal3a的交互这里,需要开启相关的log, 结合mainlog和kernellog一起梳理一下
提示:
1)找到requst中ev是填写到哪一个tag中下发给hal的,并跟踪这个tag的代码流程
2)打开P1、hal3aRawImp、ae_mgr以及aaa_sensor_mgr的log开关追踪流程
针对HDR场景拍照request在hal层的处理流程需要补充一下。
侧重点:
1)hdr场景拍照request中带了几种streambuffer,每一个streambuffer的用途是什么?
2)如何从hal层的角度分析出拍照request走了哪些节点以及如何判断request成功callback给framework
相较于普通hdr,mfnr+hdr场景hal和aps软件行为上的差异是什么?拍照张数、callback给aps的streambuffer类型、isphidldevice流程?algolist多了哪些以及为什么会多出这些algoflag(衍生高阶)

feature基础问题
1,open的逻辑id? 答:camera ID 0
2,选择到的底层驱动sensor mode是哪一组?eeprom是否有读取成功?
答:
决策在policy中,policy是针对不同阶段做对应的配置决策。
代码路径:
mtkcam3/pipeline/policy/PipelineSettingPolicyFactoryImpl.cpp
mtkcam3/pipeline/policy/config/SensorSettingPolicy.cpp
3,理解rrzo imgo的概念是什么,大小分别是多少?
答:

5:05:25.053404  9093  9093 I mtkcam-P1HwSettingPolicy: { .imgoAlloc={ format:0x2201 2304x1728} 
.imgoDefaultRequest={format:0x2201 2304x1728} .rrzoDefaultRequest={ format:0x2205 1280x960 } 
.rssoSize=288x512 .pixelMode=0 .usingCamSV=0 }

capture看的是imgo size,rrzo是针对preview,均是P1 enque 的数据buffer,P1 node中有不同的port口输出,dump图出来会更明显。
参考第五点链接。
Imgo 和 rrzo 分别是 p1 node 两个端口出来的 raw 图,p1 node 为 sensor 出图后的第一个 node;Imgo 会比 rrzo 大,一般会等于当前 sensor mode下,sensor能出的最大size;而rrzo会比较小。一般来说,imgo 用来进行拍照,rrzo 用来预览和录像。
imgo:4640×3456
rrzo:1472×1104
mtkcam-P1HwSettingPolicy
4,进入预览5秒后,帧率是多少?曝光shutter和增益补偿gain分别是多少?
答:
onFrameAvailableFPS write_shutter set_gain
5,PDAF是否有生效?af当前的DAC大小(聚焦位置)
答:PD应该是生效的;DAC初始位置为343,会随着相机移动而变化。
af_assist_mgr af_mgr_v3
dump大全 https://online.mediatek.com/FAQ#/SW/FAQ13710

6,进入预览5秒后,帧率是多少?曝光shutter和增益补偿gain分别是多少?
答:帧率fps 20002曝光值和帧率成倒数关系Gain sensor和ISP都会有补偿,综合4120ISO 理解为gain的体现,增益越大,ISO越大,噪点越多。如夜晚拍照情况

07-05 19:56:35.624433  1135  6641 D  ae_mgr  :   [updateAEInfo2ISP] m_eSensorDev: 1 State:0
eAEstate:1CCUON:0Algo:20002/8960/4120(880) P1RealSetting:20002/8960/4120(880/0/0) P2RealSetting:20002/8960/4120(880)
P1/P2GainRatioX100:880/880 FrameDuration:33350000 Index:0(104/162) m_u4ISOIdx1StableCount:0 m_u4ISOIdx2StableCount:0
IsNeedUpdateSensor:1 i4LightValue_x10(Real):64(64) Lux:80000 FaceNum:0 RequestNum:5 MagicNum:2 u4ISOBase_1xGain:100
m_u4BinSumRatio:1 i4AEComp:0 bIsAutoDetHDR:0 i4FDEVdiff:0

关于fps,分析卡顿类问题,丢帧等类型bug:
1). 通过曝光值倒数计算
2). 通过fps关键字MtkCam/P2/MWFrameRequest: [printIOMap] P2S cam 0 MWFrame:#30 MWReq:#30, frame 31 : iomap: [0]=>img[3/1], meta[3/2],fps[29.59]
3). 通过各个node拿到的帧间隔计算。如P1看出帧,FW看callback。

push so

vendor 相关so文件生成
思路:找到修改的文件所在的文件的Android.mk 文件,搜索关键字 LOCAL_MODULE 确认生成的库文件名
如果是 include $(MTK_SHARED_LIBRARY) 则生成动态 so 库
如果是 include $(MTK_STATIC_LIBRARY) 则生成静态库文件,需要继续找到依赖该静态库生成的 so 动态库文件
以人像功能为例
修改文件为:vendor/mediatek/proprietary/custom/mt6885/hal/camera/camera_custom_stereo_setting.h

opengrok中查找该文件 ,在以下几个文件中调用

vendor/mediatek/proprietary/hardware/mtkcam/utils/LogicalCam/ HalLogicalDeviceList.cpp ——>libmtkcam.logicalmodule.so (动态so文件)

vendor/mediatek/proprietary/custom/mt6885/hal/camera/camera_custom_stereo.cpp ————> libcameracustom.camera (静态文件)————>libcameracustom.so(动态so库文件)

HalLogicalDeviceList.cpp 在android.mk 编译为 libmtkcam.logicalmodule.so 文件
路径:source/vendor/mediatek/proprietary/hardware/mtkcam/utils/LogicalCam/Android.mk

https://blog.csdn.net/yan8024/article/details/22654057

https://blog.csdn.net/smfwuxiao/article/details/8530742

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值