CameraService之服务流程图
一、CameraService启动流程
二、CameraProvider启动流程
三、CameraService总流程
camara provider 服务启动,等待上层调用它
camara provider在启动的时候,就已经调用了自己的initialize()函数
camera service 启动,最后会调用到 CameraProviderManager::initialize–>providerInfo→initialize();
frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
status_t CameraProviderManager::ProviderInfo::initialize()
{
//往camera provider设置 回调,当 cameraprovider 收到 camera device status发生改变时,
//会回调 CameraProviderManager::ProviderInfo::cameraDeviceStatusChange()函数
//mInterface = ICameraProvider
hardware::Return<Status> status = mInterface->setCallback(this);
//接口来进行设备的枚举,其实这里并没有调用到具体的设备相关的HAL3内部,因为在provider初始化的的时候,
//已经调用过了,这里只是把provider里面保存的camera list返回给上层的framework
mInterface->getCameraIdList;
当底层发生camera 状态变化时,会回调 到 上层的 CameraProviderManager::ProviderInfo::cameraDeviceStatusChange
-->addDevice(cameraDeviceName, newStatus, &id);-->initializeDeviceInfo-->mInterface->getCameraDeviceInterface_V3_x//又回到camera provider中去了
}
hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp
Return<void> CameraProvider::getCameraDeviceInterface_V3_x()
{
sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
new android::hardware::camera::device::V3_2::implementation::CameraDevice(
mModule, cameraId, mCameraDeviceNames);
}
CameraProviderManager调用CameraProviderManager::openSession函数–>deviceInfo3->mInterface->open–>这样的话就顺利的调到了
hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp中的open函数
hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp
CameraDevice::open
//1 open CameraModule
status_t res;
ATRACE_BEGIN("camera3->open");
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
//2 create createSession
session = createSession(device, info.static_camera_characteristics, callback);
4 中的mModule 为 const sp mModule
hardware/interfaces/camera/common/1.0/default/CameraModule.cpp
int CameraModule::open(const char* id, struct hw_device_t** device) {
int res;
ATRACE_BEGIN("camera_module->open");
res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
ATRACE_END();
return res;
}
调用到这一步,后面就会调用到各个平台的camera hal层了,比如海思,MTK,Amlogic等,每一个平台实现的方式不一样,但是android的调用流程,调用到这一步都一样的
camera3_device_t *device;
session = createSession(device, info.static_camera_characteristics, callback);
以下的函数功能 对上:通过binder通信,接口送到了 frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp,拿到ICameraDeviceSession
即可调用到 hardware/interfaces/camera/device/3.3/default/CameraDeviceSession.cpp
对下:session调用到各个平台的 camera实现中去了
上层调用CameraProviderManager::openSession时候 得到了Session的 Bp代理,然后通过Bp调用到 Bn
soong/.intermediates/hardware/interfaces/camera/device/3.3/android.hardware.camera.device@3.3_genc++/gen/android/hardware/camera/device/3.3/CameraDeviceSessionAll.cpp
///hardware/interfaces/camera/device/3.2/default/CameraDeviceSession.cpp
mDevice->ops->process_capture_request
mDevice->ops->flush(mDevice);
mDevice->ops->initialize(mDevice, this);
mDevice->ops->dump(mDevice, fd->data[0]);
mDevice->ops->construct_default_request_settings(mDevice, (int) type);
mDevice->ops->configure_streams(mDevice, &stream_list);
使用刚刚创建好的session进行具体的业务逻辑处理
1.framework 通过ICameraDeviceSession::configureStreams() 接口来向设备相关的HAL层传递用户所需的stream配置,同时HAL内部会根据传递下来的stream来选择具体的业务进行配置
2.framework 通ICameraDeviceSession::constructDefaultRequestSettings()接口来获取一个默认的具体业务场景配置,这个操作可以在ICameraDevice::open()之后的任何时刻执行
3.framework使用上面构建的默认setting,再左以自己需要的特殊配置,然后发送第一个request 请求到HAL 里面去,这个request里面必须包含至少一个之前配置好的stream(没错,他们的地址必须相同,不能够使用copy的方式重新建立一个stream,并且这个stream地址与使用 由framework & app去维护),因为要输出buffer给framework那边,上面的request使用ICameraDeviceSession::processCaptrueRequest()进行转换,HAL内部需要阻塞本次request请求,直到准备好接受下一个request的时候返回
4.framework 持续调用ICameraDeviceSession::processCaptureRequest()进行 request的下发,如果需要切换其他场景的话,再次调用 ICameraDeviceSession::constructDefaultRequestSetting()进行具体场景的默认setting构建
5.当本次request 开始被HAL正式执行的时候,也就是HAL低下的硬件sensor开始曝光本帧的时候,HAL需要调用framework实现的ICameraDeviceCallback::notify()函数进行SHUTTER消息回调,这个消息里面包含了时间戳数据 和frame number,这个是HAL层主动发起的回调,但是不需要再第一个request下发下去之前就开始回调,并且一个request的notify完成之前,不要返回任何result给到framework
6.经过几个pipeline延迟之后,HAL开始向framework返回已经完成的结果,返回过程通过ICameraDeviceCallback::processCaptureResult()函数完成,返回的顺序按照提交request的顺序来,request也可以一次性下发多个,数量取决于队列深度,一般6~8个
上面的过程 会一直循环,等到 特定的时刻,会发生下面的事情
1.framework停止下发request请求,然后等待所有的buffer被填充完毕,且所有的result全部返回,这个时候再次调用ICameraDeviceSession::configureStream() 接口重新配置业务流,这个在HAL内部会导致整个硬件被重置一遍,然后用新的stream重新配置,继续上面的循环,----说白了就是场景切换,比如从拍照 切换到了录像(不关闭camera app)
2.framework可能会调用ICameraDeviceSession::close()接口结束整个会话,该函数可以在任何时候调用,但是framework在调用该函数的时候,不可以继续下发request,并且所以的函数调用不能够进行下去,在close函数返回之后,HAL层不得再回调framework的函数,其实在close之前,通常会有flush函数调用,这个函数的调用与close差不多,close可以认为是一个收尾动作,flush会等待所有的request完成并且所有的result全部返回到framework
3.当发生错误或者其他异步事件的时候,HAL必须调用
ICameraDeviceCallback::notify()函数来返回错误消息给framework.如果HAL内部发生了严重的设备错误,HAL内部在回复完错误消息之后需要按照close函数被调用时候的动作来清理案发现场,同时在调用notify之前,也应该停止所有的尚在队列中的request请求响应,严重错误传递给framework的时候,HAL不再返回任何结果给framework,并且在framework尝试调用close的时候需要返回 ENODEV 或者 NULL。
以上的流程 比较关键的几个点:
(1) 设备枚举
(2) session创建
(3) stream配置,request构建与下发
(4) result返回 notify事件回调
(5) 清理现场