1. HAL3 Buffer 概述

在 Camera HAL3 架构中,Buffer 是贯穿图像数据采集、处理、传递与消费的核心载体。理解 Buffer 的角色、数据流路径与生命周期,是进行内存优化管理的前提。本章从这三个维度展开,为后续的优化策略奠定基础。

1.1 Buffer 在 Camera HAL3 中的角色

Buffer 在 HAL3 中承担以下关键角色:

  • 数据容器:承载从 Sensor 输出的原始图像数据(RAW/YUV/JPEG/HEIC)。
  • 生产者-消费者模型:HAL 作为生产者填充数据,Framework(如 CameraService、SurfaceFlinger)作为消费者读取或显示数据。
  • 内存共享单元:通过 GraphicBuffer / NativeHandle 实现跨进程(HAL ↔ Framework)零拷贝共享。
  • 流控制令牌:Buffer 的分配与回收节奏直接影响预览/录像的帧率与延迟。
关键概念: HAL3 中 Buffer 的分配由 camera3_stream_t 描述,每个 Stream 对应一组 Buffer 队列。Buffer 的格式、尺寸、使用标记(如 GRALLOC_USAGE_HW_CAMERA_WRITE)在 Stream 配置阶段确定。

1.2 Buffer 数据流路径

Buffer 在 HAL3 中的典型数据流路径如下图所示,涵盖从 Sensor 到最终消费端的完整链路:

HAL3 Buffer 数据流路径 HAL3 Buffer 数据流路径 Sensor ISP / 硬件 HAL 处理管线 Gralloc Buffer SurfaceFlinger MediaCodec ImageReader 说明: • Sensor 输出 RAW 数据 → ISP 做初步处理(Bayer/去噪)→ HAL 管线执行 3A、TNR、HDR 等算法。 • 最终图像数据写入 Gralloc Buffer,通过 BufferQueue 传递给 Framework 侧消费者。

数据流路径的关键阶段:

阶段 描述 Buffer 状态
1. 分配 Framework 通过 configure_streams() 确定 Stream 参数,HAL 分配 Buffer 池。 空闲(Free)
2. 请求 Framework 下发 capture_request,指定待填充的 Buffer 句柄。 已排队(Queued)
3. 填充 HAL 驱动 Sensor 曝光、ISP 处理,将图像数据写入 Buffer。 正在使用(In Use)
4. 返回 HAL 通过 process_capture_result() 将 Buffer 返回给 Framework。 已填充(Filled)
5. 消费 Framework 将 Buffer 送显、编码或保存,完成后释放回 Buffer 池。 已释放(Released)

1.3 Buffer 生命周期

Buffer 在 HAL3 中的完整生命周期包含以下状态转换:

Buffer 生命周期状态机 Buffer 生命周期状态机 空闲 (Free) 已排队 (Queued) 正在使用 (In Use) 已填充 (Filled) 已释放 (Released) request process result consume recycle / return to pool • 虚线表示 Buffer 被释放后重新回到空闲池,等待下一次请求。整个周期中 Buffer 物理内存不释放,仅状态变更。
优化要点: Buffer 生命周期中,“已排队 → 正在使用” 阶段是内存占用的高峰期。如果 HAL 处理延迟过长,会导致 Buffer 堆积,触发 dequeueBuffer 阻塞或丢帧。优化目标之一是缩短 Buffer 在 HAL 内部的驻留时间。

1.4 Buffer 管理的关键数据结构

HAL3 中 Buffer 管理涉及以下核心数据结构:

数据结构 所属模块 作用
camera3_stream_t Framework ↔ HAL 描述 Stream 的格式、尺寸、方向、使用标记等配置信息。
camera3_stream_buffer_t Framework ↔ HAL 单个 Buffer 的句柄、状态、时间戳等元数据。
buffer_handle_t Gralloc 底层图形 Buffer 的句柄,包含共享内存的 fd 和偏移量。
CaptureRequest Framework 包含待填充的 camera3_stream_buffer_t 数组及 3A 参数。
CaptureResult HAL → Framework 包含已填充的 Buffer 及结果元数据(如 AE/AWB 状态)。

1.5 Buffer 分配策略概览

HAL3 中 Buffer 的分配策略直接影响内存占用与性能:

  • 预分配(Pre-allocation):在 configure_streams() 时一次性分配固定数量的 Buffer,减少运行时分配开销。
  • 按需分配(On-demand):根据请求动态分配 Buffer,灵活性高但可能引入延迟。
  • Buffer 池化(Pooling):维护一个 Buffer 池,请求时从池中取出,使用后归还,避免频繁分配/释放。
  • 延迟分配(Deferred Allocation):仅在 Buffer 真正被写入前才分配物理内存,减少空闲 Buffer 的内存占用。
常见陷阱: 预分配数量过多会导致内存浪费(尤其在高分辨率场景下),过少则可能因 Buffer 不足导致 dequeueBuffer 超时。通常建议预览流分配 3~5 个 Buffer,录像流分配 4~6 个 Buffer,具体需结合帧率与延迟要求调整。

1.6 本章小结