Android 5.0 Camera系统源码分析(2):Camera打开流程

来源:互联网 发布:狄克斯特拉算法图解 编辑:程序博客网 时间:2024/05/23 15:09

1. 前言

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

2. app层

从apk开始,简单列出各个入口函数

[cpp] view plain copy
  1. private void initCamera()  
  2. {  
  3.     Camera mCamera = Camera.open();  
  4.     Camera.Parameters mParameters = mCamera.getParameters();  
  5.     mParameters.setPictureFormat(PixelFormat.JPEG);  
  6.     mCamera.setParameters(mParameters);  
  7.     mCamera.setPreviewDisplay(mSurfaceHolder);  
  8.     mCamera.startPreview();  
  9.     mCamera.takePicture(null, null , mJpegCallback);  
  10. }  

3. frameworks层

这里将重点介绍Camera.open函数,其余函数将在后续博文分析。先来看看Camera.open函数在frameworks层的实现,代码路径为: frameworks/base/core/java/android/hardware/Camera.java

[cpp] view plain copy
  1. public static Camera open() {  
  2.     if (!isPermissionGranted()) {  
  3.         return null;  
  4.     }      
  5.     int numberOfCameras = getNumberOfCameras();  
  6.     CameraInfo cameraInfo = new CameraInfo();  
  7.     for (int i = 0; i < numberOfCameras; i++) {  
  8.         getCameraInfo(i, cameraInfo);  
  9.         if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {  
  10.             return new Camera(i);  
  11.         }      
  12.     }      
  13.     return null;  
  14. }      
第5行, 通过getNumberOfCameras函数来获取Camera的个数。从上一篇博文CameraService的启动流程可以看出,这个信息保存在CameraService中。
第10行,需重点关注,构造一个Camera对象,并将它返回给app层。

3.1 getNumberOfCameras函数分析

getNumberOfCameras函数进入到CameraService获取Camera个数的流程如下:


Camera.Java调用的getNumberOfCameras函数是一个JNI接口,对应的函数是android_hardware_Camera.cpp里的android_hardware_Camera_getNumberOfCameras函数

[cpp] view plain copy
  1. static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz)  
  2. {  
  3.     return Camera::getNumberOfCameras();  
  4. }  
这里只是简单调用了Camera.cpp的getNumberOfCameras函数,Camera继承了CameraBase,该函数由它实现

[cpp] view plain copy
  1. template <typename TCam, typename TCamTraits>  
  2. int CameraBase<TCam, TCamTraits>::getNumberOfCameras() {  
  3.     const sp<ICameraService> cs = getCameraService();  
  4.     return cs->getNumberOfCameras();  
  5. }  
第3行, getCameraService函数用来获取ICameraService的Bp端,代码实现如下
[cpp] view plain copy
  1. const char* kCameraServiceName = "media.camera";  
  2.   
  3. template <typename TCam, typename TCamTraits>  
  4. const sp<ICameraService>& CameraBase<TCam, TCamTraits>::getCameraService()  
  5. {     
  6.     if (gCameraService.get() == 0) {  
  7.         sp<IServiceManager> sm = defaultServiceManager();  
  8.         sp<IBinder> binder;  
  9.         binder = sm->getService(String16(kCameraServiceName));         
  10.         gCameraService = interface_cast<ICameraService>(binder);  
  11.     }  
  12.     return gCameraService;  
  13. }  

android的Binder通讯机制

第1行, 获取的ServiceName为"media.camera",结合上一篇博文CameraService的启动流程可以看出Bn端的实现在CameraService.cpp

回到之前的getNumberOfCameras函数,在获取到ICameraService的Bp端后,就可以开始和Bn端通讯了。在第4行,当调用cs->getNumberOfCameras函数时,将会进入CameraService.cpp的getNumberOfCameras函数

[cpp] view plain copy
  1. int32_t CameraService::getNumberOfCameras() {  
  2.     return mNumberOfCameras;  
  3. }  
