Android 的Camera架构介绍

来源:互联网 发布:淘宝115会员暗号 编辑:程序博客网 时间:2024/05/21 12:08

第一部分 Camera概述

Android的Camera包含取景器(viewfinder)和拍摄照片的功能。目前Android发布版的Camera程序虽然功能比较简单,但是其程序的架构分成客户端和服务器两个部分,它们建立在Android的进程间通讯Binder的结构上。

以开源的Android为例,Camera的代码主要在以下的目录中:

Camera的JAVA程序的路径:
packages/apps/Camera/src/com/android/camera/

在其中Camera.java是主要实现的文件:
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/camera/  (ICS)

Camera底层库在以下的目录中:
frameworks/base/libs/camera/ (ICS)
这部分的内容被编译成库libcamera_client.so

Camera服务部分:
frameworks/base/camera/libcameraservice/
这部分内容被编译成库libcameraservice.so

为了实现一个具体功能的Camera,在最底层还需要一个硬件相关的Camer库(例如通过调用video for linux驱动程序和Jpeg编码程序实现)。这个库将被Camera的服务库libcameraservice.so调用。

第二部分 Camera的接口与架构

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

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

libcameraservice.so是Camera的服务器程序,它通过继承libui.so的类实现服务器的功能,并且与libui.so中的另外一部分内容则通过进程间通讯(即Binder机制)的方式进行通讯。
libandroid_runtime.so和libui.so两个库是公用的,其中除了Camera还有其他方面的功能。

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

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

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

ICameraClient.h

Camera.h

ICamera.h

ICameraService.h

CameraHardwareInterface.h

在这些头文件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来实现进程间的通讯。

2.2 头文件Camera.h

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

[cpp] view plaincopyprint?
  1. class Camera : public BnCameraClient, public IBinder:: DeathRecipient  
  2. {   
  3. public:  
  4.     static  sp<Camera>  create(const sp<icamera>& camera);  
  5.     static  int32_t     getNumberOfCameras();  
  6.     static  status_t    getCameraInfo(int cameraId,  
  7.                                       struct CameraInfo* cameraInfo);  
  8.   
  9.     static  sp<Camera>  connect();   
  10.                         ~Camera();   
  11.             void        disconnect();    
  12.             status_t    getStatus() { return mStatus; }   
  13.             status_t    setPreviewDisplay(const sp<Surface>& surface);   
  14.             status_t    startPreview();   
  15.             void        stopPreview();   
  16.             status_t    autoFocus();   
  17.             status_t    takePicture();   
  18.             status_t    setParameters(const String8& params);   
  19.             String8     getParameters() const;   
  20.   
  21.             void        setShutterCallback(shutter_callback cb, void *cookie);   
  22.             void        setRawCallback(frame_callback cb, void *cookie);   
  23.             void        setJpegCallback(frame_callback cb, void *cookie);   
  24.             void        setFrameCallback(frame_callback cb, void *cookie);   
  25.             void        setErrorCallback(error_callback cb, void *cookie);   
  26.       void        setAutoFocusCallback(autofocus_callback cb, void *cookie);   
  27.   
  28.     // ICameraClient interface    
  29.     virtual void        notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);  
  30.     virtual void        dataCallback(int32_t msgType, const sp<imemory>& dataPtr,  
  31.                                      camera_frame_metadata_t *metadata);  
  32.     virtual void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<imemory>& dataPtr);  
  33.   
  34.     sp<ICamera>         remote();  
  35.   
  36. private:  
  37.             static const sp<ICameraService>& getCameraService();  
  38.             sp<ICamera>         mCamera;  
  39.             sp<CameraListener>  mListener;  
  40.             sp<ICameraRecordingProxyListener>  mRecordingProxyListener;  
  41.   
  42.             friend class DeathNotifier;  
  43.   
  44.             static  sp<ICameraService>  mCameraService;  
  45. //……   
  46. }</imemory></imemory></icamera>  
