3. Stream概念解析:定义、类型与生命周期

在Camera HAL层中,Stream(数据流)是连接图像传感器与上层应用的核心抽象。一次成功的相机预览或拍照,本质上是HAL层正确配置并持续维护一组Stream的过程。Stream配置失败,直接导致黑屏、无数据回调或应用ANR。

3.1 Stream的定义

Stream是Android Camera框架中描述图像数据生产者与消费者之间单向数据通道的接口。每个Stream包含以下关键属性:

属性 说明 典型值
Stream ID HAL层分配的唯一标识符 0, 1, 2 …
Width / Height 图像分辨率(像素) 1920x1080, 640x480
Format 像素格式 NV12, YUV420, JPEG, RAW10
Usage 消费者使用标志(Gralloc) GRALLOC_USAGE_HW_TEXTURE
Rotation 输出旋转角度 0, 90, 180, 270
Data Space 色彩空间与动态范围 HAL_DATASPACE_STANDARD_BT709
关键理解: Stream不是物理缓冲区,而是描述“谁生产、谁消费、什么格式、多大尺寸”的配置契约。HAL层根据Stream配置分配硬件资源(ISP管线、DMA通道、内存池)。

3.2 Stream的类型

根据图像数据的最终用途,Android Camera框架定义了三种核心Stream类型。每种类型对应不同的硬件处理路径和性能要求。

类型 用途 典型Format 帧率要求 Buffer数量
Preview 取景器显示 NV12 / YUV420 30 fps 3~4
Still Capture 拍照输出 JPEG / RAW10 单帧 1~2
Video Record 视频编码输入 NV12 / YUV420 30/60 fps 4~8
  • Preview Stream: 持续输出低延迟帧,通常经过GPU合成后显示到SurfaceView/TextureView。黑屏问题最常见于Preview Stream配置失败。
  • Still Capture Stream: 单次触发,输出高分辨率静止图像。HAL层需要切换ISP参数(降噪、锐化)并完成JPEG编码。
  • Video Record Stream: 持续输出给MediaCodec编码器,对帧间隔稳定性要求高,Buffer队列深度较大。
排故提示: 当应用同时请求Preview + Capture + Video三个Stream时,HAL层必须确保ISP带宽、内存带宽和MIPI CSI带宽三者同时满足。任何一个Stream的配置参数超出硬件能力,都会导致configure_streams()返回错误,进而黑屏。

3.3 Stream的生命周期

Stream从创建到销毁经历四个阶段。理解每个阶段的状态转换,是定位配置失败黑屏的关键。

Stream生命周期状态机 IDLE CONFIGURING ACTIVE ERROR DESTROYED configure_streams() 配置成功 配置失败 / 参数无效 close() / 异常 资源回收 ⚠ 黑屏根因:Stream卡在CONFIGURING→ERROR,或ACTIVE→ERROR后未重建。 HAL层必须返回错误码,CameraService才会触发重新配置或报错。

3.4 各阶段详细说明

  1. IDLE(空闲态)
    • Stream对象已创建,但未与任何硬件管线绑定。
    • 此时仅保存应用传入的配置参数(宽高、格式、usage)。
  2. CONFIGURING(配置态)
    • HAL层收到 configure_streams() 调用,开始校验参数并分配硬件资源。
    • 常见失败原因:分辨率超出ISP最大支持、Format不匹配、多个Stream总带宽超限。
    • 若失败,直接跳转到ERROR态,configure_streams() 返回 -EINVAL 或 -ENODEV。
  3. ACTIVE(活跃态)
    • Stream成功绑定硬件管线,开始持续输出帧数据。
    • HAL层通过 process_capture_request() 接收上层请求,填充输出Buffer。
    • 若运行中发生硬件异常(如MIPI失锁、ISP超时),Stream转入ERROR态。
  4. ERROR / DESTROYED(错误/销毁态)
    • ERROR态:Stream不可用,需要上层调用 close() 或重新 configure_streams() 恢复。
    • DESTROYED态:Stream对象被销毁,所有Buffer归还Gralloc,硬件资源释放。
黑屏定位要点: 在HAL层日志中搜索 configure_streams 返回值。若返回 0 但后续无帧输出,检查Stream是否在ACTIVE态下被意外置为ERROR;若返回非零,则直接定位到CONFIGURING阶段的参数校验逻辑。

3.5 Stream配置与黑屏的关联

以下表格总结了Stream配置失败导致黑屏的典型场景:

失败阶段 HAL层行为 上层表现 日志关键字
CONFIGURING 返回错误码,不创建Buffer 预览Surface无数据,黑屏 configure_streams failed: -22
ACTIVE→ERROR 调用 notifyError() 上报 预览画面冻结或黑屏 ERROR_REQUEST / ERROR_BUFFER
Buffer分配失败 返回空Buffer,不填充数据 黑屏但无错误回调 dequeueBuffer failed
Format不匹配 HAL层拒绝配置 应用闪退或黑屏 Unsupported format 0x%x