代码很简单,返回上一篇博文讲到的,千辛万苦从hal层拿到的数据

3.2 Camera构造函数分析

回到最开始的Camera.open函数,在第10行,将会构造一个Camera对象

[cpp] view plain copy
  1. private int cameraInitVersion(int cameraId, int halVersion) {  
  2.     ......  
  3.     Looper looper;  
  4.     if ((looper = Looper.myLooper()) != null) {  
  5.         mEventHandler = new EventHandler(this, looper);  
  6.     } else if ((looper = Looper.getMainLooper()) != null) {  
  7.         mEventHandler = new EventHandler(this, looper);  
  8.     } else {  
  9.         mEventHandler = null;  
  10.     }  
  11.   
  12.     String packageName = ActivityThread.currentPackageName();  
  13.   
  14.     return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);  
  15. }  
  16.   
  17. private int cameraInitNormal(int cameraId) {  
  18.     return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);  
  19. }  
  20.   
  21. Camera(int cameraId) {  
  22.     int err = cameraInitNormal(cameraId);  
  23.     ......  
  24. }  
第14行, native_setup同样是个JNI接口,对应android_hardware_Camera.cpp里的android_hardware_Camera_native_setup函数
[cpp] view plain copy
  1. static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,  
  2.     jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)  
  3. {  
  4.     camera = Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID);  
  5.   
  6. #if 1 // defined(MTK_CAMERA_BSP_SUPPORT)  
  7.     sp<JNICameraContext> context = new MtkJNICameraContext(env, weak_this, clazz, camera);  
  8. #else  
  9.     sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);  
  10. #endif  
  11. }  
第4行, 调用了Camera.cpp的connect函数,同时返回一个Camera对象,保存在JNICameraContext当中
[cpp] view plain copy
  1. sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,  
  2.         int clientUid)  
  3. {  
  4.     return CameraBaseT::connect(cameraId, clientPackageName, clientUid);  
  5. }  

先来看看Camera和CameraBase的类定义

[cpp] view plain copy
  1. /* ---------- Camera.h ---------- */  
  2. template <>  
  3. struct CameraTraits<Camera>  
  4. {  
  5.     ......  
  6.     static TCamConnectService fnConnectService;  
  7. };  
  8.   
  9. class Camera : public CameraBase<Camera>  
  10. {  
  11.     ......  
  12. }  
  13. /* -------- CameraBase.h -------- */  
  14. <pre name="code" class="cpp">template <typename TCam>  
  15. struct CameraTraits {  
  16. };  
  17.   
  18. template <typename TCam, typename TCamTraits = CameraTraits<TCam>>  
  19. class CameraBase  
  20. {  
  21.     ......  
  22.     typedef CameraBase<TCam>    CameraBaseT;  
  23. }  
这里使用了C++模版,其实就是调用CameraBase::connect函数
[cpp] view plain copy
  1. CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = &ICameraService::connect;  
  2.   
  3. template <typename TCam, typename TCamTraits>  
  4. sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,  
  5.                                                const String16& clientPackageName,  
  6.                                                int clientUid)  
  7. {  
  8.     sp<TCam> c = new TCam(cameraId);  
  9.     sp<TCamCallbacks> cl = c;  
  10.   
  11.     const sp<ICameraService>& cs = getCameraService();  
  12.     if (cs != 0) {  
  13.         TCamConnectService fnConnectService = TCamTraits::fnConnectService;  
  14.         status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,  
  15.                                              /*out*/ c->mCamera);  
  16.     }  
  17.   
  18.     return c;  
  19. }  

第1行, 将CameraTraits::fnConnectService赋为ICameraService::connect

第7行, 构造一个Camera对象

第10行, 获取ICameraService的Bp端

第13行, 从上面的解释可以看出,实际就是调用CameraService.cpp的connect函数

第17行, 将Camera对象返回给JNI层

