Android的Camera架构

一 Android Camera框架

要了解AndroidCamera架构,还是得先从Android本身的架构说起。




图1 Android Architecture

从Android框架看,分为四层:应用层、应用框架层、库层、内核层。

应用层主要工作在AndroidSDK之上,利用Android提供的API进行开发,生成APK包。

应用框架层整合了Android自带各种控件和类,为应用开发提供高效、方便的API接口。这个对上实现统一的接口,对下也提供统一的标准方便各种库的移入。

库层是Android与底层硬件通信接口,它封装底层硬件接口实现该模块的具体逻辑,并以服务的形式通过Binder通讯机制暴露给应用框架。

内核层则是直接与硬件联系的一层,可以理解为设备驱动。

通过对上面框架的简要说明,我们大致明白一个应用自上而下的各个层起什么作用,这样有助于我们对代码的理解和修改。如果要做基于Androidporting工作,就要明白在哪个层次的porting,怎么porting。

Android的Camera包含取景器(viewfinder)和拍摄照片(takepicture)的功能。目前Android原生的Camera程序虽然功能比较简单,但是其程序的架构分成客户端和服务器两个部分,它们建立在Android的进程间通讯Binder的结构上。Android中的Camera模块同样遵循Android的框架,如下图所示。

图2 Camera Architecture

二 Android Camera架构分层及代码结构

以开源的Android 为例,Camera 架构主要分为以下几个层次

2.1应用层

Camera 的JAVA应用程序的路径:

packages/apps/Camera/src/com/android/camera/

在其中Camera.java是主要实现的文件

2.2 JNI层(Camera 的 JAVA 本地调用部分):

frameworks/base/core/java/android/hardware/Camera.java

这个类是和JNI中定义的类是同一个,有些native方法通过JNI的方式调用Native代码实现具体的功能,比如startPreview、autoFocus、takePicture等。

2.3 Cameraclient层:

头文件分布以下的目录中:

frameworks/base/include/camera/

Camera底层库在以下的目录中:

frameworks/base/libs/camera/

这部分的内容被编译成库libcamera_client.so(或者libui.so),主要实现了以下几个类:

Camera---->Camera.cpp/Camera.h

CameraParameters---->CameraParameters.cpp/CameraParameters.h

ICamera---->ICamera.cpp/ ICamera.h

ICameraClient---->ICameraClient.cpp/ ICameraClient.h

ICameraService---->ICameraService.cpp/ ICameraService.h

ICamera、ICameraClient、ICameraServide三个类是按照BinderIPC通信要求的框架实现的, 用来与service端通信。

类CameraParameters接收Framework层的android.hardware.camera::Parameters类为参数, 解析与格式化所有的参数配置。

Camera是个很重要的类,它与CameraService端通过BinderIPC机制交互来实现具体功能。Cametra继承自BnCameraClient,并最终继承自ICameraClient.

2.4 CameraService层

文件分布在frameworks/base/camera/libcameraservice/这部分内容被编译成库libcameraservice.so,libcameraservice.so是Camera的服务器程序,它通过继承libcamera_client.so的类实现服务器的功能,并且与libcamera_client.so中的另外一部分内容则通过进程间通讯(即Binder机制)的方式进行通讯。

里面主要实现了两个类:

CameraService---->BnCameraService---->ICameraService

CameraService::Client---->BnCamera---->ICamera

CameraService::Client通过调用CameraHAL层来实现具体的功能。

2.5 HAL层

Libcameraservice.so::CameraService::Client类调用CameraHAL的代码实现具体的功能,CameraHAL一般实现为一个动态库libcamera.so(动态库的名字可以修改, 只需要与android.mk一致即可)。

所有java应用层中camera的功能最终会调用到HAL层这里,CameraHAL层的实现依赖于硬件, 一般通过V4L2command从linuxkernel中的cameradriver获得preview数据, 然后交给surface(overlay)显示或者保存为文件。在HAL层需要打开对应的设备文件, 并通过ioctrl访问cameradriver。Android通过这个HAL层来保证底层硬件(驱动)改变, 只需修改对应的HAL层代码,FrameWork层与JAVAAP层都不用改变。

2.6 Camera库文件分析

