Andriod Camera之Open Camera

前言       

       打开相机的第一步便是在APP里去调用openCamera(),去打开指定的Camera设备(通过Device id指定),并建立起连接。APP通过openCamera()调用成功后,可以获取到一个已经初始化过的CameraDeviceImp,它表示一个已经打开的Camera设备,后续APP便可以通过CameraDeviceImp去执行各种操作,以控制相机的各种行为。


主要流程

           下面简单地介绍一些openCamera的流程,希望可以对整个的过程有一个大概的了解, openCamera()的主要flow如下图所示

Andriod Camera之Open Camera_第1张图片

       可以将这个过程划分为3个部分来看,分别是App、native framework、Hal层,接下来也将从这三个部分去分析openCamera()这个过程。 

一、App部分:

        对应上图中CameraManager.java这部分。App首先要获取到CameraManager服务,然后才可以查询到某个CameraId所对应的相机设备信息,再调用openCamera(),去打开指定CameraId所对应的相机设备。前面的flow就是:

    ——> openCamera(String cameraId,CameraDevice.StateCallback callback,......)
    ——> openCameraForUid(String cameraId,CameraDevice.StateCallback callback,......)
    ——> openCameraDeviceUserAsync(String cameraId,CameraDevice.StateCallback callback,......)

        其中的两个参数:cameraId就不必多说了^v^;这个callback参数是一个回调对象,用来接收这个CameraDevice的状态变化情况的,这个回调对象里有提供几个回调函数(onOpened()、onClosed()、onError()、onDisconnected()),APP必须要去实作这些方法,以便于底层的CameraDevice切到对应的状态后,APP能够做出对应的反应。前面两个函数的逻辑比较简单,下面主要看一下openCameraDeviceUserAsync()里做的事情:

     1、利用获取的相机设备信息创建CameraDeviceImpl实例

               ---------> CameraDeviceImpl deviceImpl=new CameraDeviceImpl();

          但是这个deviceImpl里还有一个重要的成员-------->mRemoteDevice 没有初始化,它是这个deviceImpl的远端服务,其实后续APP对deviceImpl的操作都会转化为对这个远端服务mRemoteDevice的操作,而这个远端服务需要通过CameraService这个系统服务去获取到。

     2、调用远程CameraService获取当前相机的远程服务

              ----------> cameraUser=CameraService.connectDevice();

    3、将获取到的远程服务设置到CameraDeviceImpl实例中

              ----------> deviceImpl.setRemoteDevice(cameraUser)

           这里面最终会通过前面APP传下来的回调函数---> callback.onOpened() ,返回这个CameraDeviceImpl

   4、返回CameraDeviceImpl实例,即deviceImpl,它代表一个已经打开的相机设备。

         所以是App调用的CameraManager的openCamera()方法,调用成功后,在回调函数里可以得到一个CameraDeviceImpl的实例,这个实例里包含其对应的远端服务。接下来看一看这其中所说的“调用远程CameraService获取当前相机的远程服务”是在做什么。


二、native framework

       在App部分其中有一步叫做:调用远程CameraService获取当前相机的远程服务。这一步其实是通过AIDL调用到了CameraService::connectDevice(),这里就进入了native framework层,这个过程对应于前面流程图中CameraService.cpp到CameraProviderManager.cpp的这一部分 ,接下来看看这个过程中经历的事情。这里面有涉及到几个class:CameraService、CameraDeviceClient、Camera2ClientBase、Camera3Device、CameraProviderManager,它们之间的关系如下:

Andriod Camera之Open Camera_第2张图片

  通过这部分的flow,我们可以看到在native framework里面做的事情大概可以总结如下:

   1、handleEvictionsEvicted

         处理相机的抢占机制,可以参考:Android Camera抢占机制——handleEvictionsLocked()

   2、创建CameraDeviceClient对象,并初始化

       即CameraDeviceClient::initialize()。这里面会调用到Camera2ClientBase::initialize(),而Camera3Device继承自Camera2ClientBase,从前面关系图里可以看出,其实可以看出来Camera3Device就是CameraDeviceClient的成员变量。所以这里面其实是会调用到Camera3Device::initialize()。

   3、初始化Camera3Device

       即Camera3Device::initialize()。这里面最重要的一步便是CameraProviderManager::openSession(),接下来看看这个openSession()里面做的事情:

  •  findDeviceInfoLocked()

            根据CameraDevice的版本,从所有Provider中,找到对应的DeviceInfo。这些信息是在CameraService起来时已经保存好的,可以参考Android Camera之CameraServer的启动过程

  •  startProviderInterface()

          根据刚刚deviceInfo中对应的provider的信息,获取到对应CameraProvider服务。

  •  startDeviceInterface()

         通过CameraProvider的getCameraDeviceInterface_V3_x()实例化一个CameraDevice。这一步是通过HIDL调用到了Hal层,这个CameraDevice是Hal层实作的,和前面APP部分的CameraDevice有所不同,也有所联系

  •    interface->open()

        这个interface就是前面startDeviceInterface()得到的CameraDevice,这里是要通过CameraDevicce::open()创建一个有效的CameraDeviceSession。这一步也是通过HIDL调用到了HAL层。

      需要说一下的是,这个函数有带一个参数给Hal层:即ICameraDeviceCallback。再向前追溯,可以看到是Camera3Device,调用CameraProviderManager::openSession()时传下来的,这个参数是this,其实就是Camera3Device,其实Camera3Device也是自ICameraDeviceCallback继承下来的,这个类可以看这里定义的接口:

/hardware/interfaces/camera/device/3.x/ICameraDeviceCallback.hal 

      里面有两个重要的方法:processCaptureResult()和notify()

再根据CameraDeviceSession构造HalInterface

       将CameraDeviceSession赋值给HalInterface::mHidlSession_3_X

   4 、创建FrameProcessor

       即创建CameraDeviceClient::mFrameProcessor,并将CameraDeviceClient注册进mRangeListener中,因为CameraDeviceClient继承自FilteredListener。关于这个FrameProcessor的作用会在后面的文章中介绍,这里暂时就先跳过了。只需要知道CameraDeviceClient在初始化的时候有建立一个FrameProcessor线程就好了。

   5、返回CameraDeviceClient对象给CameraManager.

         所以到这里后,可以看出App openCamera()中,CameraDeviceImpl的RemoteDevice其实就是CameraService的CameraDeviceClient,后面App里对CameraDeviceImpl的操作,会通过AIDL调用到CameraService里的CameraDeviceClient。


三 、Hal层

        Android在hardware/interfaces/camera下定义了几个hidl interface:ICameraProvider、ICameraDevice和ICameraDeviceSession。Hal层必须要去实作这些Interface, 这部分是由各个厂商(比如MTK、高通)去实作的,因此不同厂商的平台在这部分是会有差异的,这里就不细讲了。

         前面在openSession()时,getCameraDeviceInterface_V3_x()和CameraDevice::open()会通过Hidl调用到由HAL层对应的实作里。

      getCameraDeviceInterface_V3_x()这个接口通过HIDL调用到由Hal层实作的getCameraDeviceInterface_V3_x()函数里面去获取到一个实例化的Cameradevice;CameraDevice::open(),也会通过HIDL调用到HAL层实做的CameraDevice::open()去创建一个实例化的CameraDeviceSession

getCameraDeviceInterface_V3_x()定义在:hardware/interfaces/camera/provider/2.4/ICameraProvider.hal

CameraDevice::open()定义在:hardware/interfaces/camera/device/3.2/ICameraDevice.hal


 总结

            当APP调用openCamera(),会通AIDL调用到CameraService里面,CameraService又会通过HIDL去获取到HAL层实作的CameraDevice和CameraDeviceSession,并保存在Camera3Device中;APP也会在回调函数里得到一个CameraDeviceImpl实例,这个实例中远程服务(即 RemoteDevice)其实就是CameraSevice中的CameraDeviceClient,前面所说的Camera3Device正是CameraDeviceClient的数据成员,这样就建立起了从APP、framework和HAL层之间的联系,如下图所示:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5Y-v54ix55qE5aSn5Y-v54ixaGlhaGlhaGlh,size_20,color_FFFFFF,t_70,g_se,x_16

 Google的这张图更全面一些,也更清晰明了 

Andriod Camera之Open Camera_第3张图片

你可能感兴趣的:(Android,Camera,android,音视频)