camera 框架接口函数调用流程,基于android4.0

        这段时间对android的camera框架进行了分析,现将这些天的所得记录如下:android的camera框架和其他外设的framework层一样,大致可以分为三层:应用层、cameraservice层、hal层,应用层通过binder机制与运行于后台的cameraservice进行通信,而cameraservice通过hal层最终调用到linux camera驱动。虽然这里可以分为三层,但是代码具体实现起来还是有差别的。后面将分为两部分进行描述:第一部分从应用层调用到cameraservice。第二部分cameraservics的启动。

         framework提供给应用层使用的java类位于frameworks/base/core/java/android/hardware/Camera.java,在此文件里介绍了如何使用Camera的步骤:
         1. Obtain an instance of Camera from {@link #open(int)}
通过open接口获得一个camera实例,有个地方要注意,open函数是static类型的,所以可以在还没有camera实例时调用它。
         2. Get existing (default) settings with {@link #getParameters()}
通过getParameters()接口获得camera设备的参数。
         3. If necessary, modify the returned {@link Camera.Parameters} object       and call{@link #setParameters(Camera.Parameters)}。
通过setParameters接口对camera设备的参数进行设置,比如说图片的像素。
         4. If desired, call {@link #setDisplayOrientation(int)}。
通过setDisplayOrientation接口设置图片的旋转方向。
         5.  Pass a fully initialized {@link SurfaceHolder} to{@link #setPreviewDisplay(SurfaceHolder)}.  Without a surface, the camera will be unable to start the preview.
通过setPreviewDisplay接口传送SurfaceHolder给下层,如果不设置surface,camera将不能开始工作,这里对surface、SurfaceHolder就不细说了。
         6. Call {@link #startPreview()} to start updating the preview surface.
通过startPreview()接口开始预览图片。
         7.  call {@link #takePicture(Camera.ShutterCallback,Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)} to capture a photo.
通过takePicture来拍照。
        这里对上述的open、startPreview接口进行解析,首先是open接口,camera类中的open接口有两种形式,一种带参数,一种不带参数,但是最终都会调用camera类的构造函数创建camera的实例:return new Camera(cameraId)。Camera构造函数中调用native_setup接口,native_setup是JNI实现的接口,其实现位于
frameworks/base/core/jni/android_hardware_Camera.cpp文件中,对应的函数名为

android_hardware_Camera_native_setup,此函数调用了sp camera = Camera::connect(cameraId),这里的camera对象可不是应用层Camera.java文件中的camera对象,这里处于cpp文件中,所以,不可能是java文件中对象。这里camera对象的声明位于frameworks/base/include/camera/Camera.h文件中,其一个基BnCameraClient,Bnxx是binder机制C++空间的服务端接口,其定义于同一文件夹下的ICameraClient.h中。camera对象的实现位于frameworks/base/libs/camera/Camera.cpp,Camera::connect接口创建了一个Camera实例,并使用标准的binder机制获得了CameraService的远程代理类,并使用CameraService的远程代理类调用CameraService的connect接口,从此调用流程进入了Cameraservics,下面介绍Cameraservics的启动过程。

         Cameraservics是使用native方法启动的,使用init.rc启动的,而不是使用android的system_service启动的。启动Cameraservics的服务在init.rc叫media,其位于frameworks/base/media/mediaserver/main_mediaserver.cpp中,在此中创建了一个Cameraservics对象,并将Cameraservics注册到系统的servics中。Cameraservics定义于frameworks/base/services/camera/libcameraservice中,我们首先看看CameraService.h文件,Cameraservics继承于BnCameraService,由此可知Cameraservics类是摄像头服务类的实现,也即是camera的系统服务。

          在Cameraservics类中还定义了一个重要的内部类class Client,其继承于public BnCamera,BnCamera定义于frameworks/base/include/camera/ICamera.h,这里也是binder的机制,内部类Client也是一种服务的实现。在Cameraservics类的初始化的时候会调用onFirstRef(),在onFirstRef()中使用android hal层的标准函数hw_get_module()获得camera的hal层的hw_module_t对象,并赋值给mModule,这样就可以通过hal层调用linux驱动了,虽然这里得到了hw_module_t对象,但是调用hal的具体操作并不在Cameraservics中,而是由Cameraservics调用CameraHardwareInterface的接口,再由CameraHardwareInterface调用hal层,CameraHardwareInterface定义于frameworks/base/services/camera/libcameraservice/CameraHardwareInterface.h中。

          Cameraservics服务启动了,我们继续open的调用流程,前面说到调用了Cameraservics的connect接口,connect接口里创建了两个重要的对象:class client, CameraHardwareInterface,并返回client对象,这个对象很重要。

          下面来说startPreview的流程,首先是frameworks/base/core/java/android/hardware/Camera.java的startPreview函数,它是jni实现的,位于frameworks/base/core/jni/android_hardware_Camera.cpp,jni中的startPreview调用frameworks/base/libs/camera/Camera.cpp中的startPreview,startPreview通过binder机制调用定义于Cameraservics中内部类client类中的startPreview,client的startPreview函数调用startCameraMode,startCameraMode调用startPreviewMode,startPreviewMode调用CameraHardwareInterface中的startPreview,我们去CameraHardwareInterface.h去看看:mDevice->ops->start_preview(mDevice),其中mDevice 是hw_device_t的类型,到这里,startPreview的调用就进入了camera的hal层了,这里对hal层不进行分析。

         


你可能感兴趣的:(Android)