Android 允許裝置支援相機裝置的並行串流功能。舉例來說,這種做法可讓裝置同時讓前置與後置鏡頭同時運作。自 Android 11 起,Camera2 API 包含下列方法,應用程式可呼叫這些方法,判斷相機是否支援並行串流和支援的串流設定。
getConcurrentCameraIds
:取得目前連線的攝影機裝置 ID 組合,支援並行設定相機裝置工作階段。isConcurrentSessionConfigurationSupported
:檢查提供的相機裝置組合,以及其對應的工作階段設定是否能同時設定。
透過 SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS
屬性中的相機裝置相機特性,會包含並行串流時必須支援的一組必要串流組合。
透過 getConcurrentStreamingCameraIds()
通告的每部相機裝置都必須支援下列並行串流保證設定。
目標 1 | 目標 2 | |||
---|---|---|---|---|
類型 | 大小上限 | 類型 | 大小上限 | 應用實例範例 |
YUV | s1440p | 應用程式內的影片或圖片處理作業 | ||
中華電信 | s1440p | 應用程式內取景器分析 | ||
JPEG | s1440p | 不支援透過觀景窗拍攝靜態影像 | ||
YUV / PRIV | 720p | JPEG | s1440p | 標準靜態影像 |
YUV / PRIV | 720p | YUV / PRIV | s1440p | 透過預覽或在應用程式內進行影片或處理 |
支援 Y8 的裝置 (CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
包含 CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
) 必須支援在所有保證的串流組合中,將 YUV 串流替換為 Y8。MONOCHROME
s720p
是指 720p (1280 x 720),或 StreamConfigurationMap.getOutputSizes()
回傳的特定格式支援的最高解析度。s1440p
是指 1440p (1920 x 1440),或 StreamConfigurationMap.getOutputSizes()
傳回的特定格式所支援的最大解析度。功能不包含 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
的裝置,在並行運作期間,至少必須支援單一 Y16 串流,即解析度為 sVGA 的 Dataspace::DEPTH
,其中 sVGA 是下列兩種解析度中較小的:
- 指定格式的輸出解析度上限
- 640 x 480
實作
如要讓應用程式查詢裝置,以判斷相機是否支援同時串流,請實作 ICameraProvider@2.6
HAL 介面,其中包含下列方法:
如需 ICameraProvider@2.6
HAL 介面的參考實作,請參閱 EmulatedCameraProviderHWLImpl.cpp
中的模擬相機 HAL 程式庫。
驗證
如要測試這項功能的實作方式是否正常運作,請使用 ConcurrentCameraTest.java
CTS 測試。此外,請使用可開啟多個相機並同時運作的應用程式進行測試。
資源分配問題
如果相機 HAL 宣稱支援相機裝置的並行作業,可能會發生資源配置問題,特別是在手機上有足夠的圖像訊號處理器 (ISP) 資源,可同時串流前置鏡頭和後置鏡頭 (或其他) 的情況下,但並未達到其完整容量。在此情況下,相機 HAL 必須分配有限的硬體資源給每部相機裝置。
情境示例
以下情境說明這個問題。
問題
裝置的設定如下:
- 相機 ID
0
是由廣角和超廣角相機所支援的邏輯相機,每個相機都會佔用一個網際網路服務供應商 (ISP) 資源。 - 攝影機 ID
1
是會取用一個網際網路服務供應商 (ISP) 資源的相機。
裝置 (手機) 有兩個 ISP。如果相機 ID 0
已開啟,且已設定工作階段,相機 HAL 可能會保留兩個 ISP,以便同時使用超廣角和廣角相機。
在這種情況下,前置鏡頭 (ID 1
) 無法設定任何串流,因為兩個 ISP 都已在使用中。
解決方案
為解決這個問題,架構可以在設定工作階段之前開啟相機 ID 0
和 1
,以便向相機 HAL 提供有關如何分配資源的提示 (因為現在預期相機會同時運作)。然而,這會導致功能受到限制,舉例來說,縮放可能無法處理完整的變焦範圍比率 (因為切換實體相機 ID 可能會發生問題)。
如要實作此解決方案,請對 provider@2.6::ICameraProvider::getConcurrentCameraStreamingCameraIds
進行下列更新。
規定在相機並行運作時,相機架構必須先開啟相機裝置 (
@3.2::ICameraDevice::open
),才能在相機裝置上設定任何工作階段。這樣一來,攝影機供應商就能據此分配資源。為解決無法處理完整縮放範圍比率的問題,請確保相機應用程式在同時使用攝影機時,只會使用 1x 和
MAX_DIGITAL_ZOOM
之間的ZOOM_RATIO
控制設定,而非完整的ZOOM_RATIO_RANGE
(這樣可避免在內部切換實體攝影機,這可能需要更多 ISP)。
testDualCameraPreview 發生問題
進行上述更新時,可能會發生 MultiViewTest.java#testDualCameraPreview
測試允許的行為問題。
測試 testDualCameraPreview
不會只在開啟所有相機後設定工作階段。其運作順序如下:
for each camera in cameraDevices :
device = openCamera(camera)
createCaptureSession(device);
不過,它會容許使用 ERROR_MAX_CAMERAS_IN_USE [1]
時發生的相機開啟失敗。第三方應用程式可能必須使用這項行為。
由於攝影機 HAL 在設定工作階段之前,不會知道要開啟的攝影機 ID 完整組合,因此可能很難分配硬體資源 (假設有競爭情況)。
為解決這個問題,除了支援並行串流之外,相機 HAL 還應維持向後相容性,如果無法支援所有同時執行的相機的完整串流設定,則應拒絕 openCamera
對 ERROR_MAX_CAMERAS_IN_USE
的呼叫。