以本文记录下学习sdm660 camera模块的总结:

首先特别感谢https://blog.csdn.net/armwind博主的文章

 

(一)目录

一. android camera系统架构图 
二. opencamera
(1)Bn Bp对象的理解
(2)回调函数的注册,监听
(3)aidl—ICameraService,hidl--ICameraDevice
三. takepicture(zsl)
四. 参考资料

说明:

首先是按照我的理解绘制出了android camera系统架构图,

然后说明opencameratakepicture(zsl)两个过程,其中重点是在opencamera

通过这些天的学习,我发现opencamerapreview takepicture record的基础,

opencamera会初始化很多对象,而preview takepicture record等操作是围绕着这些对象进行操作的,

所以这里我用opencamera来理清各个对象间的交互关系,

takepicture作为对象间交互关系的一个实例来讲解。

这里opencamera下列出的是需要注意的地方,opencamera时会说明

(1)Bn Bp对象的理解说明了camera工作时对象之间的关系

(2)回调函数的注册,监听为以后camera事件的回调打下基础

(3)aidl hidl涉及到binder IPC的相关内容,

aidlCameraClient进程和CameraService进程交互的接口,

Hidlframework层和hal层交互的接口!

 

(二)android camera系统架构图

 android camera系统架构图sdm660--camera学习

我将Camera模块的系统架构分为四层,

从上到下分别是package文件夹下的java层,framework文件夹下的framework层,hardware文件夹下的hal层和kernel文件夹下的driver层。

其中framework层下又细分为java framework,jni frameworkhardwareinterface framework;

hal层下又细分为hardwareinterface halmmcamera;

aidl是发生在jni framework层与hardwareinterface framework层交互的接口,即CameraClient进程与CameraService进程的交互;

hidl是发生在frame层和hal层交互的接口。

下面,我会按照java,framework,hal这三层来捋下opencamera的流程,一直捋到hal层的mmcamera层!

 

(三)opencamera

1.Java layer

sdm660--camera学习

我们先通过一张类图从java层看下camera模块是如何发送请求,并接收回调的:

Java层是通过AndroidCameraManagerImplemetation这个类来进行消息发送和数据回调的,

其中的CameraHandler类负责根据消息的不同类型调用不同的framework层接口,我们可以看到不用类型的消息用宏定义区分,

需要注意的是拍照的请求单独在一个公有接口里.

回调则是通过不同的回调类处理,这里previewCallback处理preview回调数据流,

ShutterCallbackPictureCallback处理拍照回调,shuttercallback与拍照完成瞬间的声音及动画有关,picturecallback是用来保存jpeg图片的。

需要注意的是这里回调的具体实现是在各个Module模块里,比如ShutterCallbackonshutter方法和PictureCallbackonPictureTaken方法具体是在PhotoModule.java里实现的!

在之后的回调分析中可以看到每一层都有相应的回调函数,会向上传递事件和数据,而最终处理事件和数据的地方是在Module模块里。

接下来我们根据OPEN_CAMERA继续向下看:

 

1.Framework layer

(1)Java framework layer

sdm660--camera学习

如之前说的,framework层里分为三个小层,这里先看java framework层:

Java framework层主要看的是camera类,660里使用的是camera1接口,所以这里调用的是openLegacy接口,

这里要注意的是在创建Camera对象时创建了EventHandler对象,

EventHandler对象会在一个线程里轮询事件消息,当有回调上来时,会根据消息类型调用不同的回调函数。

接下来我们顺着Native_setup这条线继续往下看,android_hardware_Camera_native_setup就到了Jni framework层!!!

 

(2)Jni framework layer

sdm660--camera学习

此图说明了opencamerajni framework层做的事情,分别是

1请求连接 2设置监听 3接收回调 4转移回调 5传回上层

native_setup里主要做了两件事:

一是请求连接,这里调用到connectLegacy接口,

二是设置监听函数。

这里需要注意下设置监听的作用,从hardwareinterface framework层接收回调后,会调用到BnCameraClient的回调接口,

但并不是由BnCameraClient对象进行回调的上层回传,而是先进行回调转移到JNICameraContext对象,之后再通过JNICameraContext对象传回上层。

这与java层与cpp层的交互总是要经过Jni层是一个道理。

接下来就是整个framework层的核心了,我们看到这里有个BnCameraClient对象,这个对象到底是什么,我们来看下面这张图:

 

sdm660--camera学习

图中六个蓝色对象贯穿了整个Camera ClientCamera Service的交互过程:

我们一行行来看:

(1)请求连接,即刚才看到的connectLegacy操作,该操作是通过实现ICameraService的接口而完成的

(2)请求预览,拍照和录像等操作,这些操作是通过实现ICamera的接口而完成的

