在 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 | ?? 視情況而定 |