Android 5.0 Camera系统源码分析(1):CameraService启动流程

1. 前言

本文将分析Android系统源码,从frameworks层到hal层,暂不涉及app层和kernel层。由于某些函数比较复杂,在贴出代码时会适当对其进行简化。本文属于自己对源码的总结,仅仅是贯穿代码流程,不会深入分析各个细节。


分析android系统源码,需要对android系统的某些知识点有所了解

涉及的知识点有:

(1)Android系统的智能指针 - 参考老罗的Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

(2)Android进程间通信Binder - 参考老罗的Android进程间通信(IPC)机制Binder简要介绍和学习计划

(3)Android硬件抽象层(HAL) - 参考老罗的Android硬件抽象层(HAL)概要介绍和学习计划

2. frameworks层

Android的各个子模块的启动都是从它们的Service的启动开始的,所以我们将从CameraService的启动开始分析。CameraService的启动就在MediaServer的main函数中,代码路径在:frameworks/av/media/mediaserver/main_mediaserver.cpp

[cpp]  view plain  copy
  1. int main(int argc __unused, char** argv)  
  2. {  
  3.     ......  
  4.     CameraService::instantiate();  
  5.     ......  
  6. }  

CameraService类定义如下:

[cpp]  view plain  copy
  1. class CameraService :  
  2.     public BinderService<CameraService>,  
  3.     public BnCameraService,  
  4.     public IBinder::DeathRecipient,  
  5.     public camera_module_callbacks_t  
  6. {  
  7.     static char const* getServiceName() { return "media.camera"; }  
  8.     ......  
  9. }  

mediaserver的main函数中调用了CameraService的instantiate函数来创建实例,该函数的实现在其父类BinderService中实现

[cpp]  view plain  copy
  1. template<typename SERVICE>  
  2. class BinderService  
  3. {  
  4.     static status_t publish(bool allowIsolated = false) {  
  5.         sp<IServiceManager> sm(defaultServiceManager());  
  6.         return sm->addService(  
  7.                 String16(SERVICE::getServiceName()),  
  8.                 new SERVICE(), allowIsolated);  
  9.     }     
  10.   
  11.     static void instantiate() { publish(); }  
  12.   
  13. }  

1. instantiate函数只是简单的调用了publish函数

2. publish函数先构造CameraService,再通过addService函数将它注册到ServiceManager当中,而getServiceName函数获取到的值为“media camera”。这一切都是为了binder通信做准备

3. 这里使用了c++模版,从上面的CameraService类定义中可以看出,这里的SERVICE等于CameraService,也就是说publish函数中的new SERVICE等于new CameraService

4. 同时还使用了智能指针,也就是说除了调用CameraService的构造函数外,还会调用onFirstRef函数

[cpp]  view plain  copy
  1. CameraService::CameraService()  
  2.     :mSoundRef(0), mModule(0)  
  3. {  
  4.     ALOGI("CameraService started (pid=%d)", getpid());  
  5.     gCameraService = this;  
  6.   
  7.     for (size_t i = 0; i < MAX_CAMERAS; ++i) {  
  8.         mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;  
  9.     }  
  10.   
  11.     this->camera_device_status_change = android::camera_device_status_change;  
  12. }  
  13.   
  14. void CameraService::onFirstRef()  
  15. {  
  16.     LOG1("CameraService::onFirstRef");  
  17.   
  18.     BnCameraService::onFirstRef();  
  19.   
  20.     if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,  
  21.                 (const hw_module_t **)&mModule) < 0) {   
  22.         ALOGE("Could not load camera HAL module");  
  23.         mNumberOfCameras = 0;   
  24.     }      
  25.     else {  
  26.         ALOGI("Loaded \"%s\" camera module", mModule->common.name);  
  27.         mNumberOfCameras = mModule->get_number_of_cameras();  
  28.         if (mNumberOfCameras > MAX_CAMERAS) {  
  29.             ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",  
  30.                     mNumberOfCameras, MAX_CAMERAS);  
  31.             mNumberOfCameras = MAX_CAMERAS;  
  32.         }  
  33.         for (int i = 0; i < mNumberOfCameras; i++) {  
  34.             LOG1("setCameraFree(%d)", i);  
  35.             setCameraFree(i);  
  36.         }      
  37.   
  38.         if (mModule->common.module_api_version >=  
  39.                 CAMERA_MODULE_API_VERSION_2_1) {  
  40.             mModule->set_callbacks(this);  
  41.         }      
  42.   
  43.         VendorTagDescriptor::clearGlobalVendorTagDescriptor();  
  44.   
  45.         if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_2) {  
  46.             setUpVendorTags();  
  47.         }      
  48.   
  49.         CameraDeviceFactory::registerService(this);  
  50.     }      
  51. }  

