1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > android_驱动_qcom_【高通SDM660平台】(4) --- Camera Init 初始化流程

android_驱动_qcom_【高通SDM660平台】(4) --- Camera Init 初始化流程

时间:2023-10-19 19:51:54

相关推荐

android_驱动_qcom_【高通SDM660平台】(4) --- Camera Init 初始化流程

【高通SDM660平台】Camera Init 初始化流程

一、Camera 系统架构二、Camera Init 初始化流程2.1 CameraService 启动2.2 CameraService::instantiate()2.3 CameraService.cpp2.4 CameraService::CameraService()2.5 CameraService::onFirstRef()2.6 获取Camera数量 mModule->getNumberOfCameras()2.7 hardware层调用 get_num_of_cameras()2.8 Camera Init 初始化流程总结 三、hw_get_module()3.1 camera.sdm660.so

《【高通SDM660平台】(1) — Camera 驱动 Bringup Guide》

《【高通SDM660平台】(2) — Camera Kernel 驱动层代码逻辑分析》

《【高通SDM660平台】(3) — Camera V4L2 驱动层分析 》

《【高通SDM660平台】(4) — Camera Init 初始化流程 》

《【高通SDM660平台】(5) — Camera Open 流程》

《【高通SDM660平台】(6) — Camera getParameters 及 setParameters 流程》

《【高通SDM660平台】(7) — Camera onPreview 代码流程》

《【高通SDM660平台】(8) — Camera MetaData介绍》

《【高通SDM660平台 Android 10.0】(9) — Qcom Camera Daemon 代码分析》

《【高通SDM660平台 Android 10.0】(10) — Camera Sensor lib 与 Kernel Camera Probe 代码分析》

《【高通SDM660平台】Camera Capture 流程》

《【高通SDM660平台】Camera mm-qcamera-app 代码分析》

Open Camera是Preview、TakePicture、Record的基础,Open Camera会初始化很多对象,

而Preview、TakePicture、Record等操作是围绕着这些对象进行操作的,所以这里用Open Camera来理清各个对象间的交互关系

一、Camera 系统架构

看到一张好图,自:《sdm660–opencamera流程详细分析》

Camera模块的系统架构分为四层,从上到下分别是

Package 文件夹下的 Java 层

Framework 文件夹下的 Framework 层

Framework层下细分为:Java Framework、JNI Framework、Hardware Interface Framework 。

Hardware 文件夹下的 Hal 层

HAL 层下又细分为 Hardware Interface 与 mm-camera 层

ADIL 是 JNI Framework 层 与 Hardware Interface Framework 层 交互的接口,即 CameraClient 进程 与 CameraService 进程的交互。

HIDL 是发生在 Framework 层 与 HAL层交互的接口。

Kernel 文件夹下的 Driver 层

接下来,我们进代码分析下 Camera Init 初始化流程

二、Camera Init 初始化流程

2.1 CameraService 启动

CameraService 是一个可执行程序放在/system/bin/cameraserver,开机时通过init.rc 文件自启动。

@ frameworks/av/camera/cameraserver/cameraserver.rc

service cameraserver /system/bin/cameraserver

class main

user cameraserver

group audio camera input drmrpc

ioprio rt 4

writepid /dev/cpuset/camera-daemon/tasks /dev/stune/foreground/tasks

12345678

cameraserver 可执行程序代码如下:

@ frameworks/av/camera/cameraserver/main_cameraserver.cpp

#define LOG_TAG “cameraserver”

//#define LOG_NDEBUG 0

#include “CameraService.h”

using namespace android;

int main(int argc __unused, charargv __unused)

