3. HAL3 关键数据结构:定义、作用与性能影响

Camera HAL3 架构的核心交互围绕一组精确定义的数据结构展开。这些结构不仅是 Framework 与 HAL 之间的通信契约,更是性能优化与 CTS 测试验证的直接操作对象。理解它们的布局、生命周期与约束,是进行 pipeline 调优和问题定位的基础。

3.1 数据结构全景图

下图展示了 HAL3 中四个核心数据结构在 Capture Request 生命周期中的流转关系:

HAL3 核心数据结构关系图 HAL3 核心数据结构流转关系 StreamConfiguration 配置 Camera 数据流拓扑 Stream 单个数据流的抽象描述 Buffer 实际图像数据的内存载体 CameraMetadata 控制参数与结果元数据 关键流转说明: 1. Framework 通过 StreamConfiguration 定义所有 Stream 的拓扑结构(分辨率/格式/方向)。 2. 每个 Stream 描述一条数据通道,包含 Buffer 的分配策略与使用方式。 3. CameraMetadata 携带每一帧的 control(请求)与 result(结果)元数据。 4. Buffer 是实际图像数据的载体,其分配/填充/释放直接影响帧率与延迟。

3.2 StreamConfiguration:数据流拓扑定义

StreamConfiguration 是 HAL3 初始化阶段最重要的结构体,它定义了 Camera 设备所有数据流的整体拓扑。Framework 在 configure_streams() 调用中传入该结构,HAL 据此分配内部资源。

核心字段与作用:

  • streams:camera3_stream_t* 数组,包含所有待配置的 Stream 指针。
  • operation_mode:uint32_t,指定操作模式(如 NORMAL、CONSTRAINED_HIGH_SPEED)。
  • num_streams:uint32_t,streams 数组的长度。
字段 类型 说明 性能影响
streams camera3_stream_t** 指向所有 Stream 的指针数组 Stream 数量与排列顺序影响 HAL 的 pipeline 调度策略
operation_mode uint32_t NORMAL / CONSTRAINED_HIGH_SPEED 等 高速模式需额外预留 ISP 带宽,影响帧率上限
num_streams uint32_t Stream 总数 过多 Stream 会竞争硬件资源,导致延迟增加

CTS 验证要点:CTS 会测试多种 operation_mode 组合,确保 HAL 在切换模式时不会出现资源泄漏或帧率骤降。性能优化中应关注 configure_streams() 的调用耗时,通常应控制在 50ms 以内。

3.3 Stream:单条数据通道的抽象

camera3_stream_t 描述一条独立的数据流通道。每个 Stream 对应一个特定的图像消费者(如 Preview Surface、Video Codec、ImageReader)。

typedef struct camera3_stream {
    int      stream_type;      // CAMERA3_STREAM_OUTPUT / INPUT / BIDIRECTIONAL
    uint32_t width;            // 图像宽度(像素)
    uint32_t height;           // 图像高度(像素)
    int      format;           // 像素格式(HAL_PIXEL_FORMAT_*)
    uint32_t usage;            // 图形缓冲区使用标志(GRALLOC_USAGE_*)
    uint32_t max_buffers;      // HAL 请求的最大 buffer 数
    void    *priv;             // HAL 私有数据指针
    uint32_t rotation;         // 旋转角度(0/90/180/270)
    int      data_space;       // 色彩空间(HAL_DATASPACE_*)
} camera3_stream_t;
字段 关键值示例 性能优化关注点
stream_type OUTPUT / INPUT INPUT 流(如 ZSL)需额外内存拷贝路径
width × height 1920×1080, 640×480 分辨率越高,ISP 处理时间与带宽占用越大
format YCbCr_420_888, RAW10 RAW 格式需额外 demosaic 处理;YUV 格式兼容性最好
usage GRALLOC_USAGE_HW_TEXTURE 错误 usage 会导致 GPU/Display 额外格式转换
max_buffers 3 ~ 8 值过小导致 dequeue 阻塞;过大增加内存压力

常见陷阱:部分 HAL 实现会忽略 rotation 字段,导致预览方向错误。CTS 测试会验证所有旋转角度下的输出正确性。性能优化时,应避免在 HAL 层做旋转操作,交由显示合成器处理。

