Android Camera学习总结

为了更全面的理解Android Camera,决定梳理一遍camera APP到HAL层的工作流程,基础平台是qcom sdm845。kernel层没有研究过,以后找时间再研究下。

首先可以从https://source.android.google.cn/devices/camera这个网址较全面的了解下Android Camera知识,我们只针对其中的几个环节做下简要的分析。

1.1 应用层主要流程

应用层主要流程如下
在这里插入图片描述

应用主要流程有:

  1. Surface资源准备
  2. openCamera流程
  3. createSession流程
  4. preview、capture申请流程
  5. 帧数据接收,主要目的有:Jepg数据接收、预览帧显示、Texture更新等

下面我们逐个分析下上边分析的流程

2.1 Surface资源准备

在Camera 系统中Surface不仅仅是一种显示控件,更是一种帧数据接收、传递载体。
首先Camera 系统需要通过 surface.dequeueBuffer来获取graphics buffer(父类ANativeWindowBuffer)。然后将该buffer传递给Camera系统,在Camera系统受到帧数据时,会将帧数据填充到该buffer,然后在调用surface.queueBuffer将帧数据返回给surface1

surface有多种类型,如SurfaceView,TextureVew,SurfaceTexture,ImageReader等,其在应用中的创建过程我们就不分析了。

2.2 openCamera流程

其简要流程图如下:
在这里插入图片描述
openCamera 主要涉及三个进程

  1. 应用所在进程,FrameworkAPI属于该进程
  2. CameraService进程
  3. CameraProvider进程,camx属于该进程

详细流程我们不展开逐步分析了,我们重点分析下openCamera 在CamX主要实现流程。

OpenCamera 在CamX主要包含两个流程

  1. 创建HALDevice对象,并初始化其成员变量m_camera3Device,m_camera3Device是一个camera3_device_t结构体对象(在CamX中重新定义一个和camera3_device_t一样的结构体Camera3Device,我们可以认为其和camera3_device_t完全相同)。
CamxResult HALDevice::Initialize(
    const HwModule* pHwModule,
    UINT32          cameraId)
{
    
    
    ....
    if (CamxResultSuccess == result)
    {
    
    
    //初始化m_camera3Device结构体对象
        m_camera3Device.hwDevice.tag     = HARDWARE_DEVICE_TAG; 
        m_camera3Device.hwDevice.version = CAMERA_DEVICE_API_VERSION_3_3;
        m_camera3Device.hwDevice.close   = reinterpret_cast<CloseFunc>(GetHwDeviceCloseFunc());
        m_camera3Device.pDeviceOps       = reinterpret_cast<Camera3DeviceOps*>(GetCamera3DeviceOps());
        m_camera3Device.pPrivateData     = this;
        // NOWHINE CP036a: Need exception here
        m_camera3Device.hwDevice.pModule = const_cast<HwModule*>(pHwModule);
    //初始化m_HALCallbacks结构体对象并传递给CHI
        m_HALCallbacks.ProcessCaptureResult = ProcessCaptureResult;
        m_HALCallbacks.NotifyResult         = Notify;
        CamX::ChiOverrideBypass(&m_HALCallbacks);
    }
    return result;
}
  1. 初始化HALDevice成员变量m_pCamera3CbOps,m_pCamera3CbOps类型为Camera3CbOps
int initialize(
    const struct camera3_device*    pCamera3DeviceAPI,
    const camera3_callback_ops_t*   pCamera3CbOpsAPI)
{
    
    
 ...
 if (NULL != pCamera3CbOps)
 {
    
    
     pCamera3CbOps->cbOps.process_capture_result = process_capture_result;
     pCamera3CbOps->cbOps.notify = notify;
     pCamera3CbOps->pCamera3Device = pCamera3DeviceAPI;
     //将CameraProvider传递的指针暂存到pCbOpsAPI 中
     pCamera3CbOps->pCbOpsAPI = pCamera3CbOpsAPI;
     //给pCamera3CbOpsAPI 赋新的指针
     pCamera3CbOpsAPI = &(pCamera3CbOps->cbOps);
 }
 //将新指针设置到HALDevice对象m_pCamera3CbOps成员
 //这样做的目的是在调用CameraProvider的process_capture_result时
 //先打印一些帧信息,可以理解为复写函数
 return pHAL3->initialize(pCamera3DeviceAPI, pCamera3CbOpsAPI);
}

2.3 createSession流程

在openCamera成功后,CameraManager会返回CameraDeviceImpl类对象给CameraAPP,然后调用
createCaptureSession方法来完成Stream的创建。createCaptureSession最终是通过configureStreamsChecked来完成创建Stream,代码如下:

扫描二维码关注公众号,回复: 11830169 查看本文章
//CameraDeviceImpl.java
public boolean configureStreamsChecked(InputConfiguration inputConfig,
        List<OutputConfiguration> outputs, int operatingMode)
                throws CameraAccessException {
    
    
    ....
    synchronized(mInterfaceLock) {
    
    
        ....
        //configStream之前首先需要停预览
        stopRepeating();

        try {
    
    
            //在configStream之前,需要等待Camera为IDLE状态
            waitUntilIdle();
            //mRemoteDevice为BpCameraDeviceUser代理对象
            //与其对应的BnCameraDeviceUser为CameraService中的
            //CameraDeviceClient
            //向CameraService申请开始config
            mRemoteDevice.beginConfigure();
            ....
            // Delete all streams first (to free up HW resources)
            for (Integer streamId : deleteList) {
    
    
                //向CameraService申请删除streamId应用Stream
                mRemoteDevice.deleteStream(streamId);
                mConfiguredOutputs.delete(streamId);
            }
            // Add all new streams
            for (OutputConfiguration outConfig : outputs) {
    
    
                if (addSet.contains(outConfig)) {
    
    
                    //向CameraService申请创建一个新的Stream
                    //outConfig包含了创建Stream必需的Surface
                    //Surface的大小尺寸格式会决定Stream的大小尺寸格式
                    //创建成功后会返回创建的streamId
                    int streamId = mRemoteDevice.createStream(outConfig);
                    mConfiguredOutputs.put(streamId, outConfig);
                }
            }
            operatingMode = (operatingMode | (customOpMode << 16));
            //向CameraService申请完成创建Stream
            //operatingMode?
            //CameraService会根据上边创建的Stream
            //向Camx申请创建HAL层Stream
            mRemoteDevice.endConfigure(operatingMode);
            success = true;
        } catch (IllegalArgumentException e) {
    
    
            .....
        } catch (CameraAccessException e) {
    
    
            ....
        } finally {
    
    
            if (success && outputs.size() > 0) {
    
    
                mDeviceHandler.post(mCallOnIdle);
            }
        }
    }

    return success;
}

通过上述函数可知,配置流的流程如下:

  1. beginConfigure
  2. deleteStream/createStream
  3. endConfigure

我们逐个分析下,其实现

2.3.1 beginConfigure流程

CameraService中对beginConfigure并没有做任何事情,代码如下:

binder::Status CameraDeviceClient::beginConfigure() {
    
    
    ALOGV("%s: Not implemented yet.", __FUNCTION__);
    return binder::Status::ok();
}

2.3.2 deleteStream/createStream流程

我们先介绍下createStream流程

2.3.2.1 createStream流程

在这里插入图片描述

2.4 preview、capture申请流程

待续。。。。。


  1. 更详细的介绍请参考Android graphics buffer在CameraService、CameraProvider、CameraHAL的申请、传递、归还流程↩︎

猜你喜欢

转载自blog.csdn.net/u010116586/article/details/106910001
今日推荐