Camera API1 从应用到CameraService分析

       文章根据这个整理而成。http://blog.chinaunix.net/uid-25314474-id-2938255.html。找到最后才发现上面介绍的Camera竟然是基于Android1.0写的文章,顿时泪奔,不过也能从中学到知识。可以通过    http://androidxref.com/  在线查看源码进行学习。

我6月4号写了大概,现在把native的binder看了一遍,再来缕下camera代码。  很多知识是从安卓框架揭秘看的。

写在前面的话android_hardware_Camera.cpp中的Camera调用Camera.cpp中的方法,然后Camera.cpp中先连接CameraService(用的是实名binder调用)。CameraService.cpp返回获取Icamera(这个是匿名Binder远程调用传递的),在Camera.cpp返回的ICamera远程调用CameraService::Client中的对应方法,然后CameraService::Client向下用hal打开驱动,在CameraService::Client中通过ICameraClient回调到Camera.cpp(这个也是匿名Binder调用)中,然后返回JNI,返回Camera.java到上层

其中涉及到三个Binder远程跨进程调用。三个接口ICameraClient,ICameraService,ICamera。

上层应用调用android/hardware/Camera.java

最上层的应用是packages/apps/Camera/src/com/android/camera/Camera.java.

android.hardware.Camera mCameraDevice;  //mCameraDevice通过CameraHolder.instance().open打开

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

public class Camera {
    //在这个类当中,大部分代码使用JNI调用下层得到,例如:  
       public void setParameters(Parameters params) {
             native_setParameters(params.flatten());
       }  
       public final void setPreviewDisplay(SurfaceHolder holder) {
              setPreviewDisplay(holder.getSurface());
        } //两个setPreviewDisplay参数不同,后一个是本地方法,参数为Surface类型, 
        //前一个通过调用后一个实现,但自己的参数以SurfaceHolder为类型。  
        private native final void setPreviewDisplay(Surface surface); 
}  

Camera的JAVA本地调用部分(JNI):
frameworks/base/core/jni/android_hardware_Camera.cpp

这个类承上启下的作用,上层调用参数传递要经过这个类,参数设置结束,结果要通过此类返回给app. 先java调c++,然后在c++调java返回camera.java
这部分内容编译成为目标是libandroid_runtime.so
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 },
  { "previewEnabled","()Z",(void *)android_hardware_Camera_previewEnabled },
  { "setHasPreviewCallback","(ZZ)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 },
  { "reconnect",  "()V",  (void*)android_hardware_Camera_reconnect },
  { "lock",  "()I", (void*)android_hardware_Camera_lock },
  { "unlock",  "()I",(void*)android_hardware_Camera_unlock },
};
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)); 
}

冻酸奶(Froyo)   2..2

/frameworks/base/include/camera/

Camera.h      CameraHardwareInterface.h   CameraParameters.h   ICamera.h   ICameraClient.h     ICameraService.h

/frameworks/base/libs/camera/ 这部分内容被编译成库libcamera_client.so

Camera.cpp   CameraParameters.cpp    ICamera.cpp    ICameraClient.cpp   ICameraService.cpp     Android.mk  LOCAL_MODULE:= libcamera_client

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

从框架结构上来看,ICameraService.h、ICameraClient.h和ICamera.h三个类定义了camera远程调用的接口。

远程调用的实现ICameraClient.cpp,ICamera.cpp,ICameraService.cpp,这些要前标I的,全部是为了实现进程间通信binder用的,没有功能实现。

然后camera.cpp继承了ICameraClient.h,实现客户端的功能,主要是数据返回,

CameraService::Client继承了ICamera.cpp,实现功能控制, cameraService.cpp继承ICameraService.cpp获取相机服务。

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

camera.java  ->>>  libandroid_runtime.so ---> libcamera_client.so--->进程间通信libcameraservice.so  ->>>

在Camera系统的各个库中,libcamera_client.so位于核心的位置,它对上层的提供的接口主要是Camera.cpp类

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


从Camera的整体结构上,类Camera是整个系统核心,ICamera类提供了Camera主要功能的接口(此Camera为native层的,非java层那个)

在客户端方面调用,CameraService是Camera服务,它通过调用实际的Camera硬件接口来实现功能。其它的部分是为上层的JAVA程序提供JNI接口。在整体结构上,左边可以视为一个客户端,右边是一个可以视为服务器,二者通过Android的 Bimder来实现进程间的通讯。


class ICameraClient: public IInterface 
{ //这个版本的我是没有找到,我找遍了1.6之前的也没有,那应该是1.6之前的代码,现在已经下不到了
public: 
    //<span style="color:#FF0000;">这个一定是.h文件,因为下面</span>DECLARE_META_INTERFACE(CameraClient)全都是声明在头文件
    DECLARE_META_INTERFACE(CameraClient); 
    virtual void shutterCallback() = 0; 
    virtual void rawCallback(const sp& picture) = 0; 
    virtual void jpegCallback(const sp& picture) = 0; 
    virtual void frameCallback(const sp& frame) = 0; 
    virtual void errorCallback(status_t error) = 0; 
    virtual void autoFocusCallback(bool focused) = 0; 
};
//Android 1.0是于2008年9月23日正式发布的Android第一版
class BnCameraClient: public BnInterface 
{ 
public: 
    virtual status_t onTransact( uint32_t code, const Parcel& data, 
								Parcel* reply, uint32_t flags = 0); 
};

这是1.6之后的

class ICameraClient: public IInterface
{
public:
    DECLARE_META_INTERFACE(CameraClient);
    virtual void            notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
    virtual void            dataCallback(int32_t msgType, const sp<IMemory>& data) = 0;
    virtual void            dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& data) = 0;
};
class BnCameraClient: public BnInterface<ICameraClient>
{
public:
  //<span style="color:#FF0000;">Bn类中都会重写该方法,作为服务端调用。</span>
 virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

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

IcameraClient这个类的主要接口是几个回调函数shutterCallback、rawCallback和jpegCallback等,它们在相应动作发生的时候被调用。作为Camera的“客户端”,需要自己实现几个回调函数,让服务器程序去“间接地”调用它们。即结果反馈回来。   请注意,camera.cpp继承了ICameraClient。camera.cpp和 ICamera 没半毛钱关系,camera.cpp中的一个ICamera类型的变量是为了进行远程调用。

头文件Camera.h

Camera.h是Camera对外的接口头文件,它被实现Camera JNI的文件android_hardware_Camera.cpp所调用 .Camera.h最主要是定义了一个Camera类:其实是定义客户端行为的,不要被名字所迷惑,它继承了BnCameraClient应该可以看出来。

class Camera : public BnCameraClient, public IBinder:: DeathRecipient 
{ 
public: 
    static  sp<Camera>  connect(); 
                        ~Camera(); 
            void        disconnect();  
            status_t    getStatus() { return mStatus; } 
            status_t    setPreviewDisplay(const sp<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_callback cb, void *cookie); 
    // ICameraClient interface 
    virtual void        shutterCallback(); 
    virtual void        rawCallback(const sp<IMemory>& picture); 
    virtual void        jpegCallback(const sp<IMemory>& picture); 
    virtual void        frameCallback(const sp<IMemory>& frame); 
    virtual void        errorCallback(status_t error); 
    virtual void        autoFocusCallback(bool focused);
//……
}
1.6以后的版本如下
// msgType in notifyCallback and dataCallback functions
enum {
    CAMERA_MSG_ERROR            = 0x001,
    CAMERA_MSG_SHUTTER          = 0x002,
    CAMERA_MSG_FOCUS            = 0x004,
    CAMERA_MSG_ZOOM             = 0x008,
    CAMERA_MSG_PREVIEW_FRAME    = 0x010,
    CAMERA_MSG_VIDEO_FRAME      = 0x020,
    CAMERA_MSG_POSTVIEW_FRAME   = 0x040,
    CAMERA_MSG_RAW_IMAGE        = 0x080,
    CAMERA_MSG_COMPRESSED_IMAGE = 0x100,
    CAMERA_MSG_ALL_MSGS         = 0x1FF
};
// ref-counted object for callbacks
class CameraListener: virtual public RefBase
{
public:
    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;
    virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
};
class Camera : public BnCameraClient, public IBinder::DeathRecipient
{
public:
            // construct a camera client from an existing remote
    static  sp<Camera>  create(const sp<ICamera>& camera);
    static  sp<Camera>  connect();
                        ~Camera();
            void        init();
            status_t    reconnect();
            void        disconnect();
            status_t    lock();
            status_t    unlock();
            status_t    getStatus() { return mStatus; }
            // pass the buffered ISurface to the camera service
            status_t    setPreviewDisplay(const sp<Surface>& surface);
            status_t    setPreviewDisplay(const sp<ISurface>& surface);
            // start preview mode, must call setPreviewDisplay first
            status_t    startPreview();
            // stop preview mode
            void        stopPreview();
            // get preview state
            bool        previewEnabled();
            // start recording mode, must call setPreviewDisplay first
            status_t    startRecording();
            // stop recording mode
            void        stopRecording();
            // get recording state
            bool        recordingEnabled();
            // release a recording frame
            void        releaseRecordingFrame(const sp<IMemory>& mem);
            // autoFocus - status returned from callback
            status_t    autoFocus();
            // cancel auto focus
            status_t    cancelAutoFocus();
            // take a picture - picture returned from callback
            status_t    takePicture();
            // set preview/capture parameters - key/value pairs
            status_t    setParameters(const String8& params);
            // get preview/capture parameters - key/value pairs
            String8     getParameters() const;
            // send command to camera driver
            status_t    sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
            void        setListener(const sp<CameraListener>& listener);  //这一个就把上面的方法包含了
            void        setPreviewCallbackFlags(int preview_callback_flag);
    // ICameraClient interface
    virtual void        notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
    virtual void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
    virtual void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
    sp<ICamera>         remote();
    private:
                        Camera();
                        Camera(const Camera&);
                        Camera& operator=(const Camera);
                        virtual void binderDied(const wp<IBinder>& who);
            class DeathNotifier: public IBinder::DeathRecipient
            {
            public:
                DeathNotifier() {
                }
                virtual void binderDied(const wp<IBinder>& who);
            };
            static sp<DeathNotifier> mDeathNotifier;
            // helper function to obtain camera service handle
            static const sp<ICameraService>& getCameraService();
            sp<ICamera>         mCamera;
            status_t            mStatus;
            sp<CameraListener>  mListener;
            friend class DeathNotifier;
            static  Mutex               mLock;
            static  sp<ICameraService>  mCameraService;

};

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

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

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

CameraService::Client继承了ICamera,往下继续调hal的方法

头文件ICameraService .h用于描述一个Camera的服务

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

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

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

"android/hardware/Camera"对应JAVA的类android.hardware.Camera。Camera本地库 libcamera_client.so /frameworks/base/libs/camera//中的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 { //得到一个名称为"media.camera" 的服务,这个调用返回值的类型为IBinder
            binder = sm->getService(String16("media.camera")); 
            if (binder != 0) 
                break; 
            usleep(500000); // 0.5 s 
        } while(true); 
        if (mDeathNotifier == NULL) { 
            mDeathNotifier = new DeathNotifier(); 
        }
        binder->linkToDeath(mDeathNotifier); 
        <span style="font-size:14px;color:#FF0000;">//把BpBinder通过interface_cast转换BpCameraService</span>,进行远程调用
        mCameraService = interface_cast<ICameraService>(binder); 
    }  //根据实现将其转换成类型ICameraService使用
    return mCameraService; 
}

sp<Camera> Camera::connect()
{
    sp<Camera> c = new Camera();
    const sp<ICameraService>& cs = getCameraService();
    if (cs != 0) {
<span style="font-size:18px;color:#FF0000;">     //c继承了ICameraClient,而Connect接收这种类型的参数</span>
       c->mCamera = cs->connect(c);
    }
    if (c->mCamera != 0) {
        c->mCamera->asBinder()->linkToDeath(c);
        c->mStatus = NO_ERROR;
    } else {
        c.clear();
    }
    return c;
}
connect通过调用getCameraService得到一个 ICameraService,再通过 ICameraService的cs->connect(c)得到一个 ICamera类型的指针。 调用connect将得到一个 Camera的指针,正常情况下Camera的成员 mCamera(在头文件中)已经初始化完成。
status_t Camera::startPreview()
{
    sp <ICamera> c = mCamera;<span style="font-size:14px;color:#FF0000;">//ICamera</span><span style="font-size:18px;">是进行远程调用的,使用的是Binder,调用CameraService::Client中的方法</span>
    if (c == 0) return NO_INIT;
    return c->startPreview();
}

在此处,tBnCameraClient和BnCameraService类虽然实现了onTransact()函数,但是由于还有纯虚函数没有实现,这个必须子类实现,这是native服务必须实现的

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的实现。

\frameworks\base\camera\libcameraservice\CameraService.h

class CameraService : public BnCameraService 
{  
    public:
    static void instantiate();
    class Client : public BnCamera {};
    wp<Client>                  mClient;
}
在CameraService中的一个静态函数instantiate()用于初始化一个Camera服务

\frameworks\base\camera\libcameraservice\CameraService.c

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。

CameraService::Client::Client(const sp<CameraService>& cameraService,
        const sp<ICameraClient>& cameraClient, pid_t clientPid)
{
    int callingPid = getCallingPid();
    LOGD("Client::Client E (pid %d)", callingPid);
    mCameraService = cameraService;
    mCameraClient = cameraClient;
    mClientPid = clientPid;
    mHardware = openCameraHardware();  //定义在头文件
    mUseOverlay = mHardware->useOverlay();

    mMediaPlayerClick = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
    mMediaPlayerBeep = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");

    // Callback is disabled by default
    mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
    cameraService->incUsers();
    LOGD("Client::Client X (pid %d)", callingPid);
}
构造函数中,调用openCameraHardware()得到一个CameraHardwareInterface类型的指针,并作为其成员mHardware。以后对实际的Camera的操作都通过对这个指针进行。这是一个简单的直接调用关系。
在这个库当中 CameraHardwareStub.h和CameraHardwareStub.cpp两个文件定义了一个桩模块的接口,在没有Camera硬件的情况下使用,例如在仿真器的情况下使用的文件就是CameraHardwareStub.cpp和它依赖的文件FakeCamera.cpp。
class CameraHardwareStub : public CameraHardwareInterface {
    class PreviewThread : public Thread {
    };
};
在类CameraHardwareStub当中,包含一个线程类PreviewThread,这个线程用于处理PreView,即负责刷新取景器的内容。实际的Camera硬件接口通常可以通过对v4l2 捕获驱动的调用来实现,同时还需要一个JPEG编码程序将从驱动中取出的数据编码成JPEG文件。


猜你喜欢

转载自blog.csdn.net/jiyilanzhou/article/details/51586552