第20行. 通过hw_get_module函数加载了一个hw_module_t模块,这个模块是与hal层对接的接口,ID为CAMERA_HARDWARE_MODULE_ID,并将它保存在mModule成员变量中。

第27行. 通过mModule->get_number_of_cameras函数进入到hal层,获取到了camera的个数。这个函数很重要,对于frameworks层来说只是拿到了camera的个数,但对于hal层和drivers层来说Camera的上电和初始化流程都是从这里开始的

3. hal层-基于MTK平台

先来看看mtk camera module的定义,代码路径在:vendor/mediatek/proprietary/hardware/mtkcam/module_hal/module/module.h

[cpp]  view plain  copy
  1. static  
  2. camera_module  
  3. get_camera_module()  
  4. {  
  5.     camera_module module = {   
  6.         common:{  
  7.              tag                    : HARDWARE_MODULE_TAG,  
  8.              #if (PLATFORM_SDK_VERSION >= 21)  
  9.              module_api_version     : CAMERA_MODULE_API_VERSION_2_3,  
  10.              #else  
  11.              module_api_version     : CAMERA_DEVICE_API_VERSION_1_0,  
  12.              #endif  
  13.              hal_api_version        : HARDWARE_HAL_API_VERSION,  
  14.              id                     : CAMERA_HARDWARE_MODULE_ID,  
  15.              name                   : "MediaTek Camera Module",  
  16.              author                 : "MediaTek",  
  17.              methods                : get_module_methods(),  
  18.              dso                    : NULL,  
  19.              reserved               : {0},  
  20.         },    
  21.         get_number_of_cameras       : get_number_of_cameras,  
  22.         get_camera_info             : get_camera_info,  
  23.         set_callbacks               : set_callbacks,  
  24.         get_vendor_tag_ops          : get_vendor_tag_ops,  
  25.         #if (PLATFORM_SDK_VERSION >= 21)  
  26.         open_legacy                 : open_legacy,  
  27.         #endif  
  28.         reserved                    : {0},  
  29.     };    
  30.     return  module;  
  31. };  
1. 保存在frameworks层CameraService的成员变量mModule里面的就是上面这个module结构体

2. 当frameworks层调用mModule->get_number_of_cameras函数时,实际就是调用上面结构体的get_number_of_cameras函数

[cpp]  view plain  copy
  1. CamDeviceManagerImp gCamDeviceManager;  
  2.   
  3. ICamDeviceManager*  
  4. getCamDeviceManager()  
  5. {  
  6.     return &gCamDeviceManager;  
  7. }  
  8.   
  9. static  
  10. int  
  11. get_number_of_cameras(void)  
  12. {  
  13.     return  NSCam::getCamDeviceManager()->getNumberOfDevices();  
  14. }  
1. 这里先通过getCamDeviceManager函数获取了CamDeviceManagerImp对象

2. CamDeviceManagerImp继承了CamDeviceManagerBase,这里的getNumberOfDevices方法将由父类CamDeviceManagerBase实现

[cpp]  view plain  copy
  1. int32_t  
  2. CamDeviceManagerBase::  
  3. getNumberOfDevices()  
  4. {  
  5.     mi4DeviceNum = enumDeviceLocked();  
  6.     return  mi4DeviceNum;  
  7. }  

这里只是调用了enumDeviceLocked函数,并将它的返回值(代表了camera的个数)返回到frameworks层。接着看enumDeviceLocked的实现

[cpp]  view plain  copy
  1. int32_t  
  2. CamDeviceManagerImp::  
  3. enumDeviceLocked()  
  4. {  
  5.     IHalSensorList*const pHalSensorList = IHalSensorList::get();  
  6.     size_t const sensorNum = pHalSensorList->searchSensors();  
  7.   
  8.     for (size_t i = 0; i < sensorNum; i++)  
  9.     {  
  10.         int32_t const deviceId = i;  
  11.   
  12.         sp<EnumInfo> pInfo = new EnumInfo;  
  13.         mEnumMap.add(deviceId, pInfo);  
  14.   
  15.         IMetadataProvider> pMetadataProvider = IMetadataProvider::create(deviceId);  
  16.         pInfo->pMetadata            = pMetadataProvider->getStaticCharacteristics();  
  17.         pInfo->iFacing              = (pMetadataProvider->getDeviceFacing() == MTK_LENS_FACING_FRONT)  
  18.                                         ? CAMERA_FACING_FRONT  
  19.                                         : CAMERA_FACING_BACK  
  20.                                         ;  
  21.         pInfo->iWantedOrientation   = pMetadataProvider->getDeviceWantedOrientation();  
  22.         pInfo->iSetupOrientation    = pMetadataProvider->getDeviceSetupOrientation();  
  23.         i4DeviceNum++;  
  24.     }  
  25.   
  26.     return i4DeviceNum;  
  27. }  