[cpp] view plain copy
  1. status_t CameraService::connectHelperLocked(  
  2.         /*out*/  
  3.         sp<Client>& client,  
  4.         /*in*/  
  5.         const sp<ICameraClient>& cameraClient,  
  6.         int cameraId,  
  7.         const String16& clientPackageName,  
  8.         int clientUid,  
  9.         int callingPid,  
  10.         int halVersion,  
  11.         bool legacyMode) {  
  12.     ......  
  13.     int deviceVersion = getDeviceVersion(cameraId, &facing);  
  14.   
  15.     switch(deviceVersion) {  
  16.         case CAMERA_DEVICE_API_VERSION_1_0:  
  17.             client = new CameraClient(this, cameraClient,  
  18.                     clientPackageName, cameraId,  
  19.                     facing, callingPid, clientUid, getpid(), legacyMode);  
  20.             break;  
  21.         case CAMERA_DEVICE_API_VERSION_2_0:  
  22.         case CAMERA_DEVICE_API_VERSION_2_1:  
  23.         case CAMERA_DEVICE_API_VERSION_3_0:  
  24.         case CAMERA_DEVICE_API_VERSION_3_1:  
  25.         case CAMERA_DEVICE_API_VERSION_3_2:  
  26.             client = new Camera2Client(this, cameraClient,  
  27.                     clientPackageName, cameraId,  
  28.                     facing, callingPid, clientUid, getpid(), legacyMode);  
  29.             break;  
  30.     }  
  31.   
  32.     status_t status = connectFinishUnsafe(client, client->getRemote());  
  33.     mClient[cameraId] = client;  
  34. }  
  35.   
  36. status_t CameraService::connect(  
  37.         const sp<ICameraClient>& cameraClient,  
  38.         int cameraId,  
  39.         const String16& clientPackageName,  
  40.         int clientUid,  
  41.         /*out*/  
  42.         sp<ICamera>& device) {  
  43.     ......  
  44.     sp<Client> client;  
  45.     status = connectHelperLocked(/*out*/client,  
  46.                                  cameraClient,  
  47.                                  cameraId,  
  48.                                  clientPackageName,  
  49.                                  clientUid,  
  50.                                  callingPid);  
  51.     device = client;  
  52.     return OK;  
  53. }  

忽略细节之后connect函数就只是调用connectHelperLocked函数

第13行, 获取api版本信息,这个函数比较简单,不细说。这里的版本为CAMERA_DEVICE_API_VERSION_1_0

第15-30行, 根据不同的api版本选择构造CameraClient或Camera2Client,这里是CameraClient

第32行, 调用connectFinishUnsafe函数,实现如下

[cpp] view plain copy
  1. status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,  
  2.                                             const sp<IBinder>& remoteCallback) {  
  3.     status_t status = client->initialize(mModule);  
  4. }  

这里的client就是上一个函数的CameraClient,mModule就是在上一篇博文CameraService的启动流程里提到的hal层的接口
[cpp] view plain copy
  1. status_t CameraClient::initialize(camera_module_t *module) {  
  2.     mHardware = new CameraHardwareInterface(camera_device_name);  
  3.     res = mHardware->initialize(&module->common);  
  4.     mHardware->setCallbacks(notifyCallback,  
  5.             dataCallback,  
  6.             dataCallbackTimestamp,  
  7.             (void *)(uintptr_t)mCameraId);  
  8.     return OK;  
  9. }  
构造一个CameraHardwareInterface对象,并调用它的initalize函数,直接看initalize函数
[cpp] view plain copy
  1. status_t initialize(hw_module_t *module)  
  2. {  
  3.     module->methods->open(module, mName.string(), (hw_device_t **)&mDevice)  
  4.     initHalPreviewWindow();  
  5. }  
第4行, 从这里进入到了hal层,hal层主要对Camera硬件进行初始化,并将操作集保存在mDevice当中

4. hal层-基于MTK平台

hal层对Camera硬件进行初始化以及返回Device操作集的流程如下


4.1 open函数分析

这里再看一次module的定义

