3. Camera HAL 核心数据结构详解
Camera HAL 层是 Android 相机框架中连接 Framework 与硬件驱动的关键桥梁。要构建一个稳定、高性能的相机系统,必须深入理解 HAL 层定义的三大核心数据结构:camera_module_t、camera_device_t 和 camera3_device_t。这三个结构体分别对应 HAL 模块的加载、设备实例的创建以及 Camera 3 架构下的设备操作接口。
camera_module_t 负责发现和枚举相机设备;camera_device_t 是 Camera 2.x 时代的设备抽象;camera3_device_t 则是 Camera 3 架构下所有操作的基础,它直接与 Framework 的 CameraDevice 交互。
3.1 camera_module_t:HAL 模块的入口
camera_module_t 是 Camera HAL 的顶层结构体,定义在 hardware/libhardware/include/hardware/camera_common.h 中。它是 HAL 模块加载时的第一个接触点,负责提供模块的基本信息以及枚举设备的能力。
| 成员变量 | 类型 | 说明 |
|---|---|---|
common |
hw_module_t |
标准 HAL 模块结构体,包含模块 ID、版本、作者等信息。 |
get_number_of_cameras |
函数指针 | 返回系统中可用的相机设备数量。 |
get_camera_info |
函数指针 | 获取指定索引相机的静态信息(camera_info),如朝向、支持的分辨率等。 |
set_callbacks |
函数指针 | 注册 HAL 模块的回调函数,用于通知 Framework 相机热插拔等事件。 |
get_vendor_tag_ops |
函数指针 | 获取厂商自定义 metadata tag 的操作接口。 |
open_legacy |
函数指针 | 以旧版 HAL 接口打开相机设备(用于兼容 Camera 2.x 应用)。 |
set_torch_mode |
函数指针 | 控制闪光灯的手电筒模式。 |
init |
函数指针 | 模块初始化函数,在 HAL 加载时调用。 |
get_camera_info 时,务必返回正确的 facing(前置/后置)和 orientation(旋转角度)。错误的朝向信息会导致预览画面颠倒或应用崩溃。
以下是一个典型的 camera_module_t 实现片段:
static int camera_get_number_of_cameras() {
return 2; // 假设系统有前后两个摄像头
}
static int camera_get_camera_info(int camera_id, struct camera_info *info) {
if (camera_id == 0) {
info->facing = CAMERA_FACING_BACK;
info->orientation = 90;
} else if (camera_id == 1) {
info->facing = CAMERA_FACING_FRONT;
info->orientation = 270;
} else {
return -EINVAL;
}
return 0;
}
struct camera_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = CAMERA_MODULE_API_VERSION_3_0,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = CAMERA_HARDWARE_MODULE_ID,
.name = "My Camera HAL Module",
.author = "Embedded Expert",
.methods = &hal_module_methods,
},
.get_number_of_cameras = camera_get_number_of_cameras,
.get_camera_info = camera_get_camera_info,
.set_callbacks = camera_set_callbacks,
.get_vendor_tag_ops = camera_get_vendor_tag_ops,
.open_legacy = NULL,
.set_torch_mode = camera_set_torch_mode,
.init = camera_init,
};
3.2 camera_device_t:Camera 2.x 的设备抽象
camera_device_t 是 Camera 2.x HAL 架构下的核心设备结构体。它代表一个具体的相机设备实例,包含设备描述符和一系列操作函数指针。虽然 Camera 3 架构已经取代了它,但在 open_legacy 接口中仍然需要实现它来兼容旧版应用。
| 成员变量 | 类型 | 说明 |
|---|---|---|
common |
hw_device_t |
标准 HAL 设备结构体,包含设备打开/关闭等通用操作。 |
ops |
camera_device_ops_t* |
指向 Camera 2.x 操作函数表的指针,包含预览、拍照、参数设置等接口。 |
priv |
void* |
私有数据指针,用于存储 HAL 实现层的设备上下文。 |
camera_device_ops_t 操作函数表包含以下关键接口:
- set_preview_window:设置预览窗口的
ANativeWindow,用于显示预览画面。 - start_preview / stop_preview:启动/停止预览流。
- take_picture:触发拍照,返回 JPEG 或原始图像数据。
- set_parameters / get_parameters:设置/获取相机参数(如分辨率、帧率、对焦模式等)。
- auto_focus:触发自动对焦。
- cancel_auto_focus:取消自动对焦。
camera_device_t 不应再作为主设备接口使用。如果系统同时支持 Camera 2.x 和 Camera 3,必须在 open_legacy 中正确实现 camera_device_t,否则旧版应用将无法打开相机。
3.3 camera3_device_t:Camera 3 架构的核心
camera3_device_t 是 Camera 3 HAL 架构中最重要的数据结构,定义在 hardware/libhardware/include/hardware/camera3.h 中。它完全取代了 camera_device_t,采用全新的 pipeline 模型,支持更灵活的流配置和更高的性能。
| 成员变量 | 类型 | 说明 |
|---|---|---|
common |
hw_device_t |
标准 HAL 设备结构体,与 camera_device_t 共用。 |
ops |
camera3_device_ops_t* |
指向 Camera 3 操作函数表的指针,包含流配置、请求提交、结果回调等接口。 |
priv |
void* |
私有数据指针,用于存储 Camera 3 设备上下文。 |
camera3_device_ops_t 是 Camera 3 架构的灵魂,它定义了以下关键操作:
- initialize:初始化设备,传入 Framework 的回调接口(
camera3_callback_ops_t)。 - configure_streams:配置相机数据流(预览流、拍照流、视频流等),这是 Camera 3 的核心能力。
- register_stream_buffers:注册流缓冲区(在 HAL3.2 之后已废弃,由 Framework 直接管理)。
- process_capture_request:提交一个捕获请求,HAL 处理完成后通过回调返回结果。
- flush:刷新所有正在处理的请求,用于快速停止相机。
- dump:导出设备调试信息。
process_capture_request 提交请求,HAL 异步处理完成后通过 process_capture_result 回调返回结果。这种模型支持多路流并发,性能更高。
// camera3_device_ops_t 核心接口定义
typedef struct camera3_device_ops {
int (*initialize)(const struct camera3_device *,
const camera3_callback_ops_t *callback_ops);
int (*configure_streams)(const struct camera3_device *,
camera3_stream_configuration_t *stream_list);
int (*register_stream_buffers)(const struct camera3_device *,
const camera3_stream_buffer_set_t *buffer_set);
int (*process_capture_request)(const struct camera3_device *,
camera3_capture_request_t *request);
void (*flush)(const struct camera3_device *);
void (*dump)(const struct camera3_device *, int fd);
} camera3_device_ops_t;
3.4 三大结构体对比总结
为了帮助你在实际项目中快速区分和使用这三个结构体,下表总结了它们的核心差异:
| 特性 | camera_module_t | camera_device_t | camera3_device_t |
|---|---|---|---|
| 层级 | 模块层(全局唯一) | 设备层(每个相机一个) | 设备层(每个相机一个) |
| 适用架构 | Camera 2.x / 3 | Camera 2.x | Camera 3 |
| 主要职责 | 枚举设备、加载 HAL | 预览、拍照、参数设置 | 流配置、请求处理、结果回调 |
| 数据模型 | 同步查询 | 同步/异步混合 | 纯异步请求-结果 |
| 关键函数 | get_camera_info |
start_preview |
process_capture_request |
| 兼容性 | 所有版本必须实现 | 仅用于 legacy 兼容 | Camera 3 必须实现 |
camera3_device_t 及其 camera3_device_ops_t。如果遇到旧版应用兼容性问题,再通过 open_legacy 接口补充 camera_device_t 的实现。这样可以保证系统性能最优,同时兼顾兼容性。