第5-6行. 这里需要重点关注pHalSensorList->searchSensors函数,它的返回值就是camera的个数

第8-24行. 循环构造并初始化一个EnumInfo对象,并把它保存在mEnumMap中

[cpp]  view plain  copy
  1. MUINT  
  2. HalSensorList::  
  3. enumerateSensor_Locked()  
  4. {     
  5.     int ret_count = 0;  
  6.     SensorDrv *const pSensorDrv = SensorDrv::get();  
  7.     int const iSensorsList = pSensorDrv->impSearchSensor(NULL);  
  8.   
  9.     if((iSensorsList & SENSOR_DEV_MAIN) == SENSOR_DEV_MAIN)  
  10.     {  
  11.         halSensorDev = SENSOR_DEV_MAIN;  
  12.         pSensorInfo = pSensorDrv->getMainSensorInfo();  
  13.         addAndInitSensorEnumInfo_Locked(halSensorDev, ret_count, mapToSensorType(pSensorInfo->GetType()), pSensorInfo->getDrvMacroName());  
  14.         ret_count++;  
  15.     }  
  16.   
  17.     if((iSensorsList & SENSOR_DEV_SUB) == SENSOR_DEV_SUB)  
  18.     {  
  19.         halSensorDev = SENSOR_DEV_SUB;  
  20.         pSensorInfo = pSensorDrv->getSubSensorInfo();  
  21.         addAndInitSensorEnumInfo_Locked(halSensorDev, ret_count, mapToSensorType(pSensorInfo->GetType()), pSensorInfo->getDrvMacroName());  
  22.         ret_count++;  
  23.     }  
  24.   
  25.     mEnumSensorCount = ret_count;  
  26.     return  ret_count;  
  27. }  
  28.   
  29. MUINT  
  30. HalSensorList::  
  31. searchSensors()  
  32. {     
  33.     return  enumerateSensor_Locked();  
  34. }     

第33行. searchSensors函数只是调用了enumerateSensor_Locked函数,这里并没有贴出enumerateSensor_Locked函数的所有代码,删减了一些我们暂时不关注的东西

第7行. 重点函数pSensorDrv->impSearchSensor,它的返回值决定了enumerateSensor_Locked的返回值,也就是camera的个数

[cpp]  view plain  copy
  1. MINT32  
  2. ImgSensorDrv::impSearchSensor(pfExIdChk pExIdChkCbf)  
  3. {  
  4.     MUINT32 SensorEnum = (MUINT32) DUAL_CAMERA_MAIN_SENSOR;  
  5.     MUINT32 i,id[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {0,0};  
  6.     MINT32 sensorDevs = SENSOR_NONE;  
  7.   
  8.     GetSensorInitFuncList(&m_pstSensorInitFunc);  
  9.     m_fdSensor = ::open("/dev/kd_camera_hw", O_RDWR);  
  10.   
  11.     for (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum <= DUAL_CAMERA_SUB_SENSOR; SensorEnum <<= 1) {  
  12.         for (i = 0; i < MAX_NUM_OF_SUPPORT_SENSOR; i++) {  
  13.             //end of driver list  
  14.             if (m_pstSensorInitFunc[i].getCameraDefault == NULL) {  
  15.                 LOG_MSG("m_pstSensorInitFunc[i].getCameraDefault is NULL: %d \n", i);  
  16.                 break;  
  17.             }  
  18.   
  19.             id[KDIMGSENSOR_INVOKE_DRIVER_0] = (SensorEnum << KDIMGSENSOR_DUAL_SHIFT) | i;  
  20.             err = ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_DRIVER,&id[KDIMGSENSOR_INVOKE_DRIVER_0] );  
  21.             err = ioctl(m_fdSensor, KDIMGSENSORIOC_T_CHECK_IS_ALIVE);  
  22.   
  23.             if (err < 0 || err2 < 0) {  
  24.                 LOG_MSG("sensor ID mismatch\n");  
  25.                 continue;  
  26.             }  
  27.   
  28.             if (SensorEnum == DUAL_CAMERA_MAIN_SENSOR) {  
  29.                 m_mainSensorDrv.index[m_mainSensorDrv.number] = i;  
  30.                 m_mainSensorDrv.type[m_mainSensorDrv.number] = sensorType;  
  31.                 m_mainSensorDrv.position = socketPos;  
  32.                 m_mainSensorDrv.sensorID = m_pstSensorInitFunc[m_mainSensorDrv.index[m_mainSensorDrv.number]].SensorId;  
  33.                 m_mainSensorDrv.number++;  
  34.             } else if (SensorEnum == DUAL_CAMERA_SUB_SENSOR) {  
  35.                 m_subSensorDrv.index[m_subSensorDrv.number] = i;  
  36.                 m_subSensorDrv.type[m_subSensorDrv.number] = sensorType;  
  37.                 m_subSensorDrv.position = socketPos;  
  38.                 m_subSensorDrv.sensorID = m_pstSensorInitFunc[m_subSensorDrv.index[m_subSensorDrv.number]].SensorId;  
  39.                 m_subSensorDrv.number++;  
  40.             }  
  41.         }  
  42.     }  
  43.   
  44.     if (BAD_SENSOR_INDEX != m_mainSensorDrv.index[0]) {  
  45.         m_mainSensorId = m_mainSensorDrv.sensorID;  
  46.         m_mainSensorIdx = m_mainSensorDrv.index[0];  
  47.         sensorDevs |= SENSOR_MAIN;  
  48.     }  
  49.     if (BAD_SENSOR_INDEX != m_subSensorDrv.index[0]) {  
  50.         m_subSensorId = m_subSensorDrv.sensorID;  
  51.         m_subSensorIdx = m_subSensorDrv.index[0];  
  52.         sensorDevs |= SENSOR_SUB;  
  53.     }  
  54.   
  55.     return sensorDevs;  
  56. }  