3.4 CameraMetadata:控制与结果元数据

CameraMetadata 是 HAL3 中传递控制参数和结果信息的核心容器。它使用键值对(tag-value)方式存储,支持静态、动态、控制三类元数据。

CameraMetadata 分类与流转 CameraMetadata 三类元数据 静态元数据 android.sensor.info.* android.lens.info.* 动态元数据 android.sensor.timestamp android.statistics.* 控制元数据 android.control.* android.tonemap.* 元数据流转规则: • 静态元数据:在 camera_info 中返回,整个生命周期不变。 • 控制元数据:Framework 通过 capture_request.settings 下发到 HAL。 • 动态元数据:HAL 在 capture_result.output_metadata 中返回每帧结果。

性能优化关键元数据 Tag:

  • ANDROID_SENSOR_FRAME_DURATION:控制帧间隔,直接影响帧率上限。
  • ANDROID_CONTROL_AE_TARGET_FPS_RANGE:AE 目标帧率范围,影响曝光策略。
  • ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES:热像素校正模式,开启后增加 ISP 负载。
  • ANDROID_TONEMAP_MODE:色调映射模式,FAST 模式可减少 GPU 后处理。

3.5 Buffer:图像数据的内存载体

camera3_stream_buffer_t 是实际图像数据的内存描述结构。它通过 Gralloc 分配图形缓冲区,在 HAL 与消费者之间传递。

typedef struct camera3_stream_buffer {
    camera3_stream_t *stream;   // 所属 Stream
    buffer_handle_t  *buffer;   // Gralloc buffer 句柄
    int              status;    // CAMERA3_BUFFER_STATUS_OK / ERROR
    int              acquire_fence;  // 获取同步 fence fd
    int              release_fence;  // 释放同步 fence fd
} camera3_stream_buffer_t;
字段 作用 性能优化要点
buffer 指向实际图像内存的句柄 使用 GRALLOC_USAGE_HW_VIDEO_ENCODER 可避免编码前额外拷贝
acquire_fence HAL 等待 buffer 可用的同步信号 fence 等待时间过长会导致 pipeline 空转
release_fence HAL 通知消费者 buffer 已填充完成 延迟释放 fence 会阻塞 dequeue 操作
status 标记 buffer 是否有效 ERROR 状态需立即丢弃,避免显示花屏

Buffer 管理最佳实践:

  • 合理设置 max_buffers:预览流通常 3~4 个,视频流 4~6 个,RAW 流 2~3 个。
  • 使用 acquire_fence 实现异步等待,避免 CPU 轮询。
  • 在 HAL 层实现 buffer 池复用,减少 Gralloc 分配/释放开销。

3.6 数据结构间的协同与性能约束

四个数据结构并非独立存在,它们之间的协同关系直接影响整体性能:

  • StreamConfiguration → Stream:配置阶段决定了 Stream 的数量与属性,后续无法动态增减。
  • Stream → Buffer:每个 Stream 关联一个 buffer 队列,队列深度由 max_buffers 控制。
  • CameraMetadata → Buffer:每帧的 control 元数据决定 ISP 如何处理 buffer 中的原始数据。
  • Buffer → CameraMetadata:HAL 在填充 buffer 后,将动态元数据(如 timestamp、AE 状态)附加到 result 中。

CTS 测试高频失败点:

  • configure_streams() 返回后,Stream 的 max_buffers 值被 HAL 修改,但 Framework 未预期到该变化。
  • CameraMetadata 中缺少强制 Tag(如 ANDROID_SENSOR_TIMESTAMP),导致 CTS 测试项失败。
  • Buffer 的 release_fence 未正确关闭,造成文件描述符泄漏。

3.7 小结:数据结构与性能优化的映射关系

数据结构 性能优化切入点 CTS 验证项示例
StreamConfiguration 减少不必要的 Stream 数量;优化 operation_mode 切换延迟 TestConfigureStreams
Stream 选择合适的分辨率与格式;合理设置 max_buffers TestStreamFormatCombination
CameraMetadata 精简 settings 中不必要的 Tag;避免重复设置相同值 TestMetadataConsistency
Buffer 使用 fence 同步;实现 buffer 池复用;减少内存拷贝 TestBufferFenceLeak