[cpp] view plain copy
  1. static  
  2. hw_module_methods_t*  
  3. get_module_methods()  
  4. {  
  5.     static  
  6.     hw_module_methods_t  
  7.     _methods =  
  8.     {  
  9.         open: open_device  
  10.     };  
  11.   
  12.     return  &_methods;  
  13. }  
  14.   
  15. static  
  16. camera_module  
  17. get_camera_module()  
  18. {  
  19.     camera_module module = {  
  20.         common:{  
  21.              tag                    : HARDWARE_MODULE_TAG,  
  22.              #if (PLATFORM_SDK_VERSION >= 21)  
  23.              module_api_version     : CAMERA_MODULE_API_VERSION_2_3,  
  24.              #else  
  25.              module_api_version     : CAMERA_DEVICE_API_VERSION_1_0,  
  26.              #endif  
  27.              hal_api_version        : HARDWARE_HAL_API_VERSION,  
  28.              id                     : CAMERA_HARDWARE_MODULE_ID,  
  29.              name                   : "MediaTek Camera Module",  
  30.              author                 : "MediaTek",  
  31.              methods                : get_module_methods(),  
  32.              dso                    : NULL,  
  33.              reserved               : {0},  
  34.         },  
  35.         get_number_of_cameras       : get_number_of_cameras,  
  36.         get_camera_info             : get_camera_info,  
  37.         set_callbacks               : set_callbacks,  
  38.         get_vendor_tag_ops          : get_vendor_tag_ops,  
  39.         #if (PLATFORM_SDK_VERSION >= 21)  
  40.         open_legacy                 : open_legacy,  
  41.         #endif  
  42.         reserved                    : {0},  
  43.     };  
  44.     return  module;  
  45. };  

通过module->methods获取到的函数为open_device,

[cpp] view plain copy
  1. static  
  2. int  
  3. open_device(hw_module_t const* module, const char* name, hw_device_t** device)  
  4. {  
  5.     return  NSCam::getCamDeviceManager()->open(device, module, name);  
  6. }  
CamDeviceManagerImp 继承了 CamDeviceManagerBase。这里直接调用了CamDeviceManagerBase的open()
[cpp] view plain copy
  1. status_t  
  2. CamDeviceManagerBase::  
  3. openDeviceLocked(  
  4.     hw_device_t** device,  
  5.     hw_module_t const* module,  
  6.     int32_t const i4OpenId,  
  7.     uint32_t device_version  
  8. )  
  9. {  
  10.     // [2] get platform  
  11.     IPlatform*const pPlatform = getPlatform();  
  12.     pDevice = pPlatform->createCam1Device(s8ClientAppMode.string(), i4OpenId);  
  13.     *device = const_cast<hw_device_t*>(pDevice->get_hw_device());  
  14. }  
  15.   
  16. status_t  
  17. CamDeviceManagerBase::  
  18. open(  
  19.     hw_device_t** device,  
  20.     hw_module_t const* module,  
  21.     char const* name,  
  22.     uint32_t device_version  
  23. )  
  24. {  
  25.     return  openDeviceLocked(device, module, i4OpenId, device_version);  
  26. }  

第11行, getPlatform函数用来加载libcam_platform.so,并获取PlatformEntry接口

第12行, 构造一个Cam1Device对象,并调用它的init函数

第13行, 获取camera device的操作集

4.2 getPlatform函数分析

[cpp] view plain copy
  1. static PlatformEntry g_PlatformEntry;  
  2.   
  3. IPlatform*  
  4. getHandleToPlatform()  
  5. {  
  6.     return &g_PlatformEntry;  
  7. }  
  8.   
  9. IPlatform*  
  10. CamDeviceManagerBase::  
  11. getPlatform()  
  12. {  
  13.     char const szModulePath[] = "libcam_platform.so";  
  14.     char const szEntrySymbol[] = "getHandleToPlatform";  
  15.     void* pfnEntry = NULL;  
  16.     IPlatform* pIPlatform = NULL;  
  17.   
  18.     mpLibPlatform = ::dlopen(szModulePath, RTLD_NOW);  
  19.     pfnEntry = ::dlsym(mpLibPlatform, szEntrySymbol);  
  20.     pIPlatform = reinterpret_cast<IPlatform*(*)()>(pfnEntry)();  
  21.     gIPlatform = pIPlatform;  
  22.   
  23.     return gIPlatform;  
  24. }  