这个函数比较长,所以只贴出关键代码

第8行, 调用GetSensorInitFuncList函数来获取hal层的sersors列表,并把它保存在m_pstSensorInitFunc变量中

第9行, 通过系统调用open函数打开camera的设备节点,后面会通过这个节点来进入到kernel层

第11-12行, 通过两个for循环来遍历sensorlist中所有可能存在的camera

第20行, 通过ioctl下达setDriver指令,并下传正在遍历的sensorlist中的ID。Driver层根据这个ID,挂载Driver层sensorlist中对应的操作接口

第21行, 通过ioctl下达check ID指令,Driver层为对应sensor上电,通过I2C读取预存在寄存器中的sensor id。然后比较读取结果,如果不匹配return error后继续遍历

第29-41行, 将sensor相关的信息保存在m_mainSensorDrv和m_subSensorDrv中

第45-56行, 给sensroDevs变量赋值,并将它返回给上一级

这里暂不分析kernel层的代码,先来看看GetSensorInitFuncList函数,代码在sensorlist.cpp中

[cpp]  view plain  copy
  1. MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[] =  
  2. {  
  3. #if defined(IMX175_MIPI_RAW)  
  4.     RAW_INFO(IMX175_SENSOR_ID, SENSOR_DRVNAME_IMX175_MIPI_RAW,NULL),  
  5. #endif  
  6. #if defined(IMX179_MIPI_RAW)  
  7.     RAW_INFO(IMX179_SENSOR_ID, SENSOR_DRVNAME_IMX179_MIPI_RAW,NULL),  
  8. #endif  
  9. #if defined(IMX219_MIPI_RAW)  
  10.     RAW_INFO(IMX219_SENSOR_ID, SENSOR_DRVNAME_IMX219_MIPI_RAW, NULL),  
  11. #endif  
  12. #if defined(IMX214_MIPI_RAW)  
  13.     RAW_INFO(IMX214_SENSOR_ID, SENSOR_DRVNAME_IMX214_MIPI_RAW,NULL),  
  14. #endif  
  15. #if defined(GC2235_RAW)  
  16.     RAW_INFO(GC2235_SENSOR_ID, SENSOR_DRVNAME_GC2235_RAW, NULL),  
  17. #endif  
  18. #if defined(GC2035_YUV)  
  19.     YUV_INFO(GC2035_SENSOR_ID, SENSOR_DRVNAME_GC2035_YUV, NULL),  
  20. #endif  
  21.     ......  
  22. }  
  23.   
  24. UINT32 GetSensorInitFuncList(MSDK_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)  
  25. {         
  26.     *ppSensorList = &SensorList[0];  
  27.     return MHAL_NO_ERROR;  
  28. }  
hal层的sensorList,再熟悉不过的代码,需要注意的是hal层sensorList和kernel层的sensorList顺序必须保持一致

4. 总结

至此,除kernel层外,简述了CameraService的启动流程,大概过程如下图所示



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值