前面已提到Camera模块主要包含libandroid_runtime.so、libcamera_client.s0(libui.so)、libcameraservice.so和一个与Camera硬件相关的硬件库libcamera.so。其中libandroid_runtime.so、libcamera_client.s0(libui.so)是与android系统构架相关的, 不需要对进行其修改,libameraservice.so和libcamera.so则是和硬件设备相关联的,而cameralib.so实际上就是设备的linxu驱动,所以Camera设备的系统继承主要是通过移植CameraLinux驱动和修改libcameraservice.so库来完成。

Libcameraservice.so构建规则中使用宏USE_CAMERA_STUB决定 是否使用真的Camera,如果宏为真,则使用CameraHardwareStub.cpp和FakeCamera.cpp构造一个假的Camera,如果为假则使用libcamera来构造一个实际上的Camera服务。

在CameraHardwareStub.cpp中定义了CameraHardwareStub类,它继承并实现了抽象类CameraHardwareInterface中定义的真正操作Camera设备的所有的纯虚函数。通过openCameraHardware()将返回一个CameraHardwareInterface类的对象,但由于CameraHardwareInterface类是抽象类所以它并不能创建对象,而它的派生类CameraHardwareStub完全实现了其父类的 纯虚函数所以openCameraHardware()返回一个指向派生类对象的基类指针用于底层设备的操作。由于CameraHardwareStub类定义的函数是去操作一个假的Camera,故通过openCameraHardware返回的指针主要用于仿真环境对Camera的模拟操作,要想通过openCameraHardware返回的指针操作真正的硬件设备则需完成以下步骤:

⑴CameraHardwareInterface类中的所有纯虚函数的声明改为虚函数的声明(即去掉虚函数声明后的“=0” );

⑵编写一个源文件去定义CameraHardwareInterface类中声明的所有虚函数;

⑶编写Android.mk文件用于生成一个包含步骤⑵编写的源文件和其他相关文件的libcamera.so文件;

⑷将宏USE_CAMERA_STUB改成false,这样生成libcameraservice.so时就会包含libcamera.so库。(注:如果CameraHardwareInterface类的成员函数并没有直接操作硬件而是调用Camera的linux驱动来间接对硬件操作,那么包含这样的CameraHardwareInterface类的libcamera.so库就相当于一个HAL)。

三 Camera的架构和代码分析

3.1 Camera的整体框架图Camera的各个库之间的结构可以用下图的表示:


图3 库结构图

在Camera系统的各个库中,libui.so位于核心的位置,它对上层的提供的接口主要是Camera类,类libandroid_runtime.so通过调用Camera类提供对JAVA的接口,并且实现了android.hardware.camera类。

libcameraservice.so是Camera的服务器程序,它通过继承libcamera_client.so(libui.so)的类实现服务器的功能,并且与libcamera_client.so(libui.so)中的另外一部分内容则通过进程间通讯(即Binder机制)的方式进行通讯。

libandroid_runtime.so和libcamera_client.so(libui.so)两个库是公用的,其中除了Camera还有其他方面的功能。

Camera部分的头文件在frameworks/base/include/ui/ 目录中,这个目录是和libmedia.so库源文件的目录frameworks/base/libs/ui/ 相对应的。

Camera主要的头文件有以下几个:

ICameraClient.h

Camera.h

ICamera.h

ICameraService.h

CameraHardwareInterface.h


图4Camera 类图

在这些头文件Camera.h提供了对上层的接口,而其他的几个头文件都是提供一些接口类(即包含了纯虚函数的类),这些接口类必须被实现类继承才能够使用。

整个Camera在运行的时候,可以大致上分成Client和Server两个部分,它们分别在两个进程中运行,它们之间使用Binder机制实现进程间通讯。这样在客户端调用接口,功能则在服务器中实现,但是在客户端中调用就好像直接调用服务器中的功能,进程间通讯的部分对上层程序不可见。

从框架结构上来看,ICameraService.h、ICameraClient.h和ICamera.h三个类定义了MeidaPlayer的接口和架构,ICameraService.cpp和Camera.cpp两个文件用于Camera架构的实现,Camera的具体功能在下层调用硬件相关的接口来实现。

