Camera_API2分析

上传人:无*** 文档编号:92746801 上传时间:2022-05-19 格式:DOC 页数:54 大小:254KB
收藏 版权申诉 举报 下载
Camera_API2分析_第1页
第1页 / 共54页
Camera_API2分析_第2页
第2页 / 共54页
Camera_API2分析_第3页
第3页 / 共54页
资源描述:

《Camera_API2分析》由会员分享,可在线阅读,更多相关《Camera_API2分析(54页珍藏版)》请在装配图网上搜索。

1、. .一. android6.0源码分析之Camera API2.0简介前面几篇主要分析的是Android Camera API1.0的架构以 及初始化流程,而google在android5.0(Lollipop)开场对Camera的架构进展了调整,为了适应HAL3,新添加实现了 CameraDeviceClient,而Camera API1.0已经被deprecated(即可能在更新的版本里会不支持此API).1、Camera API2.0的架构图Camera API2.0下的Camera架构与API1.0有所区别,下面将给出Camera API2.0以及Camera HAL3.2+下的Ca

2、mera的总体架构图:由图可知,Java层要想与C+层的CameraService层进展通信,都是通过Java层的IPC Binder进制进展的,主要包括ICameraService.aidl以及ICameraDeviceUser.aidl两个接口来实现,其会在Java层维护一个CameraDeviceImpl即Camera设备的代理,而CameraService以及CameraDeviceImpl的初始化会在此文的第二,第三节进展分析。而Java层对Camera的具体操作的操作流程大致为,Java层通过Device代理发送一个CaptureRequest,而C+层进展相应的处理,再调用相应的

3、回调来通知Java相应的处理结果,并将相应的Capture数据保存在Surface Buffer里,这样Java层在回调函数中可以对数据进展相应的处理。而对于具体操作流程的分析,请参考文章开场时的Camera2相关文章的连接。2、Java层的CameraService的实现和应用从Camera API2开场,Camera的实现方式有所不同,最主要的区别是不再使用JNI来调用本地代码,从而获得本地CameraService,并实现其C/S 模式的通信,而是直接在Java层通过Java层的IPC Binder机制来获取Java层的CameraService的代理对象,从而直接在Java层获取本地的

4、CameraService与Camera Device进展相应的通信。相应的代码及目录:ICameraService.aidl:frameworks/base/core/java/android/hardware CameraService.cpp:frameworks/av/services/camera/libcameraservice CameraManager.java:frameworks/base/core/java/android/hardware/camera2获取CameraService的核心代码如下:/CameraManager.javaprvate void conne

5、ctCameraServiceLocked() if(mCameraService != null)return; /获取Binder IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME); if(cameraServiceBinder = null) return; try cameraServiceBinder.linkToDeath(this,/*flags*/ 0); catch(RemoteException e) return; ICameraService camer

6、aServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder); /根据cameraServiceRaw 创立CameraService实例 ICameraService cameraService = CameraServiceDecorator.newInstance(cameraServiceRaw); . try /添加监听 cameraService.addListener(this); /赋值给mCameraService的全局变量 mCameraService = cameraService; catch(Ca

7、meraRuntimeException e) . 由代码可知,通过Java层的Binder从ServiceManager里获取了一个Java层的CameraService实例,在翻开Camera的流程中,会通过此CameraService(Native的CameraService)与Camera通信,而其中的通信通过ICameraDeviceUser来实现,接下来分析ICameraDeviceUser的实现。3、ICameraDeviceUser.aidl的通信实现Java层与C+ CameraService层之间的通信,通过封装了一个CameraDeviceUser来实现,它只是在Java

8、层使用了AIDL技术来实现Client,即在Java层维护了一个CameraDevice,这样的好处是响应速度更快,因为这样不需要通过每次进入Native层来完成通信,而可以通过Java层的IPC Binder机制即可完成。即API2.0通过AIDL实现一个接口ICameraDeviceUser,从而在Java层维护一个Camera proxy,之后的通信都是通过此代理CameraDeviceImpl来实现。相关代码及目录:ICameraDeviceUser.aidl:frameworks/base/core/java/android/hardware/camera2 ICameraDevic

9、eUser.cpp:frameworks/av/camera/camera2 CameraDeviceImpl.java:frameworks/base/core/java/android/hardware/camera2/impl获取Camera Device的Java层代理的核心代码如下:/CameraManager.javaprivate CameraDevice openCameraDeviceUserAsync(.) /初始化Camera Java层代理对象 CameraDevice device = null; try synchronized(mLock) /初始化ICamera

