之前主要做的是MTK平台camera驱动,高通平台这块只是简单了解架构。为了做成一个系列,简单梳理下高通camx架构
图片内容来自:https://source.android.google.cn/setup
Android分层架构:
APP层:每一个应用程序由一个或多个活动组成,都是java写的
Framework层:用java编写一些规范化的模块封装框架。用Java Native Interface(JNI 是java调用native语言的一种特性,通过JNI可以使java可以调用C/C++的代码)
Libraries系统库:核心库,主要包含基本的C库等。和我们相关主要是Bionic系统C库
Android运行时库:提供Java编程语言核心库的大多数功能。每一个Android应用程序都在它自己的进程中运行,都有一个独立的Dalvik虚拟机实例。
HAL层:硬件抽象层,Android frameworks中JNI调用hardware.c中定义hw_get_module函数来获取硬件模块。然后调用硬件模块中的方法,硬件模块中的方法直接调用内核接口完成相应功能。
Linux核心层:Android的核心系统服务依赖于Linux内核。如安全性、内存管理、进程管理、网络协议栈、和驱动模型。
SELinux:是Linux内核模块,也是Linux的一个安全子系统。主要作用最大限度地减少系统中服务进程可访问的的资源(最小权限原则)
图片来源:me
高通平台《80-pc212-1_a_chi_api_specifications_for_qualcomm_spectra_2xx_camera.pdf》所示,对高通平台对Camxhal3有个初步的认识。
camera驱动开发需要在source insight 中需要加入的文件:
system仓下: camera_metadata_tags.h、camera_metadata_tag.c、camera_metadata.c、camera_metadata.h
framework/av仓下 camerametadata.cpp、camerametadata.h
kernel仓下: arch/arm/boot/dts
hardware仓下:camera3.h等
framework/av仓下:framework层camera文件
vendor仓下:vendor/qcom/proprietary/camx
vendor\qcom\proprietary\chi-cdk\vendor\
驱动文件:actuator eeprom fd flash ois sensor
usecase:topology
//TODO,完善细节
Usecase :摄像机管道的特定配置,实现了已经定义良好的功能。例如,20万像素的ZSL快照和2k显示的预览是单一的用途的情况。Chi API被设计为在一定范围内指定任何可想象的用户定义用例底层硬件,不需要修改驱动程序。
Session:单个会话是摄像机管道配置完成,从随时准备处理图像,直到摄像机管道被破坏,而另一个管道可能在它的位置配置。支持多个并行会话。
Request:使摄像机管道处理数据的动作。这可以是请求处理从图像传感器中提取的一帧数据,或处理从存储器中提取的一帧数据。结果必须从驱动程序返回到相机应用程序。
Sub-Request:将单个请求分解为多个内部请求的操作。驱动处理完的子请求的结果不会直接返回,而是合并成为单个结果对应原始请求。子请求用于启用诸如HDR,其中多次曝光变化的传感器需要产生单一的图像,或
多帧后处理,其中多个图像合并创建一个单一的输出图像。
Steam:用于处理的具有相同大小和格式的缓冲区序列图像数据。可以指定多个不同类型的流作为相机的输入和输出管道。这组流是定义用例的关键组件。
Per-session setting:影响相机处理管道的设置。这些设置不在会话开始时更改。例如,允许图像稳定处理。
Per-request setting:影响单个请求的设置。例如,手动曝光值。
拓扑结构 :表示单个用例的有向无环图(DAG)。划好了道格一系列处理节点和一组链接,它们描述正在处理的缓冲区通过这些节点。拓扑是通过XML文件指定的。
Engine:可以用来处理数据的硬件。光谱ISP,骁龙CPU,Adreno,和DSP是Chi API可用引擎的例子。
Node:camera管道中的一个逻辑功能块,它在单个引擎节点连接在一起形成拓扑结构。在Chi API的初始版本中,所有ISP外部的节点通过CPU代码调用,CPU代码调用本机API。本机API驱动OpenCL和FastCV等引擎。Chi API可以在未来扩 展到允许缓存和重用硬件命令,而不需要重用本地api。
Pipeline:支持数据操作的惟一上下文。每个管道都可以维护自己的状态跨多个请求,而不受其他管道的影响。管道利用拓扑来定义使用的引擎和数据处理流程。
Statistics:算法包括3A,这是用来自动控制图像传感器和相机ISP,以达到更好的图像质量。这些领域特定的算法是作为Chi API的专用部分处理。
Live Stream:处理从图像传感器接收数据的任何配置,并且不能修改以前请求中的任何数据。实时流处理速度不适合的处理传感器数据速率可以移动到offline stream去处理。
Offline Stream:离线流处理过程不接收来自图像传感器的数据的任何配置。在Chi API中,离线流可以与实时流配对,而无需额外添加延迟。离线流的结果可以返回给相机应用程序。
MTK和高通用的都是Android的架构,在framework层的都是一样的代码。但是为了读者有更好的阅读体验,我还这里写一下这部分的代码(Android Q 之MTK代码分析(一)--Camera Hal3 Service_Cam_韦的博客-CSDN博客)
CameraService服务启动是通过LoadBootScripts() 函数加载cameraserver.rc
camera provider进程和cameraserver进程和底层的驱动交互,camera provider进程非常重要,camera HAL层几乎全部运行在camera provider进程中完成。
首先看下camera provider所在源码中的位置:hardware/interfaces/camera/provider/2.4/default/android.hardware.camera.provider@2.4-service.rc
根据Android Camera分层架构可以看出来,framework有四个组件。(CameraService、CameraDeviceClient、Camera3Device、CameraProviderManager)
CameraService::CameraService() {
ALOGI("CameraService started (pid=%d)", getpid());
}
void CameraService::onFirstRef()
{
ALOGI("CameraService process starting");
res = enumerateProviders();
}
status_t CameraService::enumerateProviders() {
status_t res;
//创建对象,要判断Provider对象为0才能创建
mCameraProviderManager = new CameraProviderManager();
res = mCameraProviderManager->initialize(this);
deviceIds = mCameraProviderManager->getCameraDeviceIds();
return OK;
}
从camera分层架构来看,CameraService要创建CameraProviderMangaer
cameraservice.cpp中 enumerateProviders枚举Provider开始创建CameraProviderManager对象并初始化
CameraDeviceClient::CameraDeviceClient(const sp& cameraService,
{
ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}
status_t CameraDeviceClient::initialize(sp manager,
const String8& monitorTags) {
return initializeImpl(manager, monitorTags);
}
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
res = Camera2ClientBase::initialize(providerPtr, monitorTags);
return OK;
}
frameworks\av\services\camera\libcameraservice\common\Camera2ClientBase.cpp
Camera2ClientBase
::Camera2ClientBase(
mDevice(new Camera3Device(cameraId)),
{
ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),String8(clientPackageName).string(), clientPid, clientUid);
}
从这块CameraDeviceClient就创建Camera3Device对象
template
status_t Camera2ClientBase::initialize(sp manager,
const String8& monitorTags) {
return initializeImpl(manager, monitorTags);
}
template
template
status_t Camera2ClientBase::initializeImpl(TProviderPtr providerPtr,
const String8& monitorTags) {
res = mDevice->initialize(providerPtr, monitorTags);
return OK;
}
ICameraDeviceSession 这块让framework和HAL又联系在一起
status_t Camera3Device::initialize(sp manager, const String8& monitorTags) {
ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
sp session;
}
#include
这样通过头文件的形式ICameraDevice.h,framework就和HAL的联系上
status_t CameraProviderManager::ProviderInfo::initialize(
sp& interface,
hardware::hidl_bitfield currentDeviceState) {
ALOGI("Connecting to new camera provider: %s, isRemote? %d",
mProviderName.c_str(), interface->isRemote());
Status status;
// Get initial list of camera devices, if any
std::vector devices;
hardware::Return ret = interface->getCameraIdList([&status, this, &devices](
hardware::Return st = interface->setCallback(this); //这块用ICameraProvider 接口连接上HAL
ALOGI("Camera provider %s ready with %zu camera devices",
mProviderName.c_str(), mDevices.size());
mInitialized = true;
return OK;
}
ICameraProvider ,interface->setCallback(this)让framework连上HAL之后。
以上就是framework的四个组件,以及framework和HAL的联系
图片内容来自:Android Camera简单整理(二)-Qcom HAL3 Camx架构学习 - 简书 (jianshu.com)
在CameraService中,主要接口在CameraService.cpp 和 Camera3Device.cpp中
在CameraProvider总, 主要接口在CameraDevice.cpp 和CameraDeviceSession.cpp
在provider中,mDevice->ops即为Camera3.h中的camera3_device_ops结构体
hardware\libhardware\modules\camera\3_0\Camera.cpp
这样就找到Camera hal层的函数指针的映射关系。
映射到vendor\qcom\proprietary\camx\src\core\hal\camxhal3entry.cpp 的g_Camera3DeviceOps
Camx的架构入口为Camx包中的camxhal3entry.cpp(\vendor\qcom\proprietary\camx\src\core\hal\camxhal3entry.cpp)
/// Array containing hw_module_methods_t methods
static hw_module_methods_t g_hwModuleMethods =
{
CamX::open
};
/// Array containing camera3_device_ops_t methods
#if defined (_LINUX)
static camera3_device_ops_t g_camera3DeviceOps =
{
.initialize = CamX::initialize,
.configure_streams = CamX::configure_streams,
.construct_default_request_settings = CamX::construct_default_request_settings,
.process_capture_request = CamX::process_capture_request,
.dump = CamX::dump,
.flush = CamX::flush,
};
#else // _LINUX
static camera3_device_ops_t g_camera3DeviceOps =
{
CamX::initialize,
CamX::configure_streams,
NULL,
CamX::construct_default_request_settings,
CamX::process_capture_request,
NULL,
CamX::dump,
CamX::flush,
NULL,
{0},
};
#endif // _LINUX
/// Array of HwDeviceCloseOps to hold the close method
static HwDeviceCloseOps g_hwDeviceCloseOps =
{
close
};
在camhal3.cpp中,定义了g_jumpTableHAL3
camxchitypes.h定义了CHIAppCallback结构体
camxhal3module.h中定义了 chi_hal_callback_ops_t
camhal3module.cpp 中的构造函数HAL3Module中
CHIHALOverrideEntry funcCHIHALOverrideEntry =
reinterpret_cast(
CamX::OsUtils::LibGetAddr(m_hChiOverrideModuleHandle, "chi_hal_override_entry"));
chxextensioninterface.cpp中函数chi_hal_override_entry
chi这块代码有点生疏了,看个博客快速回忆下。感谢xiaozi63大佬的博客
图片内容来自:深入理解Android相机体系结构之六_u012596975的博客-CSDN博客
//TODO
以上将介绍高通平台的camx架构,后面会对这块补充细节。
参考文档:Android Camera简单整理(二)-Qcom HAL3 Camx架构学习 - 简书 (jianshu.com)
推荐文档:深入理解Android相机体系结构之六_u012596975的博客-CSDN博客