从AndroidP 开始,高通camera系统全面使用HAL3,之前的HAL1已经被移除,对应HAL3主流的相机开发接口是camera API2 ,但是依然存在大量的使用Camera API 1开发的相机应用,为此Android专门设计了一套兼容API1调用HAL3的中间转换接口,本门主要从几个方面简要介绍下这部分相关的知识。**
相机应用在调用
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
中的sp
成员变量,是在opencamera是获取的对象,之后所有的constructDefaultRequestSettings,configureStreams
等操作,都是通过该对象与HAL3进行通信完成的。
下边给出ICameraDeviceSession类图:
该类是定义在hardware\interfaces\camera\device
中,是cameraservice与cameraprovider通信的接口。
下边分析 openCamera具体流程
从流程图上看,opencamera主要完成了两件事:
从上述过程看,Camera2Client
实现的是Camera API1
的接口,在opencamera时,通过Camera3Device中的BpHwCameraDevice类型对象deviceInfo3->mInterface的open方法完成与HAL3通信来打开相机,并该方法返回结果为ICameraDeviceSession类型对象session,表示相机成功打开,之后所有的相机相关操作全是通过该对象完成。
startPreview时序图如下:
从上述时序图看,startpreive过程主要有两个过程,
开启相机后会启动一个拍照处理线程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;
}
状态图如下:
待续。。。。