Android 10 推出了選用功能 相機 HAL3 緩衝區 管理 API 實作緩衝區管理邏輯,實現不同的記憶體 相機 HAL 實作的延遲時間取捨。
相機 HAL 需有 N 個要求 (其中 N 等於 管道深度) 會排入其管道的佇列中,但通常不需要全部的 N 集合 會同時輸出緩衝區。
例如 HAL 可能有八個要求在管道中排入佇列 只需針對最後一個階段的最後兩個要求 這種模型通常已開放原始碼 可以透過自訂筆記本或管線微調在搭載 Android 9 以下版本的裝置上,相機架構會配置 緩衝區,因此可能會有六組 中未使用的緩衝區。在 Android 10 中, 相機 HAL3 緩衝區管理 API 可將輸出內容分離 才能釋放六組緩衝區。這會導致 在高階裝置上節省多達 MB 的記憶體容量 且記憶體容量不足的裝置
圖 1 顯示執行中裝置的相機 HAL 介面圖 Android 9 以下版本。圖 2 顯示 Android 中的相機 HAL 介面 10 搭配 相機 HAL3 緩衝區管理 API
圖 1. Android 9 以下版本的相機 HAL 介面
圖 2. Android 10 中使用緩衝區管理 API 的相機 HAL 介面
實作緩衝區管理 API
如要實作緩衝區管理 API,相機 HAL 必須:
- 實作 HIDL
ICameraDevice@3.5
。 - 設定相機特性鍵
android.info.supportedBufferManagementVersion
敬上 至HIDL_DEVICE_3_5
。
相機 HAL 會使用
requestStreamBuffers
敬上
和
returnStreamBuffers
。
用於
ICameraDeviceCallback.hal
要求並傳回緩衝區。HAL 也必須導入
signalStreamFlush
敬上
方法
ICameraDeviceSession.hal
。
指示相機 HAL 傳回緩衝區。
requestStreamBuffers
使用
requestStreamBuffers
敬上
方法來要求相機架構中的緩衝區。使用相機 HAL3 時
緩衝區管理 API,從相機架構擷取要求就不會
包含輸出緩衝區,也就是 bufferId
欄位
StreamBuffer
為 0
。因此,相機 HAL 必須使用 requestStreamBuffers
提出要求
才能擷取到相機架構中的緩衝區
requestStreamBuffers
方法可讓呼叫端要求多個緩衝區
以便減少 HIDL IPC
呼叫。然而,若是呼叫出更多緩衝區,則呼叫會花費較多時間
這樣可能會對產生結果的總延遲時間造成負面影響
此外,因為對 requestStreamBuffers
的呼叫在相機中序列化
服務,建議相機 HAL 使用專屬的高優先順序
執行緒要求,以要求緩衝區。
如果緩衝區要求失敗,相機 HAL 必須能正確處理 一般錯誤。下方清單說明緩衝的常見原因 要求及應如何由相機 HAL 處理。
- 應用程式與輸出串流中斷連線:
這是一般錯誤。相機 HAL 應該
ERROR_REQUEST
敬上 任何擷取要求 指定已取消連結的串流並準備好處理後續要求 一般問題。 - 逾時:應用程式忙碌時,就可能發生這種情況
會密集處理,但會保留一些緩衝區。相機 HAL 應該
傳送
ERROR_REQUEST
敬上 很方便擷取 逾時錯誤並準備好正常處理後續要求。 - 相機架構正在準備新的串流設定:
相機 HAL 應會等待下一次
configureStreams
敬上 呼叫完成,才能再次呼叫requestStreamBuffers
。 - 相機 HAL 達到了
緩衝區限制
(
maxBuffers
欄位): 相機 HAL 應會等待 直到其在呼叫之前傳回至少一個串流緩衝區requestStreamBuffers
。
returnStreamBuffers
使用
returnStreamBuffers
敬上
方法,將額外的緩衝區傳回相機架構。相機 HAL 正常
會透過
processCaptureResult
敬上
方法,但只會處理已傳送至
相機 HAL使用 requestStreamBuffers
方法時,
相機 HAL 實作能保留更多緩衝區,超過
相機架構因此,returnStreamBuffers
方法應
如果 HAL 實作所保留的緩衝區不超過所要求的數量,
相機 HAL 實作不需要呼叫 returnStreamBuffers
方法。
訊號串流 Flush
signalStreamFlush
敬上
方法是由相機架構呼叫 方法,藉此通知相機 HAL 傳回所有
大量緩衝區當相機架構即將接近時,通常就會呼叫此方法
通話
configureStreams
敬上
因此必須清空相機拍攝管道和「returnStreamBuffers
」類似
方法,如果相機 HAL 實作所保留的緩衝區超過
此方法可以有空白的實作。
相機架構呼叫後
signalStreamFlush
、
架構會停止向相機 HAL 傳送新的擷取要求
緩衝區傳回相機架構當所有緩衝區皆處於
傳回,requestStreamBuffers
方法呼叫失敗,且相機
讓架構繼續保持乾淨接著,相機架構
會呼叫
configureStreams
敬上
或
processCaptureRequest
。
方法。如果相機架構呼叫 configureStreams
方法,相機
HAL 可以在 configureStreams
呼叫傳回後,再次開始要求緩衝區
如果相機架構呼叫 processCaptureRequest
方法,
相機 HAL 可以在 processCaptureRequest
期間開始要求緩衝區
呼叫。
signalStreamFlush
方法和
flush
方法。呼叫 flush
方法後,HAL 可以取消待處理擷取
要求
ERROR_REQUEST
以盡快清空管道時間
系統會呼叫 signalStreamFlush
方法,HAL 必須完成所有待處理
正常擷取要求,然後將所有緩衝區傳回相機架構。
signalStreamFlush
方法和其他方法的另一個差異為
指定 signalStreamFlush
是單向的 HIDL 方法,也就是說,相機
架構可能會在 HAL 收到
signalStreamFlush
呼叫。也就是說
signalStreamFlush
方法和其他方法 (特別是
configureStreams
方法) 抵達相機 HAL 的順序可能不同
比起相機架構中的呼叫順序解決方式
非同步問題,streamConfigCounter
欄位已新增至
StreamConfiguration
並新增為 signalStreamFlush
的引數
方法。相機 HAL 實作應使用 streamConfigCounter
引數,判斷 signalStreamFlush
呼叫是否晚於其它的抵達時間
對應的 configureStreams
呼叫。請參閱圖 3 範例。
圖 3. 相機 HAL 應如何偵測及處理延遲抵達的 SignalStreamFlush 通話
實作緩衝區管理 API 時的行為變更
使用緩衝區管理 API 實作緩衝區管理邏輯時, 請考慮以下潛在的相機行為變化 和相機 HAL 實作:
更快收到相機 HAL 發出的要求 :如果沒有緩衝區管理 API,相機架構就會要求 每個擷取要求都會輸出緩衝區,再傳送擷取要求給 相機 HAL使用緩衝區管理 API 時,相機架構 不必等待緩衝區,進而傳送擷取要求 相機 HAL
此外,如果沒有緩衝區管理 API,相機架構就會停止運作 如果擷取的輸出串流的其中一個輸出串流,則傳送擷取要求 要求已達到 HAL 可以保留的緩衝區數量上限 一次 (這個值是由相機 HAL 指定
configureStreams
傳回值中的HalStream::maxBuffers
欄位 呼叫)。透過緩衝區管理 API,這項調節行為就不再出現 且相機 HAL 實作不得接受 當 HAL 有太多擷取要求時,processCaptureRequest
呼叫 已排入佇列。requestStreamBuffers
呼叫的延遲時間差異很大: 導致requestStreamBuffers
呼叫花費的時間 例如:- 針對新建串流的前幾個緩衝區,呼叫 也可能需要更長的時間,因為裝置需要分配記憶體。
- 預估延遲時間會隨 緩衝區。
- 應用程式保留緩衝區,且正在處理中。這個 可能會導致緩衝區要求速度變慢或命中逾時, 就沒有緩衝區或 CPU 速度緩慢
緩衝區管理策略
緩衝區管理 API 可讓您進行不同類型的緩衝區管理 適合執行的策略例如:
- 回溯相容:擷取要求的 HAL 要求緩衝區
在
processCaptureRequest
呼叫期間執行此步驟這項策略不提供 節省記憶體,但可做為緩衝區的第一次實作 Management API,只需極少修改現有相機 HAL 的程式碼即可。 - 盡可能節省記憶體:相機 HAL 僅要求輸出緩衝區 才會填入廣告這項策略能讓 最大記憶體節省量潛在的缺點是增加相機管道 當緩衝區要求完成異常長時,就會卡頓。
- 快取:相機 HAL 會快取一些緩衝區,降低 可能會受到暫時性的緩衝要求影響
相機 HAL 可以針對特定用途採用不同策略, 例如,針對大量使用情境,使用最大記憶體節省策略 記憶體用量,並針對其他用途使用回溯相容策略。
外部相機 HAL 中的實作範例
外接式相機 HAL 是在 Android 9 中推出,可在
來源樹狀結構
hardware/interfaces/camera/device/3.5/
。
Android 10 已更新,現在加入了
ExternalCameraDeviceSession.cpp
、
緩衝管理 API 的實作。這部外接鏡頭 HAL
採行「緩衝區管理」中所述的最大記憶體節省策略
採用這些策略
C++ 程式碼。