2. Stream 基础概念:定义、类型与用途
在 Camera HAL3 架构中,Stream(流)是连接图像传感器、ISP(图像信号处理器)与上层应用消费端之间的核心抽象。一个 Stream 定义了一条从硬件到内存的完整数据通道,包含分辨率、格式、使用方向及最大缓冲数等关键属性。理解 Stream 是掌握复用与性能优化的前提。
核心认知:Stream 不是“帧”,而是“管道”。帧是流经管道的数据单元,而 Stream 描述了管道的规格与行为。
2.1 Stream 的定义
在 HAL3 的 camera3_stream_t 结构体中,Stream 由以下关键字段定义:
| 字段 | 类型 | 说明 |
|---|---|---|
stream_type | camera3_stream_type_t | CAMERA3_STREAM_INPUT / OUTPUT / BIDIRECTIONAL |
width | uint32_t | 图像宽度(像素) |
height | uint32_t | 图像高度(像素) |
format | int | 像素格式,如 HAL_PIXEL_FORMAT_YCbCr_420_888 |
usage | uint32_t | GRALLOC_USAGE_* 标志,定义内存访问模式 |
max_buffers | uint32_t | 该流允许的最大缓冲数(由 HAL 填充) |
data_space | android_dataspace_t | 色彩空间与动态范围 |
rotation | int | 输出旋转角度(0/90/180/270) |
Stream 的配置发生在 configure_streams() 调用中,此时 HAL 会检查所有 Stream 的组合是否合法,并分配硬件管道资源。一旦配置完成,Stream 的规格在会话生命周期内不可变更。
2.2 Stream 类型:Input / Output / Bidirectional
根据数据流动方向,Stream 分为三种类型:
- Output Stream(输出流):数据从 Camera HAL 流向消费者(如 SurfaceView、ImageReader)。这是最常见的类型,用于预览、录制、拍照等。
- Input Stream(输入流):数据从外部源(如 GPU 渲染、另一路 Camera)流入 HAL 进行再处理。典型场景是视频美颜、背景虚化等需要回录处理的用例。
- Bidirectional Stream(双向流):同时支持输入和输出,通常用于零拷贝的再处理场景,如 ZSL(零快门延迟)的输入输出复用。
复用关注点:Output Stream 是复用的主要目标。Input 和 Bidirectional Stream 由于涉及数据回灌,复用约束更严格,通常需要独立的硬件管道。
下表对比三种类型的核心差异:
| 特性 | Output | Input | Bidirectional |
|---|---|---|---|
| 数据方向 | HAL → 消费者 | 外部 → HAL | 双向 |
| 典型用途 | 预览、录像、拍照 | 再处理、美颜 | ZSL、HDR 融合 |
| 复用难度 | 低(可共享管道) | 高(需独立输入路径) | 中(需双工硬件支持) |
| 缓冲所有权 | 消费者释放后 HAL 可重用 | HAL 处理完成后释放 | 按帧交替 |
2.3 Stream 用途:Preview / Record / Snapshot
在 Android Camera 应用中,Stream 的用途决定了其配置参数与性能特征。三种核心用途如下:
2.3.1 Preview Stream(预览流)
- 分辨率:通常匹配屏幕尺寸(如 1080×1920)或更小以节省带宽。
- 帧率:要求稳定 30fps 或 60fps,延迟敏感。
- 格式:多为
HAL_PIXEL_FORMAT_YCbCr_420_888或IMPLEMENTATION_DEFINED。 - 复用价值:预览流是复用策略的核心受益者,多个预览窗口可共享同一硬件输出管道。
2.3.2 Record Stream(录制流)
- 分辨率:视频编码器支持的分辨率(如 4K、1080p)。
- 帧率:与编码器能力匹配(30fps 或 60fps)。
- 格式:通常为
HAL_PIXEL_FORMAT_YCbCr_420_888或HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED。 - 复用约束:录制流对缓冲时序要求严格,复用不当会导致编码器饥饿或丢帧。
2.3.3 Snapshot Stream(拍照流)
- 分辨率:传感器全分辨率(如 12MP、48MP、64MP)。
- 帧率:单帧或连拍,不要求持续高帧率。
- 格式:
HAL_PIXEL_FORMAT_BLOB(JPEG 输出)或HAL_PIXEL_FORMAT_YCbCr_420_888(YUV 输出)。 - 复用挑战:全分辨率拍照流占用大量带宽和内存,复用不当会阻塞预览或录制流。
常见误区:不要将 Preview 和 Record 的 Stream 配置为完全相同的分辨率与格式就认为可以“自动复用”。复用需要 HAL 显式声明支持,且受硬件管道数量限制。
2.4 Stream 用途与配置关系图
下图展示了三种用途 Stream 在 Camera HAL3 管道中的典型配置关系:
2.5 Stream 配置的关键参数对比
下表汇总了三种用途 Stream 在典型配置下的参数差异,帮助理解复用可行性:
| 参数 | Preview | Record | Snapshot |
|---|---|---|---|
| 典型分辨率 | 1920×1080 | 3840×2160 | 4000×3000 |
| 帧率要求 | 30 / 60 fps | 30 / 60 fps | 单帧 / 连拍 |
| 像素格式 | YCbCr_420_888 | YCbCr_420_888 | BLOB (JPEG) |
| 延迟敏感度 | 高(< 33ms) | 中(< 50ms) | 低(可接受 100ms+) |
| 带宽需求 | ~373 MB/s | ~1.49 GB/s | ~720 MB/s(YUV 阶段) |
| 复用优先级 | 高 | 中 | 低(独立管道) |
复用判断准则:当两个 Stream 的
width、height、format 完全一致,且 usage 标志兼容时,HAL 可以尝试将它们映射到同一个硬件输出管道。这是 Stream 复用的基本前提。
2.6 小结
Stream 是 Camera HAL3 中连接硬件与软件的核心抽象。理解其定义、类型(Input/Output/Bidirectional)以及用途(Preview/Record/Snapshot)的差异,是后续学习 Stream 复用策略的基础。在实际项目中,Output Stream 的复用是性能优化的主要战场,而 Preview 与 Record 的兼容性配置是复用成功的关键。