Android 50 Camera系统源码分析2Camera打开流程.docx
- 文档编号:11380529
- 上传时间:2023-02-28
- 格式:DOCX
- 页数:27
- 大小:78.70KB
Android 50 Camera系统源码分析2Camera打开流程.docx
《Android 50 Camera系统源码分析2Camera打开流程.docx》由会员分享,可在线阅读,更多相关《Android 50 Camera系统源码分析2Camera打开流程.docx(27页珍藏版)》请在冰豆网上搜索。
Android50Camera系统源码分析2Camera打开流程
Android5.0Camera系统源码分析
(2):
Camera打开流程
1.前言
本文将分析Android系统源码,从frameworks层到hal层,暂不涉及app层和kernel层。
由于某些函数比较复杂,在贴出代码时会适当对其进行简化。
本文属于自己对源码的总结,仅仅是贯穿代码流程,不会深入分析各个细节。
欢迎联系讨论,QQ:
1026656828
2.app层
从apk开始,简单列出各个入口函数
[cpp]viewplaincopy
privatevoidinitCamera()
{
CameramCamera=Camera.open();
Camera.ParametersmParameters=mCamera.getParameters();
mParameters.setPictureFormat(PixelFormat.JPEG);
mCamera.setParameters(mParameters);
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
mCamera.takePicture(null,null,mJpegCallback);
}
3.frameworks层
这里将重点介绍Camera.open函数,其余函数将在后续博文分析。
先来看看Camera.open函数在frameworks层的实现,代码路径为:
frameworks/base/core/java/android/hardware/Camera.java
[cpp]viewplaincopy
publicstaticCameraopen(){
if(!
isPermissionGranted()){
returnnull;
}
intnumberOfCameras=getNumberOfCameras();
CameraInfocameraInfo=newCameraInfo();
for(inti=0;i getCameraInfo(i,cameraInfo); if(cameraInfo.facing==CameraInfo.CAMERA_FACING_BACK){ returnnewCamera(i); } } returnnull; } 第5行,通过getNumberOfCameras函数来获取Camera的个数。 从上一篇博文CameraService的启动流程可以看出,这个信息保存在CameraService中。 第10行,需重点关注,构造一个Camera对象,并将它返回给app层。 3.1getNumberOfCameras函数分析 getNumberOfCameras函数进入到CameraService获取Camera个数的流程如下: Camera.Java调用的getNumberOfCameras函数是一个JNI接口,对应的函数是android_hardware_Camera.cpp里的android_hardware_Camera_getNumberOfCameras函数 [cpp]viewplaincopy staticjintandroid_hardware_Camera_getNumberOfCameras(JNIEnv*env,jobjectthiz) { returnCamera: : getNumberOfCameras(); } 这里只是简单调用了Camera.cpp的getNumberOfCameras函数,Camera继承了CameraBase,该函数由它实现 [cpp]viewplaincopy template intCameraBase : getNumberOfCameras(){ constsp returncs->getNumberOfCameras(); } 第3行,getCameraService函数用来获取ICameraService的Bp端,代码实现如下 [cpp]viewplaincopy constchar*kCameraServiceName="media.camera"; template constsp : getCameraService() { if(gCameraService.get()==0){ sp sp binder=sm->getService(String16(kCameraServiceName)); gCameraService=interface_cast } returngCameraService; } Android的Binder通讯机制 第1行,获取的ServiceName为"media.camera",结合上一篇博文CameraService的启动流程可以看出Bn端的实现在CameraService.cpp 回到之前的getNumberOfCameras函数,在获取到ICameraService的Bp端后,就可以开始和Bn端通讯了。 在第4行,当调用cs->getNumberOfCameras函数时,将会进入CameraService.cpp的getNumberOfCameras函数 [cpp]viewplaincopy int32_tCameraService: : getNumberOfCameras(){ returnmNumberOfCameras; } 代码很简单,返回上一篇博文讲到的,千辛万苦从hal层拿到的数据 3.2Camera构造函数分析 回到最开始的Camera.open函数,在第10行,将会构造一个Camera对象 [cpp]viewplaincopy privateintcameraInitVersion(intcameraId,inthalVersion){ ...... Looperlooper; if((looper=Looper.myLooper())! =null){ mEventHandler=newEventHandler(this,looper); }elseif((looper=Looper.getMainLooper())! =null){ mEventHandler=newEventHandler(this,looper); }else{ mEventHandler=null; } StringpackageName=ActivityThread.currentPackageName(); returnnative_setup(newWeakReference } privateintcameraInitNormal(intcameraId){ returncameraInitVersion(cameraId,CAMERA_HAL_API_VERSION_NORMAL_CONNECT); } Camera(intcameraId){ interr=cameraInitNormal(cameraId); ...... } 第14行,native_setup同样是个JNI接口,对应android_hardware_Camera.cpp里的android_hardware_Camera_native_setup函数 [cpp]viewplaincopy staticjintandroid_hardware_Camera_native_setup(JNIEnv*env,jobjectthiz, jobjectweak_this,jintcameraId,jinthalVersion,jstringclientPackageName) { camera=Camera: : connect(cameraId,clientName,Camera: : USE_CALLING_UID); #if1//defined(MTK_CAMERA_BSP_SUPPORT) sp #else sp #endif } 第4行,调用了Camera.cpp的connect函数,同时返回一个Camera对象,保存在JNICameraContext当中 [cpp]viewplaincopy sp : connect(intcameraId,constString16&clientPackageName, intclientUid) { returnCameraBaseT: : connect(cameraId,clientPackageName,clientUid); } 先来看看Camera和CameraBase的类定义 [cpp]viewplaincopy /*----------Camera.h----------*/ template<> structCameraTraits { ...... staticTCamConnectServicefnConnectService; }; classCamera: publicCameraBase { ...... } /*--------CameraBase.h--------*/ structCameraTraits{ }; template classCameraBase { ...... typedefCameraBase } 这里使用了C++模版,其实就是调用CameraBase: : connect函数 [cpp]viewplaincopy CameraTraits : TCamConnectServiceCameraTraits : fnConnectService=&ICameraService: : connect; template sp : connect(intcameraId, constString16&clientPackageName, intclientUid) { sp sp constsp if(cs! =0){ TCamConnectServicefnConnectService=TCamTraits: : fnConnectService; status=(cs.get()->*fnConnectService)(cl,cameraId,clientPackageName,clientUid, /*out*/c->mCamera); } returnc; } 第1行,将CameraTraits: : fnConnectService赋为ICameraService: : connect 第7行,构造一个Camera对象 第10行,获取ICameraService的Bp端 第13行,从上面的解释可以看出,实际就是调用CameraService.cpp的connect函数 第17行,将Camera对象返回给JNI层 [cpp]viewplaincopy status_tCameraService: : connectHelperLocked( /*out*/ sp /*in*/ constsp intcameraId, constString16&clientPackageName, intclientUid, intcallingPid, inthalVersion, boollegacyMode){ ...... intdeviceVersion=getDeviceVersion(cameraId,&facing); switch(deviceVersion){ caseCAMERA_DEVICE_API_VERSION_1_0: client=newCameraClient(this,cameraClient, clientPackageName,cameraId, facing,callingPid,clientUid,getpid(),legacyMode); break; caseCAMERA_DEVICE_API_VERSION_2_0: caseCAMERA_DEVICE_API_VERSION_2_1: caseCAMERA_DEVICE_API_VERSION_3_0: caseCAMERA_DEVICE_API_VERSION_3_1: caseCAMERA_DEVICE_API_VERSION_3_2: client=newCamera2Client(this,cameraClient, clientPackageName,cameraId, facing,callingPid,clientUid,getpid(),legacyMode); break; } status_tstatus=connectFinishUnsafe(client,client->getRemote()); mClient[cameraId]=client; } status_tCameraService: : connect( constsp intcameraId, constString16&clientPackageName, intclientUid, /*out*/ sp ...... sp status=connectHelperLocked(/*out*/client, cameraClient, cameraId, clientPackageName, clientUid, callingPid); device=client; returnOK; } 忽略细节之后connect函数就只是调用connectHelperLocked函数 第13行,获取api版本信息,这个函数比较简单,不细说。 这里的版本为CAMERA_DEVICE_API_VERSION_1_0 第15-30行,根据不同的api版本选择构造CameraClient或Camera2Client,这里是CameraClient 第32行,调用connectFinishUnsafe函数,实现如下 [cpp]viewplaincopy status_tCameraService: : connectFinishUnsafe(constsp constsp status_tstatus=client->initialize(mModule); } 这里的client就是上一个函数的CameraClient,mModule就是在上一篇博文CameraService的启动流程里提到的hal层的接口 [cpp]viewplaincopy status_tCameraClient: : initialize(camera_module_t*module){ mHardware=newCameraHardwareInterface(camera_device_name); res=mHardware->initialize(&module->common); mHardware->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, (void*)(uintptr_t)mCameraId); returnOK; } 构造一个CameraHardwareInterface对象,并调用它的initalize函数,直接看initalize函数 [cpp]viewplaincopy status_tinitialize(hw_module_t*module) { module->methods->open(module,mName.string(),(hw_device_t**)&mDevice) initHalPreviewWindow(); } 第4行,从这里进入到了hal层,hal层主要对Camera硬件进行初始化,并将操作集保存在mDevice当中 4.hal层-基于MTK平台 hal层对Camera硬件进行初始化以及返回Device操作集的流程如下 4.1open函数分析 这里再看一次module的定义 [cpp]viewplaincopy static hw_module_methods_t* get_module_methods() { static hw_module_methods_t _methods= { open: open_device }; return&_methods; } static camera_module get_camera_module() { camera_modulemodule={ common: { tag: HARDWARE_MODULE_TAG, #if(PLATFORM_SDK_VERSION>=21) module_api_version: CAMERA_MODULE_API_VERSION_2_3, #else module_api_version: CAMERA_DEVICE_API_VERSION_1_0, #endif hal_api_version: HARDWARE_HAL_API_VERSION, id: CAMERA_HARDWARE_MODULE_ID, name: "MediaTekCameraModule", author: "MediaTek", methods: get_module_methods(), dso: NULL, reserved: {0}, }, get_number_of_cameras: get_number_of_cameras, get_camera_info: get_camera_info, set_callbacks: set_callbacks, get_vendor_tag_ops: get_vendor_tag_ops, #if(PLATFORM_SDK_VERSION>=21) open_legacy: open_legacy, #endif reserved: {0}, }; returnmodule; }; 通过module->methods获取到的函数为open_device, [cpp]viewplaincopy static int open_device(hw_module_tconst*module,constchar*name,hw_device_t**device) { returnNSCam: : getCamDeviceManager()->open(device,module,name); } CamDeviceManagerImp继承了CamDeviceManagerBase。 这里直接调用了CamDeviceManagerBase的open() [cpp]viewplaincopy status_t CamDeviceManagerBase: : openDeviceLocked( hw_device_t**device, hw_module_tconst*modul
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 50 Camera系统源码分析2Camera打开流程 Camera 系统 源码 分析 打开 流程