💡 \frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.cpp
💡 \hardware\interfaces\camera\device\3.2\default\CameraDevice.cpp 💡 \hardware\interfaces\camera\common\1.0\default\CameraModule.cpp
这个调用是在这里做的函数指针映射:
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhal3entry.cpp
同时这里也是CamX的入口
同一个文件,看看这些函数分别都是怎么实现的:
通过一个JumpTableHAL3类型的对象pHAL3来分发(dispatch)或者说跳转到实际的实现中
g_jumpTableHAL3描述的跳转关系在
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhal3.cpp
于是到了真正调用的函数中,
开头没什么好说的,看上去就是assert一些必要的信息是否完整
接下来看,注释还是写得比较清楚的
568行,检查了一下闪光灯的情况,如果此时闪光灯处于开启状态,就关闭并留给正在打开的这个camera用
第一个红框,此时真正开始开启一个camera,调用ProcessCameraOpen
根据命名空间的提示,找到调用的位置:
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhal3module.cpp
很快啊,找到了下一步的调用,这里比较让人在意,通过m_ChiAppCallback进行调用,根据上一篇的初步理解,CHI模块应该是与Camx对接的,厂商自定义的代码,这里和App扯上关系不太明白是为什么,并且还是一个callback。这个时候应该停止揣测,read the fucking source code,接着往下跟流程
果然,源码不会骗你,这里解释了这个callback确实是向framework通知的作用
并且出现了一个看上去很重要的结构体chi_hal_callback_ops_t,注释告诉我们这是CHI的入口,看来vendor们实现的接口就通过这个callback丢上去给CamX了
理解这个变量的时候,看到一段解释非常精准清晰的话,原文来自:
深入理解Android相机体系结构之六_xiaozi63的博客-CSDN博客_深入理解android相机体系结构
“在HAL3Module构造方法中会去通过dlopen方法加载com.qti.chi.override.so库,并通过dlsym映射出CHI部分的入口方法chi_hal_override_entry,并调用该方法将HAL3Module对象中的成员变量m_ChiAppCallbacks(CHIAppCallbacks)传入CHI中,其中包含了很多函数指针,这些函数指针分别对应着CHI部分的操作方法集合中的方法,一旦进入到CHI中,就会将CHI本地的操作方法集合中的函数地址依次赋值给m_ChiAppCallbacks,这样CamX后续就可以通过这个成员变量调用到CHI中方法,从而保持了与CHI的通讯。”
跟着这段话去查看代码,过程变得无比丝滑
首先,HAL3Module的构造函数中:
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhal3module.cpp
第一个框,LibMap中通过dlopen打开so库,获得这个动态库的句柄m_hChiOverrideModuleHandle
第二个框,LibGetAddr中通过dlsym找到so库中名为chi_hal_override_entry函数的地址,并让函数指针funcCHIHALOverrideEntry指向这个地址
函数指针的定义见:
可见这个指针指向的函数接收一个类型为chi_hal_callback_ops_t的参数
第三个框,把m_ChiAppCallbacks传入funcCHIHALOverrideEntry指向的函数,也就是chi_hal_override_entry
💡 \vendor\qcom\proprietary\chi-cdk\core\chiframework\chxextensioninterface.cpp
果然,将chi中的函数和传入的m_ChiAppCallbacks联系起来,CamX就可以通过m_ChiAppCallbacks来调用CHI中的函数了
回到ProcessCameraOpen函数中,这句调用终于理顺了
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhal3module.cpp
看看chi_extend_open中做了什么
💡 \vendor\qcom\proprietary\chi-cdk\core\chiframework\chxextensioninterface.cpp
again,通过pExtensionModule来调用,看了上下几个函数都需要GetInstance来获取实例,看来这个ExtensionModule的对象是一个单例
ExtendOpen的调用位置在:
💡 \vendor\qcom\proprietary\chi-cdk\core\chiframework\chxextensionmodule.cpp
看上去做了很多设置,没有像tv一样去和V4L2进行交互
接下来,一路返回直至
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhal3.cpp
第二个框,调用HALDevice::Create去创造一个halDevice,这个HALDevice最后会用来创造一个返回给上层的Camera3Device(第三个框中)
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhaldevice.cpp
映射了几个函数到m_HALCallbacks,甚至设置了一堆参数、metadata
这里结束之后,又看回camxhal3.cpp中,这个open终于算是快结束了
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhal3.cpp
最后一个框里,ppHwDeviceAPI丢给上层,一路返回到
💡 \hardware\interfaces\camera\device\3.2\default\CameraDevice.cpp
经历了这么多创造出来的device对象,用于创建CameraDeviceSession:
接下来的调用就和上述过程类似了,从provider又到Camx
💡 \hardware\interfaces\camera\device\3.2\default\CameraDeviceSession.cpp
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhal3entry.cpp
💡 \vendor\qcom\proprietary\camx\src\core\hal\camxhal3.cpp
至此,把HALDevice注册之后,本篇也差不多该完结了
大致流程如下: