从AndroidP 开始,高通camera系统全面使用HAL3,之前的HAL1已经被移除,对应HAL3主流的相机开发接口是camera API2 ,但是依然存在大量的使用Camera API 1开发的相机应用,为此Android专门设计了一套兼容API1调用HAL3的中间转换接口,本门主要从几个方面简要介绍下这部分相关的知识。**

  • opencamera
  • startpreview
  • takepicture
  • setparameter、getparameter

1. opencamera

相机应用在调用

Camera open(int cameraId)

时, 经过Binder IPC进入CameraService.cpp,调用的接口是

CameraService::connectHelper(....){    ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "           "Camera API version %d");   ret = makeClient(......))       err = client->initialize(mCameraProviderManager);//重点分析}

通过makeClient会创建相应的client

Status CameraService::makeClient(.....) {         ......        // Default path: HAL version is unspecified by caller, create CameraClient        // based on device version reported by the HAL.        switch(deviceVersion) {             //Android P 之后不再存在CAMERA_DEVICE_API_VERSION_1_0          case CAMERA_DEVICE_API_VERSION_1_0:            if (effectiveApiLevel == API_1) {  // Camera1 API route                 *client = new CameraClient(....),            } else { // Camera2 API route            }            break;          case CAMERA_DEVICE_API_VERSION_3_0:          case CAMERA_DEVICE_API_VERSION_3_1:          case CAMERA_DEVICE_API_VERSION_3_2:          case CAMERA_DEVICE_API_VERSION_3_3:          case CAMERA_DEVICE_API_VERSION_3_4:            //API1+HAL3 对应的client            if (effectiveApiLevel == API_1) { // Camera1 API route                *client = new Camera2Client(.....);            } else { // Camera2 API route                //API2+HAL3 对应的client                *client = new CameraDeviceClient(.....);            }            break;          default:            // Should not be reachable            ALOGE("Unknown camera device HAL version: %d", deviceVersion);            .....        }}

通过上述代码分析发现API1+HAL3对用的client是Camera2Client
其类图如下:

从上边看Camera2Client继承实现了ICamera定义的camera API1接口,但是其内部的成员变量mDevice是`Camera3Device 类型,其是针对HAL3设计的,其类的备注如下:

/** * CameraDevice for HAL devices with version CAMERA_DEVICE_API_VERSION_3_0 or higher. */class Camera3Device :            public CameraDeviceBase,            virtual public hardware::camera::device::V3_2::ICameraDeviceCallback,            private camera3_callback_ops

Camera3Device类图如下:


Camera3Device内部类HalInterface中的spmHidlSession成员变量,是在opencamera是获取的对象,之后所有的constructDefaultRequestSettings,configureStreams等操作,都是通过该对象与HAL3进行通信完成的。
下边给出ICameraDeviceSession类图:

该类是定义在hardware\interfaces\camera\device中,是cameraservice与cameraprovider通信的接口。
下边分析 openCamera具体流程

从流程图上看,opencamera主要完成了两件事:

  • makeclient 创建camera2client对象及Camera3Device对象
  • 初始化camera2client,真正完成打开相机的地方

    从上述过程看,Camera2Client实现的是Camera API1的接口,在opencamera时,通过Camera3Device中的BpHwCameraDevice类型对象deviceInfo3->mInterface的open方法完成与HAL3通信来打开相机,并该方法返回结果为ICameraDeviceSession类型对象session,表示相机成功打开,之后所有的相机相关操作全是通过该对象完成。

2. startpreview

startPreview时序图如下:

从上述时序图看,startpreive过程主要有两个过程,

  • configureStreams
  • 将request插入到mRepeatingRequests队列中,并启动RequestThread,向HAL层不断发送processCaptureRequest申请

3. takepicture

开启相机后会启动一个拍照处理线程mCaptureSequencer:

template<typename TProviderPtr>status_t Camera2Client::initializeImpl(TProviderPtr providerPtr){    ATRACE_CALL();    ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);    status_t res;    res = Camera2ClientBase::initialize(providerPtr);    ...#ifdef USE_QTI_CAMERA2CLIENT    mQTICamera2Client = new QTICamera2Client(this);#endif    mStreamingProcessor = new StreamingProcessor(this);    threadName = String8::format("C2-%d-StreamProc",            mCameraId);    mFrameProcessor = new FrameProcessor(mDevice, this);    threadName = String8::format("C2-%d-FrameProc",            mCameraId);    mFrameProcessor->run(threadName.string());    //创建拍照处理线程并启动    mCaptureSequencer = new CaptureSequencer(this);    threadName = String8::format("C2-%d-CaptureSeq",            mCameraId);    mCaptureSequencer->run(threadName.string());    mJpegProcessor = new JpegProcessor(this, mCaptureSequencer);    threadName = String8::format("C2-%d-JpegProc",            mCameraId);    mJpegProcessor->run(threadName.string());#ifdef USE_QTI_CAMERA2CLIENT    mRawProcessor = new RawProcessor(this, mCaptureSequencer);    threadName = String8::format("C2-%d-RawProc",            mCameraId);    mRawProcessor->run(threadName.string());#endif    mZslProcessor = new ZslProcessor(this, mCaptureSequencer);    threadName = String8::format("C2-%d-ZslProc",            mCameraId);    mZslProcessor->run(threadName.string());    mCallbackProcessor = new CallbackProcessor(this);    threadName = String8::format("C2-%d-CallbkProc",            mCameraId);    mCallbackProcessor->run(threadName.string());    ...    return OK;}

线程中包含有一个状态机,不断检测是否有拍照命令下发,
状态机状态定义如下:

    enum CaptureState {        IDLE,        START,        ZSL_START,        ZSL_WAITING,        ZSL_REPROCESSING,        STANDARD_START,        STANDARD_PRECAPTURE_WAIT,        STANDARD_CAPTURE,        STANDARD_CAPTURE_WAIT,        DONE,        ERROR,        NUM_CAPTURE_STATES    } mCaptureState;

对应的状态处理函数定义如下:

const CaptureSequencer::StateManager        CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = {    &CaptureSequencer::manageIdle,    &CaptureSequencer::manageStart,    &CaptureSequencer::manageZslStart,    &CaptureSequencer::manageZslWaiting,    &CaptureSequencer::manageZslReprocessing,    &CaptureSequencer::manageStandardStart,    &CaptureSequencer::manageStandardPrecaptureWait,    &CaptureSequencer::manageStandardCapture,    &CaptureSequencer::manageStandardCaptureWait,    &CaptureSequencer::manageDone,};

在有拍照命令下发时,状态机进入下一状态START,否则一直停留在IDLE状态

bool CaptureSequencer::threadLoop() {    sp<Camera2Client> client = mClient.promote();    if (client == 0) return false;    CaptureState currentState;    {        Mutex::Autolock l(mStateMutex);        currentState = mCaptureState;    }    //状态机处理流程    currentState = (this->*kStateManagers[currentState])(client);    Mutex::Autolock l(mStateMutex);    if (currentState != mCaptureState) {        if (mCaptureState != IDLE) {            ATRACE_ASYNC_END(kStateNames[mCaptureState], mStateTransitionCount);        }        mCaptureState = currentState;        mStateTransitionCount++;        if (mCaptureState != IDLE) {            ATRACE_ASYNC_BEGIN(kStateNames[mCaptureState], mStateTransitionCount);        }        ALOGV("Camera %d: New capture state %s",                client->getCameraId(), kStateNames[mCaptureState]);        mStateChanged.signal();    }    if (mCaptureState == ERRORmanageStart) {        ALOGE("Camera %d: Stopping capture sequencer due to error",                client->getCameraId());        return false;    }    return true;}

状态图如下:

4. setparameter、getparameter

待续。。。。

更多相关文章

  1. Android(安卓)性能优化(二)Handler运行机制原理,源码分析
  2. android收集应用崩溃信息
  3. Android学习笔记--Binder
  4. Android中Intent概述及使用
  5. Android关机流程解析---从reboot说起
  6. Android当中切换图片
  7. [android] HttpURLConnection的初步学习
  8. Android原生Json解析
  9. Android(安卓)中Message,MessageQueue,Looper,Handler详解+实例

随机推荐

  1. android的触摸事件
  2. CyanogenMod wiki reading tips | Androi
  3. Android运行异常一:token android.os.Bind
  4. [Tools]Android Studio代码提示功能--Ctr
  5. Android以太网固定ip
  6. android判断和创建快捷方式(4.03测试通过
  7. QuickActionBar
  8. 【Android】浅谈Android中的图像资源自动
  9. Android中实现ListView横向滑动
  10. RadioButton 设置文字居中