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返回的完整流程:

Camera设备枚举与static_metadata构建流程 Camera设备枚举与static_metadata构建流程 CameraService get_number_of_cameras() 返回摄像头数量 N 循环 i = 0 到 N-1 getCameraCharacteristics(i) 构建 static_camera_metadata 填充 availableCapabilities 等Tag 返回 metadata 给 Framework 关键检查点 availableCapabilities 必须与硬件一致

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 相机测试用例。