4. Stream配置:configure_streams()接口详解、Stream类型与格式、Stream配置策略

configure_streams() 是 Camera HAL3 接口中承上启下的核心调用点。它在 Camera 打开之后、首次 request 提交之前被调用,用于协商并确立 Camera 硬件与框架之间的数据通道(Stream)集合。本章将深入剖析该接口的调用契约、Stream 类型与格式体系,以及实际集成中必须遵循的配置策略。

4.1 configure_streams() 接口详解

该接口由 Camera 框架发起,HAL 端负责解析配置并返回最终确认的 Stream 参数。其函数原型如下:

int (*configure_streams)(
    const struct camera3_device *device,
    camera3_stream_configuration_t *stream_list
);

参数 stream_list 包含以下关键字段:

字段 类型 说明
num_streams uint32_t 请求配置的 Stream 数量,至少为 1
streams camera3_stream_t ** 指向 Stream 指针数组,每个元素描述一条数据流
operation_mode uint32_t 操作模式,如 NORMAL / CONSTRAINED_HIGH_SPEED

HAL 实现必须在此函数中完成以下工作:

  1. 校验 Stream 组合:检查框架请求的 Stream 集合在当前硬件能力下是否可行。
  2. 分配内部资源:为每个 Stream 分配 buffer queue、ISP 管线资源、内存池等。
  3. 回填 Stream 参数:修改 camera3_stream_t 中的 usage、max_buffers、priv 等字段,告知框架最终配置。
  4. 返回状态码:成功返回 0,失败返回负值(如 -EINVAL、-ENODEV)。
关键约束: 一旦 configure_streams() 返回成功,HAL 必须保证后续所有 request 都能按此配置输出数据。框架不会在未调用 flush() 的情况下重复调用此接口。

4.2 Stream 类型与格式体系

每个 camera3_stream_t 通过 stream_type 和 format 字段定义数据流的性质。下表列出 HAL3 中定义的三种 Stream 类型:

Stream 类型 枚举值 典型用途 方向
CAMERA3_STREAM_OUTPUT 0 预览、拍照、视频编码输出 HAL → 框架
CAMERA3_STREAM_INPUT 1 YUV 重处理输入(如美颜后处理) 框架 → HAL
CAMERA3_STREAM_BIDIRECTIONAL 2 双向流(极少使用,用于特定 SoC 私有通路) 双向

格式方面,HAL3 强制要求支持以下核心格式:

  • HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED(0x22):由 HAL 自主选择最优格式,通常对应硬件原生格式。
  • HAL_PIXEL_FORMAT_YCbCr_420_888(0x23):标准 YUV420 灵活格式,用于第三方应用或算法库。
  • HAL_PIXEL_FORMAT_BLOB(0x21):JPEG 编码输出专用格式。
  • HAL_PIXEL_FORMAT_RAW16(0x20):RAW 数据输出,用于专业拍照模式。
集成建议: 对于预览和视频流,优先使用 IMPLEMENTATION_DEFINED 格式,让 HAL 选择最直接的硬件通路,减少格式转换开销。仅当应用明确要求 YUV 或 RAW 时,才暴露具体格式。

4.3 Stream 配置策略

实际集成中,HAL 需要根据硬件能力和使用场景制定配置策略。以下是最常见的三种策略模式:

  1. 最小资源策略:当 num_streams 较小时(如仅预览),HAL 应关闭不用的 ISP 管线模块以降低功耗。
  2. 最大复用策略:当存在多个同尺寸、同格式的 OUTPUT Stream 时,HAL 应尝试复用同一物理管线,通过内部 splitter 分发数据。
  3. 降级协商策略:若框架请求的 Stream 组合超出硬件能力(如同时请求 4K 预览 + 4K 视频 + RAW),HAL 应返回错误或通过修改 usage 字段提示框架调整。

以下 SVG 图展示了从框架发起配置到 HAL 确认的完整流程:

configure_streams() 调用流程 Camera 框架 构建 stream_configuration_t HAL configure_streams() 校验 Stream 组合 分配 ISP 管线 / Buffer 池 成功? 是 返回 0 否 返回负值

4.4 配置策略实战要点

在集成过程中,以下要点直接影响配置的成功率与性能:

  • usage 字段回填:HAL 必须根据硬件特性修改 usage 位掩码,告知框架 buffer 的预期使用方式(如 GRALLOC_USAGE_HW_TEXTURE、GRALLOC_USAGE_HW_VIDEO_ENCODER)。
  • max_buffers 计算:该值表示 HAL 需要同时持有的 buffer 数量。过小会导致 dequeue 阻塞,过大会浪费内存。通常预览设为 3~4,视频设为 6~8。
  • Stream 尺寸对齐:HAL 应检查 width/height 是否满足硬件对齐要求(如 16 像素对齐),若不满足应返回错误或向上取整。
  • 操作模式适配:当 operation_mode 为 CONSTRAINED_HIGH_SPEED 时,HAL 必须限制 Stream 数量不超过 2 个,且格式必须为 IMPLEMENTATION_DEFINED。
案例: 某平台集成时,框架请求 3 个 Stream(预览 1080p、视频 4K、拍照 JPEG)。HAL 检测到 ISP 仅支持 2 条独立输出管线,于是将预览和视频合并为同一物理管线,通过 scaler 输出不同分辨率,成功返回 0。若无法合并,则返回 -EINVAL 并打印错误日志。

4.5 Stream 配置的常见错误码

错误码 值 含义 典型场景
-EINVAL -22 无效参数 Stream 组合不支持、格式错误、尺寸未对齐
-ENODEV -19 设备不可用 Camera 硬件异常或电源未就绪
-ENOMEM -12 内存不足 无法分配 buffer 池或 ISP 内部内存
-EACCES -13 权限不足 安全摄像头模式下非法配置

以下 SVG 图展示了一个典型的 Stream 配置拓扑,包含预览、视频和拍照三条流在 HAL 内部的映射关系:

典型 Stream 配置拓扑(预览 + 视频 + 拍照) 框架 Stream 请求 预览 1080p 视频 4K 拍照 JPEG HAL 配置管理器 ISP 管线映射 管线0: 预览 + 视频 (复用) | 管线1: 拍照 配置策略说明 • 预览与视频同尺寸时复用管线 • 拍照流独立占用 JPEG 编码器 • max_buffers 按流类型分别计算

通过以上接口详解、类型格式分析和配置策略的梳理,开发者可以在集成 configure_streams() 时做到逻辑清晰、错误处理完备,从而为后续的 request 处理阶段打下坚实基础。