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 到最终消费端的完整链路:
数据流路径的关键阶段:
| 阶段 | 描述 | 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 生命周期中,“已排队 → 正在使用” 阶段是内存占用的高峰期。如果 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,具体需结合帧率与延迟要求调整。