分享

Camera显示之Hal层的适配(一)

 barry798 2014-04-28
本篇接着上一篇:

Camera显示之Framework层设置显示窗口

话说上一篇说道

else if ( window == 0 ) {  

        result = mHardware->setPreviewWindow(window);//将window设置到hal层, Android代码架构真正的实现就止于此,hal层的东西就看具体厂家根据自身情况进行实现了。   } 


那究竟mHardware是如何和hal联系起来的的呢?


1.在CameraClient.cpp中:

  1. status_t CameraClient::initialize(camera_module_t *module) {  
  2.     int callingPid = getCallingPid();  
  •     LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);  
  •   
  •     char camera_device_name[10];  
  •     status_t res;  
  •     snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);  
  •   
  •     mHardware = new CameraHardwareInterface(camera_device_name);//<SPAN style="COLOR: #ff0000">注意到此处。</SPAN>   
  •     res = mHardware->initialize(&module->common);//<SPAN style="COLOR: #ff0000">注意此处</SPAN>   
  •     if (res != OK) {  
  •         ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",  
  •                 __FUNCTION__, mCameraId, strerror(-res), res);  
  •         mHardware.clear();  
  •         return NO_INIT;  
  •     }  
  •   
  •     mHardware->setCallbacks(notifyCallback,  
  •             dataCallback,  
  •             dataCallbackTimestamp,  
  •             (void *)mCameraId);  
  •   
  •     // Enable zoom, error, focus, and metadata messages by default   
  •     enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |  
  •                   CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);  
  •   
  • //!++   
  • #ifdef  MTK_CAMERA_BSP_SUPPORT   
  •     // Enable MTK-extended messages by default   
  •     enableMsgType(MTK_CAMERA_MSG_EXT_NOTIFY | MTK_CAMERA_MSG_EXT_DATA);  
  • #endif   
  • //!--   
  •   
  •     LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);  
  •     return OK;  
  • }  

  • 从代码片段:
    1. mHardware = new CameraHardwareInterface(camera_device_name);//注意到此处。  

    mHardware 定义是 CameraHardwareInterface, 他也是Android的通用接口。 各个厂家提供的功能都要通过CameraHardwareInterface适配向CameraService提供硬件操作接口。

    这篇的主题就是主要分享CameraHardwareInterface如何进行适配的。

    2. 接着1中的代码片段:

    1. res = mHardware->initialize(&module->common);//涉及到module,module即为CameraClient::initialize(camera_module_t *module)传进来的参数, 为一个结构体变量的指针。  

    1. CameraClient::initialize(camera_module_t *module)调用的地方为CameraService中connect camera的时候调用:  

    1. sp<ICamera> CameraService::connect(  
    2.         const sp<ICameraClient>& cameraClient, int cameraId) {  
    3. #ifdef  MTK_CAMERAPROFILE_SUPPORT   
    4.     initCameraProfile();   
    5.     AutoCPTLog cptlog(Event_CS_connect);  
    6. #endif   
    7.     int callingPid = getCallingPid();  
    8.   
    9.     LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);  
    10.   
    11.     if (!mModule) {  
    12.         ALOGE("Camera HAL module not loaded");  
    13. ...........................  
    14. ............................  
    15.   
    16. #endif   
    17.   
    18.     if (client->initialize(mModule) != OK) {//在这里调用CameraClient的initialize, 而传入的参数为mModule。   
    19. #ifdef  MTK_CAMERAPROFILE_SUPPORT   
    20.         CPTLogStr(Event_CS_newCamHwIF, CPTFlagEnd,  "new CameraHardwareInterface failed");  
    21. #endif     
    22. #ifdef  MTK_CAMERA_BSP_SUPPORT  

    所以这里我们就关注下mModule这成员, mModule的定义:

    1. Mutex               mSoundLock;  
    2. sp<MediaPlayer>     mSoundPlayer[NUM_SOUNDS];  
    3. int                 mSoundRef;  // reference count (release all MediaPlayer when 0)   
    4.   
    5. camera_module_t *mModule;//  

    为一个camera_module_t结构体变量的指针。

    Camera最先被使用到的地方是在onFirstRef()函数中, 在这里主要是初始化了mModule的一些变量。 至于onFirstRef何时调用, 后续进行相关的分享, 这里大家只要记住,这个是和sp相关的, 并且在构建sp的时候就会调用。 可以参考这位的博客:http://blog.csdn.net/gzzaigcnforever/article/details/20649781


    1. void CameraService::onFirstRef()  
    2. {  
    3.     BnCameraService::onFirstRef();  
    4.   
    5.     if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,//这个定义为"came"   
    6.                 (const hw_module_t **)&mModule) < 0) {//<SPAN style="COLOR: #ff0000">注意这个函数调用</SPAN>   
    7.         ALOGE("Could not load camera HAL module");  
    8.         mNumberOfCameras = 0;  
    9.     }  
    10.     else {  
    11.         mNumberOfCameras = mModule->get_number_of_cameras();  
    12.         if (mNumberOfCameras > MAX_CAMERAS) {  
    13.             ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",  
    14.                     mNumberOfCameras, MAX_CAMERAS);  
    15.             mNumberOfCameras = MAX_CAMERAS;  
    16.         }  
    17.         for (int i = 0; i < mNumberOfCameras; i++) {  
    18.             setCameraFree(i);  
    19.         }  
    20.     }  
    21. }  
    22.   
    23.   
    24.   
    25. /** Base path of the hal modules */  
    26. #define HAL_LIBRARY_PATH1 "/system/lib/hw"   
    27. #define HAL_LIBRARY_PATH2 "/vendor/lib/hw"   
    28. #define HAL_LIBRARY_PATH3 "/system/lib"   
    29.   
    30.   
    31. int hw_get_module(const char *id, const struct hw_module_t **module)  
    32. {  
    33.     return hw_get_module_by_class(id, NULL, module);  
    34. }  
    35.   
    36.   
    37. int hw_get_module_by_class(const char *class_id, const char *inst,  
    38.                            const struct hw_module_t **module)  
    39. {  
    40.     int status;  
    41.     int i;  
    42.     const struct hw_module_t *hmi = NULL;  
    43.     char prop[PATH_MAX];  
    44.     char path[PATH_MAX];  
    45.     char name[PATH_MAX];  
    46.   
    47.     if (inst)  
    48.         snprintf(name, PATH_MAX, "%s.%s", class_id, inst);//class_id为camera, inst为null, 所以现在name=“camera”   
    49.     else  
    50.         strlcpy(name, class_id, PATH_MAX);  
    51.   
    52.     /* 
    53.      * Here we rely on the fact that calling dlopen multiple times on 
    54.      * the same .so will simply increment a refcount (and not load 
    55.      * a new copy of the library). 
    56.      * We also assume that dlopen() is thread-safe. 
    57.      */  
    58.   
    59.     /* Loop through the configuration variants looking for a module */  
    60.     for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {  
    61.         if (i < HAL_VARIANT_KEYS_COUNT) {  
    62.             if (property_get(variant_keys[i], prop, NULL) == 0) {  
    63.                 continue;  
    64.             }  
    65.             snprintf(path, sizeof(path), "%s/%s.%s.so",  
    66.                      HAL_LIBRARY_PATH2, name, prop);//path=/vendor/lib/hw/camera.**.so, 根据属性的配置值生成文件名。   
    67.   
    68.             if (access(path, R_OK) == 0) break;//判断是否有读文件权限。   
    69.   
    70.             snprintf(path, sizeof(path), "%s/%s.%s.so",//path=/system/lib/hw/camera.**.so   
    71.                      HAL_LIBRARY_PATH1, name, prop);  
    72.             if (access(path, R_OK) == 0) break;  
    73.   
    74.             snprintf(path, sizeof(path), "%s/%s.%s.so",  
    75.                      HAL_LIBRARY_PATH3, name, prop);//path=/system/lib/camera.**.so   
    76.             if (access(path, R_OK) == 0) break;  
    77.         } else {  
    78.             snprintf(path, sizeof(path), "%s/%s.default.so",  
    79.                      HAL_LIBRARY_PATH1, name);//path=/vendor/lib/hw/camera.default.so   
    80.             if (access(path, R_OK) == 0) break;  
    81.   
    82.             snprintf(path, sizeof(path), "%s/%s.default.so",//path=/system/lib/camera.default.so   
    83.                      HAL_LIBRARY_PATH3, name);  
    84.             if (access(path, R_OK) == 0) break;  
    85.         }  
    86.     }  
    87.   
    88.     status = -ENOENT;  
    89.     if (i < HAL_VARIANT_KEYS_COUNT+1) {  
    90.         /* load the module, if this fails, we're doomed, and we should not try 
    91.          * to load a different variant. */  
    92.         status = load(class_id, path, module);//动态加载动态库。   
    93.     }  
    94.   
    95.     return status;  
    96. }  


    上面的思路就是:

    遍历

    1. #define HAL_LIBRARY_PATH1 "/system/lib/hw"   
    2. #define HAL_LIBRARY_PATH2 "/vendor/lib/hw"   
    3. #define HAL_LIBRARY_PATH3 "/system/lib"  
    这几个目录下的so库,so库的名字为: a.camera.属性名.so和b.camera.default.so。 其中会优先找到a, 在没找到a后再去找到b。 在mtk平台上, 编译生成的so库就为 camera.default.so, 所以最终加载的会是camera.default.so这个库。


    继续看看:load(class_id, path, module);:

    1. static int load(const char *id,  
    2.         const char *path,  
    3.         const struct hw_module_t **pHmi)  
    4. {  
    5.     int status;  
    6.     void *handle;  
    7.     struct hw_module_t *hmi;  
    8.   
    9.     /* 
    10.      * load the symbols resolving undefined symbols before 
    11.      * dlopen returns. Since RTLD_GLOBAL is not or'd in with 
    12.      * RTLD_NOW the external symbols will not be global 
    13.      */  
    14.     handle = dlopen(path, RTLD_NOW);  
    15.     if (handle == NULL) {  
    16.         char const *err_str = dlerror();  
    17.         ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");  
    18.         status = -EINVAL;  
    19.         goto done;  
    20.     }  
    21.   
    22.     /* Get the address of the struct hal_module_info. */  
    23.     const char *sym = HAL_MODULE_INFO_SYM_AS_STR;  
    24.     hmi = (struct hw_module_t *)dlsym(handle, sym);//关注这两句   
    25.     if (hmi == NULL) {  
    26.         ALOGE("load: couldn't find symbol %s", sym);  
    27.         status = -EINVAL;  
    28.         goto done;  
    29.     }  
    30.   
    31.     /* Check that the id matches */  
    32.     if (strcmp(id, hmi->id) != 0) {  
    33.         ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);  
    34.         status = -EINVAL;  
    35.         goto done;  
    36.     }  
    37.   
    38.     hmi->dso = handle;  
    39.   
    40.     /* success */  
    41.     status = 0;  
    42.   
    43.     done:  
    44.     if (status != 0) {  
    45.         hmi = NULL;  
    46.         if (handle != NULL) {  
    47.             dlclose(handle);  
    48.             handle = NULL;  
    49.         }  
    50.     } else {  
    51.         ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",  
    52.                 id, path, *pHmi, handle);  
    53.     }  
    54.   
    55.     *pHmi = hmi;  
    56.   
    57.     return status;  
    58. }  

    关注这两句:

    1. const char *sym = HAL_MODULE_INFO_SYM_AS_STR;  
    2. hmi = (struct hw_module_t *)dlsym(handle, sym);//关注这两句  

    1. HAL_MODULE_INFO_SYM_AS_STR:  
    1. /** 
    2.  * Name of the hal_module_info 
    3.  */  
    4. #define HAL_MODULE_INFO_SYM         HMI   
    5.   
    6. /** 
    7.  * Name of the hal_module_info as a string 
    8.  */  
    9. #define HAL_MODULE_INFO_SYM_AS_STR  "HMI"  
    从上面可以看出就是要获取名为“HMI”函数的指针, 而HMI又是HAL_MODULE_INFO_SYM 的宏定义, 所以最终就是要找HAL_MODULE_INFO_SYM实现的地方:


    1. static  
    2. camera_module  
    3. instantiate_camera_module()  
    4. {  
    5.     CAM_LOGD("[%s]", __FUNCTION__);  
    6.     //   
    7.     //  (1) Prepare One-shot init.   
    8.     MtkCamUtils::Property::clear();  
    9.   
    10.     //  (2)   
    11.     camera_module module = {  
    12.         common: {  
    13.              tag:                   HARDWARE_MODULE_TAG,  
    14.              module_api_version:    1,  
    15.              hal_api_version:       0,  
    16.              id:                    CAMERA_HARDWARE_MODULE_ID,  
    17.              name:                  "MTK Camera Module",  
    18.              author:                "MTK",  
    19.              methods:               CamDeviceManager::get_module_methods(),  
    20.              dso:                   NULL,   
    21.              reserved:              {0},   
    22.         },   
    23.         get_number_of_cameras:  CamDeviceManager::get_number_of_cameras,   
    24.         get_camera_info:        CamDeviceManager::get_camera_info,   
    25.     };  
    26.     return  module;  
    27. }  
    28.   
    29.   
    30. /******************************************************************************* 
    31. * Implementation of camera_module 
    32. *******************************************************************************/  
    33. camera_module HAL_MODULE_INFO_SYM = instantiate_camera_module();  

    上面这个代码片段就是mtk实现的, 结合上边, 可以得到*pHmi指向了module这个结构体。 也即是说最后将*pHmi指向这里的module。 进一步回到上面, 就是CameraService中的mModule指向了这里的module。所以说后面的引用大概是CameraService中通过mModule->common->methods这种方式去或则mModule->get_number_of_cameras实现到MTK的hal层的调用。 这样就将Android原生CameraService通过CameraHardwareInterface连接到MTK实现的Hal层, 通过CamDeviceManager来承上启下的作用。

    3.继续2关注到CamDeviceManager::get_module_methods()这个函数:

    1. hw_module_methods_t*  
    2. CamDeviceManager::  
    3. get_module_methods()  
    4. {  
    5.     static  
    6.     hw_module_methods_t  
    7.     _methods =  
    8.     {  
    9.         open:   CamDeviceManager::open_device  
    10.     };  
    11.   
    12.     return  &_methods;  
    13. }  

    呵呵, 可以看到通过mModule->common->methods-->open可以引用到CamDeviceManager::open_device。

    通过名字可以猜测到这个方法应该是在Camera启动的时候会去调用。

    所以我们看看何时调用CamDeviceManager::open_device这个方法:


    回到CameraService:CameraClient:

    1. status_t CameraClient::initialize(camera_module_t *module) {  
    2.     int callingPid = getCallingPid();  
    3.     LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);  
    4.   
    5.     char camera_device_name[10];  
    6.     status_t res;  
    7.     snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);  
    8.   
    9.     mHardware = new CameraHardwareInterface(camera_device_name);  
    10.     res = mHardware->initialize(&module->common);//这里初始化了, 并且传入的module->common  


    回到CameraHardwareInterface:

    1. status_t initialize(hw_module_t *module)  
    2.     {  
    3.         ALOGI("Opening camera %s", mName.string());  
    4.         int rc = module->methods->open(module, mName.string(),  
    5.                                        (hw_device_t **)&mDevice);//这里进行了打开camera的操作, 这里调用到的已经是MTK hal层的方法了, 注意最后一个参数。   
    6.         if (rc != OK) {  
    7.             ALOGE("Could not open camera %s: %d", mName.string(), rc);  
    8.             return rc;  
    9.         }  
    10.         initHalPreviewWindow();  
    11.         return rc;  
    12.     }  

    关注到CamDeviceManager::open_device

    1. int  
    2. CamDeviceManager::  
    3. open_device(const hw_module_t* module, const char* name, hw_device_t** device)  
    4. {  
    5.     return  CamDeviceManager::getInstance().openDevice(module, name, device);  
    6. }  
    7.   
    8.   
    9. int  
    10. CamDeviceManager::  
    11. openDevice(const hw_module_t* module, const char* name, hw_device_t** device)  
    12. {  
    13.     int err = OK;  
    14.     //   
    15.     ICamDevice* pdev = NULL;  
    16.     int32_t     i4OpenId = 0;  
    17.     //   
    18.     Mutex::Autolock lock(mMtxOpenLock);  
    19.     //   
    20.     MY_LOGI("+ mi4OpenNum(%d), mi4DeviceNum(%d)", mi4OpenNum, mi4DeviceNum);  
    21.   
    22.     if (name != NULL)  
    23.     {  
    24.         i4OpenId = ::atoi(name);  
    25.         //   
    26.         if  ( DevMetaInfo::queryNumberOfDevice() < i4OpenId )  
    27.         {  
    28.             err = -EINVAL;  
    29.             goto lbExit;  
    30.         }  
    31.         //   
    32.         if  ( MAX_SIMUL_CAMERAS_SUPPORTED <= mi4OpenNum )  
    33.         {  
    34.             MY_LOGW("open number(%d) >= maximum number(%d)", mi4OpenNum, MAX_SIMUL_CAMERAS_SUPPORTED);  
    35.             MY_LOGE("does not support multi-open");  
    36.             err = -ENOMEM;  
    37.             goto lbExit;  
    38.         }  
    39.         //   
    40.         pdev = createIDevice(  
    41.             i4OpenId,   
    42.             *get_hw_device(),   
    43.             module  
    44.         );//注意此处, 进行camDevice的创建   
    45.         //   
    46.         if  ( ! pdev )  
    47.         {  
    48.             MY_LOGE("camera device allocation fail: pdev(0)");  
    49.             err = -ENOMEM;  
    50.             goto lbExit;  
    51.         }  
    52.   
    53.         *device = pdev->get_hw_device();//此处将CamDevice的指针付给传进来形参, 最终是CameraHardwareInterface中的mDevice指向了CamDevice。   
    54.         //   
    55.         mi4OpenNum++;  
    56.     }  
    57.   
    58. lbExit:  
    59.     if  ( OK != err )  
    60.     {  
    61.         if  ( pdev )  
    62.         {  
    63.             destroyDevice(pdev);  
    64.             pdev = NULL;  
    65.         }  
    66.         //   
    67.         *device = NULL;  
    68.     }  
    69.     MY_LOGI("- mi4OpenNum(%d)", mi4OpenNum);  
    70.     return  err;  
    71. }  

    4.继续往下关注到

    1. pdev = createIDevice(  
    2.            i4OpenId,   
    3.            *get_hw_device(),   
    4.            module  
    5.        );  
    的实现:

    1. static  
    2. ICamDevice*  
    3. createIDevice(  
    4.     int32_t const           i4DevOpenId,   
    5.     hw_device_t const&      hwdevice,   
    6.     hw_module_t const*const hwmodule  
    7. )  
    8. {  
    9.     g_s8ClientAppMode = queryClientAppMode();  
    10.     //   
    11.     MY_LOGI("+ tid:%d OpenID:%d ClientAppMode:%s", ::gettid(), i4DevOpenId, g_s8ClientAppMode.string());  
    12.     //   
    13.     ICamDevice* pdev = NSCamDevice::createDevice(g_s8ClientAppMode, i4DevOpenId);//pDeve 指向的就是ICamDevice的一个对象   
    14.     //   
    15.     if  ( pdev != 0 )  
    16.     {  
    17.         pdev->incStrong(pdev);  
    18.         //   
    19.         hw_device_t* hwdev = pdev->get_hw_device();//   
    20.         *hwdev = hwdevice;  
    21.         hwdev->module = const_cast<hw_module_t*>(hwmodule);  
    22.         //   
    23.         if  ( ! pdev->init() )//在这里初始化了ICamDvice   
    24.         {  
    25.             MY_LOGE("fail to initialize a newly-created instance");  
    26.             pdev->uninit();  
    27.             pdev = NULL;  
    28.         }  
    29.     }  
    30.     //   
    31.     MY_LOGI("- created instance=%p", &(*pdev));  
    32.     return  pdev;//返回创建的ICamDevice。   
    33. }  

    现在可以得出pdev即是指向ICamDevice对象


    注意到ICamDevice对象的构造函数:

    1. ICamDevice::  
    2. ICamDevice()  
    3.     : camera_device_t()  
    4.     , RefBase()  
    5.     , mDevOps()  
    6.     //   
    7.     , mMtxLock()  
    8.     //   
    9. {  
    10.     MY_LOGD("ctor");  
    11.     ::memset(static_cast<camera_device_t*>(this), 0, sizeof(camera_device_t));  
    12.     this->priv  = this;  
    13.     this->ops   = &mDevOps;//ops指向了mDevOps   
    14.     mDevOps     = gCameraDevOps;//mDevOps为gCameraDevOps指向的结构体   
    15. }  

    1. gCameraDevOps:  
    1. static camera_device_ops_t const gCameraDevOps = {  
    2.     set_preview_window:         camera_set_preview_window,   
    3.     set_callbacks:              camera_set_callbacks,   
    4.     enable_msg_type:            camera_enable_msg_type,   
    5.     disable_msg_type:           camera_disable_msg_type,   
    6.     msg_type_enabled:           camera_msg_type_enabled,   
    7.     start_preview:              camera_start_preview,   
    8.     stop_preview:               camera_stop_preview,   
    9.     preview_enabled:            camera_preview_enabled,   
    10.     store_meta_data_in_buffers: camera_store_meta_data_in_buffers,   
    11.     start_recording:            camera_start_recording,   
    12.     stop_recording:             camera_stop_recording,   
    13.     recording_enabled:          camera_recording_enabled,   
    14.     release_recording_frame:    camera_release_recording_frame,   
    15.     auto_focus:                 camera_auto_focus,   
    16.     cancel_auto_focus:          camera_cancel_auto_focus,   
    17.     take_picture:               camera_take_picture,   
    18.     cancel_picture:             camera_cancel_picture,   
    19.     set_parameters:             camera_set_parameters,   
    20.     get_parameters:             camera_get_parameters,   
    21.     put_parameters:             camera_put_parameters,   
    22.     send_command:               camera_send_command,   
    23.     release:                    camera_release,   
    24.     dump:                       camera_dump,   
    25.   
    26. };  

    所以在CameraHardwareInterface中通过:

    mDevice->ops->set_preview_window(mDevice, 0)类似的方法就可以调用到ICamDevice中对应的方法了。


    5. 我们回到Camera显示相关的东西,

    在CameraClient中//!++
        else if ( window == 0 ) {
            result = mHardware->setPreviewWindow(window);
        }

    进而在CameraHardwareInterface中:

    1. /** Set the ANativeWindow to which preview frames are sent */  
    2.    status_t setPreviewWindow(const sp<ANativeWindow>& buf)  
    3.    {  
    4.        ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());  
    5.   
    6.        if (mDevice->ops->set_preview_window) {  
    7.            //!++   
    8.            if  ( buf == 0 ) {  
    9.                ALOGD("set_preview_window(0) before mPreviewWindow = 0");  
    10.                mDevice->ops->set_preview_window(mDevice, 0);//直接调用了ICamDevice的相关的方法。   
    11.                mPreviewWindow = 0;  
    12.                return  OK;  
    13.            }  
    14.            //!--   
    15.            mPreviewWindow = buf;  
    16.            mHalPreviewWindow.user = this;  
    17.            ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p", __FUNCTION__,  
    18.                    &mHalPreviewWindow, mHalPreviewWindow.user);  
    19.            return mDevice->ops->set_preview_window(mDevice,  
    20.                    buf.get() ? &mHalPreviewWindow.nw : 0);  
    21.        }  
    22.        return INVALID_OPERATION;  
    23.    }  

    5.说到这里, CameraService::CameraClient--->CameraHardwareInterface-->CamDeviceManager-->ICamDevice这一条完整的路线非常清楚。


    具体思路就是:

    a.CameraHardwareInterface是Android原生定义的和硬件hal层连接的适配接口。各个厂家根据需要去具体实现这些接口,并具体实现底层的相关功能。

    b.为了代码通用性和模块的分离性, 对hal层模块的实现封装成动态库(so), CameraService根据需要动态加载hal层的库。

    c.CamDeviceManager是Hal层的一个入口类, 从CameraService打开关闭camera的时候都是通过它进行总的安排。

    d.hal层下具体的实现都是不断的适配CameraHardwareInterface向上提供的接口的一个过程。


    附上以一个打开Camera的流程图供参考:


      本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
      转藏 分享 献花(0

      0条评论

      发表

      请遵守用户 评论公约

      类似文章 更多