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

来源:互联网 发布:用mac怎么该音频格式 编辑:程序博客网 时间:2024/04/29 19:20

转来研究下Camera HAL问题

from:http://blog.csdn.net/wsb1321/article/details/21975951

(二在这)http://blog.csdn.net/wsb1321/article/details/22080325

本篇接着上一篇:

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

话说上一篇说道

else if ( window == 0 ) {  

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


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


1.在CameraClient.cpp中:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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);//<span style="color:#FF0000;">注意到此处。</span>  
  10.     res = mHardware->initialize(&module->common);//<span style="color:#FF0000;">注意此处</span>  
  11.     if (res != OK) {  
  12.         ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",  
  13.                 __FUNCTION__, mCameraId, strerror(-res), res);  
  14.         mHardware.clear();  
  15.         return NO_INIT;  
  16.     }  
  17.   
  18.     mHardware->setCallbacks(notifyCallback,  
  19.             dataCallback,  
  20.             dataCallbackTimestamp,  
  21.             (void *)mCameraId);  
  22.   
  23.     // Enable zoom, error, focus, and metadata messages by default  
  24.     enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |  
  25.                   CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);  
  26.   
  27. //!++  
  28. #ifdef  MTK_CAMERA_BSP_SUPPORT  
  29.     // Enable MTK-extended messages by default  
  30.     enableMsgType(MTK_CAMERA_MSG_EXT_NOTIFY | MTK_CAMERA_MSG_EXT_DATA);  
  31. #endif  
  32. //!--  
  33.   
  34.     LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);  
  35.     return OK;  
  36. }  

从代码片段:
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. mHardware = new CameraHardwareInterface(camera_device_name);//注意到此处。  

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

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

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

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. res = mHardware->initialize(&module->common);//涉及到module,module即为CameraClient::initialize(camera_module_t *module)传进来的参数, 为一个结构体变量的指针。  

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. CameraClient::initialize(camera_module_t *module)调用的地方为CameraService中connect camera的时候调用:  
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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的定义:
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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


[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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. }  


上面的思路就是:

遍历

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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);:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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. }  

关注这两句:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. const char *sym = HAL_MODULE_INFO_SYM_AS_STR;  
  2. hmi = (struct hw_module_t *)dlsym(handle, sym);//关注这两句  
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. HAL_MODULE_INFO_SYM_AS_STR:  
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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实现的地方:


[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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()这个函数:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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.继续往下关注到

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. pdev = createIDevice(  
  2.            i4OpenId,   
  3.            *get_hw_device(),   
  4.            module  
  5.        );  
的实现:
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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对象的构造函数:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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. }  

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. gCameraDevOps:  
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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中:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  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
原创粉丝点击