Android 的相機硬件抽象層 (HAL) 可將 Camera 2 中較高級別的相機框架 API 鏈接到底層的相機驅動程序和硬件。相機子系統包括相機管道組件的實現,而相機 HAL 則可提供用於實現您的這些組件版本的接口。html
下面這張圖較好的說明了Camera各組件之間的關係:android
應用框架:應用代碼位於應用框架級別,它使用 Camera 2 API 與相機硬件進行交互。在內部,這些代碼會調用相應的 Binder 接口,以訪問與相機互動的原生代碼。
AIDL:與 CameraService 關聯的 Binder 接口可在 frameworks/av/camera/aidl/android/hardware 中找到。生成的代碼會調用較低級別的原生代碼以獲取對實體相機的訪問權限,並返回用於在框架級別建立 CameraDevice 並最終建立 CameraCaptureSession 對象的數據。
原生框架:此框架位於 frameworks/av/
中,並提供至關於 CameraDevice 和 CameraCaptureSession 類的原生類。另請參閱 NDK camera2 參考。
Binder IPC 接口:IPC binder 接口用於實現跨越進程邊界的通訊。調用相機服務的若干個相機 Binder 類位於 frameworks/av/camera/camera/aidl/android/hardware
目錄中。 ICameraService 是相機服務的接口;ICameraDeviceUser 是已打開的特定相機設備的接口;ICameraServiceListener 和 ICameraDeviceCallbacks 分別是對應用框架的 CameraService 和 CameraDevice 回調。
相機服務:位於 frameworks/av/services/camera/libcameraservice/CameraService.cpp 下的相機服務是與 HAL 進行互動的實際代碼。
HAL:硬件抽象層定義了由相機服務調用、且您必須實現以確保相機硬件正常運行的標準接口。算法
2.1 capture請求架構
應用框架會針對捕獲的結果向相機子系統發出請求。一個請求對應一組結果。請求包含有關捕獲和處理這些結果的全部配置信息。其中包括分辨率和像素格式;手動傳感器、鏡頭和閃光燈控件;3A 操做模式;RAW 到 YUV 處理控件;以及統計信息的生成等。這樣一來,即可更好地控制結果的輸出和處理。一次可發起多個請求,並且提交請求時不會出現阻塞。請求始終按照接收的順序進行處理。框架
2.2 HAL 和相機子系統異步
相機子系統包括相機管道中組件的實現,例如 3A 算法和處理控件。相機 HAL 爲您提供了用於實現您的這些組件版本的接口。爲了保持多個設備製造商和圖像信號處理器(ISP,也稱爲相機傳感器)供應商之間的跨平臺兼容性,相機管道模型是虛擬的,且不直接對應於任何真正的 ISP。不過,它與真正的處理管道足夠類似,所以您能夠有效地將其映射到硬件。此外,它足夠抽象,可支持多種不一樣的算法和運算順序,而不會影響質量、效率或跨設備兼容性。ide
相機管道還支持應用框架能夠啓動來開啓自動對焦等功能的觸發器。它還會將通知發送迴應用框架,以通知應用自動對焦鎖定或錯誤等事件。函數
請注意,上圖所示的一些圖像處理塊在初始版本中沒有明肯定義。相機管道作出如下假設:google
- RAW Bayer 輸出在 ISP 內部不通過任何處理。
- 統計信息根據原始傳感器數據生成。
- 將原始傳感器數據轉換爲 YUV 的各類處理塊按任意順序排列。
- 當顯示多個刻度和剪裁單元時,全部縮放器單元共享輸出區域控件(數字縮放)。不過,每一個單元均可能具備不一樣的輸出分辨率和像素格式。
API 用途摘要
下面簡要介紹了使用 Android Camera API 的步驟。有關這些步驟(包括 API 調用)的詳細說明,請參閱「啓動和預期操做順序」部分。spa
- 1.監聽和枚舉相機設備。
- 2.打開設備並鏈接監聽器。
- 3.配置目標使用情形的輸出(如靜態捕獲、錄製等)。
- 4.爲目標使用情形建立請求。
- 5.捕獲/重複請求和連拍。
- 6.接收結果元數據和圖片數據。
- 7.切換使用情形時,返回到第 3 步。
HAL 操做摘要
- 捕獲的異步請求來自於框架。
- HAL 設備必須按順序處理請求。對於每一個請求,均生成輸出結果元數據以及一個或多個輸出圖像緩衝區。
- 請求和結果以及後續請求引用的信息流遵照先進先出規則。
- 指定請求的全部輸出的時間戳必須徹底相同,以便框架能夠根據須要將它們匹配在一塊兒。
- 全部捕獲配置和狀態(不包括 3A 例程)都包含在請求和結果中。
下面是相機HAL概覽:
2.3 啓動和預期操做順序
本部分詳細說明了使用 Camera API 時應遵循的步驟。有關 HIDL 接口的定義,請參閱 platform/hardware/interfaces/camera/。
枚舉、打開相機設備並建立有效會話
- 1.初始化後,框架開始監聽實現 ICameraProvider 接口的任何現有相機提供程序。若是存在一個或多個此類提供程序,框架將嘗試創建鏈接。
- 2.框架經過
ICameraProvider::getCameraIdList()
枚舉相機設備。- 3.框架經過調用相應的
ICameraProvider::getCameraDeviceInterface_VX_X()
來實例化一個新的ICameraDevice
。- 4.框架調用
ICameraDevice::open()
來建立一個新的有效捕獲會話 ICameraDeviceSession。
使用有效相機會話
- 1.框架調用
ICameraDeviceSession::configureStreams()
並傳入到 HAL 設備的輸入/輸出流列表。- 2.框架經過調用
ICameraDeviceSession::constructDefaultRequestSettings()
來爲某些使用情形請求默認設置。這可能會在ICameraDevice::open
建立ICameraDeviceSession
以後的任什麼時候間發生。- 3.框架經過基於某一組默認設置的設置以及框架以前註冊的至少一個輸出流來構建第一個捕獲請求並將其發送到 HAL。此請求經過
ICameraDeviceSession::processCaptureRequest()
發送到 HAL。HAL 必須阻止此調用返回,直到準備好發送下一個請求爲止。- 4.框架繼續提交請求並根據須要調用
ICameraDeviceSession::constructDefaultRequestSettings()
以獲取其餘使用情形的默認設置緩衝區。- 5.當請求捕獲開始(傳感器開始曝光以進行捕獲)時,HAL 會調用
ICameraDeviceCallback::notify()
並顯示 SHUTTER 消息,包括幀號和開始曝光的時間戳。此通知回調沒必要在對請求第一次調用processCaptureResult()
以前發生,但直到針對相應的捕獲調用 notify() 以後,纔會嚮應用提供有關該捕獲的結果。- 6.通過必定的管道延遲後,HAL 開始使用
ICameraDeviceCallback::processCaptureResult()
將完成的捕獲返回到框架。這些捕獲按照與提交請求相同的順序返回。一次可發起多個請求,具體取決於相機 HAL 設備的管道深度。
一段時間後,會出現如下某種狀況:
- 框架可能會中止提交新的請求,等待現有捕獲完成(全部緩衝區都已填充,全部結果都已返回),而後再次調用
ICameraDeviceSession::configureStreams()
。這會重置相機硬件和管道,以得到一組新的輸入/輸出流。可重複使用先前配置中的部分信息流。若是至少還有一個已註冊的輸出流,則框架將從發送到 HAL 的第一個捕獲請求繼續。(不然,須要先調用ICameraDeviceSession::configureStreams()
。)- 框架可能會調用
ICameraDeviceSession::close()
以結束相機會話。當框架中沒有其餘處於有效狀態的調用時,可能隨時會調用此函數;不過,在全部發起的捕獲完成(全部結果都已返回,全部緩衝區都已填充)以前,調用可能會阻塞。close() 調用返回後,不容許再從 HAL 對ICameraDeviceCallback
進行調用。一旦進行 close() 調用,框架便不能再調用其餘任何 HAL 設備函數。- 在發生錯誤或其餘異步事件時,HAL 必須調用
ICameraDeviceCallback::notify()
並返回相應的錯誤/事件消息。從嚴重的設備範圍錯誤通知返回後,HAL 的行爲方式應像對其調用了 close() 同樣。可是,HAL 必須在調用 notify() 以前取消或完成全部待處理的捕獲,以便在調用 notify() 並返回嚴重錯誤時,框架不會收到來自設備的更多回調。在 notify() 方法從嚴重錯誤消息返回後,close() 以外的方法應返回 -ENODEV 或 NULL。
下面是相機操做流程:
2.4 硬件級別
相機設備能夠根據其功能實現多個硬件級別。有關詳情,請參閱支持的硬件級別。
2.5 應用捕獲請求、3A 控件和處理管道之間的交互
根據 3A 控件塊中的設置,相機管道會忽略應用捕獲請求中的某些參數,而改用 3A 控件例程提供的值。例如,啓用自動曝光後,傳感器的曝光時間、幀時長和感光度參數由平臺 3A 算法控制,全部應用指定的值都會被忽略。必須在輸出元數據中報告由 3A 例程爲幀選擇的值。下表描述了 3A 控件塊的不一樣模式以及由這些模式控制的屬性。有關這些屬性的定義,請參閱 platform/system/media/camera/docs/docs.html 文件。
在圖三中,圖像處理塊中的控件都以相似的原理操做,而且每一個塊通常都具備 3 種模式:
- OFF:該處理塊處於停用狀態。沒法停用去馬賽克、色彩校訂和色調曲線調整塊。
- FAST:與 OFF 模式相比,在這種模式下,處理塊可能不會下降輸出幀速率,可是考慮到限制條件,它應該會產生可以產生的最優質輸出。一般,該模式會用於預覽或視頻錄製模式,或用於連拍靜態圖像。在一些設備上,該模式可能等同於 OFF 模式(進行任何處理都會下降幀速率);而在另一些設備上,該模式可能等同於 HIGH_QUALITY 模式(最佳質量仍不會下降幀速率)。
- HIGH_QUALITY:在這種模式下,處理塊應儘量產生最優質結果,根據須要下降輸出幀速率。一般,該模式會用於拍攝優質靜態圖像。一些塊包括能夠被選中的手動控件(而非 FAST 或 HIGH_QUALITY)。例如,色彩校訂塊支持顏色變換矩陣,而色調曲線調整支持任意的全局色調映射曲線。
相機子系統能夠支持的最大幀速率受到多種因素的影響:
- 所請求的輸出圖像流的分辨率
- 成像器上像素組合/跳過模式的可用性
- 成像器接口的帶寬
- 各類 ISP 處理塊的帶寬
因爲這些因素在不一樣的 ISP 和傳感器之間可能有很大差別,所以相機 HAL 接口會設法將帶寬限制抽象爲儘量簡單的模型。顯示的模型具備如下特性:
- 考慮到應用的請求輸出流大小,圖像傳感器始終配置爲輸出儘量最小的分辨率。最小分辨率定義爲至少與請求的最大輸出流同樣大。
- 由於任何請求均可能使用當前配置的任意或全部輸出流,因此傳感器和 ISP 必須配置爲支持將單個捕獲同時擴展到全部信息流。
- 對於不包含 JPEG 流的請求,JPEG 流表現得像通過處理的 YUV 流同樣;在直接引用它們的請求中,它們用做 JPEG 流。
- JPEG 處理器能夠並行運行到相機管道的剩餘部分,但不能一次處理多個捕獲。