http://android.yesky.com/thread-14399-1-1.html

一.Camera构架分析

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

Camera ArchitectureCamera模块主要包含了libandroid_runtime.so、libui.so和libcameraservice.so等几个库文件,它们之间的调用关系如下所示:

在Camera模块的各个库中,libui.so位于核心的位置,它对上层的提供的接口主要是Camera类。

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

libandroid_runtime.so和libui.so两个库是公用的,其中除了Camera还有其他方面的功能。整个Camera在运行的 时候,可以大致上分成Client和Server两个部分,它们分别在两个进程中运行,它们之间使用Binder机制实现进程间通讯。这样在client 调用接口,功能则在server中实现,但是在client中调用就好像直接调用server中的功能,进程间通讯的部分对上层程序不可见。

    从框架结构上来看,源码中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的 Bimder来实现进程间的通讯。

二.Camera工作流程概述

1.Camera Service的启动

①.App_main process: 进程通过AndroidRuntime调用register_jni_procs向JNI注册模块的native函数供JVM调用。

AndroidRuntime::registerNativeMethods(env, "android/hardware/Camera",

camMethods, NELEM(camMethods));

        其中camMethods定义如下: 

            
  1. static JNINativeMethod camMethods[] = { 
  2.  
  3.   { "native_setup"
  4.  
  5.     "(Ljava/lang/Object;)V"
  6.  
  7.     (void*)android_hardware_Camera_native_setup }, 
  8.  
  9.   { "native_release"
  10.  
  11.     "()V"
  12.  
  13.     (void*)android_hardware_Camera_release }, 
  14.  
  15.   { "setPreviewDisplay"
  16.  
  17.     "(Landroid/view/Surface;)V"
  18.  
  19.     (void *)android_hardware_Camera_setPreviewDisplay }, 
  20.  
  21.   { "startPreview"
  22.  
  23.     "()V"
  24.  
  25.     (void *)android_hardware_Camera_startPreview }, 
  26.  
  27.   { "stopPreview"
  28.  
  29.     "()V"
  30.  
  31.     (void *)android_hardware_Camera_stopPreview }, 
  32.  
  33.   { "previewEnabled"
  34.  
  35.     "()Z"
  36.  
  37.     (void *)android_hardware_Camera_previewEnabled }, 
  38.  
  39.   { "setHasPreviewCallback"
  40.  
  41.     "(ZZ)V"
  42.  
  43.     (void *)android_hardware_Camera_setHasPreviewCallback }, 
  44.  
  45.   { "native_autoFocus"
  46.  
  47.     "()V"
  48.  
  49.     (void *)android_hardware_Camera_autoFocus }, 
  50.  
  51.   { "native_takePicture"
  52.  
  53.     "()V"
  54.  
  55.     (void *)android_hardware_Camera_takePicture }, 
  56.  
  57.   { "native_setParameters"
  58.  
  59.     "(Ljava/lang/String;)V"
  60.  
  61.     (void *)android_hardware_Camera_setParameters }, 
  62.  
  63.   { "native_getParameters"
  64.  
  65.     "()Ljava/lang/String;"
  66.  
  67.     (void *)android_hardware_Camera_getParameters }, 
  68.  
  69.   { "reconnect"
  70.  
  71.     "()V"
  72.  
  73.     (void*)android_hardware_Camera_reconnect }, 
  74.  
  75.   { "lock"
  76.  
  77.     "()I"
  78.  
  79.     (void*)android_hardware_Camera_lock }, 
  80.  
  81.   { "unlock"
  82.  
  83.     "()I"
  84.  
  85.     (void*)android_hardware_Camera_unlock }, 
  86.  
  87. }; 

JNINativeMethod的第一个成员是一个字符串,表示了JAVA本地调用方法的名称,这个名称是在JAVA程序中调用的名称;第二个成员也是一个字符串,表示JAVA本地调用方法的参数和返回值;第三个成员是JAVA本地调用方法对应的C语言函数。

②.Mediaserver proces:进程注册了以下几个server: AudioFlinger、 MediaPlayerServer、CameraService. 

            
  1. int main(int argc, char** argv) 
  2.  
  3.  
  4.     sp proc(ProcessState::self()); 
  5.  
  6.     sp sm = defaultServiceManager(); 
  7.  
  8.     LOGI("ServiceManager: %p", sm.get()); 
  9.  
  10.     AudioFlinger::instantiate(); 
  11.  
  12.     MediaPlayerService::instantiate(); 
  13.  
  14.     CameraService::instantiate(); 
  15.  
  16.     ProcessState::self()->startThreadPool(); 
  17.  
  18.     IPCThreadState::self()->joinThreadPool(); 
  19.  

 当向ServiceManager注册了CameraService服务后就可以响应client的请求了

