RK Camera HAL3 工作流程简要分析
1. 系统架构概述
Rockchip Camera HAL3 是基于 Android Camera3 API 实现的硬件抽象层,位于 Android 相机框架与底层硬件之间,负责将上层应用的相机请求转换为硬件可执行的命令,并将硬件捕获的图像数据返回给上层。
1.1 核心组件层级结构
┌─────────────────────────────────────────────────────────┐
│ Android 相机框架 │
├─────────────────────────────────────────────────────────┤
│ Camera3 API 接口 │
├─────────────────────────────────────────────────────────┤
│ Camera3HAL 实现 │
│ ┌─────────────────┐ ┌─────────────────┐ ┌───────────┐│
│ │ Camera3HAL │ │ RequestThread │ │ResultProc.││
│ └─────────────────┘ └─────────────────┘ └───────────┘│
├─────────────────────────────────────────────────────────┤
│ ICameraHw 接口 │
├─────────────────────────────────────────────────────────┤
│ PSL 层实现 │
│ ┌─────────────────┐ ┌─────────────────┐ ┌───────────┐│
│ │ ControlUnit │ │ CaptureUnit │ │ ImguUnit ││
│ └─────────────────┘ └─────────────────┘ └───────────┘│
├─────────────────────────────────────────────────────────┤
│ 底层硬件驱动 │
└─────────────────────────────────────────────────────────┘
2. 核心组件详解
2.1 Camera3HAL
作用 :实现 Android 定义的 camera3_device_ops_t API,是 HAL 的入口点。
主要职责:
- 初始化和销毁 HAL 设备实例
- 实现相机设备的核心操作接口
- 管理其他 HAL 组件的生命周期
关键文件 :AAL/Camera3HAL.cpp、AAL/Camera3HAL.h
2.2 RequestThread
作用:处理捕获请求的线程,负责请求的队列管理和调度。
主要职责:
- 接收并处理来自上层的捕获请求
- 管理请求的生命周期
- 协调硬件处理和结果返回
关键文件 :AAL/RequestThread.cpp、AAL/RequestThread.h
2.3 Camera3Request
作用:表示单个相机捕获请求,包含请求的所有信息。
主要职责:
- 封装
camera3_capture_request结构 - 管理请求的输入输出缓冲区
- 处理请求的设置和结果
关键文件 :AAL/Camera3Request.cpp、AAL/Camera3Request.h
2.4 ICameraHw
作用:硬件抽象层接口,定义了与相机硬件交互的标准方法。
主要职责:
- 初始化和配置相机硬件
- 处理捕获请求
- 管理相机流
关键文件 :AAL/ICameraHw.cpp、AAL/ICameraHw.h
2.5 ResultProcessor
作用:处理和返回捕获结果给上层框架。
主要职责:
- 接收硬件处理完成的结果
- 处理和封装结果数据
- 通过回调函数返回结果给上层
关键文件 :AAL/ResultProcessor.cpp、AAL/ResultProcessor.h
3. 详细工作流程
3.1 初始化流程
-
相机模块加载 :Android 系统加载相机 HAL 模块,调用
camera_module_t::get_number_of_cameras获取相机数量。 -
相机设备打开 :上层调用
camera_module_t::open打开相机设备,创建Camera3HAL实例。 -
Camera3HAL 初始化:
cppCamera3HAL::Camera3HAL(int cameraId, const hw_module_t* module) { // 初始化设备结构 mDevice.ops = &hal_dev_ops; mDevice.priv = this; } status_t Camera3HAL::init(void) { // 创建相机硬件实例 mCameraHw = ICameraHw::createCameraHW(mCameraId); // 初始化硬件 mCameraHw->init(); // 创建请求线程 mRequestThread = std::unique_ptr<RequestThread>(new RequestThread(mCameraId, mCameraHw)); } -
设备初始化完成 :返回
camera3_device_t结构给上层。
3.2 流配置流程
-
上层请求流配置 :调用
camera3_device_ops_t::configure_streams配置相机流。 -
Camera3HAL 处理流配置:
cppint Camera3HAL::configure_streams(camera3_stream_configuration_t *stream_list) { // 委托给 RequestThread 处理 return mRequestThread->configureStreams(stream_list); } -
RequestThread 处理流配置:
- 验证流配置参数
- 创建和配置
CameraStream实例 - 调用
ICameraHw::bindStreams绑定流到硬件 - 调用
ICameraHw::configStreams配置硬件流
3.3 请求处理流程
-
上层发送捕获请求 :调用
camera3_device_ops_t::process_capture_request发送捕获请求。 -
Camera3HAL 处理请求:
cppint Camera3HAL::process_capture_request(camera3_capture_request_t *request) { // 委托给 RequestThread 处理 return mRequestThread->process_capture_request(request); } -
RequestThread 处理请求:
- 创建
Camera3Request实例 - 初始化请求设置和缓冲区
- 调用
ICameraHw::preProcessRequest预处理请求 - 调用
ICameraHw::processRequest处理请求
- 创建
-
ICameraHw 处理请求:
- 检查 ISP 模式是否需要更改
- 配置 ISP 和硬件流
- 将请求发送到 AAA 处理器和其他硬件组件
- 启动硬件捕获
3.4 结果返回流程
-
硬件捕获完成:相机硬件完成图像捕获和处理。
-
ICameraHw 返回结果 :调用回调函数通知
ResultProcessor结果可用。 -
ResultProcessor 处理结果:
- 接收硬件处理结果
- 处理图像数据和元数据
- 调用
camera3_callback_ops_t回调函数返回结果给上层
-
上层接收结果:通过回调函数接收捕获结果,包括图像数据和元数据。
3.5 设备关闭流程
-
上层关闭相机设备 :调用
camera3_device_t::common.close关闭相机。 -
Camera3HAL 清理资源:
cppstatus_t Camera3HAL::deinit(void) { // 刷新请求队列 mRequestThread->flush(); // 销毁相机硬件实例 delete mCameraHw; // 清理其他资源 } -
释放所有资源:释放所有相关组件和资源,完成设备关闭。
4. 关键 API 调用链
4.1 初始化调用链
camera_module_t::open →
Camera3HAL::Camera3HAL() →
Camera3HAL::init() →
ICameraHw::createCameraHW() →
ICameraHw::init() →
RequestThread::RequestThread()
4.2 流配置调用链
camera3_device_ops_t::configure_streams →
hal_dev_configure_streams() →
Camera3HAL::configure_streams() →
RequestThread::configureStreams() →
RequestThread::handleConfigureStreams() →
ICameraHw::bindStreams() →
ICameraHw::configStreams()
4.3 请求处理调用链
camera3_device_ops_t::process_capture_request →
hal_dev_process_capture_request() →
Camera3HAL::process_capture_request() →
RequestThread::process_capture_request() →
Camera3Request::init() →
ICameraHw::preProcessRequest() →
ICameraHw::processRequest()
4.4 结果返回调用链
硬件捕获完成 →
ICameraHw 回调 →
ResultProcessor::processResult() →
camera3_callback_ops_t::process_capture_result →
上层接收结果
5. 代码示例解析
5.1 Camera3HAL 初始化示例
cpp
Camera3HAL::Camera3HAL(int cameraId, const hw_module_t* module) :
mCameraId(cameraId),
mCameraHw(nullptr),
mRequestThread(nullptr)
{
// 初始化设备结构
CLEAR(mDevice);
mDevice.common.tag = HARDWARE_DEVICE_TAG;
mDevice.common.version = info.device_version;
mDevice.common.module = (hw_module_t *)(module);
mDevice.ops = &hal_dev_ops;
mDevice.priv = this;
}
status_t Camera3HAL::init(void) {
// 创建相机硬件实例
mCameraHw = ICameraHw::createCameraHW(mCameraId);
// 初始化硬件
status_t status = mCameraHw->init();
if (status != NO_ERROR) {
LOGE("Error initializing Camera HW");
return status;
}
// 创建请求线程
mRequestThread = std::unique_ptr<RequestThread>(new RequestThread(mCameraId, mCameraHw));
return NO_ERROR;
}
5.2 请求处理示例
cpp
status_t RequestThread::handleProcessCaptureRequest(Message & msg) {
// 获取请求数据
camera3_capture_request *req = msg.data.request.req;
// 创建请求实例
Camera3Request* request = mRequestsPool.acquire();
// 初始化请求
status = request->init(req, this, mLastSettings, mCameraId);
// 预处理请求
status = mCameraHw->preProcessRequest(request, mRequestsInHAL);
// 处理请求
status = mCameraHw->processRequest(request, mRequestsInHAL);
return status;
}
6. 性能优化关键点
-
请求队列管理:
- 使用请求池复用
Camera3Request实例,减少内存分配开销 - 实现合理的请求流水线深度,平衡吞吐量和延迟
- 使用请求池复用
-
流管理:
- 优化流绑定策略,减少流切换开销
- 合理配置流缓冲区数量,平衡内存使用和性能
-
回调优化:
- 异步处理结果回调,减少主线程阻塞
- 批量处理相似请求,提高处理效率
7. 常见问题与解决方案
7.1 流配置失败
问题 :configure_streams 返回错误码。
可能原因:
- 流配置参数无效
- 硬件不支持请求的流格式或分辨率
- 流数量超过硬件限制
解决方案:
- 验证流配置参数的有效性
- 检查硬件支持的流格式和分辨率
- 减少流数量或调整流配置
7.2 请求处理超时
问题:请求处理时间超过预期,导致卡顿。
可能原因:
- 硬件处理能力不足
- 请求流水线深度设置不合理
- 内存带宽限制
- sensor输出数据问题
解决方案:
- 优化硬件配置和参数
- 调整请求流水线深度
- 优化内存使用和带宽分配
- 优化sensor的配置序列
7.3 图像质量问题
问题:捕获的图像质量不符合预期。
可能原因:
- ISP 配置不当
- 自动对焦、曝光、白平衡等算法参数不合理
- 图像格式转换问题
解决方案:
- 调整 ISP 配置参数
- 优化 aiq 算法参数
- 检查图像格式转换流程
8. 总结与展望
这里只是简要了解一下RK HAL3的基本流程,后面有机会我们继续学习里面具体的组件是如何工作的。