{

signal(SIGPIPE, SIG_IGN);

sp<span class="token operator">&lt;</span>ProcessState<span class="token operator">&gt;</span> <span class="token function">proc</span><span class="token punctuation">(</span>ProcessState<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">self</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>sp<span class="token operator">&lt;</span>IServiceManager<span class="token operator">&gt;</span> sm <span class="token operator">=</span> <span class="token function">defaultServiceManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">ALOGI</span><span class="token punctuation">(</span><span class="token string">"ServiceManager: %p"</span><span class="token punctuation">,</span> sm<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>CameraService<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">instantiate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>ProcessState<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">self</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">startThreadPool</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>IPCThreadState<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">self</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">disableBackgroundScheduling</span><span class="token punctuation">(</span>true<span class="token punctuation">)</span><span class="token punctuation">;</span>IPCThreadState<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">self</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">joinThreadPool</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

12345678910111213141516171819

2.2 CameraService::instantiate()

@ frameworks/native/include/binder/BinderService.h

public:

static status_t publish(bool allowIsolated = false) {

sp<IServiceManager> sm(defaultServiceManager());

return sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);

}

static void instantiate() {publish(); }

12345678

这段代码的意思是,向ServiceManager添加 name 为"media.camera"的service 。

String16(SERVICE::getServiceName())=============>// Implementation of BinderService<T>static char const* getServiceName() {return "media.camera"; }

new SERVICE()

=>

相当于调用 new CameraService()

12345678

2.3 CameraService.cpp

由于是还 强指针的引用类型,代码new CameraService()

在调用CameraService::CameraService()同时还会调用void CameraService::onFirstRef()

2.4 CameraService::CameraService()

主要工作如下:

定义全局 CameraService 指针对象 gCameraService初始化变量mNumberOfCameras = 0mNumberOfNormalCameras = 0mModule = NULL将当前对象保存在 全局 CameraService 指针 gCameraService 中

@ frameworks/av/services/camera/libcameraservice/CameraService.cpp

static CameraService *gCameraService; // 1. 定义全局 CameraService 指针对象

CameraService::CameraService() :

mEventLog(DEFAULT_EVENT_LOG_LENGTH),

mNumberOfCameras(0), mNumberOfNormalCameras(0),

mSoundRef(0), mModule(nullptr) {

ALOGI(“CameraService started (pid=%d)”, getpid());

gCameraService = this; // 2. 将当前对象保存在 全局 CameraService 指针中

this<span class="token operator">-&gt;</span>camera_device_status_change <span class="token operator">=</span> android<span class="token punctuation">:</span><span class="token punctuation">:</span>camera_device_status_change<span class="token punctuation">;</span>this<span class="token operator">-&gt;</span>torch_mode_status_change <span class="token operator">=</span> android<span class="token punctuation">:</span><span class="token punctuation">:</span>torch_mode_status_change<span class="token punctuation">;</span>mServiceLockWrapper <span class="token operator">=</span> std<span class="token punctuation">:</span><span class="token punctuation">:</span>make_shared<span class="token operator">&lt;</span>WaitableMutexWrapper<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mServiceLock<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

12345678910111213141516

2.5 CameraService::onFirstRef()

主要工作如下:

加载 hal 层 camera module,保存在rawModule中 ,module定义在hardware/libhardware/include/hardware/camera_common.h初始化CameraModule对像,将camera_module_t *rawModule保存在mModule中调用 Camera HAL module 的init方法,调用mModule->get_number_of_cameras(),用来设置mCameraInfoMapvector 的容量打印hardware camera module的 name ,hal 层代码定义在hardware/qcom/camera/QCamera2/QCamera2Hal.cpp获取 camera 个数,保存在CameraService的私有变量mNumberOfCamerasmNumberOfNormalCameras中初始化CameraFlashlight模块,根据 camera number 初始化mHasFlashlightMapvector 数组变量调用mModule->getCameraInfo()返回hal 层mHalDescriptors 的信息,保存在 info 中通过 BpCameraServiceProxy 远程调用 BnCameraService 的 pingForUserUpdate() 函数

@ frameworks/av/services/camera/libcameraservice/CameraService.cppvoid CameraService::onFirstRef(){ALOGI("CameraService process starting");BnCameraService::onFirstRef();

<span class="token comment">// 1. 加载 hal 层 camera module,保存在 rawModule 中</span><span class="token comment">// #define CAMERA_HARDWARE_MODULE_ID "camera"</span><span class="token comment">// module定义在 hardware/libhardware/include/hardware/camera_common.h </span>camera_module_t <span class="token operator">*</span>rawModule<span class="token punctuation">;</span> <span class="token keyword">int</span> err <span class="token operator">=</span> <span class="token function">hw_get_module</span><span class="token punctuation">(</span>CAMERA_HARDWARE_MODULE_ID<span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token keyword">const</span> hw_module_t <span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>rawModule<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 2. 初始化 CameraModule 对像,将 camera_module_t *rawModule 保存在 mModule 中</span>mModule <span class="token operator">=</span> new <span class="token function">CameraModule</span><span class="token punctuation">(</span>rawModule<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 3. 调用 Camera HAL module 的 init 方法</span><span class="token comment">// 从 hardware/libhardware/include/hardware/camera_common.h 中得知 </span><span class="token comment">// #define CAMERA_MODULE_API_VERSION_CURRENT CAMERA_MODULE_API_VERSION_2_4</span><span class="token comment">// 因此,hal 层代码位于 hardware/qcom/camera/QCamera2/QCamera2Hal.cpp</span>err <span class="token operator">=</span> mModule<span class="token operator">-&gt;</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span><span class="token operator">+</span>@ frameworks<span class="token operator">/</span>frameworks<span class="token operator">-</span>new<span class="token operator">/</span>av<span class="token operator">/</span>services<span class="token operator">/</span>camera<span class="token operator">/</span>libcameraservice<span class="token operator">/</span>common<span class="token operator">/</span>CameraModule<span class="token punctuation">.</span>cpp<span class="token operator">+</span><span class="token keyword">int</span> CameraModule<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token operator">+</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">getModuleApiVersion</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&gt;=</span> CAMERA_MODULE_API_VERSION_2_4 <span class="token operator">&amp;&amp;</span> mModule<span class="token operator">-&gt;</span>init <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token operator">+</span> <span class="token function">ATRACE_BEGIN</span><span class="token punctuation">(</span><span class="token string">"camera_module-&gt;init"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span> res <span class="token operator">=</span> mModule<span class="token operator">-&gt;</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 从 QCamera2Hal.cpp 中得知,init = NULL</span><span class="token operator">+</span> <span class="token punctuation">}</span><span class="token operator">+</span> mCameraInfoMap<span class="token punctuation">.</span><span class="token function">setCapacity</span><span class="token punctuation">(</span><span class="token function">getNumberOfCameras</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 设置CameraInfoMap vector的大小</span><span class="token operator">+</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span><span class="token operator">+</span>numCameras <span class="token operator">=</span> mModule<span class="token operator">-&gt;</span><span class="token function">get_number_of_cameras</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span> <span class="token keyword">return</span> res<span class="token punctuation">;</span><span class="token operator">+</span><span class="token punctuation">}</span><span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token comment">// 4. 打印 hardware camera module 的name ,定义在 hardware/qcom/camera/QCamera2/QCamera2Hal.cpp</span><span class="token function">ALOGI</span><span class="token punctuation">(</span><span class="token string">"Loaded \"%s\" camera module"</span><span class="token punctuation">,</span> mModule<span class="token operator">-&gt;</span><span class="token function">getModuleName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "QCamera Module"</span><span class="token comment">// 5. 获取 camera 个数,保存在CameraService 的私有变量 mNumberOfCameras 及 mNumberOfNormalCameras 中</span>mNumberOfCameras <span class="token operator">=</span> mModule<span class="token operator">-&gt;</span><span class="token function">getNumberOfCameras</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>mNumberOfNormalCameras <span class="token operator">=</span> mNumberOfCameras<span class="token punctuation">;</span><span class="token comment">// 6. 初始化 CameraFlashlight 模块,根据 camera number 初始化 mHasFlashlightMap vector 数组变量</span>mFlashlight <span class="token operator">=</span> new <span class="token function">CameraFlashlight</span><span class="token punctuation">(</span><span class="token operator">*</span>mModule<span class="token punctuation">,</span> <span class="token operator">*</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span>status_t res <span class="token operator">=</span> mFlashlight<span class="token operator">-&gt;</span><span class="token function">findFlashUnits</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 7. 调用mModule-&gt;getCameraInfo()</span><span class="token keyword">int</span> latestStrangeCameraId <span class="token operator">=</span> INT_MAX<span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> mNumberOfCameras<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>String8 cameraId <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"%d"</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// Get camera info</span><span class="token keyword">struct</span> camera_info info<span class="token punctuation">;</span>bool haveInfo <span class="token operator">=</span> true<span class="token punctuation">;</span>status_t rc <span class="token operator">=</span> mModule<span class="token operator">-&gt;</span><span class="token function">getCameraInfo</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token operator">&amp;</span>info<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 8. 返回 hardware 层 mHalDescriptors 的信息,保存在 info 中</span><span class="token comment">// Defaults to use for cost and conflicting devices</span><span class="token keyword">int</span> cost <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span><span class="token keyword">char</span><span class="token operator">*</span><span class="token operator">*</span> conflicting_devices <span class="token operator">=</span> nullptr<span class="token punctuation">;</span>size_t conflicting_devices_length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">// If using post-2.4 module version, query the cost + conflicting devices from the HAL</span><span class="token keyword">if</span> <span class="token punctuation">(</span>mModule<span class="token operator">-&gt;</span><span class="token function">getModuleApiVersion</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&gt;=</span> CAMERA_MODULE_API_VERSION_2_4 <span class="token operator">&amp;&amp;</span> haveInfo<span class="token punctuation">)</span> <span class="token punctuation">{</span>cost <span class="token operator">=</span> info<span class="token punctuation">.</span>resource_cost<span class="token punctuation">;</span>conflicting_devices <span class="token operator">=</span> info<span class="token punctuation">.</span>conflicting_devices<span class="token punctuation">;</span>conflicting_devices_length <span class="token operator">=</span> info<span class="token punctuation">.</span>conflicting_devices_length<span class="token punctuation">;</span><span class="token punctuation">}</span>std<span class="token punctuation">:</span><span class="token punctuation">:</span>set<span class="token operator">&lt;</span>String8<span class="token operator">&gt;</span> conflicting<span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> conflicting_devices_length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>conflicting<span class="token punctuation">.</span><span class="token function">emplace</span><span class="token punctuation">(</span><span class="token function">String8</span><span class="token punctuation">(</span>conflicting_devices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// Initialize state for each camera device</span><span class="token punctuation">{</span>Mutex<span class="token punctuation">:</span><span class="token punctuation">:</span>Autolock <span class="token function">lock</span><span class="token punctuation">(</span>mCameraStatesLock<span class="token punctuation">)</span><span class="token punctuation">;</span>mCameraStates<span class="token punctuation">.</span><span class="token function">emplace</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> std<span class="token punctuation">:</span><span class="token punctuation">:</span>make_shared<span class="token operator">&lt;</span>CameraState<span class="token operator">&gt;</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> cost<span class="token punctuation">,</span> conflicting<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">if</span> <span class="token punctuation">(</span>mFlashlight<span class="token operator">-&gt;</span><span class="token function">hasFlashUnit</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>mTorchStatusMap<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> ICameraServiceListener<span class="token punctuation">:</span><span class="token punctuation">:</span>TORCH_STATUS_AVAILABLE_OFF<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">if</span> <span class="token punctuation">(</span>mModule<span class="token operator">-&gt;</span><span class="token function">getModuleApiVersion</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&gt;=</span> CAMERA_MODULE_API_VERSION_2_1<span class="token punctuation">)</span> <span class="token punctuation">{</span>mModule<span class="token operator">-&gt;</span><span class="token function">setCallbacks</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 9. 通过 BpCameraServiceProxy 远程调用 BnCameraService 的 pingForUserUpdate() 函数</span><span class="token comment">// 远程函数位于 IMPLEMENT_META_INTERFACE(CameraServiceProxy, "android.hardware.ICameraServiceProxy");</span>CameraService<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">pingCameraServiceProxy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

123456789101112131415161718192223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889

2.6 获取Camera数量 mModule->getNumberOfCameras()

进入hardware 层代码中:

@ hardware/qcom/camera/QCamera2/QCamera2Hal.cpp

camera_module_t HAL_MODULE_INFO_SYM = {

.common = camera_common,

.get_number_of_cameras = qcamera::QCamera2Factory::get_number_of_cameras,

.get_camera_info = qcamera::QCamera2Factory::get_camera_info,

.set_callbacks = qcamera::QCamera2Factory::set_callbacks,

.get_vendor_tag_ops = qcamera::QCamera3VendorTags::get_vendor_tag_ops,

.open_legacy = qcamera::QCamera2Factory::open_legacy,

.set_torch_mode = qcamera::QCamera2Factory::set_torch_mode,

.init = NULL,

.reserved = {0}

};

12345678910111213

首先初始化gQCamera2Factory对像,接着判断当前camera hal 层走 HAL1 还是 HAL3,调用对应的接口。

camera 个数是直接返回的变量mNumOfCameras_expose

mNumOfCameras_expose变量是在gQCamera2Factory()中赋值的。

接着,通过判定是否支持 双摄,来调用不同的getNumberOfCameras()函数

@ hardware/qcom/camera/QCamera2/QCamera2Factory.cpp

int QCamera2Factory::get_number_of_cameras()

{

int numCameras = 0;

if (!gQCamera2Factory) {

gQCamera2Factory = new QCamera2Factory();

}

#ifdef QCAMERA_HAL1_SUPPORT

if(gQCameraMuxer)

numCameras = gQCameraMuxer->get_number_of_cameras();

else

#endif

numCameras = gQCamera2Factory->getNumberOfCameras();

===> return mNumOfCameras_expose;

<span class="token function">LOGH</span><span class="token punctuation">(</span><span class="token string">"num of cameras: %d"</span><span class="token punctuation">,</span> numCameras<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> numCameras<span class="token punctuation">;</span>

}

12345678910111213141516171819

接下来进入函数QCamera2Factory()看下:

打开/dev/mediax节点 获取camera 的个数,保存在g_cam_ctrl.num_cam返回g_cam_ctrl.num_cam_to_expose = g_cam_ctrl.num_cam - is_secure;,此处我们没有 secure ,所就它就是camera 个数判断当前Camera系统 是否支待 HAL3,且如果没有定义QCAMERA_HAL1_SUPPORT,则默认支持 HAL3判断当前Camera系统是否支持双摄,如果是走HAL3 ,即未定义QCAMERA_HAL1_SUPPORT,默认不支待双摄判断当前Camera系统中所有camera是否走的是HAL3, YUV sensor是只能走HAL1 了更新 mHalDescriptors 中每个camear id 所对应的 HAL API VERSION

QCamera2Factory::QCamera2Factory(){mHalDescriptors = NULL;mCallbacks = NULL;mNumOfCameras = get_num_of_cameras();// 1. 打开/dev/mediax 节点 获取camera 的个数,保存在g_cam_ctrl.num_cammNumOfCameras_expose = get_num_of_cameras_to_expose(); // 2. 返回 g_cam_ctrl.num_cam_to_expose = g_cam_ctrl.num_cam - is_secure; ,此处我们没有 secure ,所就它就是camera 个数int bDualCamera = 0;char propDefault[PROPERTY_VALUE_MAX];char prop[PROPERTY_VALUE_MAX];// 3. 判断当前Camera系统 是否支待 HAL3,且如果没有定义QCAMERA_HAL1_SUPPORT ,则默认支持 HAL3property_get("persist.camera.HAL3.enabled", prop, "0");int isHAL3Enabled = atoi(prop);#ifndef QCAMERA_HAL1_SUPPORTisHAL3Enabled = 1;#endif

<span class="token comment">// 4. 判断当前Camera系统是否支持双摄,如果是走HAL3 ,即未定义QCAMERA_HAL1_SUPPORT ,默认不支待双摄</span><span class="token comment">// Signifies whether system has to enable dual camera mode</span><span class="token function">snprintf</span><span class="token punctuation">(</span>propDefault<span class="token punctuation">,</span> PROPERTY_VALUE_MAX<span class="token punctuation">,</span> <span class="token string">"%d"</span><span class="token punctuation">,</span> <span class="token function">isDualCamAvailable</span><span class="token punctuation">(</span>isHAL3Enabled<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.dual.camera"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>bDualCamera <span class="token operator">=</span> <span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">LOGH</span><span class="token punctuation">(</span><span class="token string">"dualCamera:%d "</span><span class="token punctuation">,</span> bDualCamera<span class="token punctuation">)</span><span class="token punctuation">;</span>

#ifndef QCAMERA_HAL1_SUPPORT

bDualCamera = 0;

#endif

<span class="token keyword">if</span><span class="token punctuation">(</span>bDualCamera<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"Enabling QCamera Muxer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

#ifdef QCAMERA_HAL1_SUPPORT

if (!gQCameraMuxer) {

QCameraMuxer::getCameraMuxer(&gQCameraMuxer, mNumOfCameras);

if (!gQCameraMuxer) {

LOGE(“Error !! Failed to get QCameraMuxer”);

}

}

#endif

}

#ifdef QCAMERA_HAL1_SUPPORT

if (!gQCameraMuxer && (mNumOfCameras > 0) &&(mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {

#else

if ((mNumOfCameras > 0) &&(mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {

#endif

mHalDescriptors = new hal_desc[mNumOfCameras];

if ( NULL != mHalDescriptors) {

uint32_t cameraId = 0;

<span class="token comment">// 5. 判断当前Camera系统中所有camera是否走的是HAL3, YUV sensor是只能走HAL1 了</span><span class="token comment">// 6. 更新 mHalDescriptors 中每个camear id 所对应的 HAL API VERSION</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> mNumOfCameras <span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">,</span> cameraId<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>mHalDescriptors<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>cameraId <span class="token operator">=</span> cameraId<span class="token punctuation">;</span><span class="token comment">// Set Device version to 3.x when both HAL3 is enabled &amp; its BAYER sensor</span><span class="token keyword">if</span> <span class="token punctuation">(</span>isHAL3Enabled <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token punctuation">(</span><span class="token function">is_yuv_sensor</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>mHalDescriptors<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>device_version <span class="token operator">=</span> CAMERA_DEVICE_API_VERSION_3_0<span class="token punctuation">;</span><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>mHalDescriptors<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>device_version <span class="token operator">=</span> CAMERA_DEVICE_API_VERSION_1_0<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span>

}

12345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960

2.7 hardware层调用 get_num_of_cameras()

打开/dev/media0 -->(msm_config)msm_sensor_init/dev/media1 ---->(msm_camera)v4l2调用MEDIA_IOC_DEVICE_INFO获取设备信息如果判断不是msm_config则直接continue寻找entity.id = 2的所有subdev,且type=MEDIA_ENT_T_V4L2_SUBDEV , group_id=14 , name = "msm_sensor_init"找开/dev/media0 /dev/media1 ...,开始查找camear 个数,保存在g_cam_ctrl.num_cam中如果判断不是msm_config则直接continue遍历 V4L2 下camear 的个数获取所有信息,保存在g_cam_ctrl

hardware/qcom/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c

uint8_t get_num_of_cameras()

{

struct media_device_info mdev_info;

int num_media_devices = 0;

int8_t num_cameras = 0;

char subdev_name[32];

char prop[PROPERTY_VALUE_MAX];

LOGD(“E”);

memset <span class="token punctuation">(</span><span class="token operator">&amp;</span>g_cam_ctrl<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span> <span class="token punctuation">(</span>g_cam_ctrl<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>uint32_t num_entities <span class="token operator">=</span> <span class="token number">1U</span><span class="token punctuation">;</span><span class="token keyword">char</span> dev_name<span class="token punctuation">[</span><span class="token number">32</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">// 1. 打开 /dev/media0 --&gt;(msm_config)msm_sensor_init/dev/media1 ----&gt;(msm_camera)v4l2</span><span class="token function">snprintf</span><span class="token punctuation">(</span>dev_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>dev_name<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"/dev/media%d"</span><span class="token punctuation">,</span> num_media_devices<span class="token punctuation">)</span><span class="token punctuation">;</span>dev_fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span>dev_name<span class="token punctuation">,</span> O_RDWR <span class="token operator">|</span> O_NONBLOCK<span class="token punctuation">)</span><span class="token punctuation">;</span>num_media_devices<span class="token operator">++</span><span class="token punctuation">;</span><span class="token comment">// 2. 调用 MEDIA_IOC_DEVICE_INFO 获取设备信息</span>rc <span class="token operator">=</span> <span class="token function">ioctl</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">,</span> MEDIA_IOC_DEVICE_INFO<span class="token punctuation">,</span> <span class="token operator">&amp;</span>mdev_info<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span><span class="token operator">+</span><span class="token comment">// kernel/msm-4.4/drivers/media/media-device.c</span><span class="token operator">+</span><span class="token keyword">static</span> <span class="token keyword">long</span> <span class="token function">media_device_ioctl</span><span class="token punctuation">(</span><span class="token keyword">struct</span> file <span class="token operator">*</span>filp<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span> cmd<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">long</span> arg<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token operator">+</span><span class="token keyword">switch</span> <span class="token punctuation">(</span>cmd<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token operator">+</span><span class="token keyword">case</span> MEDIA_IOC_DEVICE_INFO<span class="token punctuation">:</span><span class="token operator">+</span>ret <span class="token operator">=</span> <span class="token function">media_device_get_info</span><span class="token punctuation">(</span>dev<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> media_device_info __user <span class="token operator">*</span><span class="token punctuation">)</span>arg<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span><span class="token operator">+</span><span class="token operator">-</span><span class="token function">strlcpy</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>driver<span class="token punctuation">,</span> dev<span class="token operator">-&gt;</span>dev<span class="token operator">-&gt;</span>driver<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">-</span><span class="token function">strlcpy</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>model<span class="token punctuation">,</span> dev<span class="token operator">-&gt;</span>model<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>model<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">-</span><span class="token function">strlcpy</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>serial<span class="token punctuation">,</span> dev<span class="token operator">-&gt;</span>serial<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>serial<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">-</span><span class="token function">strlcpy</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>bus_info<span class="token punctuation">,</span> dev<span class="token operator">-&gt;</span>bus_info<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>bus_info<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">-</span><span class="token operator">+</span><span class="token operator">-</span>info<span class="token punctuation">.</span>media_version <span class="token operator">=</span> MEDIA_API_VERSION<span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">-</span>info<span class="token punctuation">.</span>hw_revision <span class="token operator">=</span> dev<span class="token operator">-&gt;</span>hw_revision<span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">-</span>info<span class="token punctuation">.</span>driver_version <span class="token operator">=</span> dev<span class="token operator">-&gt;</span>driver_version<span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">-</span><span class="token function">copy_to_user</span><span class="token punctuation">(</span>__info<span class="token punctuation">,</span> <span class="token operator">&amp;</span>info<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>__info<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">+</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token keyword">case</span> MEDIA_IOC_ENUM_ENTITIES<span class="token punctuation">:</span><span class="token operator">+</span>ret <span class="token operator">=</span> <span class="token function">media_device_enum_entities</span><span class="token punctuation">(</span>dev<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> media_entity_desc __user <span class="token operator">*</span><span class="token punctuation">)</span>arg<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token punctuation">}</span><span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token comment">// 3. 如果判断不是 msm_config 则直接continue </span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>mdev_info<span class="token punctuation">.</span>model<span class="token punctuation">,</span> MSM_CONFIGURATION_NAME<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mdev_info<span class="token punctuation">.</span>model<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">close</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">)</span><span class="token punctuation">;</span>dev_fd <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">continue</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">struct</span> media_entity_desc entity<span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>entity<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>entity<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>entity<span class="token punctuation">.</span>id <span class="token operator">=</span> num_entities<span class="token operator">++</span><span class="token punctuation">;</span><span class="token comment">// 2</span><span class="token function">LOGD</span><span class="token punctuation">(</span><span class="token string">"entity id %d"</span><span class="token punctuation">,</span> entity<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 4. 寻找 entity.id = 2 的所有subdev ,且 type=MEDIA_ENT_T_V4L2_SUBDEV , group_id=14 , name = "msm_sensor_init"</span>rc <span class="token operator">=</span> <span class="token function">ioctl</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">,</span> MEDIA_IOC_ENUM_ENTITIES<span class="token punctuation">,</span> <span class="token operator">&amp;</span>entity<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span><span class="token operator">+</span> <span class="token function">media_device_enum_entities</span><span class="token punctuation">(</span>dev<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> media_entity_desc __user <span class="token operator">*</span><span class="token punctuation">)</span>arg<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-&gt;</span><span class="token operator">+</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>entity<span class="token punctuation">.</span>type <span class="token operator">=</span> MEDIA_ENT_T_DEVNODE_V4L<span class="token punctuation">;</span> <span class="token comment">// V4L</span><span class="token operator">+</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>entity<span class="token punctuation">.</span>group_id <span class="token operator">=</span> QCAMERA_VNODE_GROUP_ID<span class="token punctuation">;</span> <span class="token comment">// #define QCAMERA_VNODE_GROUP_ID 2</span><span class="token operator">+</span><span class="token operator">&lt;</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span><span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token function">LOGD</span><span class="token punctuation">(</span><span class="token string">"entity name %s type %d group id %d"</span><span class="token punctuation">,</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">,</span> entity<span class="token punctuation">.</span>type<span class="token punctuation">,</span> entity<span class="token punctuation">.</span>group_id<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>entity<span class="token punctuation">.</span>type <span class="token operator">==</span> MEDIA_ENT_T_V4L2_SUBDEV <span class="token operator">&amp;&amp;</span> entity<span class="token punctuation">.</span>group_id <span class="token operator">==</span> MSM_CAMERA_SUBDEV_SENSOR_INIT<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">snprintf</span><span class="token punctuation">(</span>subdev_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>dev_name<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"/dev/%s"</span><span class="token punctuation">,</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token function">close</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">)</span><span class="token punctuation">;</span>dev_fd <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">}</span>num_media_devices <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>uint32_t num_entities <span class="token operator">=</span> <span class="token number">1U</span><span class="token punctuation">;</span><span class="token keyword">char</span> dev_name<span class="token punctuation">[</span><span class="token number">32</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">// 5. 找开 /dev/media0 /dev/media1 ... ,开始查找camear 个数</span><span class="token function">snprintf</span><span class="token punctuation">(</span>dev_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>dev_name<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"/dev/media%d"</span><span class="token punctuation">,</span> num_media_devices<span class="token punctuation">)</span><span class="token punctuation">;</span>dev_fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span>dev_name<span class="token punctuation">,</span> O_RDWR <span class="token operator">|</span> O_NONBLOCK<span class="token punctuation">)</span><span class="token punctuation">;</span>num_media_devices<span class="token operator">++</span><span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mdev_info<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mdev_info<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>rc <span class="token operator">=</span> <span class="token function">ioctl</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">,</span> MEDIA_IOC_DEVICE_INFO<span class="token punctuation">,</span> <span class="token operator">&amp;</span>mdev_info<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 6. 如果判断不是 `msm_camera` 则直接`continue` </span><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>mdev_info<span class="token punctuation">.</span>model<span class="token punctuation">,</span> MSM_CAMERA_NAME<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mdev_info<span class="token punctuation">.</span>model<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">close</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">)</span><span class="token punctuation">;</span>dev_fd <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">continue</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">struct</span> media_entity_desc entity<span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>entity<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>entity<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>entity<span class="token punctuation">.</span>id <span class="token operator">=</span> num_entities<span class="token operator">++</span><span class="token punctuation">;</span>rc <span class="token operator">=</span> <span class="token function">ioctl</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">,</span> MEDIA_IOC_ENUM_ENTITIES<span class="token punctuation">,</span> <span class="token operator">&amp;</span>entity<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 7. 遍历 V4L2 下camear 的个数</span><span class="token keyword">if</span><span class="token punctuation">(</span>entity<span class="token punctuation">.</span>type <span class="token operator">==</span> MEDIA_ENT_T_DEVNODE_V4L <span class="token operator">&amp;&amp;</span> entity<span class="token punctuation">.</span>group_id <span class="token operator">==</span> QCAMERA_VNODE_GROUP_ID<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">strlcpy</span><span class="token punctuation">(</span>g_cam_ctrl<span class="token punctuation">.</span>video_dev_name<span class="token punctuation">[</span>num_cameras<span class="token punctuation">]</span><span class="token punctuation">,</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>entity<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"dev_info[id=%d,name='%s']\n"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>num_cameras<span class="token punctuation">,</span> g_cam_ctrl<span class="token punctuation">.</span>video_dev_name<span class="token punctuation">[</span>num_cameras<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>num_cameras<span class="token operator">++</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token function">close</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">)</span><span class="token punctuation">;</span>dev_fd <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>num_cameras <span class="token operator">&gt;=</span> MM_CAMERA_MAX_NUM_SENSORS<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">LOGW</span><span class="token punctuation">(</span><span class="token string">"Maximum number of camera reached %d"</span><span class="token punctuation">,</span> num_cameras<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span>g_cam_ctrl<span class="token punctuation">.</span>num_cam <span class="token operator">=</span> num_cameras<span class="token punctuation">;</span><span class="token comment">// 8. 获取所有信息,保存在 g_cam_ctrl 中</span><span class="token function">get_sensor_info</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 9. 重新整理 g_cam_ctrl 中的camear 顺序,确保 后摄inx 比前摄大</span><span class="token comment">/* Order of the camera exposed is0 - Back Main Camera1 - Front Main Camera++ - Back Aux Camera++ - Front Aux Camera++ - Back Main + Back Aux camera++ - Front Main + Front Aux camera++ - Secure Camera*/</span><span class="token function">sort_camera_info</span><span class="token punctuation">(</span>g_cam_ctrl<span class="token punctuation">.</span>num_cam<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">/* unlock the mutex */</span><span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"num_cameras=%d\n"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>g_cam_ctrl<span class="token punctuation">.</span>num_cam<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span><span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span>g_cam_ctrl<span class="token punctuation">.</span>num_cam<span class="token punctuation">;</span>

}

1234567891011121314151617181922232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811911122123124125126127128129130131132133134135136137138139140141142143

2.8 Camera Init 初始化流程总结

在Init 整个过程中,主要做了如下事情:

定义全局 CameraService 指针对象 gCameraService。加载 hal 层 camera module,保存在rawModule中 ,module定义在hardware/libhardware/include/hardware/camera_common.h。调用Camera hardware module 的mModule->get_number_of_cameras(),获得Camera Number。调用 MEDIA_IOC_DEVICE_INFO 获取驱动层 Camera V4L2 的所有设备信息。同时初始化 hardware 层的 mHalDescriptors 数组,更新每个Camera 使用的 camera hal1 还是 hal3。

三、hw_get_module()

在前面代码中,主要是通过hw_get_module(CAMERA_HARDWARE_MODULE_ID,(const hw_module_t **)&rawModule)来获取到驱动层的相关接口。

接下来,我们来看下hw_get_module具体做了什么操作:

@ hardware/libhardware/hardware.c

int hw_get_module(const charid, const struct hw_module_t *module)

{

return hw_get_module_by_class(id, NULL, module);

}

123456

由此可知,CameraService.cpp中调用hw_get_module,传递的参数为CAMERA_HARDWARE_MODULE_ID&rawModule

#define CAMERA_HARDWARE_MODULE_ID "camera"

进入hw_get_module_by_class()分析下:

id = "camera"inst = NULLmodule = &rawModule拼凑出 PATH_MAX = "camera"

@ hardware/libhardware/hardware.c

int hw_get_module_by_class(const charclass_id, const char inst, const struct hw_module_tmodule)

{

int i = 0;

char prop[PATH_MAX] = {0};

char path[PATH_MAX] = {0};

char name[PATH_MAX] = {0};

char prop_name[PATH_MAX] = {0};

<span class="token comment">// 1. 拼凑出 PATH_MAX = "camera"</span><span class="token keyword">if</span> <span class="token punctuation">(</span>inst<span class="token punctuation">)</span><span class="token function">snprintf</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> PATH_MAX<span class="token punctuation">,</span> <span class="token string">"%s.%s"</span><span class="token punctuation">,</span> class_id<span class="token punctuation">,</span> inst<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">else</span><span class="token function">strlcpy</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> class_id<span class="token punctuation">,</span> PATH_MAX<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 2. 拼凑出 prop_name = "ro.hardware.camera"</span><span class="token comment">/* First try a property specific to the class and possibly instance */</span><span class="token function">snprintf</span><span class="token punctuation">(</span>prop_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop_name<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"ro.hardware.%s"</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">property_get</span><span class="token punctuation">(</span>prop_name<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">hw_module_exists</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">,</span> name<span class="token punctuation">,</span> prop<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">goto</span> found<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment">/* Loop through the configuration variants looking for a module */</span><span class="token keyword">for</span> <span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">0</span> <span class="token punctuation">;</span> i<span class="token operator">&lt;</span>HAL_VARIANT_KEYS_COUNT<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">property_get</span><span class="token punctuation">(</span>variant_keys<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">continue</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">hw_module_exists</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">,</span> name<span class="token punctuation">,</span> prop<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">goto</span> found<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment">/* Nothing found, try the default */</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">hw_module_exists</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">,</span> name<span class="token punctuation">,</span> <span class="token string">"default"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">goto</span> found<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">return</span> <span class="token operator">-</span>ENOENT<span class="token punctuation">;</span>

found:

/* load the module, if this fails, we’re doomed, and we should not try

* to load a different variant. */

return load(class_id, path, module);

}

1234567891011121314151617181922232425262728293031323334353637383940414243

可以看出,在hardware.c 中,在如下三个目录依次查找 ”camera.sdm660.so“ ,找到 后,

接下来load 库文件

// @ hardware/libhardware/hardware.c#define HAL_LIBRARY_PATH1 "/system/lib64/hw"#define HAL_LIBRARY_PATH2 "/vendor/lib64/hw"#define HAL_LIBRARY_PATH3 "/odm/lib64/hw"

/*

Check if a HAL with given name and subname exists, if so return 0, otherwise

otherwise return negative. On success path will contain the path to the HAL.

/

static int hw_module_exists(charpath, size_t path_len, const charname, const char subname)

{

snprintf(path, path_len, “%s/%s.%s.so”, HAL_LIBRARY_PATH3, name, subname);

if (access(path, R_OK) == 0)

return 0;

snprintf(path, path_len, “%s/%s.%s.so”, HAL_LIBRARY_PATH2, name, subname);

if (access(path, R_OK) == 0)

return 0;

snprintf(path, path_len, “%s/%s.%s.so”, HAL_LIBRARY_PATH1, name, subname);

if (access(path, R_OK) == 0)

return 0;

return -ENOENT;

}

123456789101112131415161718192223242526

3.1 camera.sdm660.so

camera.sdm660.so文件代码位于hardware/qcom/camera/QCamera2/

# Enable SDLLVM compiler option for build flavour >= N flavourPLATFORM_SDK_NPDK = 24

LOCAL_COPY_HEADERS_TO := qcom/camera

LOCAL_COPY_HEADERS := QCameraFormat.h

LOCAL_SRC_FILES :=

util/QCameraBufferMaps.cpp

util/QCameraCmdThread.cpp

util/QCameraFlash.cpp

util/QCameraPerf.cpp

util/QCameraQueue.cpp

util/QCameraCommon.cpp

util/QCameraTrace.cpp

util/camscope_packet_type.cpp

QCamera2Hal.cpp

QCamera2Factory.cpp

#HAL 3.0 source

LOCAL_SRC_FILES +=

HAL3/QCamera3HWI.cpp

HAL3/QCamera3Mem.cpp

HAL3/QCamera3Stream.cpp

HAL3/QCamera3Channel.cpp

HAL3/QCamera3VendorTags.cpp

HAL3/QCamera3PostProc.cpp

HAL3/QCamera3CropRegionMapper.cpp

HAL3/QCamera3StreamMem.cpp

LOCAL_CFLAGS := -Wall -Wextra -Werror

#HAL 1.0 source

ifeq ($(TARGET_SUPPORT_HAL1),false)

LOCAL_CFLAGS += -DQCAMERA_HAL3_SUPPORT

else

LOCAL_CFLAGS += -DQCAMERA_HAL1_SUPPORT

LOCAL_SRC_FILES +=

HAL/QCamera2HWI.cpp

HAL/QCameraMuxer.cpp

HAL/QCameraMem.cpp

HAL/QCameraStateMachine.cpp

util/QCameraDisplay.cpp

HAL/QCameraChannel.cpp

HAL/QCameraStream.cpp

HAL/QCameraPostProc.cpp

HAL/QCamera2HWICallbacks.cpp

HAL/QCameraParameters.cpp

HAL/QCameraParametersIntf.cpp

HAL/QCameraThermalAdapter.cpp

util/QCameraFOVControl.cpp

util/QCameraHALPP.cpp

util/QCameraDualFOVPP.cpp

util/QCameraExtZoomTranslator.cpp

util/QCameraPprocManager.cpp

util/QCameraBokeh.cpp

util/QCameraClearSight.cpp

endif

LOCAL_MODULE_RELATIVE_PATH := hw

LOCAL_MODULE := camera.$(TARGET_BOARD_PLATFORM)

LOCAL_MODULE_TAGS := optional

LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)

include $(BUILD_SHARED_LIBRARY)

123456789101112131415161718192223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

参考:

《sdm660–opencamera流程详细分析》

《Android camera fw学习(二)-open camera操作过程&准备工作分析》

《高通平台Camera框架部分浅谈–Camera C/S 的init流程》

《Android6.0 camera初始化及预览流程》

</div><link href="/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet"></div>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。