从Camera的整体结构上,类Camera是整个系统核心,ICamera类提供了Camera主要功能的接口,在客户端方面调用,CameraService是Camera服务,它通过调用实际的Camera硬件接口来实现功能。事实上,图中红色虚线框的部分都是Camera程序的框架部分,它主要利用了Android的系统的Binder机制来完成通讯。蓝色的部分通过调用Camera硬件相关的接口完成具体的Camera服务功能,其它的部分是为上层的JAVA程序提供JNI接口。在整体结构上,左边可以视为一个客户端,右边是一个可以视为服务器,二者通过Android的Binder来实现进程间的通讯。

3.2 头文件ICameraClient.h

ICameraClient.h用于描述一个Camera客户端的接口,定义如下所示:

class ICameraClient:public IInterface

{

public:

DECLARE_META_INTERFACE(CameraClient);

virtual void shutterCallback() = 0;

virtual void rawCallback(constsp<IMemory>& picture) = 0;

virtual void jpegCallback(constsp<IMemory>& picture) = 0;

virtual void frameCallback(constsp<IMemory>& frame) = 0;

virtual void errorCallback(status_t error)= 0;

virtual void autoFocusCallback(boolfocused) = 0;

};

classBnCameraClient: public BnInterface<ICameraClient>

{

public:

virtual status_t onTransact( uint32_t code,

constParcel& data,

Parcel* reply,

uint32_t flags= 0);

};

在定义中,ICameraClient类继承IInterface,并定义了一个Camera客户端的接口,BnCameraClient继承了BnInterface<ICameraClient>,这是为基于Android的基础类Binder机制实现在进程通讯而构建的。根据BnInterface类模版的定义BnInterface<ICameraClient>类相当于双继承了BnInterface和ICameraClient。

IcameraClient这个类的主要接口是几个回调函数shutterCallback、rawCallback和jpegCallback等,它们在相应动作发生的时候被调用。作为Camera的“客户端”,需要自己实现几个回调函数,让服务器程序去“间接地”调用它们。

3.3 头文件Camera.h

Camera.h是Camera对外的接口头文件,它被实现CameraJNI的文件android_hardware_Camera.cpp所调用。Camera.h最主要是定义了一个Camera类:

classCamera : public BnCameraClient, public IBinder:: DeathRecipient

{

public:

staticsp<Camera> connect();

~Camera();

void disconnect();

status_t getStatus() { return mStatus; }

status_t setPreviewDisplay(constsp<Surface>& surface);

status_t startPreview();

void stopPreview();

status_t autoFocus();

status_t takePicture();

status_t setParameters(const String8& params);

String8 getParameters() const;

void setShutterCallback(shutter_callback cb,void *cookie);

void setRawCallback(frame_callback cb, void*cookie);

void setJpegCallback(frame_callback cb, void*cookie);

void setFrameCallback(frame_callback cb,void *cookie);

void setErrorCallback(error_callback cb,void *cookie);

void setAutoFocusCallback(autofocus_callbackcb, void *cookie);

// ICameraClient interface

virtual void shutterCallback();

virtual void rawCallback(constsp<IMemory>& picture);

virtual void jpegCallback(constsp<IMemory>& picture);

virtual void frameCallback(constsp<IMemory>& frame);

virtual void errorCallback(status_t error);

virtual void autoFocusCallback(bool focused);

//……

}

从接口中可以看出Camera类刚好实现了一个Camera的基本操作,例如播放(startPreview)、停止(stopPreview)、暂停(takePicture)等。在Camera类中connect()是一个静态函数,它用于得到一个Camera的实例。在这个类中,具有设置回调函数的几个函数:setShutterCallback、setRawCallback和setJpegCallback等,这几个函数是为了提供给上层使用,上层利用这几个设置回调函数,这些回调函数在相应的回调函数中调用,例如使用setShutterCallback设置的回调函数指针被shutterCallback所调用。

在定义中,ICameraClient类双继承了IInterface和IBinder::DeathRecipient,并定义了一个Camera客户端的接口,BnCameraClient继承了BnInterface<ICameraClient>,这是为基于Android的基础类Binder机制实现在进程通讯而构建的。事实上,根据BnInterface类模版的定义BnInterface<ICameraClient>类相当于双继承了BnInterface和ICameraClient。这是Android一种常用的定义方式。

继承了DeathNotifier类之后,这样当这个类作为IBinder使用的时候,当这个Binder即将Died的时候被调用其中的binderDied函数。继承这个类基本上实现了一个回调函数的功能。