<textarea style="BACKGROUND-COLOR: rgb(240,240,240); MARGIN: 4px 0px; DISPLAY: none" class="cpp" readonly="readonly" name="code">class Camera : public BnCameraClient, public IBinder:: DeathRecipient{ public: static sp&lt;Camera&gt; create(const sp&lt;icamera&gt;&amp; camera); static int32_t getNumberOfCameras(); static status_t getCameraInfo(int cameraId, struct CameraInfo* cameraInfo); static sp&lt;Camera&gt; connect(); ~Camera(); void disconnect(); status_t getStatus() { return mStatus; } status_t setPreviewDisplay(const sp&lt;Surface&gt;&amp; surface); status_t startPreview(); void stopPreview(); status_t autoFocus(); status_t takePicture(); status_t setParameters(const String8&amp; 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_callback cb, void *cookie); // ICameraClient interface virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2); virtual void dataCallback(int32_t msgType, const sp&lt;imemory&gt;&amp; dataPtr, camera_frame_metadata_t *metadata); virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp&lt;imemory&gt;&amp; dataPtr); sp&lt;ICamera&gt; remote();private: static const sp&lt;ICameraService&gt;&amp; getCameraService(); sp&lt;ICamera&gt; mCamera; sp&lt;CameraListener&gt; mListener; sp&lt;ICameraRecordingProxyListener&gt; mRecordingProxyListener; friend class DeathNotifier; static sp&lt;ICameraService&gt; mCameraService;//……}&lt;/imemory&gt;&lt;/imemory&gt;&lt;/icamera&gt;</textarea>

从接口中可以看出Camera类刚好实现了一个Camera的基本操作,例如播放(startPreview)、停止(stopPreview)、暂停(takePicture)等,其实这些函数都是直接调用了BpCamera中相应的函数

在Camera类中connect()是一个静态函数,它用于得到一个Camera的实例,该函数在JNI中被调用,被赋给JNI的mCamera,在JNI中,主要调用了mCamera->setPreviewCallbackFlags()函数。这里的Camera类继承自BnCameraClient,在CameraService类中,包含有ICameraClient类,主要调用了BpCameraClient中的函数。

Camera类还包含Create()函数,该函数需要通过已存在的远程BpCamera,才能创建得到一个sp<Camera>。可能是录像用的,详见CameraSource实现。

在这个类中,具有设置回调函数的几个函数: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函数。继承这个类基本上实现了一个回调函数的功能。

在Camera类中,定义了sp<ICameraService> mCameraService对象,该对象通过getCameraService()得到,具体实现如下:

[cpp] view plaincopyprint?
  1. // establish binder interface to camera service  
  2. const sp<ICameraService>& Camera::getCameraService()  
  3. {  
  4.     Mutex::Autolock _l(mLock);  
  5.     if (mCameraService.get() == 0) {  
  6.         sp<IServiceManager> sm = defaultServiceManager();  
  7.         sp<IBinder> binder;  
  8.         do {  
  9.             binder = sm->getService(String16("media.camera"));  
  10.             if (binder != 0)  
  11.                 break;  
  12.             LOGW("CameraService not published, waiting...");  
  13.             usleep(500000); // 0.5 s  
  14.         } while(true);  
  15.         if (mDeathNotifier == NULL) {  
  16.             mDeathNotifier = new DeathNotifier();  
  17.         }  
  18.         binder->linkToDeath(mDeathNotifier);  
  19.         mCameraService = interface_cast<ICameraService>(binder);  
  20.     }  
  21.     LOGE_IF(mCameraService==0, "no CameraService!?");  
  22.     return mCameraService;  
  23. }  

getCameraService其实得到的是BpCameraService对象,getNumberOfCamera, getCameraInfo, connect的函数实现中调用了BpCameraService中相应的函数。connect()的实现如下:

[cpp] view plaincopyprint?
  1. sp<Camera> Camera::connect(int cameraId)  
  2. {  
  3.     LOGV("connect");  
  4.     sp<Camera> c = new Camera();  
  5.     const sp<ICameraService>& cs = getCameraService();  
  6.     if (cs != 0) {  
  7.         c->mCamera = cs->connect(c, cameraId);  
  8.     }  
  9.     if (c->mCamera != 0) {  
  10.         c->mCamera->asBinder()->linkToDeath(c);  
  11.         c->mStatus = NO_ERROR;  
  12.     } else {  
  13.         c.clear();  
  14.     }  
  15.     return c;  
  16. }  

在connect()中,调用BpCameraService->connect(),得到BpCamera,赋给mCamera.这样Camera类有了<ICameraService>和<ICamera>两个接口类的代理类实例。

2.3 头文件ICamera.h

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

[cpp] view plaincopyprint?
  1. namespace android {  
  2.   
  3. class ICameraClient;  
  4.   
  5. class ICamera: public IInterface  
  6. {  
  7. public:  
  8.     DECLARE_META_INTERFACE(Camera);  
  9.   
  10.     virtual void            disconnect() = 0;  
  11.   
  12.     // connect new client with existing camera remote  
  13.     virtual status_t        connect(const sp<ICameraClient>& client) = 0;  
  14.   
  15.     // prevent other processes from using this ICamera interface  
  16.     virtual status_t        lock() = 0;  
  17.   
  18.     // allow other processes to use this ICamera interface  
  19.     virtual status_t        unlock() = 0;  
  20.   
  21.     // pass the buffered Surface to the camera service  
  22.     virtual status_t        setPreviewDisplay(const sp<Surface>& surface) = 0;  
  23.   
  24.     // pass the buffered ISurfaceTexture to the camera service  
  25.     virtual status_t        setPreviewTexture(  
  26.             const sp<ISurfaceTexture>& surfaceTexture) = 0;  
  27.   
  28.     // set the preview callback flag to affect how the received frames from  
  29.     // preview are handled.   
  30.     virtual void            setPreviewCallbackFlag(int flag) = 0;  
  31.   
  32.     // start preview mode, must call setPreviewDisplay first  
  33.     virtual status_t        startPreview() = 0;  
  34.   
  35.     // stop preview mode   
  36.     virtual void            stopPreview() = 0;  
  37.   
  38.     // get preview state   
  39.     virtual bool            previewEnabled() = 0;  
  40.   
  41.     // start recording mode   
  42.     virtual status_t        startRecording() = 0;  
  43.   
  44.     // stop recording mode   
  45.     virtual void            stopRecording() = 0;  
  46.   
  47.     // get recording state   
  48.     virtual bool            recordingEnabled() = 0;  
  49.   
  50.     // release a recording frame   
  51.     virtual void            releaseRecordingFrame(const sp<IMemory>& mem) = 0;  
  52.   
  53.     // auto focus   
  54.     virtual status_t        autoFocus() = 0;  
  55.   
  56.     // cancel auto focus   
  57.     virtual status_t        cancelAutoFocus() = 0;  
  58.   
  59.     /* 
  60.      * take a picture. 
  61.      * @param msgType the message type an application selectively turn on/off 
  62.      * on a photo-by-photo basis. The supported message types are: 
  63.      * CAMERA_MSG_SHUTTER, CAMERA_MSG_RAW_IMAGE, CAMERA_MSG_COMPRESSED_IMAGE, 
  64.      * and CAMERA_MSG_POSTVIEW_FRAME. Any other message types will be ignored. 
  65.      */  
  66.     virtual status_t        takePicture(int msgType) = 0;  
  67.   
  68.     // set preview/capture parameters - key/value pairs  
  69.     virtual status_t        setParameters(const String8& params) = 0;  
  70.   
  71.     // get preview/capture parameters - key/value pairs  
  72.     virtual String8         getParameters() const = 0;  
  73.   
  74.     // send command to camera driver   
  75.     virtual status_t        sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;  
  76.   
  77.     // tell the camera hal to store meta data or real YUV data in video buffers.  
  78.     virtual status_t        storeMetaDataInBuffers(bool enabled) = 0;  
  79. };  
  80.   
  81. // ----------------------------------------------------------------------------  
  82.   
  83. class BnCamera: public BnInterface<ICamera>  
  84. {  
  85. public:  
  86.     virtual status_t    onTransact( uint32_t code,  
  87.                                     const Parcel& data,  
  88.                                     Parcel* reply,  
  89.                                     uint32_t flags = 0);  
  90. };  
  91.   
  92. }; // namespace android  
<textarea style="DISPLAY: none" class="cpp" readonly="readonly" name="code">namespace android {class ICameraClient;class ICamera: public IInterface{public: DECLARE_META_INTERFACE(Camera); virtual void disconnect() = 0; // connect new client with existing camera remote virtual status_t connect(const sp&lt;ICameraClient&gt;&amp; client) = 0; // prevent other processes from using this ICamera interface virtual status_t lock() = 0; // allow other processes to use this ICamera interface virtual status_t unlock() = 0; // pass the buffered Surface to the camera service virtual status_t setPreviewDisplay(const sp&lt;Surface&gt;&amp; surface) = 0; // pass the buffered ISurfaceTexture to the camera service virtual status_t setPreviewTexture( const sp&lt;ISurfaceTexture&gt;&amp; surfaceTexture) = 0; // set the preview callback flag to affect how the received frames from // preview are handled. virtual void setPreviewCallbackFlag(int flag) = 0; // start preview mode, must call setPreviewDisplay first virtual status_t startPreview() = 0; // stop preview mode virtual void stopPreview() = 0; // get preview state virtual bool previewEnabled() = 0; // start recording mode virtual status_t startRecording() = 0; // stop recording mode virtual void stopRecording() = 0; // get recording state virtual bool recordingEnabled() = 0; // release a recording frame virtual void releaseRecordingFrame(const sp&lt;IMemory&gt;&amp; mem) = 0; // auto focus virtual status_t autoFocus() = 0; // cancel auto focus virtual status_t cancelAutoFocus() = 0; /* * take a picture. * @param msgType the message type an application selectively turn on/off * on a photo-by-photo basis. The supported message types are: * CAMERA_MSG_SHUTTER, CAMERA_MSG_RAW_IMAGE, CAMERA_MSG_COMPRESSED_IMAGE, * and CAMERA_MSG_POSTVIEW_FRAME. Any other message types will be ignored. */ virtual status_t takePicture(int msgType) = 0; // set preview/capture parameters - key/value pairs virtual status_t setParameters(const String8&amp; params) = 0; // get preview/capture parameters - key/value pairs virtual String8 getParameters() const = 0; // send command to camera driver virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0; // tell the camera hal to store meta data or real YUV data in video buffers. virtual status_t storeMetaDataInBuffers(bool enabled) = 0;};// ----------------------------------------------------------------------------class BnCamera: public BnInterface&lt;ICamera&gt;{public: virtual status_t onTransact( uint32_t code, const Parcel&amp; data, Parcel* reply, uint32_t flags = 0);};}; // namespace android</textarea>

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

2.4 头文件ICameraService .h

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

[cpp] view plaincopyprint?
  1. namespace android {  
  2.   
  3. class ICameraService : public IInterface  
  4. {  
  5. public:  
  6.     enum {  
  7.         GET_NUMBER_OF_CAMERAS = IBinder::FIRST_CALL_TRANSACTION,  
  8.         GET_CAMERA_INFO,  
  9.         CONNECT  
  10.     };  
  11.   
  12. public:  
  13.     DECLARE_META_INTERFACE(CameraService);  
  14.   
  15.     virtual int32_t         getNumberOfCameras() = 0;  
  16.     virtual status_t        getCameraInfo(int cameraId,  
  17.                                           struct CameraInfo* cameraInfo) = 0;  
  18.     virtual sp<ICamera>     connect(const sp<ICameraClient>& cameraClient,  
  19.                                     int cameraId) = 0;  
  20. };  
  21.   
  22. // ----------------------------------------------------------------------------  
  23.   
  24. class BnCameraService: public BnInterface<ICameraService>  
  25. {  
  26. public:  
  27.     virtual status_t    onTransact( uint32_t code,  
  28.                                     const Parcel& data,  
  29.                                     Parcel* reply,  
  30.                                     uint32_t flags = 0);  
  31. };  
  32.   
  33. }; // namespace android  

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

2.5 头文件ICameraClient.h

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

[cpp] view plaincopyprint?
  1. class ICameraClient: public IInterface  
  2. {  
  3. public:  
  4.     DECLARE_META_INTERFACE(CameraClient);  
  5.   
  6.     virtual void            notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;  
  7.     virtual void            dataCallback(int32_t msgType, const sp<IMemory>& data,  
  8.                                          camera_frame_metadata_t *metadata) = 0;  
  9.     virtual void            dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& data) = 0;  
  10. };  
  11.   
  12. // ----------------------------------------------------------------------------  
  13.   
  14. class BnCameraClient: public BnInterface<ICameraClient>  
  15. {  
  16. public:  
  17.     virtual status_t    onTransact( uint32_t code,  
  18.                                     const Parcel& data,  
  19.                                     Parcel* reply,  
  20.                                     uint32_t flags = 0);  
  21. };  

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

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

2.6 头文件CameraHardwareInterface.h

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

    CameraHardwareInterface 定以Camera硬件的接口,如下所示:
class CameraHardwareInterface : 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,
                                      bool cancel_raw,
                                      bool cancel_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, const Vector<String16>& args) const = 0;
};


    使用C语言的方式导出符号:
extern "C" sp<CameraHardwareInterface> openCameraHardware();

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

第三部分 Camera的主要实现分析

3.1 JAVA程序部分      

        在packages/apps/Camera/src/com/android/camera/目录的Camera.java文件中,包含了对Camera的调用
在Camera.java中包含对包的引用:
import android.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;
}


    对Camera功能的一些调用如下所示:
mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
mCameraDevice.startPreview();
mCameraDevice.stopPreview();


    startPreview、stopPreview 和takePicture等接口就是通过JAVA本地调用(JNI)来实现的。

    frameworks/base/core/java/android/hardware/目录中的Camera.java文件提供了一个JAVA类:Camera。

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 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本地调用方法)类型的数组gMethods,如下所示:
static JNINativeMethod camMethods[] = {
{"native_setup","(Ljava/lang/Object;)V",(void*)android_hardware_Camera_native_setup },
  {"native_release","()V",(void*)android_hardware_Camera_release },
  {"setPreviewDisplay","(Landroid/view/Surface;)V",(void *)android_hardware_Camera_setPreviewDisplay },
  {"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", "()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程序中调用的名称;第二个成员也是一个字符串,表示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(camMethods));
}
    "android/hardware/Camera"对应JAVA的类android.hardware.Camera。


3.3 Camera本地库libui.so
    frameworks/base/libs/ui/中的Camera.cpp文件用于实现Camera.h提供的接口,其中一个重要的片段如下所示:
const sp<ICameraService>& Camera::getCameraService()
{
    Mutex::Autolock _l(mLock);
    if (mCameraService.get() == 0) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            binder = sm->getService(String16("media.camera"));
            if (binder != 0)
                break;
            LOGW("CameraService not published, waiting...");
            usleep(500000); // 0.5 s
        } while(true);
        if (mDeathNotifier == NULL) {
            mDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(mDeathNotifier);
        mCameraService = interface_cast<ICameraService>(binder);
    }
    LOGE_IF(mCameraService==0, "no CameraService!?");
    return mCameraService;
}
      其中最重要的一点是binder =sm->getService(String16("media.camera"));;这个调用用来得到一个名称为"media.camera"的服务,这个调用返回值的类型为IBinder,根据实现将其转换成类型ICameraService使用。
       一个函数 connect的实现 如下所示:
sp<Camera> Camera::connect()
{
    sp<Camera> c = new Camera();
    const sp<ICameraService>& cs = getCameraService();
    if (cs != 0) {
        c->mCamera = cs->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::startPreview()
{
    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类虽然实现了onTransact()函数,但是由于还有纯虚函数没有实现,因此这个类都是不能实例化的。
       ICameraClient.cpp中的BnCameraClient在别的地方也没有实现;而ICameraService.cpp中的BnCameraService类在别的地方被继承并实现,继承者实现了Camera服务的具体功能。

3.4 Camera服务libcameraservice.so

      frameworks/base/camera/libcameraservice/ 用于实现一个Camera的服务,这个服务是继承ICameraService的具体实现。
    在这里的Android.mk文件中,使用宏USE_CAMERA_STUB决定是否使用真的Camera,如果宏为真,则使用CameraHardwareStub.cpp和FakeCamera.cpp构造一个假的Camera,如果为假则使用CameraService.cpp构造一个实际上的Camera服务。
      CameraService.cpp是继承BnCameraService的实现,在这个类的内部又定义了类Client,CameraService::Client继承了BnCamera。在运作的过程中CameraService::connect()函数用于得到一个CameraService::Client,在使用过程中,主要是通过调用这个类的接口来实现完成Camera的功能,由于CameraService::Client本身继承了BnCamera类,而BnCamera类是继承了ICamera,因此这个类是可以被当成ICamera来使用的。
      CameraService和CameraService::Client两个类的结果如下所示:
class CameraService : public BnCameraService
{  
    class Client : public BnCamera {};
    wp<Client>                  mClient;
}


     在CameraService中的一个静态函数instantiate()用于初始化一个Camera服务,寒暑如下所示:
void CameraService::instantiate() {
    defaultServiceManager()->addService( String16("media.camera"), new CameraService());
}

      事实上,CameraService::instantiate()这个函数注册了一个名称为"media.camera"的服务,这个服务和Camera.cpp中调用的名称相对应。
    Camera整个运作机制是:在Camera.cpp中可以调用ICameraService的接口,这时实际上调用的是BpCameraService,而BpCameraService又通过Binder机制和BnCameraService实现两个进程的通讯。而BpCameraService的实现就是这里的CameraService。因此,Camera.cpp虽然是在另外一个进程中运行,但是调用ICameraService的接口就像直接调用一样,从connect()中可以得到一个ICamera类型的指针,真个指针的实现实际上是CameraService::Client。
      而这些Camera功能的具体实现,就是CameraService::Client所实现的了,其构造函数如下所示:
CameraService::Client::Client(const sp<CameraService>& cameraService,
        const sp<ICameraClient>& cameraClient) :
    mCameraService(cameraService), mCameraClient(cameraClient), mHardware(0)
{
    mHardware = openCameraHardware();
    mHasFrameCallback = false;
}

      构造函数中,调用openCameraHardware()得到一个CameraHardwareInterface类型的指针,并作为其成员mHardware。以后对实际的Camera的操作都通过对这个指针进行。这是一个简单的直接调用关系。
    事实上,真正的Camera功能己通过实现CameraHardwareInterface类来完成。在这个库当中CameraHardwareStub.h和CameraHardwareStub.cpp两个文件定义了一个桩模块的接口,在没有Camera硬件的情况下使用,例如在仿真器的情况下使用的文件就是CameraHardwareStub.cpp和它依赖的文件FakeCamera.cpp。
      CameraHardwareStub类的结构如下所示:
class CameraHardwareStub : public CameraHardwareInterface {
    class PreviewThread : public Thread {
    };
};

    在类CameraHardwareStub当中,包含一个线程类PreviewThread,这个线程用于处理PreView,即负责刷新取景器的内容。实际的Camera硬件接口通常可以通过对v4l2捕获驱动的调用来实现,同时还需要一个JPEG编码程序将从驱动中取出的数据编码成JPEG文件。



原创粉丝点击