10、DeviceUser ICameraDeviceUser cameraUser = null; /初始化具体的CameraDevice代理 android.hardware.camera2.impl.CameraDeviceImpl deviceImpl = new android.hardware. camera2.impl.CameraDeviceImpl(cameraId,callback,handler,characteristics); BinderHolder holder = new BinderHolder(); ICameraDeviceCallbacks callbacks

11、 = deviceImpl.getCallbacks(); . try /如果支持HAL3.2+的devices if(supportsCamera2ApiLocked(cameraId) /获取CameraService ICameraService cameraService = CameraManagerGlobal.get().getCameraService(); . /连接设备 cameraService.connectDevice(callbacks,id,mContextgetOpPackageName() ,USE_CALLING_UID,holder); /通过Binder

12、获得翻开的Camera设备返回的Camera代理 cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder(); else/否那么用遗产API cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks,id); catch(.) . /包装代理对象 deviceImpl.setRemoteDevice(cameraUser); device = deviceImpl; catch(.) . 返回Camera代理 return device;由代码可知,首先获

13、取CameraService,然后通过它来开启Camera,而开启成功后,C+层会返回一个Camera device代理对象,此处即为ICameraDeviceUser,所以在Java层对其进展相应的封装,变成一个CameraDeviceImpl对象,此后,只要需要对Camera进展操作,都会调用CameraDeviceImpl对象的相关方法,并通过ICameraDeviceUser以及Java IPC Binder来与本地的Camera device进展通信,至此,Camera API2.0的框架就分析完毕了,具体的操作,如Camera的初始化,preview,capture等流程的分析,请

14、看文章开场时,所列出的分析。二. android6.0源码分析之Camera2 HAL分析在上一篇文章对Camera API2.0的框架进展了简单的介绍,其中Camera HAL屏蔽了底层的实现细节,并且为上层提供了相应的接口,具体的HAL的原理,个人觉得老罗的文章Android硬件抽象层HAL概要介绍和学习方案分析的很详细,这里不做分析,本文将只分析Camera HAL的初始化等相关流程。1、Camera HAL的初始化Camera HAL的初始加载是在Native的CameraService初始化流程中的,而CameraService初始化是在Main_mediaServer.cpp的ma