2.client端向service发送请求

①.在java应用层调用onCreate()函数得到一个上层的Camera对象 

            
  1. public void onCreate(Bundle icicle) { 
  2.  
  3. super.onCreate(icicle); 
  4.  
  5. Thread openCameraThread = new Thread( 
  6.  
  7. new Runnable() { 
  8.  
  9. public void run() { 
  10.  
  11.                 mCameraDevice = android.hardware.Camera.open(); 
  12.  
  13.  
  14.  
  15. ); 
  16.  
  17. ……………………… 
  18.  
  19. }     

②.通过Camera对象的调用成员函数,而这些成员函数会调用已向JNI注册过的native函数来调用ICamera接口的成员函数向Binder Kernel Driver发送服务请求。

③. Binder Kernel Driver接收到client的请求后,通过唤醒service的进程来处理client的请求,处理完后通过回调函数传回数据并通知上层处理已完成。

三.Camera库文件分析

    上面已提到Camera模块主要包含libandroid_runtime.so、libui.so、libcameraservice.so和一个与 Camera硬件相关的底层库。其中libandroid_runtime.so、libui.so是与Android系统构架相关的不需要对其进行修 改, libcameraservice.so和Camera硬件相关的底层库则是和硬件设备相关联的,而Canera硬件相关的底层库实际上就是设备的 Linux驱动,所以Camera设备的系统集成主要通过移植Camera Linux驱动和修改libcameraservice.so库来完成。

    libcameraservice.so库通过以下规则来构建: 

            
  1. LOCAL_PATH:= $(call my-dir) 
  2.  
  3.  
  4. Set USE_CAMERA_STUB for non-emulator and non-simulator builds, if you want 
  5.  
  6. # the camera service to use the fake camera.  For emulator or simulator builds, 
  7.  
  8. # we always use the fake camera. 
  9.  
  10. ifeq ($(USE_CAMERA_STUB),) 
  11.  
  12. USE_CAMERA_STUB:=false 
  13.  
  14. ifneq ($(filter sooner generic sim,$(TARGET_DEVICE)),) 
  15.  
  16. USE_CAMERA_STUB:=true 
  17.  
  18. endif #libcamerastub 
  19.  
  20. endif ifeq ($(USE_CAMERA_STUB),true
  21.  
  22.  
  23. # libcamerastub 
  24.  
  25.  
  26. include $(CLEAR_VARS) 
  27.  
  28. LOCAL_SRC_FILES:=               \ 
  29.  
  30.     CameraHardwareStub.cpp      \ 
  31.  
  32.     FakeCamera.cpp 
  33.  
  34. LOCAL_MODULE:= libcamerastub 
  35.  
  36. LOCAL_SHARED_LIBRARIES:= libui 
  37.  
  38. include $(BUILD_STATIC_LIBRARY) 
  39.  
  40. endif # USE_CAMERA_STUB 
  41.  
  42.  
  43. # libcameraservice 
  44.  
  45.  
  46. include $(CLEAR_VARS) 
  47.  
  48. LOCAL_SRC_FILES:=               \ 
  49.  
  50.     CameraService.cpp 
  51.  
  52. LOCAL_SHARED_LIBRARIES:= \ 
  53.  
  54.     libui \ 
  55.  
  56.     libutils \ 
  57.  
  58.     libcutils \ 
  59.  
  60.     libmedia 
  61.  
  62. LOCAL_MODULE:= libcameraservice 
  63.  
  64. LOCAL_CFLAGS+=-DLOG_TAG=\"CameraService\" 
  65.  
  66. ifeq ($(USE_CAMERA_STUB), true
  67.  
  68. LOCAL_STATIC_LIBRARIES += libcamerastub 
  69.  
  70. LOCAL_CFLAGS += -include CameraHardwareStub.h 
  71.  
  72. else 
  73.  
  74. LOCAL_SHARED_LIBRARIES += libcamera 
  75.  
  76. endif 
  77.  
  78. include $(BUILD_SHARED_LIBRARY) 

     在上面的构建规则中可以看到使用了宏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返回的指针操作真正的硬件设备则需完成以下步骤:

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

            
  1. class CameraHardwareInterface : public virtual RefBase { 
  2.  
  3. public
  4.  
  5.     virtual ~CameraHardwareInterface() { } 
  6.  
  7.     virtual sp         getPreviewHeap() const
  8.  
  9.     virtual sp         getRawHeap() const
  10.  
  11.     virtual status_t    startPreview(preview_callback cb, void* user); 
  12.  
  13.     virtual bool useOverlay() {return false;} 
  14.  
  15.     virtual status_t setOverlay(const sp &overlay) {return BAD_VALUE;} 
  16.  
  17.     virtual void        stopPreview(); 
  18.  
  19.     virtual bool        previewEnabled(); 
  20.  
  21.     virtual status_t    startRecording(recording_callback cb, void* user); 
  22.  
  23.     virtual void        stopRecording(); 
  24.  
  25.     virtual bool        recordingEnabled(); 
  26.  
  27.     virtual void        releaseRecordingFrame(const sp& mem); 
  28.  
  29.     virtual status_t    autoFocus(autofocus_callback, 
  30.  
  31.                                   void* user); 
  32.  
  33.   
  34.  
  35.     virtual status_t    takePicture(shutter_callback, 
  36.  
  37.                                     raw_callback, 
  38.  
  39.                                     jpeg_callback, 
  40.  
  41.                                     void* user); 
  42.  
  43.     virtual status_t    cancelPicture(bool cancel_shutter, 
  44.  
  45.                                       bool cancel_raw, 
  46.  
  47.                                       bool cancel_jpeg); 
  48.  
  49.     virtual status_t    setParameters(const CameraParameters& params); 
  50.  
  51.     virtual CameraParameters  getParameters() const
  52.  
  53.     virtual void release(); 
  54.  
  55.     virtual status_t dump(int fd, const Vector& args) const ; 
  56.  
  57. }; 

2.    编写一个源文件去定义CameraHardwareInterface类中声明的所有虚函数,并实现openCameraHardware()函数让该函数返回一个CameraHardwareInterface类对象的指针;例如: 

            
  1. extern "C" sp openCameraHardware() 
  2.  
  3.  
  4.     CameraHardwareInterface realCamera; 
  5.  
  6.     return &realCamera; 
  7.  

3.    仿照其他.mk文件编写Android.mk文件用于生成一个包含步骤2编写的源文件和其他相关文件的libcamera.so文件;例如 

            
  1. LOCAL_PATH := $(call my-dir) 
  2.  
  3. include $(CLEAR_VARS) 
  4.  
  5. LOCAL_MODULE := libcamera 
  6.  
  7. LOCAL_SHARED_LIBRARIES := \ 
  8.  
  9.     libutils \ 
  10.  
  11.     librpc \ 
  12.  
  13.     liblog 
  14.  
  15. LOCAL_SRC_FILES += MyCameraHardware.cpp 
  16.  
  17. LOCAL_CFLAGS += 
  18.  
  19. LOCAL_C_INCLUDES += 
  20.  
  21. LOCAL_STATIC_LIBRARIES += \ 
  22.  
  23.     libcamera-common \ 
  24.  
  25.     libclock-rpc \ 
  26.  
  27.     libcommondefs-rpc 
  28.  
  29. include $(BUILD_SHARED_LIBRARY) 

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

      上面左图中libcamera.so库直接操作Camera设备,这样相对于右图来说就相当于libcamera.so库包含了Camera驱动,而右图 则将驱动从库中分离出来并形成一层HAL这样做的好处是:移植不同型号或不同厂商的同类设备时只需修改HAL中很少代码即可。

更多相关文章

  1. Android(安卓)学习
  2. 【Android自助餐】Handler消息机制完全解析(三)Handler解析
  3. Android(安卓)的Camera架构介绍
  4. Android自定义权限
  5. Android横竖屏切换问题
  6. Android之自定义View
  7. Android--DatePickerDialog日期控件
  8. Android重要控件概览(中)
  9. Android启动过程

随机推荐

  1. android 多线程下载文件案例
  2. 近日
  3. 安卓通知栏自定义布局提示(NotificationC
  4. Scrollable可拖动的TabActivity
  5. Toast util
  6. android 登录界面 记住多组账号与密码
  7. 百度地图SDK 手机报错java.lang.Unsatisf
  8. 状态栏获取信息
  9. Android(安卓)ExpandableListActivity
  10. Android获取当前时间与星期几