4. Camera HAL 初始化流程:核心结构与静态信息填充
Camera HAL 的初始化是上层框架与底层硬件驱动建立通信的第一道关卡。本章深入剖析初始化阶段最核心的三个要素:camera_module_t 结构体、get_number_of_cameras() 的实现逻辑,以及 get_camera_info() 如何填充静态信息。理解这一流程,是后续进行 Stream 配置和 Camera 管道控制的基础。
4.1 camera_module_t:HAL 模块的“身份证”
camera_module_t 是 Android Camera HAL 中定义的标准模块结构体,它继承自 hw_module_t,是上层框架通过 hw_get_module() 加载 HAL 库后获取的第一个对象。该结构体不仅标识了 HAL 的版本和作者,更重要的是提供了两个关键的初始化接口指针。
| 成员 | 类型 | 说明 |
|---|---|---|
common |
hw_module_t |
标准硬件模块结构体,包含 tag、module_api_version、hal_api_version、name、author、methods 等基础字段。 |
get_number_of_cameras |
函数指针 | 返回设备上可用的 Camera 数量,是框架了解硬件拓扑的第一步。 |
get_camera_info |
函数指针 | 填充 camera_info 结构体,提供指定 Camera 的静态能力信息。 |
set_callbacks |
函数指针 | (可选)注册框架回调,用于通知 HAL 模块状态变化。 |
get_vendor_tag_ops |
函数指针 | (可选)提供厂商自定义 metadata tag 的操作接口。 |
open_legacy |
函数指针 | (可选)打开旧版本 HAL 接口,用于兼容性场景。 |
set_torch_mode |
函数指针 | (可选)控制闪光灯手电筒模式。 |
init |
函数指针 | (可选)HAL 模块级初始化,在 hw_get_module 之后调用。 |
get_number_of_cameras 和 get_camera_info 是每个 Camera HAL 必须实现的两个接口,它们是框架获取设备能力信息的唯二入口。
4.2 get_number_of_cameras():探测 Camera 数量
该接口的实现通常非常直接,其核心任务是返回一个非负整数,代表系统中可用的 Camera 设备数量。这个数字决定了后续框架会调用多少次 get_camera_info()。
典型的实现方式包括:
- 静态定义: 在 HAL 模块的
.cpp文件中直接定义一个常量,例如#define CAMERA_DEVICE_NUM 2,适用于硬件拓扑固定的嵌入式设备。 - 动态扫描: 遍历
/dev/video*节点或读取设备树(Device Tree)信息,动态统计可用的 Camera 设备数量,适用于模块化或可插拔 Camera 方案。 - 配置文件驱动: 从
.cfg或.xml配置文件中读取 Camera 列表,增加灵活性。
// 示例:基于静态定义的 get_number_of_cameras 实现
#include <hardware/camera_common.h>
#define BACK_CAMERA_ID 0
#define FRONT_CAMERA_ID 1
#define CAMERA_DEVICE_NUM 2
static int camera_device_open(const struct hw_module_t* module,
const char* id,
struct hw_device_t** device);
static int get_number_of_cameras(void) {
// 对于固定硬件平台,直接返回常量
ALOGI("get_number_of_cameras: returning %d", CAMERA_DEVICE_NUM);
return CAMERA_DEVICE_NUM;
}
static struct hw_module_methods_t camera_module_methods = {
.open = camera_device_open
};
camera_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = CAMERA_MODULE_API_VERSION_2_4,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = CAMERA_HARDWARE_MODULE_ID,
.name = "Example Camera HAL Module",
.author = "Embedded System Team",
.methods = &camera_module_methods,
},
.get_number_of_cameras = get_number_of_cameras,
.get_camera_info = get_camera_info,
.set_callbacks = NULL,
.get_vendor_tag_ops = NULL,
.open_legacy = NULL,
.set_torch_mode = NULL,
.init = NULL,
};
get_number_of_cameras() 中添加日志输出,便于在调试初期快速确认 HAL 模块是否被正确加载以及 Camera 数量是否与预期一致。
4.3 get_camera_info():填充静态信息
get_camera_info() 负责填充 camera_info 结构体,该结构体包含了 Camera 设备的静态属性,这些属性在设备生命周期内不会改变。框架通过此接口了解每个 Camera 的朝向、安装位置、是否支持闪光灯等基本信息。
camera_info 结构体定义如下:
typedef struct camera_info {
int device_version; // HAL 设备版本号
uint32_t static_camera_characteristics_size; // metadata 大小
camera_metadata_t* static_camera_characteristics; // 静态 metadata 指针
int resource_cost; // 资源开销(0-100)
int conflicting_devices_length; // 冲突设备数量
char** conflicting_devices; // 冲突设备 ID 列表
} camera_info_t;
填充 static_camera_characteristics 是 get_camera_info() 中最复杂、最核心的部分。它需要构建一个包含大量 Camera 能力信息的 metadata 包,例如:
- 基础信息:
ANDROID_LENS_FACING(前置/后置/外接)、ANDROID_SENSOR_ORIENTATION(图像方向)。 - 分辨率支持:
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS(支持的输出格式和尺寸列表)。 - 帧率范围:
ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES。 - 硬件能力:
ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL(LIMITED / FULL / LEVEL_3)。 - 同步能力:
ANDROID_SYNC_MAX_LATENCY。
static_camera_characteristics 的构建必须严格遵循 Android CDD(兼容性定义文档)的要求。遗漏关键 tag 或填充错误的值,可能导致 Camera 服务无法正常启动或上层应用崩溃。建议使用 camera_metadata 库提供的 API(如 allocate_camera_metadata()、add_camera_metadata_entry())进行构建,避免手动操作内存。
4.4 初始化流程全景图
下面的 SVG 图展示了从框架加载 HAL 模块到获取所有 Camera 静态信息的完整流程。
4.5 静态信息填充的关键字段对比
在 get_camera_info() 中,static_camera_characteristics 的构建质量直接决定了上层应用的能力。以下表格对比了三个关键字段的典型值及其影响:
| Metadata Tag | 典型值 | 对上层的影响 |
|---|---|---|
ANDROID_LENS_FACING |
LENS_FACING_BACK / LENS_FACING_FRONT |
决定 Camera 应用默认打开前置还是后置 Camera;影响 UI 镜像逻辑。 |
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS |
例如:{HAL_PIXEL_FORMAT_YCbCr_420_888, 1920, 1080, ...} |
限制应用可以请求的预览/拍照/录像分辨率;配置错误会导致 Stream 创建失败。 |
ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL |
INFO_SUPPORTED_HARDWARE_LEVEL_FULL |
定义 Camera 设备的能力等级(LIMITED/FULL/LEVEL_3);影响是否支持 RAW、YUV reprocessing 等高级功能。 |
get_camera_info() 的成功执行标志着 HAL 初始化阶段的完成。此时,框架已经掌握了所有 Camera 设备的静态能力,为后续的 open() 调用和 Stream 配置做好了准备。任何静态信息的错误或遗漏,都会在后续的配置阶段暴露出来,导致难以调试的问题。