15、in方法开场的:/Main_mediaServer.cppint main(int argc _unused, char* argv) sp proc(ProcessState:self(); /获取ServieManager sp sm = defaultServiceManager(); ALOGI(ServiceManager: %p, sm.get(); AudioFlinger:instantiate(); /初始化media效劳 MediaPlayerService:instantiate(); /初始化资源管理效劳 ResourceManagerService:instantia

16、te(); /初始化Camera效劳 CameraService:instantiate(); /初始化音频效劳 AudioPolicyService:instantiate(); SoundTriggerHwService:instantiate(); /初始化Radio效劳 RadioService:instantiate(); registerExtensions(); /开场线程池 ProcessState:self()-startThreadPool(); IPCThreadState:self()-joinThreadPool();其中,CameraService继承自Binder

17、Service,instantiate也是在BinderService中定义的,此方法就是调用publish方法,所以来看publish方法:/ BinderService.hstatic status_t publish(bool allowIsolated = false) sp sm(defaultServiceManager(); /将效劳添加到ServiceManager return sm-addService(String16(SERVICE:getServiceName(),new SERVICE(), allowIsolated);这里,将会把CameraService效劳参

18、加到ServiceManager进展管理。 而在前面的文章android6.0源码分析之Camera API2.0简介中,需要通过Java层的IPC Binder来获取此CameraService对象,在此过程中会初始CameraService的sp类型的对象,而对于sp,此处不做过多的分析,具体的可以查看深入理解Android卷中的第五章中的相关容。此处,在CameraService的构造时,会调用CameraService的onFirstRef方法:/CameraService.cppvoid CameraService:onFirstRef() BnCameraService:onFir

19、stRef(); . camera_module_t *rawModule; /根据CAMERA_HARDWARE_MODULE_ID(字符串camera)来获取camera_module_t对象 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t *)&rawModule); /创立CameraModule对象 mModule = new CameraModule(rawModule); /模块初始化 err = mModule-init(); . /通过Module获取Camera的数量 mNumber

20、OfCameras = mModule-getNumberOfCameras(); mNumberOfNormalCameras = mNumberOfCameras; /初始化闪光灯 mFlashlight = new CameraFlashlight(*mModule, *this); status_t res = mFlashlight-findFlashUnits(); int latestStrangeCameraId = INT_MAX; for (int i = 0; i getCameraInfo(i, &info); . /如果Module版本高于2.4,找出冲突的设备参数

21、if (mModule-getModuleApiVersion() = CAMERA_MODULE_API_VERSION_2_4 & haveInfo) cost = info.resource_cost; conflicting_devices = info.conflicting_devices; conflicting_devices_length = info.conflicting_devices_length; /将冲突设备参加冲突set集中 std:set conflicting; for (size_t i = 0; i getModuleApiVersion() = CAM

22、ERA_MODULE_API_VERSION_2_1) mModule-setCallbacks(this); /假设大于2.2,那么设置供应商的Tag if (mModule-getModuleApiVersion() = CAMERA_MODULE_API_VERSION_2_2) setUpVendorTags(); /将此效劳注册到CameraDeviceFactory CameraDeviceFactory:registerService(this); CameraService:pingCameraServiceProxy();onFirstRef方法中,首先会通过HAL框架的hw

23、_get_module来获取CameraModule对象,然后会对其进展相应的初始化,并会进展一些参数的设置,如camera的数量,闪光灯的初始化,以及回调函数的设置等,到这里,Camera2 HAL的模块就初始化完毕了,下面给出初始化时序图:2、Camera HAL的open流程分析通过阅读android6.0源码发现,它提供了高通的Camera实现,并且提供了高通的Camera库,也实现了高通的Camera HAL的相应接口,对于高通的Camera,它在后台会有一个守护进程daemon,daemon是介于应用和驱动之间翻译ioctl的中间层(委托处理)。本节将以Camera中的open流程

24、为例,来分析Camera HAL的工作过程,在应用对硬件发出open请求后,会通过Camera HAL来发起open请求,而Camera HAL的open入口在QCamera2Hal.cpp进展了定义:/QCamera2Hal.cppcamera_module_t HAL_MODULE_INFO_SYM = /它里面包含模块的公共方法信息 common: camera_common, get_number_of_cameras: qcamera:QCamera2Factory:get_number_of_cameras, get_camera_info: qcamera:QCamera2Fac

25、tory:get_camera_info, set_callbacks: qcamera:QCamera2Factory:set_callbacks, get_vendor_tag_ops: qcamera:QCamera3VendorTags:get_vendor_tag_ops, open_legacy: qcamera:QCamera2Factory:open_legacy, set_torch_mode: NULL, init : NULL, reserved: 0;static hw_module_t camera_common = tag: HARDWARE_MODULE_TAG,

26、 module_api_version: CAMERA_MODULE_API_VERSION_2_3, hal_api_version: HARDWARE_HAL_API_VERSION, id: CAMERA_HARDWARE_MODULE_ID, name: QCamera Module, author: Qualcomm Innovation Center Inc, /它的方法数组里绑定了open接口 methods: &qcamera:QCamera2Factory:mModuleMethods, dso: NULL, reserved: 0;struct hw_module_meth

27、ods_t QCamera2Factory:mModuleMethods = /open方法的绑定 open: QCamera2Factory:camera_device_open,;Camera HAL层的open入口其实就是camera_device_open方法:/ QCamera2Factory.cppint QCamera2Factory:camera_device_open(const struct hw_module_t *module, const char *id, struct hw_device_t *hw_device) . return gQCamera2Factor

28、y-cameraDeviceOpen(atoi(id), hw_device);它调用了cameraDeviceOpen方法,而其中的hw_device就是最后要返回给应用层的CameraDeviceImpl在Camera HAL层的对象,继续分析cameraDeviceOpen方法:/ QCamera2Factory.cppint QCamera2Factory:cameraDeviceOpen(int camera_id, struct hw_device_t *hw_device) . /Camera2采用的Camera HAL版本为HAL3.0 if ( mHalDescriptors

29、camera_id.device_version = CAMERA_DEVICE_API_VERSION_3_0 ) /初始化QCamera3HardwareInterface对象,这里构造函数里将会进展configure_streams以及 /process_capture_result等的绑定 QCamera3HardwareInterface *hw = new QCamera3HardwareInterface( mHalDescriptorscamera_id.cameraId, mCallbacks); /通过QCamera3HardwareInterface来翻开Camera r

30、c = hw-openCamera(hw_device); . else if (mHalDescriptorscamera_id.device_version = CAMERA_DEVICE_API_VERSION_1_0) /HAL API为2.0 QCamera2HardwareInterface *hw = new QCamera2HardwareInterface(uint32_t)camera_id); rc = hw-openCamera(hw_device); . else . return rc;此方法有两个关键点:一个是QCamera3HardwareInterface对象

31、的创立,它是用户空间与核空间进展交互的接口;另一个是调用它的openCamera方法来翻开Camera,下面将分别进展分析。2.1 QCamera3HardwareInterface构造函数分析在它的构造函数里面有一个关键的初始化,即mCameraDevice.ops = &mCameraOps,它会定义Device操作的接口:/QCamera3HWI.cppcamera3_device_ops_t QCamera3HardwareInterface:mCameraOps = initialize: QCamera3HardwareInterface:initialize, /配置流数据的相关

32、处理 configure_streams: QCamera3HardwareInterface:configure_streams, register_stream_buffers: NULL, construct_default_request_settings: QCamera3HardwareInterface:construct_default_request_settings, /处理结果的接口 process_capture_request: QCamera3HardwareInterface:process_capture_request, get_metadata_vendor

33、_tag_ops: NULL, dump: QCamera3HardwareInterface:dump, flush: QCamera3HardwareInterface:flush, reserved: 0,; 其中,会在configure_streams中配置好流的处理handle:/QCamera3HWI.cppint QCamera3HardwareInterface:configure_streams(const struct camera3_device *device, camera3_stream_configuration_t *stream_list) /获得QCamer

34、a3HardwareInterface对象 QCamera3HardwareInterface *hw =reinterpret_cast(device-priv); . /调用它的configureStreams进展配置 int rc = hw-configureStreams(stream_list); . return rc;继续追踪configureStream方法:/QCamera3HWI.cppint QCamera3HardwareInterface:configureStreams(camera3_stream_configuration_t *streamList) . /初

35、始化Camera版本 al_version = CAM_HAL_V3; . /开场配置stream . /初始化相关Channel为NULL if (mMetadataChannel) delete mMetadataChannel; mMetadataChannel = NULL; if (mSupportChannel) delete mSupportChannel; mSupportChannel = NULL; if (mAnalysisChannel) delete mAnalysisChannel; mAnalysisChannel = NULL; /创立Metadata Chan

36、nel,并对其进展初始化 mMetadataChannel = new QCamera3MetadataChannel(mCameraHandle-camera_handle, mCameraHandle-ops, captureResultCb,&gCamCapabilitymCameraId-padding_info, CAM_QCOM_FEATURE_NONE, this); . /初始化 rc = mMetadataChannel-initialize(IS_TYPE_NONE); . /如果h/w support可用,那么创立分析stream的Channel if (gCamCapa

37、bilitymCameraId-hw_analysis_supported) mAnalysisChannel = new QCamera3SupportChannel(mCameraHandle-camera_handle, mCameraHandle-ops,&gCamCapabilitymCameraId-padding_info, CAM_QCOM_FEATURE_PP_SUPERSET_HAL3,CAM_STREAM_TYPE_ANALYSIS, &gCamCapabilitymCameraId-analysis_recommended_res,this); . bool isRaw

38、StreamRequested = false; /清空stream配置信息 memset(&mStreamConfigInfo, 0, sizeof(cam_stream_size_info_t); /为requested stream分配/QCamera3HWI.cppint QCamera3HardwareInterface:configureStreams(camera3_stream_configuration_t *streamList) . /初始化Ca相关的channel对象 for (size_t i = 0; i num_streams; i+) camera3_strea

39、m_t *newStream = streamList-streamsi; uint32_t stream_usage = newStream-usage; mStreamConfigInfo.stream_sizesmStreamConfigInfo.num_streams.width = (int32_t)newStream- width; mStreamConfigInfo.stream_sizesmStreamConfigInfo.num_streams.height = (int32_t)newStream- height; if (newStream-stream_type = C

40、AMERA3_STREAM_BIDIRECTIONAL|newStream-usage & GRALLOC_USAGE_HW_CAMERA_ZSL) &newStream-format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED & jpegStream) mStreamConfigInfo.typemStreamConfigInfo.num_streams = CAM_STREAM_TYPE_SNAPSHOT; mStreamConfigInfo.postprocess_maskmStreamConfigInfo.num_streams = CAM_Q

41、COM_FEATURE_NONE; else if(newStream-stream_type = CAMERA3_STREAM_INPUT) else switch (newStream-format) /为非zsl streams查找他们的format . if (newStream-priv = NULL) /为新的stream构造Channel switch (newStream-stream_type) /分类型构造 case CAMERA3_STREAM_INPUT: newStream-usage |= GRALLOC_USAGE_HW_CAMERA_READ; newStrea

42、m-usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;/WR for inplace algos break; case CAMERA3_STREAM_BIDIRECTIONAL: . break; case CAMERA3_STREAM_OUTPUT: . break; default: break; /根据前面的得到的stream的参数类型以及format分别对各类型的channel进展构造 if (newStream-stream_type = CAMERA3_STREAM_OUTPUT | newStream-stream_type = CAMERA3_ST

43、REAM_BIDIRECTIONAL) QCamera3Channel *channel = NULL; switch (newStream-format) case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: /* use higher number of buffers for HFR mode */ . /创立Regular Channel channel = new QCamera3RegularChannel(mCameraHandle-camera_handle, mCameraHandle-ops, captureResultCb,&gCam

44、CapabilitymCameraId- padding_info,this,newStream,(cam_stream_type_t)mStreamConfigInfo.type mStreamConfigInfo.num_streams,mStreamConfigInfo.postprocess_mask mStreamConfigInfo.num_streams,mMetadataChannel,numBuffers); . mPendingRequestInfo newStream-max_buffers = channel-getNumBuffers(); newStream-pri

45、v = channel; break; case HAL_PIXEL_FORMAT_YCbCr_420_888: /创立YWV Channel . break; case HAL_PIXEL_FORMAT_RAW_OPAQUE: case HAL_PIXEL_FORMAT_RAW16: case HAL_PIXEL_FORMAT_RAW10: /创立Raw Channel . break; case HAL_PIXEL_FORMAT_BLOB: /创立QCamera3PicChannel . break; default: break; else if (newStream-stream_ty

46、pe = CAMERA3_STREAM_INPUT) newStream-max_buffers = MAX_INFLIGHT_REPROCESS_REQUESTS; else for (List:iterator it=mStreamInfo.begin();it != mStreamInfo.end(); it+) if (*it)-stream = newStream) (*it)-channel = (QCamera3Channel*) newStream-priv; break; else if (newStream-stream_type != CAMERA3_STREAM_INP

47、UT) mStreamConfigInfo.num_streams+; if (isZsl) if (mPictureChannel) mPictureChannel-overrideYuvSize(zslStream-width, zslStream-height); else if (mPictureChannel & m_bIs4KVideo) mPictureChannel-overrideYuvSize(videoWidth, videoHeight); /RAW DUMP channel if (mEnableRawDump & isRawStreamRequested = fal

48、se) cam_dimension_t rawDumpSize; rawDumpSize = getMaxRawSize(mCameraId); mRawDumpChannel = new QCamera3RawDumpChannel(mCameraHandle-camera_handle, mCameraHandle-ops,rawDumpSize,&gCamCapabilitymCameraId-padding_info, this, CAM_QCOM_FEATURE_NONE); . /进展相关Channel的配置 . /* Initialize mPendingRequestInfo

49、and mPendnigBuffersMap */ for (List:iterator i = mPendingRequestsList.begin(); i != mPendingRequestsList.end(); i+) clearInputBuffer(i-input_buffer); i = mPendingRequestsList.erase(i); mPendingFrameDropList.clear(); / Initialize/Reset the pending buffers list mPendingBuffersMap.num_buffers = 0; mPen

50、dingBuffersMap.mPendingBufferList.clear(); mPendingReprocessResultList.clear(); return rc;此方法容比较多,只抽取其中核心的代码进展说明,它首先会根据HAL的版本来对stream进展相应的配置初始化,然后再根据stream类型对stream_list的stream创立相应的Channel,主要有QCamera3MetadataChannel,QCamera3SupportChannel等,然后再进展相应的配置,其中QCamera3MetadataChannel在后面的处理capture request的时候会用到,这里就不做分析,而Camerametadata那么是Java层和CameraService之间传递的元数据,见android6.0源码分析之Camera API2.0简介中的Camera2架构图,至此,QCamera3HardwareInterface构造完毕,与本文相关的就是配置了mCameraDevice.ops。2.2 openCamera分析本节主要分析Module是如何翻开Camera的,openCamera的代码如下:/QCamera3HWI

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!