为了更全面的理解Android Camera,决定梳理一遍camera APP到HAL层的工作流程,基础平台是qcom sdm845。kernel层没有研究过,以后找时间再研究下。
首先可以从https://source.android.google.cn/devices/camera这个网址较全面的了解下Android Camera知识,我们只针对其中的几个环节做下简要的分析。
1.1 应用层主要流程
应用层主要流程如下
应用主要流程有:
- Surface资源准备
- openCamera流程
- createSession流程
- preview、capture申请流程
- 帧数据接收,主要目的有: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 主要涉及三个进程
- 应用所在进程,FrameworkAPI属于该进程
- CameraService进程
- CameraProvider进程,camx属于该进程
详细流程我们不展开逐步分析了,我们重点分析下openCamera 在CamX主要实现流程。
OpenCamera 在CamX主要包含两个流程
- 创建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;
}
- 初始化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,代码如下:
//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;
}
通过上述函数可知,配置流的流程如下:
- beginConfigure
- deleteStream/createStream
- 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申请流程
待续。。。。。