第18行, 加载libcam_platform.so

第19 20行, 获取getHandleToPlatform函数入口,并调用,最后返回PlatformEntry接口

4.3 pPlatform->createCam1Device函数分析

[cpp] view plain copy
  1. NSCam::Cam1Device*  
  2. createCam1Device(  
  3.     String8 const   s8ClientAppMode,  
  4.     int32_t const   i4OpenId  
  5. )  
  6. {  
  7.     NSCam::Cam1Device* pdev = NULL;  
  8.   
  9.     String8 const s8LibPath = String8::format("libcam.device1.so");  
  10.     void *handle = ::dlopen(s8LibPath.string(), RTLD_GLOBAL);  
  11.   
  12.     String8 const s8CamDeviceInstFactory = String8::format("createCam1Device_Default");  
  13.     void* pCreateInstance = ::dlsym(handle, s8CamDeviceInstFactory.string());  
  14.     pdev = reinterpret_cast<NSCam::Cam1Device* (*)(String8 const&, int32_t const)>  
  15.                     (pCreateInstance)(s8ClientAppMode, i4OpenId);  
  16.   
  17.     pdev->initialize();  
  18. }  
  19.   
  20. ICamDevice*  
  21. PlatformEntry::  
  22. createCam1Device(   
  23.     char const*         szClientAppMode,  
  24.     int32_t const       i4OpenId  
  25. )  
  26. {  
  27.     return  ::createCam1Device(String8(szClientAppMode), i4OpenId);  
  28. }  

pPlatform->createCam1Device函数调用的是Cam1DeviceFactory.cpp里的createCam1Device函数

第10行, 加载libcam.device1.so

第12-15行, 获取createCam1Device_Default函数入口并调用

第17行, Cam1Device初始化

先来看createCam1Device_Default函数,以及类的继承关系

[cpp] view plain copy
  1. class Cam1DeviceBase : public Cam1Device  
  2. {  
  3. }  
  4.   
  5. class DefaultCam1Device : public Cam1DeviceBase  
  6. {  
  7. }  
  8.   
  9. NSCam::Cam1Device*  
  10. createCam1Device_Default(  
  11.     String8 const&          rDevName,   
  12.     int32_t const           i4OpenId  
  13. )  
  14. {  
  15.     return new DefaultCam1Device(rDevName, i4OpenId);  
  16. }  
接着看DefaultCam1Device的构造函数

[cpp] view plain copy
  1. Cam1Device::  
  2. Cam1Device()  
  3. {     
  4.     ::memset(&mDevice, 0, sizeof(mDevice));  
  5.     mDevice.priv    = this;  
  6.     mDevice.common  = gHwDevice;  
  7.     mDevice.ops     = (camera_device_ops*)&mDeviceOps;  
  8.     mDeviceOps      = gCameraDevOps;  
  9. }    
  10.   
  11. Cam1DeviceBase::  
  12. Cam1DeviceBase(  
  13.     String8 const&          rDevName,  
  14.     int32_t const           i4OpenId  
  15. )  
  16.     : Cam1Device()  
  17.     , mDevName(rDevName)  
  18.     , mi4OpenId(i4OpenId)  
  19. {  
  20.     MY_LOGD("");  
  21. }  
  22.   
  23. DefaultCam1Device::  
  24. DefaultCam1Device(  
  25.     String8 const&          rDevName,  
  26.     int32_t const           i4OpenId  
  27. )  
  28.     : Cam1DeviceBase(rDevName, i4OpenId)  
  29. {  
  30. }   