(3)通知消息,回调等,这些操作是通过实现ICameraClient接口而完成的

刚开始看到这六个对象时我是晕头转向的,

首先不知道Bn Bp的含义,

再者就是在我看的代码中只看到了CameraClient进程中的camera对象和CameraService进程中的cameraclient对象,哪里来的这么多对象???

为此,我们画一个简化的IInterface类图来慢慢说明!!!

 

sdm660--camera学习

这张IInerface类图的信息量比较大,主要包含以下几点:

1)第一,我们看下接口负责的功能:

ICameaClient类负责定义回调等接口;

Icamera类负责定义请求预览,拍照,录像,自动对焦等接口;

ICameraService类则负责定义请求连接connectLegacy这个接口;

2)第二,Bp Bn对象的说明:

这里Bn是指Binder native对象,即Binder本地对象;Bp是指Binder proxy对象,即Binder代理对象;

本地对象是指实际处理事件的对象,而代理对象的作用是通过Binder机制通知本地对象去处理相应的事件。

这里我们以BpCameraBnCamera为例来说明下:

CameraClient进程的BpCamera对象发送startPreview请求后,会通过remote Binder IPC的方式找到

CameraService进程的BnCamera对象,进而调用BnCamerastartPreview方法。

3)第三,我们来看下由ICameraClient ICameraServiceIcamera衍生出来的对象:

首先是ICameraClient的衍生对象是CameraClient进程的camera对象,但观察camera对象可以看到camera对象不仅有ICameaClient的回调方法,

还有ICamera的预览拍照等方法,ICameraServiceconnectLegacy方法,刚开始这是有疑问的,

这里注意下camera对象的基类,是个模板类,分别有两个成员,

一个返回ICameraService对象,另一个是TCamUser成员,而TCamUser实际上是Icamera的类型别名,

这时所有疑问就都打开了:

原来CameraClient进程中的camera对象就是BnCameraClient对象,而BpCamera对象和BpCameraService对象则是BnCameraClient对象的两个成员!!!

同理:

CameraService进程中的cameraclient对象就是BnCamera对象,而BpCameraClient对象则是BnCamera对象的一个成员!!!

CameraService进程中的cameraservice对象就是BnCameraService对象.

4)说明上一页PPT对应的三组操作对应的函数接口

根据如上所说的,就是三个对象在相互作用,CameraClient进程中的camera对象和CameraService进程的cameraclient对象 cameraservice对象。

Cameraservice对象是在手机开机过程中创建的,

那么现在还剩最后一个问题,CameraClient进程中的camera对象和CameraService进程的cameraclient对象是何时创建的?

其实就是在opencamera中的这个openLegacy!!!我们来看下openLegacy流程图:

 

sdm660--camera学习

说明下CameraClient进程中的camera对象和CameraService进程的cameraclient对象是如何创建的:

由此图可以看出,CameraconnectLegacy会调用到CameaServiceconnectLegacy,

CameraconnectLegacy的最后一个参数为输出参数,就是camera对象,对应BnCameraClient;

CameraServiceconnectLegacy的最后一个参数对应BnCamera,就是CameraClient对象。

CameraServiceconnectLegacy会调用到CameraClient::initialize,到下一层hardwareinterface framework layer.

 

(3)Hardwareinterface framework layer

sdm660--camera学习

这是Framework层的最后一层hardware接口层:

hardware接口层主要工作有两个:

(1)openSession,然后通过hidl实现与HAL层的交互

(2)第二,就是设置回调函数了

 

3.Hal layer

sdm660--camera学习

Hal层也有对应的hardware接口层,openCamera:

首先创建了hardware接口类的实例,然后调用到mm_camera_open接口并register_event_notify注册了事件通知器,

其中mm_camera_open主要完成一下操作:

打开节点,创建socket,起相关线程。

 

(四)takepicture(zsl)

1.发送请求流程

sdm660--camera学习

sdm660--camera学习

Java,framework层和hal层依次下发takepicture请求,主要的流程同之前的分析所描述;

这里主要说下HAL,从流程图中可以看出两点:

(1)Zsl takepictre的流程主要分两步:

Pre_take_picture

takpicture

(2)以消息队列的方式处理消息事件

2.接收回调流程

sdm660--camera学习

sdm660--camera学习

sdm660--camera学习

Takepicture涉及到的回调函数主要有两个:分别是shutterCallback jpepCallback

从图中我们可以看到:

Hardwareinterface hal layer对应的叫playShuterprocessJpegNotify

而之后HAL层向上每个layer会有对应的notifycallback datacallback

 

(五)参考资料

1.https://blog.csdn.net/armwind

2.linux_camera_software_design_document.pdf

3.camera_frontend_code_walkthrough_for_msm8974_msm8x26_linux_camera_software.pdf

相关文章: