《2022年Android的Camera架构介绍 2.pdf》由会员分享,可在线阅读,更多相关《2022年Android的Camera架构介绍 2.pdf(11页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、查看文章Android 的 Camera架构介绍 (转)2009-05-12 22:55 第一部分 Camera 概述 Android的 Camera 包含取景器(viewfinder)和拍摄照片的功能。目前Android发布版的Camera 程序虽然功能比较简单,但是其程序的架构分成客户端和服务器两个部分,它们建立在Android的进程间通讯Binder的结构上。以开源的Android为例,Camera的代码主要在以下的目录中:Camera的JAVA程序的路径:packages/apps/Camera/src/com/android/camera/在其中 Camera.java是主要实现的文
2、件frameworks/base/core/java/android/hardware/Camera.java这个类是和JNI 中定义的类是一个,有些方法通过JNI 的方式调用本地代码得到,有些方法自己实现。Camera的 JAVA本地调用部分(JNI):frameworks/base/core/jni/android_hardware_Camera.cpp这部分内容编译成为目标是libandroid_runtime.so。主要的头文件在以下的目录中:frameworks/base/include/ui/Camera底层库在以下的目录中:frameworks/base/libs/ui/这部分的
3、内容被编译成库libui.so。Camera服务部分:frameworks/base/camera/libcameraservice/这部分内容被编译成库libcameraservice.so。为了实现一个具体功能的Camera,在最底层还需要一个硬件相关的Camer 库(例如通过调用video for linux驱动程序和Jpeg 编码程序实现)。这个库将被Camera 的服务库libcameraservice.so调用。第二部分 Camera 的接口与架构2.1 Camera的整体框架图Camera的各个库之间的结构可以用下图的表示:名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页
4、,共 11 页 -在 Camera 系统的各个库中,libui.so位于核心的位置,它对上层的提供的接口主要是Camera 类,类 libandroid_runtime.so通过调用Camera 类提供对JAVA的接口,并且实现了android.hardware.camera 类。libcameraservice.so是 Camera 的服务器程序,它通过继承libui.so的类实现服务器的功能,并且与 libui.so中的另外一部分内容则通过进程间通讯(即Binder机制)的方式进行通讯。libandroid_runtime.so和 libui.so两个库是公用的,其中除了Camera 还有
5、其他方面的功能。Camera 部分的头文件在frameworks/base/include/ui/目录中,这个目录是和libmedia.so库源文件的目录frameworks/base/libs/ui/相对应的。Camera 主要的头文件有以下几个:ICameraClient.h Camera.h ICamera.h ICameraService.h CameraHardwareInterface.h在这些头文件Camera.h 提供了对上层的接口,而其他的几个头文件都是提供一些接口类(即包含了纯虚函数的类),这些接口类必须被实现类继承才能够使用。整个 Camera 在运行的时候,可以大致上分
6、成Client和 Server 两个部分,它们分别在两个进程中运行,它们之间使用Binder机制实现进程间通讯。这样在客户端调用接口,功能则在服务器中实现,但是在客户端中调用就好像直接调用服务器中的功能,进程间通讯的部分对上层程序不可见。从框架结构上来看,ICameraService.h、ICameraClient.h和 ICamera.h三个类定义了MeidaPlayer的接口和架构,ICameraService.cpp和 Camera.cpp 两个文件用于Camera 架构的实现,Camera的具体功能在下层调用硬件相关的接口来实现。从 Camera 的整体结构上,类Camera 是整个系
7、统核心,ICamera 类提供了Camera 主要功能的接口,在客户端方面调用,CameraService是 Camera服务,它通过调用实际的Camera 硬件接口来实现功能。事实上,图中红色虚线框的部分都是Camera程序的框架部分,它主要利用了Android的系统的Binder机制来完成通讯。蓝色的部分通过调用Camera 硬件相关的接口完成具体的 Camera 服务功能,其它的部分是为上层的JAVA程序提供JNI 接口。在整体结构上,左边可以视为一个客户端,右边是一个可以视为服务器,二者通过Android的 Bimder 来实现进程间的通讯。2.2 头文件 ICameraClient.
8、h ICameraClient.h用于描述一个Camera客户端的接口,定义如下所示:class ICameraClient:public IInterface public:DECLARE_META_INTERFACE(CameraClient);virtual void shutterCallback()=0;virtual void rawCallback(const sp&picture)=0;virtual void jpegCallback(const sp&picture)=0;名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 11 页 -virtual void f
9、rameCallback(const sp&frame)=0;virtual void errorCallback(status_t error)=0;virtual void autoFocusCallback(bool focused)=0;class BnCameraClient:public BnInterface public:virtual status_t onTransact(uint32_t code,const Parcel&data,Parcel*reply,uint32_t flags=0);在定义中,ICameraClient 类继承 IInterface,并定义了一
10、个Camera客户端的接口,BnCameraClient 继承了 BnInterface,这是为基于Android的基础类Binder机制实现在进程通讯而构建的。根据BnInterface类模版的定义BnInterface类相当于双继承了BnInterface和 ICameraClient。IcameraClient这个类的主要接口是几个回调函数shutterCallback、rawCallback和jpegCallback等,它们在相应动作发生的时候被调用。作为 Camera 的“客户端”,需要自己实现几个回调函数,让服务器程序去“间接地”调用它们。2.3 头文件 Camera.h Came
11、ra.h是 Camera 对外的接口头文件,它被实现Camera JNI的文件android_hardware_Camera.cpp所调用。Camera.h 最主要是定义了一个Camera 类:class Camera:public BnCameraClient,public IBinder:DeathRecipient public:static sp connect();Camera();void disconnect();status_t getStatus()return mStatus;status_t setPreviewDisplay(const sp&surface);stat
12、us_t startPreview();void stopPreview();status_t autoFocus();status_t takePicture();status_t setParameters(const String8¶ms);String8 getParameters()const;void setShutterCallback(shutter_callback cb,void*cookie);void setRawCallback(frame_callback cb,void*cookie);void setJpegCallback(frame_callback
13、 cb,void*cookie);名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 11 页 -void setFrameCallback(frame_callback cb,void*cookie);void setErrorCallback(error_callback cb,void*cookie);void setAutoFocusCallback(autofocus_callback cb,void*cookie);/ICameraClient interface virtual void shutterCallback();virtual void rawCallbac
14、k(const sp&picture);virtual void jpegCallback(const sp&picture);virtual void frameCallback(const sp&frame);virtual void errorCallback(status_t error);virtual void autoFocusCallback(bool focused);/,从接口中可以看出Camera 类刚好实现了一个Camera的基本操作,例如播放(startPreview)、停止(stopPreview)、暂停(takePicture)等。在 Camera类中 conne
15、ct()是一个静态函数,它用于得到一个Camera的实例。在这个类中,具有设置回调函数的几个函数:setShutterCallback、setRawCallback和 setJpegCallback等,这几个函数是为了提供给上层使用,上层利用这几个设置回调函数,这些回调函数在相应的回调函数中调用,例如使用setShutterCallback设置的回调函数指针被 shutterCallback所调用。在定义中,ICameraClient 类双继承了IInterface和 IBinder:DeathRecipient,并定义了一个Camera 客户端的接口,BnCameraClient 继承了 B
16、nInterface,这是为基于Android的基础类Binder机制实现在进程通讯而构建的。事实上,根据BnInterface类模版的定义BnInterface类相当于双继承了 BnInterface和ICameraClient。这是 Android一种常用的定义方式。继承了 DeathNotifier类之后,这样当这个类作为IBinder使用的时候,当这个 Binder即将 Died 的时候被调用其中的binderDied函数。继承这个类基本上实现了一个回调函数的功能。2.4 头文件 ICamera.h ICamera.h描述的内容是一个实现Camera功能的接口,其定义如下所示:clas
17、s ICamera:public IInterface public:DECLARE_META_INTERFACE(Camera);virtual void disconnect()=0;virtual status_t setPreviewDisplay(const sp&surface)=0;virtual void setHasFrameCallback(bool installed)=0;virtual status_t startPreview()=0;virtual void stopPreview()=0;virtual status_t autoFocus()=0;virtua
18、l status_t takePicture()=0;名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 11 页 -virtual status_t setParameters(const String8¶ms)=0;virtual String8 getParameters()const=0;class BnCamera:public BnInterface public:virtual status_t onTransact(uint32_t code,const Parcel&data,Parcel*reply,uint32_t flags=0);ICamera.h描
19、述的内容是一个实现Camera功能的接口,其定义如下所示:在 camera 类中,主要定义Camera 的功能接口,这个类必须被继承才能够使用。值得注意的是,这些接口和Camera 类的接口有些类似,但是它们并没有直接的关系。事实上,在Camera 类的各种实现中,一般都会通过调用ICamera 类的实现类来完成。2.5 头文件 ICameraService.h ICameraService.h用于描述一个Camera 的服务,定义方式如下所示:class ICameraService:public IInterface public:DECLARE_META_INTERFACE(Camera
20、Service);virtual sp connect(const sp&cameraClient)=0;class BnCameraService:public BnInterface public:virtual status_t onTransact(uint32_t code,const Parcel&data,Parcel*reply,uint32_t flags=0);由于具有纯虚函数,ICameraService 以及 BnCameraService必须被继承实现才能够使用,在ICameraService 只定义了一个connect()接口,它的返回值的类型是sp,这个ICame
21、ra 是提供实现功能的接口。注意,ICameraService只有连接函数connect(),没有断开函数,断开的功能由ICamera 接口来提供。2.6 头文件 CameraHardwareInterface.h CameraHardwareInterface.h定义的是一个Camera 底层的接口,这个类的实现者是最终实现Camera 的。名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 11 页 -CameraHardwareInterface 定以 Camera 硬件的接口,如下所示:class CameraHardwareInterface:public virtual
22、RefBase public:virtual CameraHardwareInterface()virtual sp 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_ca
23、llback,void*user)=0;virtual status_t cancelPicture(bool cancel_shutter,bool cancel_raw,bool cancel_jpeg)=0;virtual status_t setParameters(const CameraParameters¶ms)=0;virtual CameraParameters getParameters()const=0;virtual void release()=0;virtual status_t dump(int fd,const Vector&args)const=0;使
24、用 C 语言的方式导出符号:extern C sp openCameraHardware();在程序的其他地方,使用openCameraHardware()就可以得到一个CameraHardwareInterface,然后调用 CameraHardwareInterface的接口完成Camera的功能。第三部分 Camera 的主要实现分析3.1 JAVA 程序部分在 packages/apps/Camera/src/com/android/camera/目录的 Camera.java文件中,包含了对 Camera 的调用在 Camera.java中包含对包的引用:import android
25、.hardware.Camera.PictureCallback;import android.hardware.Camera.Size;在这里定义的Camera 类继承了活动Activity类,在它的内部,包含了一个android.hardware.Camera public class Camera extends Activity implements View.OnClickListener,SurfaceHolder.Callback android.hardware.Camera mCameraDevice;名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 11 页 -
26、对 Camera 功能的一些调用如下所示:mCameraDevice.takePicture(mShutterCallback,mRawPictureCallback,mJpegPictureCallback);mCameraDevice.startPreview();mCameraDevice.stopPreview();startPreview、stopPreview 和 takePicture等接口就是通过JAVA本地调用(JNI)来实现的。frameworks/base/core/java/android/hardware/目录中的Camera.java文件提供了一个JAVA类:Cam
27、era。public class Camera 在这个类当中,大部分代码使用JNI 调用下层得到,例如:public void setParameters(Parameters params)Log.e(TAG,setParameters();/params.dump();native_setParameters(params.flatten();再者,例如以下代码:public final void setPreviewDisplay(SurfaceHolder holder)setPreviewDisplay(holder.getSurface();private native final
28、 void setPreviewDisplay(Surface surface);两个 setPreviewDisplay参数不同,后一个是本地方法,参数为Surface类型,前一个通过调用后一个实现,但自己的参数以SurfaceHolder为类型。3.2 Camera的 JAVA本地调用部分 Camera的 JAVA本地调用(JNI)部分在frameworks/base/core/jni/目录的android_hardware_Camera.cpp中的文件中实现。android_hardware_Camera.cpp之中定义了一个JNINativeMethod(JAVA本地调用方法)类型的数
29、组 gMethods,如下所示:static JNINativeMethod camMethods=native_setup,(Ljava/lang/Object;)V,(void*)android_hardware_Camera_native_setup,名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 11 页 -native_release,()V,(void*)android_hardware_Camera_release,setPreviewDisplay,(Landroid/view/Surface;)V,(void*)android_hardware_Camera_s
30、etPreviewDisplay,startPreview,()V,(void*)android_hardware_Camera_startPreview,stopPreview,()V,(void*)android_hardware_Camera_stopPreview,setHasPreviewCallback,(Z)V,(void*)android_hardware_Camera_setHasPreviewCallback,native_autoFocus,()V,(void*)android_hardware_Camera_autoFocus,native_takePicture,()
31、V,(void*)android_hardware_Camera_takePicture,native_setParameters,(Ljava/lang/String;)V,(void*)android_hardware_Camera_setParameters,native_getParameters,()Ljava/lang/String;,(void*)android_hardware_Camera_getParameters ;JNINativeMethod的第一个成员是一个字符串,表示了JAVA本地调用方法的名称,这个名称是在 JAVA程序中调用的名称;第二个成员也是一个字符串,表
32、示JAVA本地调用方法的参数和返回值;第三个成员是JAVA本地调用方法对应的C 语言函数。register_android_hardware_Camera 函数将 gMethods 注册为的类 android/media/Camera,其主要的实现如下所示。int register_android_hardware_Camera(JNIEnv*env)/Register native functions return AndroidRuntime:registerNativeMethods(env,android/hardware/Camera,camMethods,NELEM(camMeth
33、ods);android/hardware/Camera对应 JAVA 的类 android.hardware.Camera。3.3 Camera本地库 libui.so frameworks/base/libs/ui/中的 Camera.cpp 文件用于实现Camera.h 提供的接口,其中一个重要的片段如下所示:const sp&Camera:getCameraService()Mutex:Autolock _l(mLock);if(mCameraService.get()=0)sp sm=defaultServiceManager();sp binder;do binder=sm-get
34、Service(String16(media.camera);if(binder!=0)break;LOGW(CameraService not published,waiting.);usleep(500000);/0.5 s 名师资料总结-精品资料欢迎下载-名师精心整理-第 8 页,共 11 页 -while(true);if(mDeathNotifier=NULL)mDeathNotifier=new DeathNotifier();binder-linkToDeath(mDeathNotifier);mCameraService=interface_cast(binder);LOGE_
35、IF(mCameraService=0,no CameraService!?);return mCameraService;其中最重要的一点是binder=sm-getService(String16(media.camera);这个调用用来得到一个名称为media.camera 的服务,这个调用返回值的类型为IBinder,根据实现将其转换成类型ICameraService使用。一个函数 connect的实现如下所示:sp Camera:connect()sp c=new Camera();const sp&cs=getCameraService();if(cs!=0)c-mCamera=c
36、s-connect(c);if(c-mCamera!=0)c-mCamera-asBinder()-linkToDeath(c);c-mStatus=NO_ERROR;return c;connect通过调用getCameraService得到一个 ICameraService,再通过 ICameraService的 cs-connect(c)得到一个 ICamera类型的指针。调用 connect将得到一个 Camera 的指针,正常情况下Camera 的成员 mCamera 已经初始化完成。一个具体的函数startPreview 如下所示:status_t Camera:startPrev
37、iew()return mCamera-startPreview();这些操作可以直接对 mCamera 来进行,它是ICamera 类型的指针。其他一些函数的实现也与setDataSource类似。libmedia.so中的其他一些文件与头文件的名称相同,它们是:frameworks/base/libs/ui/ICameraClient.cpp frameworks/base/libs/ui/ICamera.cpp frameworks/base/libs/ui/ICameraService.cpp 在此处,BnCameraClient和 BnCameraService类虽然实现了onTra
38、nsact()函数,但是由于还有纯虚函数没有实现,因此这个类都是不能实例化的。ICameraClient.cpp中的 BnCameraClient在别的地方也没有实现;而ICameraService.cpp名师资料总结-精品资料欢迎下载-名师精心整理-第 9 页,共 11 页 -中的 BnCameraService类在别的地方被继承并实现,继承者实现了Camera 服务的具体功能。3.4 Camera服务 libcameraservice.so frameworks/base/camera/libcameraservice/用于实现一个Camera 的服务,这个服务是继承 ICameraSer
39、vice的具体实现。在这里的Android.mk文件中,使用宏USE_CAMERA_STUB决定是否使用真的Camera,如果宏为真,则使用 CameraHardwareStub.cpp和 FakeCamera.cpp 构造一个假的Camera,如果为假则使用 CameraService.cpp构造一个实际上的Camera服务。CameraService.cpp是继承 BnCameraService 的实现,在这个类的内部又定义了类Client,CameraService:Client继承了 BnCamera。在运作的过程中 CameraService:connect()函数用于得到一个Cam
40、eraService:Client,在使用过程中,主要是通过调用这个类的接口来实现完成Camera 的功能,由于CameraService:Client本身继承了BnCamera 类,而 BnCamera类是继承了 ICamera,因此这个类是可以被当成ICamera 来使用的。CameraService和 CameraService:Client两个类的结果如下所示:class CameraService:public BnCameraService class Client:public BnCamera;wp mClient;在 CameraService中的一个静态函数instanti
41、ate()用于初始化一个Camera 服务,寒暑如下所示:void CameraService:instantiate()defaultServiceManager()-addService(String16(media.camera),new CameraService();事实上,CameraService:instantiate()这个函数注册了一个名称为media.camera的服务,这个服务和Camera.cpp 中调用的名称相对应。Camera整个运作机制是:在 Camera.cpp 中可以调用ICameraService的接口,这时实际上调用的是 BpCameraService,
42、而 BpCameraService又通过 Binder机制和 BnCameraService实现两个进程的通讯。而 BpCameraService的实现就是这里的CameraService。因此,Camera.cpp 虽然是在另外一个进程中运行,但是调用 ICameraService的接口就像直接调用一样,从 connect()中可以得到一个ICamera 类型的指针,真个指针的实现实际上是 CameraService:Client。而这些 Camera 功能的具体实现,就是CameraService:Client所实现的了,其构造函数如下所示:CameraService:Client:Cli
43、ent(const sp&cameraService,const sp&cameraClient):mCameraService(cameraService),mCameraClient(cameraClient),mHardware(0)mHardware=openCameraHardware();mHasFrameCallback=false;构造函数中,调用openCameraHardware()得到一个CameraHardwareInterface类型的指针,名师资料总结-精品资料欢迎下载-名师精心整理-第 10 页,共 11 页 -并作为其成员mHardware。以后对实际的Came
44、ra 的操作都通过对这个指针进行。这是一个简单的直接调用关系。事实上,真正的Camera功能己通过实现CameraHardwareInterface类来完成。在这个库当中 CameraHardwareStub.h和 CameraHardwareStub.cpp两个文件定义了一个桩模块的接口,在没有 Camera 硬件的情况下使用,例如在仿真器的情况下使用的文件就是CameraHardwareStub.cpp和它依赖的文件FakeCamera.cpp。CameraHardwareStub类的结构如下所示:class CameraHardwareStub:public CameraHardware
45、Interface class PreviewThread:public Thread ;在类 CameraHardwareStub当中,包含一个线程类PreviewThread,这个线程用于处理PreView,即负责刷新取景器的内容。实际的 Camera硬件接口通常可以通过对v4l2 捕获驱动的调用来实现,同时还需要一个JPEG编码程序将从驱动中取出的数据编码成JPEG文件。类别:Android|添加到搜藏|浏览(259)|评论(0)上一篇:/ld.so.conf;ldconfig;PKG_C.下一篇:Ubuntu 代理上网设置(firefox,.名师资料总结-精品资料欢迎下载-名师精心整理-第 11 页,共 11 页 -