要求
應用程式架構會向相機子系統發出擷取結果要求。每個要求都會對應到一個結果集。要求會封裝所有與擷取及處理這些結果相關的設定資訊。這包括解析度和像素格式、手動感應器、鏡頭和閃光燈控制、3A 運作模式、RAW 到 YUV 處理控制,以及統計資料產生。這樣一來,您就能進一步控管結果的輸出和處理作業。可以同時傳送多個要求,且提交要求不會造成阻斷。而且我們一律會按照收到的順序處理要求。

圖 1. 相機型號
HAL 和相機子系統
相機子系統包含相機管道中元件的實作項目,例如 3A 演算法和處理控制項。相機 HAL 會提供介面,讓您實作這些元件的版本。為維持多個裝置製造商和圖像訊號處理器 (ISP,或相機感應器) 供應商之間的跨平台相容性,相機管道模型是虛擬的,不會直接對應任何實際的 ISP。不過,它與實際的處理管道非常相似,因此您可以有效地將其對應至硬體。此外,它足夠抽象,可允許多種不同的演算法和運作順序,且不會影響品質、效率或跨裝置相容性。
相機管道也支援觸發事件,讓應用程式架構可以啟動自動對焦等功能。它也會將通知傳回應用程式架構,通知應用程式自動對焦鎖定或錯誤等事件。

圖 2. 相機管道
請注意,上圖中顯示的部分圖像處理區塊在初始版本中並未明確定義。攝影機管道會做出以下假設:
- RAW Bayer 輸出內容不會在 ISP 中進行任何處理。
- 統計資料會根據原始感應器資料產生。
- 將原始感應器資料轉換為 YUV 的各種處理區塊,會以任意順序排列。
- 雖然會顯示多個縮放和裁剪單位,但所有縮放單位都會共用輸出區域控制項 (數位縮放)。不過,每個裝置的輸出解析度和像素格式可能不同。
API 使用摘要
以下簡要說明使用 Android 相機 API 的步驟。如需這些步驟 (包括 API 呼叫) 的詳細說明,請參閱「啟動和預期的操作順序」一節。
- 監聽及列舉攝影機裝置。
- 開啟裝置和連線事件監聽器。
- 針對目標用途設定輸出內容 (例如靜態影像擷取、錄影等)。
- 為指定用途建立要求。
- 擷取/重複要求和突發事件。
- 接收結果中繼資料和圖片資料。
- 切換用途時,請返回步驟 3。
HAL 作業摘要
- 擷取畫面的非同步要求來自架構。
- HAL 裝置必須依序處理要求。並針對每項要求產生輸出結果中繼資料,以及一或多個輸出圖片緩衝區。
- 針對要求和結果,以及後續要求參照的串流,採用先進先出模式。
- 特定要求的所有輸出內容都必須具有相同的時間戳記,這樣架構才能在必要時將這些內容配對。
- 所有擷取設定和狀態 (3A 例程除外) 都會封裝在要求和結果中。

圖 3. 相機 HAL 總覽
啟動和預期的操作順序
本節將詳細說明使用相機 API 時的預期步驟。如要瞭解 HIDL 介面定義,請參閱 platform/hardware/interfaces/camera/。
列舉、開啟相機裝置,並建立有效工作階段
- 初始化後,架構會開始監聽任何實作
ICameraProvider
介面的現有攝影機供應器。如果有此類供應商,架構會嘗試建立連線。 - 這個架構會透過
ICameraProvider::getCameraIdList()
列舉攝影機裝置。 - 架構會透過呼叫相應的
ICameraProvider::getCameraDeviceInterface_VX_X()
例項化新的ICameraDevice
。 - 架構會呼叫
ICameraDevice::open()
來建立新的有效擷取工作階段 ICameraDeviceSession。
使用有效的相機工作階段
- 此架構會呼叫
ICameraDeviceSession::configureStreams()
,並將輸入/輸出串流清單傳送至 HAL 裝置。 - 此架構會透過對
ICameraDeviceSession::constructDefaultRequestSettings()
的呼叫,為某些用途要求預設設定。ICameraDevice::open
建立ICameraDeviceSession
後,隨時都可能發生這種情況。 - 架構會根據其中一個預設設定組合,建構並傳送第一個擷取要求給 HAL,並附上至少一個先前由架構註冊的輸出串流。這會透過
ICameraDeviceSession::processCaptureRequest()
傳送至 HAL。HAL 必須阻斷此呼叫的傳回,直到準備好傳送下一個要求為止。 - 架構會繼續提交要求並呼叫
ICameraDeviceSession::constructDefaultRequestSettings()
,以便視需要為其他用途取得預設設定緩衝區。 - 當擷取要求開始時 (感應器開始曝光以便擷取),HAL 會使用 SHUTTER 訊息呼叫
ICameraDeviceCallback::notify()
,其中包含影格編號和曝光開始時間戳記。這個通知回呼不必在首次processCaptureResult()
呼叫請求前發生,但在呼叫該擷取畫面的notify()
之前,系統不會將結果傳送至應用程式。 - 在管道延遲一段時間後,HAL 會開始使用
ICameraDeviceCallback::processCaptureResult()
將已完成的擷取結果傳回至架構。這些項目會按照提交要求的順序傳回。視相機 HAL 裝置的管道深度而定,可以同時執行多個要求。
一段時間後,系統會採取下列其中一種做法:
- 架構可能會停止提交新要求,等待現有擷取作業完成 (所有緩衝區已填滿,所有結果已傳回),然後再次呼叫
ICameraDeviceSession::configureStreams()
。這會為新一組輸入/輸出串流重設相機硬體和管道。部分串流可能會從先前的設定中重複使用。如果仍有至少一個已註冊的輸出串流,架構就會從第一個擷取要求繼續傳送至 HAL。(否則必須先使用ICameraDeviceSession::configureStreams()
)。 - 架構可能會呼叫
ICameraDeviceSession::close()
來結束攝影機工作階段。在沒有其他架構呼叫處於活動狀態時,您隨時可以呼叫此方法,但此呼叫可能會阻斷,直到所有執行中的擷取作業完成為止 (所有結果已傳回,所有緩衝區已填滿)。close()
呼叫傳回後,HAL 就不會再允許呼叫ICameraDeviceCallback
。close()
呼叫開始後,架構可能不會呼叫任何其他 HAL 裝置函式。 - 如果發生錯誤或其他非同步事件,HAL 必須使用適當的錯誤/事件訊息呼叫
ICameraDeviceCallback::notify()
。從裝置端的致命錯誤通知傳回後,HAL 應會以close()
已呼叫的方式運作。不過,HAL 必須在呼叫notify()
之前取消或完成所有未完成的擷取作業,這樣一來,一旦notify()
發生致命錯誤,架構就不會再從裝置接收回呼。close()
以外的方法應在notify()
方法從致命錯誤訊息傳回後,傳回 -ENODEV 或 NULL。