删除了一些暂不关注的代码,DefaultCam1Device的构造函数会不断调用父类的构造函数,需要关注的是它的父类Cam1Device的构造函数。其中的gCameraDevOps结构体很重要,是Camera Device的操作集,预览、拍照、录像都是通过它来操作,来看下它的定义

[cpp] view plain copy
  1. static mtk_camera_device_ops const  
  2. gCameraDevOps =  
  3. {  
  4.     #define OPS(name) name: camera_##name  
  5.   
  6.     {  
  7.         OPS(set_preview_window),  
  8.         OPS(set_callbacks),   
  9.         OPS(enable_msg_type),  
  10.         OPS(disable_msg_type),  
  11.         OPS(msg_type_enabled),   
  12.         OPS(start_preview),  
  13.         OPS(stop_preview),   
  14.         OPS(preview_enabled),   
  15.         OPS(store_meta_data_in_buffers),  
  16.         OPS(start_recording),   
  17.         OPS(stop_recording),   
  18.         OPS(recording_enabled),  
  19.         OPS(release_recording_frame),  
  20.         OPS(auto_focus),   
  21.         OPS(cancel_auto_focus),  
  22.         OPS(take_picture),  
  23.         OPS(cancel_picture),   
  24.         OPS(set_parameters),   
  25.         OPS(get_parameters),   
  26.         OPS(put_parameters),   
  27.         OPS(send_command),  
  28.         OPS(release),  
  29.         OPS(dump)  
  30.     },  
  31.     OPS(mtk_set_callbacks),  
  32.   
  33.     #undef  OPS  
  34. };  

回到createCam1Device函数,最后调用了pdev->initialize函数,这个函数过程比较复杂,在它的父类Cam1DeviceBase中实现

[cpp] view plain copy
  1. bool  
  2. DefaultCam1Device::  
  3. onInit()  
  4. {  
  5.     //  (1) power on sensor  
  6.     if( pthread_create(&mThreadHandle, NULL, doThreadInit, this) != 0 )  
  7.     {  
  8.         goto lbExit;  
  9.     }  
  10.   
  11.     //  (2) Open 3A  
  12.     mpHal3a = NS3A::IHal3A::createInstance(  
  13.             NS3A::IHal3A::E_Camera_1,  
  14.             getOpenId(),  
  15.             LOG_TAG);  
  16.   
  17.     //  (3) Init Base.  
  18.     if  ( ! Cam1DeviceBase::onInit() )  
  19.     {  
  20.         goto lbExit;  
  21.     }  
  22. }  
  23.   
  24. status_t  
  25. Cam1DeviceBase::  
  26. initialize()  
  27. {  
  28.     onInit();  
  29.     return  OK;    
  30. }  
initialize函数只是简单的回调了onInit函数,如注释所示,主要做了3件事情。其中(2)和(3)主要是初始化3A和CamClient,这两个这里暂时不会关注,所以暂时不进行分析。重点关注(1),也就是doThreadInit函数

[cpp] view plain copy
  1. bool  
  2. DefaultCam1Device::  
  3. powerOnSensor()  
  4. {  
  5.     IHalSensorList* pHalSensorList = IHalSensorList::get();  
  6.     mpHalSensor = pHalSensorList->createSensor(USER_NAME, getOpenId());  
  7.     sensorIdx = getOpenId();  
  8.     if( !mpHalSensor->powerOn(USER_NAME, 1, &sensorIdx) )  
  9.     {  
  10.         MY_LOGE("sensor power on failed: %d", sensorIdx);  
  11.         goto lbExit;  
  12.     }  
  13.     ......  
  14. }  
  15.   
  16. void*     
  17. DefaultCam1Device::  
  18. doThreadInit(void* arg)  
  19. {  
  20.     DefaultCam1Device* pSelf = reinterpret_cast<DefaultCam1Device*>(arg);  
  21.     pSelf->mRet = pSelf->powerOnSensor();  
  22.     pthread_exit(NULL);  
  23.     return NULL;  
  24. }  