3.4 头文件ICamera.h

ICamera.h描述的内容是一个实现Camera功能的接口,其定义如下所示:

classICamera: public IInterface

{

public:

DECLARE_META_INTERFACE(Camera);

virtual void disconnect() = 0;

virtual status_t setPreviewDisplay(constsp<ISurface>& surface) = 0;

virtual void setHasFrameCallback(bool installed) = 0;

virtual status_t startPreview() = 0;

virtual void stopPreview() = 0;

virtual status_t autoFocus() = 0;

virtual status_t takePicture() = 0;

virtual status_t setParameters(const String8& params) = 0;

virtual String8 getParameters() const = 0;

};

classBnCamera: public BnInterface<ICamera>

{

public:

virtual status_t onTransact( uint32_t code,

constParcel& data,

Parcel* reply,

uint32_tflags = 0);

};

ICamera.h描述的内容是一个实现Camera功能的接口,其定义如下所示:

在camera类中,主要定义Camera的功能接口,这个类必须被继承才能够使用。值得注意的是,这些接口和Camera类的接口有些类似,但是它们并没有直接的关系。事实上,在Camera类的各种实现中,一般都会通过调用ICamera类的实现类来完成。

3.5 头文件ICameraService .h

ICameraService.h 用于描述一个Camera的服务,定义方式如下所示:

classICameraService : public IInterface

{

public:

DECLARE_META_INTERFACE(CameraService);

virtual sp<ICamera> connect(const sp<ICameraClient>&cameraClient) = 0;

};

classBnCameraService: public BnInterface<ICameraService>

{

public:

virtual status_t onTransact( uint32_t code,

constParcel& data,

Parcel*reply,

uint32_tflags = 0);

};

由于具有纯虚函数,ICameraService 以及BnCameraService必须被继承实现才能够使用,在ICameraService只定义了一个connect()接口,它的返回值的类型是sp<ICamera>,这个ICamera是提供实现功能的接口。注意,ICameraService只有连接函数connect(),没有断开函数,断开的功能由ICamera接口来提供。

3.6 头文件CameraHardwareInterface.h

CameraHardwareInterface.h定义的是一个Camera底层的接口,这个类的实现者是最终实现Camera的。

CameraHardwareInterface 定以Camera硬件的接口,如下所示:

classCameraHardwareInterface : public virtual RefBase {

public:

virtual ~CameraHardwareInterface() { }

virtual sp<IMemoryHeap> getPreviewHeap() const = 0;

virtual status_t startPreview(preview_callback cb, void*user) = 0;

virtual void stopPreview() = 0;

virtual status_t autoFocus(autofocus_callback,

void* user) = 0;

virtual status_t takePicture(shutter_callback,

raw_callback,

jpeg_callback,

void* user)= 0;

virtual status_t cancelPicture(bool cancel_shutter,

boolcancel_raw,

boolcancel_jpeg) = 0;

virtual status_t setParameters(const CameraParameters&params) = 0;

virtual CameraParameters getParameters() const = 0;

virtual void release() = 0;

virtual status_t dump(int fd, constVector<String16>& args) const = 0;

};

使用C语言的方式导出符号:

extern"C" sp<CameraHardwareInterface> openCameraHardware();

在程序的其他地方,使用openCameraHardware()就可以得到一个CameraHardwareInterface,然后调用CameraHardwareInterface的接口完成Camera的功能。

更多相关文章

  1. android APP如何实现launcher
  2. android camera研究
  3. Android(安卓)UI开发第二十八篇——Fragment中使用左右滑动菜单
  4. Android的多媒体框架OpenCore介绍
  5. Android系列之浅谈Android(安卓)3D旋转
  6. Android实现上下滑动效果
  7. Android(安卓)监控程序安装和删除的实现
  8. Android应用程序启动过程源代码分析
  9. Android: AIDL --- Android中的远程接口

随机推荐

  1. Android(安卓)开机启动App
  2. Android通过图片名字获得ID
  3. 安装android studio 不能启动
  4. android 自定义View 对话框
  5. Android(安卓)Http通信(使用 标准Java接
  6. android kill package
  7. Android菜单实现两种方式
  8. Android(安卓)开发之JNI学习笔记
  9. android中Json数据保存方式
  10. android xml属性的单位大全