4. Camera设备枚举与静态信息:static_camera_metadata的构建与关键Tag配置
在Camera HAL平台移植过程中,设备枚举与静态元数据(static_camera_metadata)的正确构建是上层Framework发现摄像头能力的基础。本章聚焦于HAL层如何向系统报告摄像头设备、如何填充static_camera_metadata,以及android.control.availableCapabilities等关键Tag的配置要点。
核心原则: static_camera_metadata 必须在 HAL 的
getCameraCharacteristics() 调用中一次性完整返回,且所有声明的能力必须与底层硬件实际支持一致。任何不一致都会导致相机应用崩溃或功能异常。
4.1 设备枚举流程与HAL接口
Android Camera HAL3 通过 camera_module_t 结构体中的 get_number_of_cameras() 和 get_camera_info() 完成设备枚举。平台移植时,必须确保这两个接口返回正确的摄像头数量和ID。
// HAL 模块定义示例
static 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",
.author = "Platform Vendor",
.methods = &hal_module_methods,
},
.get_number_of_cameras = hal_get_number_of_cameras,
.get_camera_info = hal_get_camera_info,
.set_callbacks = hal_set_callbacks,
.get_vendor_tag_ops = NULL,
.open_legacy = NULL,
.set_torch_mode = hal_set_torch_mode,
.init = NULL,
.reserved = {0},
};
排查要点: 如果系统只检测到部分摄像头,优先检查
get_number_of_cameras() 返回值是否与硬件实际数量一致,以及 get_camera_info() 中 device_version 是否设置为 HARDWARE_DEVICE_API_VERSION(2, 0) 或更高。
4.2 static_camera_metadata 的构建策略
static_camera_metadata 是描述摄像头固定能力的只读数据块,在 HAL 的 getCameraCharacteristics() 中构建并返回。构建方式通常有两种:
| 构建方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 完全静态定义 | 硬件能力固定、无需运行时判断 | 性能最优,无运行时开销 | 灵活性差,硬件变更需重新编译 |
| 运行时动态构建 | 多平台、多SKU、硬件能力可配置 | 灵活适配不同硬件变体 | 增加启动延迟,需谨慎管理内存 |
| 混合模式 | 大部分固定 + 少量运行时调整 | 兼顾性能与灵活性 | 代码结构复杂,需维护两套逻辑 |
以下是一个使用 android::CameraMetadata 工具类动态构建的代码片段:
// 在 getCameraCharacteristics() 中构建 static metadata
status_t getCameraCharacteristics(int32_t cameraId,
camera_metadata_t **characteristics) {
android::CameraMetadata metadata;
// 1. 设置基本信息
uint8_t facing = ANDROID_LENS_FACING_BACK;
metadata.update(ANDROID_LENS_FACING, &facing, 1);
// 2. 设置可用能力
std::vector<uint8_t> capabilities = {
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR,
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW,
};
metadata.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
capabilities.data(), capabilities.size());
// 3. 设置输出流配置
std::vector<int32_t> formats = {
HAL_PIXEL_FORMAT_YCbCr_420_888,
HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
HAL_PIXEL_FORMAT_BLOB,
};
metadata.update(ANDROID_SCALER_AVAILABLE_FORMATS,
formats.data(), formats.size());
// 4. 设置传感器信息
android::Rect sensorInfoActiveArraySize = {0, 0, 1920, 1080};
metadata.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
&sensorInfoActiveArraySize, 1);
*characteristics = metadata.release();
return OK;
}
4.3 android.control.availableCapabilities 关键Tag详解
android.control.availableCapabilities 是 Framework 判断摄像头高级功能支持的核心依据。该Tag是一个枚举数组,每个枚举值代表一种能力。平台移植时,必须根据硬件实际能力精确声明。
常见陷阱: 声明了
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR 但未正确实现曝光时间、感光度等控制接口,会导致三方相机应用设置手动参数时无响应或崩溃。
| 能力枚举值 | 含义 | 硬件依赖 | 常见问题 |
|---|---|---|---|
| BACKWARD_COMPATIBLE | 基础兼容能力(必须包含) | 所有摄像头 | 缺失会导致相机服务无法启动 |
| MANUAL_SENSOR | 手动传感器控制(曝光、ISO等) | 支持手动曝光的传感器 | 声明后未实现对应控制Tag |
| MANUAL_POST_PROCESSING | 手动后处理(色调、对比度等) | ISP支持后处理参数调节 | 与3A算法冲突导致画面异常 |
| RAW | 输出RAW格式数据 | 传感器支持RAW输出 | RAW尺寸与ActiveArraySize不匹配 |
| PRIVATE_REPROCESSING | 私有重处理(美颜、滤镜等) | ISP支持重处理管线 | 未实现 reprocess 接口 |
| READ_SENSOR_SETTINGS | 读取传感器实时设置 | 传感器支持寄存器读取 | 返回数据与硬件状态不同步 |
| BURST_CAPTURE | 连拍能力 | ISP/驱动支持快速捕获 | 连拍帧率低于预期 |
| CONSTRAINED_HIGH_SPEED_VIDEO | 高速视频(慢动作) | 传感器支持高帧率模式 | 未配置对应的FPS范围 |
4.4 关键Tag配置清单与依赖关系
除了 availableCapabilities,以下Tag在平台移植中极易出错,需要重点检查:
- ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE:传感器有效像素阵列尺寸,必须与硬件实际分辨率一致。
- ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE:有效成像区域,通常小于等于像素阵列尺寸。
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS:支持的输出流配置(分辨率+格式),必须覆盖所有应用场景。
- ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:各分辨率下的最小帧时长,直接影响帧率表现。
- ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES:自动曝光支持的FPS范围,与高速视频能力关联。
- ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES:人脸检测模式,需与ISP能力匹配。
依赖关系示例: 如果声明了
CONSTRAINED_HIGH_SPEED_VIDEO 能力,则必须同时配置 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES 包含高帧率范围(如 [240, 240]),并且 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS 中对应分辨率的最小帧时长必须支持该帧率。
4.5 设备枚举与元数据构建流程图
以下SVG图展示了从HAL设备枚举到static_metadata返回的完整流程:
4.6 平台移植常见兼容性问题排查
在平台移植过程中,以下问题出现频率最高,建议作为排查清单:
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 相机应用无法启动 | BACKWARD_COMPATIBLE 能力缺失 | dumpsys media.camera 查看能力列表 | 确保该能力始终包含在数组中 |
| 预览黑屏但可拍照 | 预览流配置与硬件实际支持不匹配 | 检查 logcat 中 StreamConfiguration 错误 | 修正 SCALER_AVAILABLE_STREAM_CONFIGURATIONS |
| 手动模式参数无效 | MANUAL_SENSOR 能力声明但未实现控制 | 检查 SENSOR_EXPOSURE_TIME 等Tag是否被处理 | 实现对应的 request/result 处理逻辑 |
| RAW拍照返回空数据 | RAW尺寸与 ACTIVE_ARRAY_SIZE 不一致 | 对比两个Tag的尺寸值 | 确保 RAW 输出尺寸在有效阵列范围内 |
| 连拍帧率低 | BURST_CAPTURE 能力声明但未优化驱动 | 测量实际帧间隔时间 | 优化驱动中断处理或增加buffer数量 |
| 高速视频无法选择 | CONSTRAINED_HIGH_SPEED_VIDEO 缺少FPS范围 | 检查 AE_AVAILABLE_TARGET_FPS_RANGES | 添加对应的高帧率范围配置 |
调试利器: 使用
adb shell dumpsys media.camera 可以查看当前系统识别的摄像头信息、能力列表和所有静态元数据。对比实际硬件规格书,逐项核对关键Tag的值是否正确。
4.7 静态元数据验证工具与自动化测试
为减少人工排查的工作量,建议在平台移植阶段引入自动化验证工具:
- CTS Verifier Camera Test:Android 兼容性测试套件中的相机测试,可验证静态元数据的完整性和一致性。
- CameraMetadataValidator:开源工具,可对比实际硬件能力与声明的元数据是否匹配。
- 自定义 dump 脚本:通过
camera_metadata_t的 dump 接口输出所有Tag,与基线配置进行 diff 对比。
// 使用 CameraMetadata 的 dump 方法输出所有Tag
void dumpCameraMetadata(const camera_metadata_t *metadata) {
size_t entryCount = get_camera_metadata_entry_count(metadata);
for (size_t i = 0; i < entryCount; i++) {
camera_metadata_entry_t entry;
if (get_camera_metadata_entry(metadata, i, &entry) == 0) {
// 打印Tag ID和值
ALOGI("Tag 0x%x: type=%d, count=%zu",
entry.tag, entry.type, entry.count);
}
}
}
重要提醒: 切勿在生产环境中使用未经验证的 static_metadata 配置。一个错误的 Tag 值可能导致整个相机子系统无法正常工作,甚至引发系统级稳定性问题。建议在每次修改后运行完整的 CTS 相机测试用例。