doThreadInit函数只是回调自身的了powerOnSensor函数,而powerOnSensor函数先调用pHalSensorList->createSensor函数创建一个HalSensor实例,然后再调用它的PowerOn函数来开始相关的硬件操作,来看powerOn的实现

[cpp] view plain copy
  1. MBOOL  
  2. HalSensor::  
  3. powerOn(  
  4.     char const* szCallerName,  
  5.     MUINT const uCountOfIndex,  
  6.     MUINT const*pArrayOfIndex  
  7. )  
  8. {  
  9.     ......  
  10.     ret = mpSeninfDrv->init();  
  11.     ret = mpSensorDrv->init(sensorDev);  
  12.     ret = setTgPhase(sensorDev, pcEn);  
  13.     ret = setSensorIODrivingCurrent(sensorDev);  
  14.     ret = mpSensorDrv->open(sensorDev);  
  15.     ......  
  16. }  
powerOn函数比较长,这里暂时只关注SensorDrv的init和open函数
[cpp] view plain copy
  1. MINT32  
  2. ImgSensorDrv::init(MINT32 sensorIdx)  
  3. {  
  4.     m_fdSensor = ::open("dev/kd_camera_hw", O_RDWR);  
  5.   
  6.     //set driver  
  7.     ret = ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_DRIVER,sensorDrvInit);  
  8.   
  9.     //init resolution  
  10.     pSensorResInfo[0] = &m_SenosrResInfo[0];  
  11.     pSensorResInfo[1] = &m_SenosrResInfo[1];  
  12.     ret = getResolution(pSensorResInfo);  
  13.   
  14.     if(SENSOR_MAIN & sensorIdx ) {  
  15.         sensorDevId = SENSOR_MAIN;  
  16.   
  17.         FeatureParaLen = sizeof(MUINTPTR);  
  18.         ret = featureControl((CAMERA_DUAL_CAMERA_SENSOR_ENUM)sensorDevId, SENSOR_FEATURE_GET_PIXEL_CLOCK_FREQ,  (MUINT8*)&FeaturePara32,(MUINT32*)&FeatureParaLen);  
  19.   
  20.         FeatureParaLen = sizeof(pFeaturePara16);  
  21.         ret = featureControl((CAMERA_DUAL_CAMERA_SENSOR_ENUM)sensorDevId, SENSOR_FEATURE_GET_PERIOD,  (MUINT8*)pFeaturePara16,(MUINT32*)&FeatureParaLen);  
  22.     }  
  23.     ......  
  24. }  
  25.   
  26. MINT32  
  27. ImgSensorDrv::open(MINT32 sensorIdx)  
  28. {  
  29.     MINT32 err = SENSOR_NO_ERROR;  
  30.   
  31.     ......  
  32.     err = ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_CURRENT_SENSOR, &sensorIdx);  
  33.     err = ioctl(m_fdSensor, KDIMGSENSORIOC_T_OPEN);  
  34.   
  35.     return err;  
  36. }  
这两个函数逻辑比较简单,就是通过ioctl进入到kernel层来对sensor硬件进行初始化和获取硬件相关的信息。kernel层的代码暂不分析

4.4 get_hw_device函数分析

回到4.1的openDeviceLocked函数,最后调用了pDevice->get_hw_device函数,并将它的返回值赋给*device

[cpp] view plain copy
  1. class Cam1Device : public ICamDevice  
  2. {  
  3.     virtual hw_device_t const*      get_hw_device() const { return &mDevice.common; }  
  4. }  

这个函数很简单,就是获取4.3里面提到的mDevice,这个mDevice最终将被保存在frameworks层的CameraHardwareInterface.h的mDevice变量当中,以便日后访问

5. 总结

Camera打开流程的重点工作在4.3和4.4章节,也就是对Camera硬件进行初始化和将gCameraDevOps操作集返回给frameworks层。

阅读全文
0 0
原创粉丝点击