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从创建到销毁经历四个阶段。理解每个阶段的状态转换,是定位配置失败黑屏的关键。
3.4 各阶段详细说明
- IDLE(空闲态)
- Stream对象已创建,但未与任何硬件管线绑定。
- 此时仅保存应用传入的配置参数(宽高、格式、usage)。
- CONFIGURING(配置态)
- HAL层收到
configure_streams()调用,开始校验参数并分配硬件资源。 - 常见失败原因:分辨率超出ISP最大支持、Format不匹配、多个Stream总带宽超限。
- 若失败,直接跳转到ERROR态,
configure_streams()返回-EINVAL或-ENODEV。
- HAL层收到
- ACTIVE(活跃态)
- Stream成功绑定硬件管线,开始持续输出帧数据。
- HAL层通过
process_capture_request()接收上层请求,填充输出Buffer。 - 若运行中发生硬件异常(如MIPI失锁、ISP超时),Stream转入ERROR态。
- ERROR / DESTROYED(错误/销毁态)
- ERROR态:Stream不可用,需要上层调用
close()或重新configure_streams()恢复。 - DESTROYED态:Stream对象被销毁,所有Buffer归还Gralloc,硬件资源释放。
- ERROR态:Stream不可用,需要上层调用
黑屏定位要点: 在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 |