在 Android 的 SurfaceFlinger 体系中,外部流输入的 Layer 通常通过 Sideband Stream
或 BufferQueue
机制传递给 SurfaceFlinger,然后由 HWC(Hardware Composer)或 OpenGL ES 进行合成。
1. 什么是外部流输入的 Layer?
外部流输入的 Layer 通常指的是:
-
硬件视频解码(MediaCodec 硬件解码的输出)
-
Camera HAL 的预览流
-
Miracast / DisplayLink 无线显示
-
外部 HDMI / USB-C 连接的显示设备
这些 Layer 不是应用程序直接绘制的,而是由外部设备或硬件解码器提供的流。
2. Sideband Stream
机制
在 dumpsys SurfaceFlinger
里,你看到的:
sideband stream=0x0
说明这个 Layer 没有使用 sideband stream,但如果有值(例如 0xb40000770a9cf000
),说明它是一个外部流输入的 Layer。
什么是 Sideband Stream?
-
Sideband Stream 是 Android 提供的一种 "旁路" 机制,让 HWC 直接接受外部设备或者MediaCodec 硬件解码的流,而不需要经过 CPU/GPU 处理。
-
这种机制可以极大提高视频播放性能,避免 GPU 复制大量像素数据,提高功耗效率。
SurfaceFlinger 如何处理 Sideband Stream?
-
应用程序或系统服务(如 MediaCodec)创建一个 Surface
-
Surface 绑定到外部流(比如硬件解码器)
-
SurfaceFlinger 检测到
sideband stream
并交给 HWC 进行合成 -
HWC 直接从解码器获取数据,绕过 GPU
-
最终显示在屏幕上
📌 举例:MediaCodec 硬解码
// 创建 Surface
sp<Surface> surface = new Surface(bufferProducer);// MediaCodec 绑定 Sideband Stream
mediaCodec->setOutputSurface(surface);
当 MediaCodec 开启硬件解码时,它会把解码后的帧直接输出到 Surface,而 SurfaceFlinger 看到这个 Surface 绑定了 Sideband Stream,就不会让 OpenGL ES 处理,而是交给 HWC。
3. BufferQueue
机制
对于 大部分普通的外部流输入(比如 Camera 预览),Android 使用 BufferQueue
在应用、SurfaceFlinger 和 HWC 之间传递 buffer。
流程:
-
Camera HAL / MediaCodec 产生 YUV/NV12/NV21 buffer
-
Buffer 通过 BufferQueue 传递给 SurfaceFlinger
-
SurfaceFlinger 决定是用 HWC 还是 GPU 进行合成
-
最终渲染到屏幕
📌 举例:Camera 预览
// 创建 Surface
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);// 绑定到 Camera HAL
camera->setPreviewTarget(producer);
这样 Camera 直接向 Surface 发送帧数据,SurfaceFlinger 会收到 buffer 并决定是否使用 HWC 直接合成。
4. 如何区分 Sideband Stream 和 BufferQueue?
在 dumpsys SurfaceFlinger
里,你可以检查:
-
如果
sideband stream != 0x0
,说明这个 Layer 使用的是 Sideband Stream,HWC 可能直接处理它。 -
如果
buffer != 0x0
,说明这个 Layer 使用的是 BufferQueue,SurfaceFlinger 可能需要用 GPU 合成它。
如果你 dump 的内容里:
sideband stream=0xb40000770a9cf000
buffer: buffer=0x0
那么这个 Layer 是 直接由 HWC 处理的,可能是 MediaCodec 硬解码输出 或 外部 HDMI 输入。
而如果:
sideband stream=0x0
buffer: buffer=0xb40000770a9d0000
那么这个 Layer 是 普通的 BufferQueue 方式提交给 SurfaceFlinger,可能是 Camera 预览 或 APP 绘制的 UI 界面。
5. 总结
方式 | 适用场景 | SurfaceFlinger 处理方式 | 性能 |
---|---|---|---|
Sideband Stream | MediaCodec 硬解码、HDMI 输入 | HWC 直接合成(不经过 OpenGL ES) | ✅ 高效 |
BufferQueue | Camera 预览、普通图层 | 可能用 GPU 处理或交给 HWC | ⚠️ 视情况而定 |