圖 4. 攝影機操作流程
硬體層級
相機裝置可根據其功能實作多個硬體層級。詳情請參閱「 支援的硬體等級」。
應用程式擷取要求、3A 控制項和處理管道之間的互動
視 3A 控制區塊中的設定而定,相機管道會忽略應用程式擷取要求中的部分參數,並改用 3A 控制例程提供的值。舉例來說,當自動曝光功能處於啟用狀態時,感應器的曝光時間、影格持續時間和靈敏度參數會由平台 3A 演算法控制,而任何應用程式指定的值都會遭到忽略。3A 例程為影格選擇的值必須在輸出中繼資料中回報。下表說明 3A 控制區塊的不同模式,以及這些模式所控制的屬性。如要瞭解這些屬性的定義,請參閱 platform/system/media/camera/docs/docs.html 檔案。
參數 | 狀態 | 受控的屬性 |
---|---|---|
android.control.aeMode | 關閉 | 無 |
開啟 | android.sensor.exposureTime android.sensor.frameDuration android.sensor.sensitivity android.lens.aperture (如果支援) android.lens.filterDensity (如果支援) | |
ON_AUTO_FLASH | 所有設定都設為「開啟」,加上 android.flash.firingPower、android.flash.firingTime 和 android.flash.mode | |
ON_ALWAYS_FLASH | 與 ON_AUTO_FLASH 相同 | |
ON_AUTO_FLASH_RED_EYE | 與 ON_AUTO_FLASH 相同 | |
android.control.awbMode | 關閉 | 無 |
WHITE_BALANCE_* | android.colorCorrection.transform. 如果 android.colorCorrection.mode 為 FAST 或 HIGH_QUALITY,則會進行平台專屬調整。 | |
android.control.afMode | 關閉 | 無 |
FOCUS_MODE_* | android.lens.focusDistance | |
android.control.videoStabilization | 關閉 | 無 |
開啟 | 可調整 android.scaler.cropRegion 來實作影像防震功能 | |
android.control.mode | 關閉 | 已停用自動曝光、自動白平和自動對焦 |
自動 | 使用個別的自動曝光、自動白平和自動對焦設定 | |
SCENE_MODE_* | 可覆寫上述所有參數。個別 3A 控制項已停用。 |
圖 2 中「圖片處理」區塊的控制項皆以類似原則運作,通常每個區塊都有三種模式:
- 關閉:停用此處理區塊。無法停用去馬賽克、色彩校正和色調曲線調整區塊。
- FAST:在這個模式中,處理區塊可能不會降低輸出影格率,但在限制下,應可產生最佳品質的輸出內容。這通常用於預覽或錄影模式,或連拍靜態影像。在某些裝置上,這可能等同於「關閉」模式 (如果不降低影格速率,就無法進行處理),在某些裝置上,這可能等同於「HIGH_QUALITY」模式 (即使以最佳品質處理,也不會降低影格速率)。
- HIGH_QUALITY:在這個模式中,處理區塊應盡可能產生最佳品質的結果,並視需要減慢輸出影格速率。這通常用於拍攝高品質靜態影像。部分區塊包含手動控制選項,可選擇取代 FAST 或 HIGH_QUALITY。舉例來說,色彩校正區塊支援色彩轉換矩陣,而色調曲線調整則支援任意全域色調對應曲線。
相機子系統可支援的最高影格速率取決於許多因素:
- 輸出圖片串流要求的解析度
- 影像感測器是否提供區塊/略過模式
- 影像介面的頻寬
- 各種 ISP 處理區塊的頻寬
由於不同 ISP 和感應器之間的這些因素可能差異極大,相機 HAL 介面會盡可能將頻寬限制抽象化為簡單的模型。這項模型具有下列特性:
- 根據應用程式要求的輸出串流大小,圖像感應器一律會設為輸出最小解析度的圖片。最小解析度的定義為至少與要求的最大輸出串流大小相同。
- 由於任何要求都可能使用目前已設定的任何或所有輸出串流,因此必須設定感應器和 ISP,以便同時將單一擷取內容縮放至所有串流。
- 如果要求未納入 JPEG 串流,則 JPEG 串流會像經過處理的 YUV 串流一樣運作;如果要求直接參照 JPEG 串流,則會以 JPEG 串流的形式運作。
- JPEG 處理器可與相機管道的其他部分同時執行,但一次只能處理一個擷取畫面。