相機擴展

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

設備製造商可以通過 OEM 供應商庫提供的 Camera Extensions 接口向第三方開發者公開散景、夜間模式和 HDR 等特殊效果。開發人員可以使用Camera2 ExtensionsCameraX Extensions API 來啟用效果,這些效果在設備上的 OEM 供應商庫中作為擴展實現。

有關支持的擴展列表(在 Camera2 和 CameraX 中相同),請參閱CameraX Extensions API 。如果您想添加擴展,請在此處提交錯誤。

本頁介紹如何在設備上實施和啟用 OEM 供應商庫。

建築學

下圖描述了 Camera Extensions 接口或extensions-interface的架構:建築學

圖 1. Camera Extensions 架構圖

如圖所示,要支持 Camera Extensions,您需要實現 OEM 供應商庫提供的extensions-interface 。您的 OEM 供應商庫啟用兩個 API: CameraX Extensions APICamera2 Extensions API ,分別由 CameraX 和 Camera2 應用程序用於訪問供應商擴展。

實施 OEM 供應商庫

要實現 OEM 供應商庫,請將camera-extensions-stub文件複製到系統庫項目中。這些文件定義了相機擴展接口。

camera-extensions-stub文件分為以下幾類:

基本接口文件(不要修改)

  • PreviewExtenderImpl.java
  • ImageCaptureExtenderImpl.java
  • ExtenderStateListener.java
  • ProcessorImpl.java
  • PreviewImageProcessorImpl.java
  • CaptureProcessorImpl.java
  • CaptureStageImpl.java
  • RequestUpdateProcessorImpl.java
  • ProcessResultImpl.java
  • advanced/AdvancedExtenderImpl.java
  • advanced/Camera2OutputConfigImpl.java
  • advanced/Camera2SessionConfigImpl.java
  • advanced/ImageProcessorImpl.java
  • advanced/ImageReaderOutputConfigImpl.java
  • advanced/ImageReferenceImpl.java
  • advanced/MultiResolutionImageReaderOutputConfigImpl.java
  • advanced/OutputSurfaceImpl.java
  • advanced/RequestProcessorImpl.java
  • advanced/SessionProcessorImpl.java
  • advanced/SurfaceOutputConfigImpl.java

強制實施(添加您的實施)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Bokeh 擴展器類(如果支持 Bokeh 擴展,則實現它)

  • BokehImageCaptureExtenderImpl.java
  • BokehPreviewExtenderImpl.java
  • advanced/BokehAdvancedExtenderImpl.java

夜間擴展器類(如果支持夜間擴展,則實現它)

  • NightImageCaptureExtenderImpl.java
  • NightPreviewExtenderImpl.java
  • advanced/NightAdvancedExtenderImpl.java

自動擴展器類(如果支持自動擴展,則實現它)

  • AutoImageCaptureExtenderImpl.java
  • AutoPreviewExtenderImpl.java
  • advanced/AutoAdvancedExtenderImpl.java

HDR 擴展器類(如果支持 HDR 擴展,則實現它)

  • HdrImageCaptureExtenderImpl.java
  • HdrPreviewExtenderImpl.java
  • advanced/HdrAdvancedExtenderImpl.java

Face Retouch 擴展類(如果支持 Face Retouch 擴展,則實現它)

  • BeautyImageCaptureExtenderImpl.java
  • BeautyPreviewExtenderImpl.java
  • advanced/BeautyAdvancedExtenderImpl.java

實用程序(可選,可刪除)

  • advanced/Camera2OutputConfigImplBuilder.java
  • advanced/Camera2SessionConfigImplBuilder.java

您不需要為每個擴展提供實現。如果您不實現擴展,請將isExtensionAvailable()設置為返回false或刪除相應的 Extender 類。 Camera2 和 CameraX 擴展 API 向應用報告擴展不可用。

讓我們了解一下 Camera2 和 CameraX 擴展 API 如何與供應商庫交互以啟用擴展。下圖以 Night 擴展為例說明了端到端流程:

主流

圖 2.夜間擴展實施

  1. 版本驗證:

    Camera2/X 調用ExtensionVersionImpl.checkApiVersion()以確保 OEM 實現的extensions-interface版本與 Camera2/X 支持的版本兼容。

  2. 供應商庫初始化:

    InitializerImpl有一個方法init()用於初始化供應商庫。 Camera2/X 在訪問 Extender 類之前完成初始化。

  3. 實例化擴展器類:

    實例化擴展的擴展器類。有兩種擴展器類型:基本擴展器和高級擴展器。您必須為所有擴展實現一種擴展器類型。有關更多信息,請參閱基本擴展器與高級擴展器

    Camera2/X 實例化 Extender 類並與之交互以檢索信息並啟用擴展。對於給定的擴展,Camera2/X 可以多次實例化 Extender 類。因此,不要在構造函數或init()調用中進行繁重的初始化。僅在相機會話即將開始時執行onInit()的工作,例如在 Basic Extender 中調用 onInit() 或在 Advanced Extender 中調用initSession()時。

    對於 Night 擴展,為 Basic Extender 類型實例化了以下 Extender 類:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    對於高級擴展器類型:

    • NightAdvancedExtenderImpl.java
  4. 檢查擴展可用性:

    在啟用擴展之前, isExtensionAvailable()通過 Extender 實例檢查指定相機 ID 上的擴展是否可用。

  5. 使用相機信息初始化擴展器:

    Camera2/X 在 Extender 實例上調用init()並將相機 ID 和CameraCharacteristics傳遞給它。

  6. 查詢信息:

    調用 Extender 類以檢索支持的分辨率等信息,仍然捕獲估計的延遲,並從 Extender 捕獲請求密鑰,為啟用擴展做準備。

  7. 在擴展器上啟用擴展:

    Extender 類提供啟用該類所需的所有接口。它提供了一種將 OEM 實現掛鉤到 Camera2 管道的機制,例如注入捕獲請求參數或啟用後處理器。

    對於 Advanced Extender 類型,Camera2/X 與SessionProcessorImpl交互以啟用擴展。 Camera2/X 通過在 Extender 上調用createSessionProcessor()來檢索SessionProcessorImpl實例。

以下部分更詳細地描述了擴展流程。

版本驗證

在運行時從設備加載 OEM 供應商庫時,Camera2/X 會驗證該庫是否與extensions-interface版本兼容。 extensions-interface使用語義版本控製或 MAJOR.MINOR.PATCH,例如 1.1.0 或 1.2.0。但是,在版本驗證過程中只使用主要和次要版本。

為了驗證版本,Camera2/X 使用支持的extensions-interface版本調用ExtensionVersionImpl.checkApiVersion() 。然後,Camera2/X 使用 OEM 庫報告的版本來確定是否可以啟用擴展以及應該調用哪些功能。

主要版本兼容性

如果 Camera2/X 和供應商庫之間的擴展接口的主要版本不同,則認為它不兼容並禁用擴展。

向後兼容性

只要主要版本相同,Camera2/X 就可確保與使用先前extensions-interface版本構建的 OEM 供應商庫向後兼容。例如,如果 Camera2/X 支持extensions-interface 1.3.0,則實現 1.0.0、1.1.0 和 1.2.0 的 OEM 供應商庫仍然兼容。這也意味著在您實現特定版本的供應商庫後,Camera2/X 會確保該庫與即將推出extension-interface版本向後兼容。

前向兼容性

與較新extensions-interface的供應商庫的前向兼容性取決於您,即 OEM。如果您需要一些功能來實現擴展,您可能希望從某個版本開始啟用擴展。在這種情況下,當 Camera2/X 庫版本滿足要求時,您可以返回支持的extensions-interface版本。如果不支持 Camera2/X 版本,您可以返回不兼容的版本,例如 99.0.0 以禁用擴展。

供應商庫初始化

在驗證了 OEM 庫實現的extensions-interface版本後,Camera2/X 開始初始化過程。 InitializerImpl.init()方法向 OEM 庫發出應用程序正在嘗試使用擴展的信號。

Camera2/X 不會對 OEM 庫進行其他調用(除了版本檢查),直到 OEM 供應商庫調用OnExtensionsInitializedCallback.onSuccess()來通知初始化完成。

您必須從extensions-interface 1.1.0 開始實施InitializerImpl 。如果 OEM 供應商庫實現extensions-interface 1.0.0,Camera2/X 將跳過庫初始化步驟。

基本擴展器與高級擴展器

有兩種類型的extensions-interface實現:基本擴展器和高級擴展器。自extensions-interface 1.2.0 起支持 Advanced Extender。

為在相機 HAL 中處理圖像或使用能夠處理 YUV 流的後處理器的擴展實施 Basic Extender。

為需要自定義 Camera2 流配置並根據需要發送捕獲請求的擴展實施 Advanced Extender。

對比見下表:

基本擴展器高級擴展器
流配置固定的
預覽: PRIVATEYUV_420_888 (如果存在處理器)
靜態捕捉: JPEGYUV_420_888 (如果存在處理器)
可由 OEM 定制。
發送捕獲請求只有 Camera2/X 可以發送捕獲請求。您可以為這些請求設置參數。當處理器用於圖像採集時,Camera2/X 可以發送多個採集請求,並將所有圖像和採集結果發送給處理器。為您提供了一個RequestProcessorImpl實例來執行 camera2 捕獲請求並獲取結果和 Image。

Camera2/X 調用SessionProcessorImpl上的startRepeatingstartCapture來通知 OEM 開始重複預覽請求並分別開始靜態捕獲序列。

相機管道中的掛鉤
  • onPresetSession提供會話參數。
  • onEnableSession在配置CameraCaptureSession後立即發送單個請求。
  • onDisableSessionCameraCaptureSession關閉之前發送一個請求。
  • initSession初始化並返回用於創建捕獲會話的自定義 camera2 會話配置。
  • 在配置onCaptureSessionStart後立即調用CameraCaptureSession
  • onCaptureSessionEndCameraCaptureSession關閉之前被調用。
適用於在相機 HAL 或處理 YUV 圖像的處理器中實現的擴展。
  • 具有基於 Camera2 的效果實現。
  • 需要自定義流配置,例如 RAW 流。
  • 需要交互式捕獲序列。
支持的 API 版本Camera2 擴展:Android T(AOSP 實驗性)或更高版本
CameraX 擴展: camera-extensions 1.1.0 或更高版本
Camera2 擴展:Android 12L 或更高版本
CameraX 擴展: camera-extensions 1.2.0-alpha03 或更高版本

應用程序流

下表顯示了三種類型的應用程序流及其對應的相機擴展 API 調用。雖然 Camera2/X 提供了這些 API,但您必須正確實現供應商庫以支持這些流程,我們將在後面的部分中更詳細地描述。

Camera2 擴展CameraX 擴展
查詢擴展可用性CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
查詢信息CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX 處理庫中的其餘信息。

啟用擴展的預覽和靜態捕獲CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector

bindToLifecycle(lifecycleOwner, cameraSelector, preview, ...)

基本擴展器

Basic Extender 接口提供了到相機管道中多個位置的掛鉤。每個擴展類型都有相應的擴展器類,OEM 需要實現這些類。

下表列出了 OEMS 需要為每個擴展實現的擴展器類:

要實現的擴展器類
夜晚NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java

HdrImageCaptureExtenderImpl.java

汽車AutoPreviewExtenderImpl.java

AutoImageCaptureExtenderImpl.java

散景BokehPreviewExtenderImpl.java

BokehImageCaptureExtenderImpl.java

面部修飾BeautyPreviewExtenderImpl.java

BeautyImageCaptureExtenderImpl.java

我們在以下示例中使用PreviewExtenderImplImageCaptureExtenderImpl作為佔位符。將這些替換為您正在實施的實際文件的名稱。

基本擴展器具有以下功能:

  • 在配置CameraCaptureSession ( onPresetSession ) 時注入會話參數。
  • 通知您捕獲會話開始和關閉事件,並發送一個請求以通知 HAL 並返回參數( onEnableSessiononDisableSession )。
  • 為請求注入捕獲參數( PreviewExtenderImpl.getCaptureStageImageCaptureExtenderImpl.getCaptureStages )。
  • 添加處理器以進行預覽並仍然捕獲能夠處理YUV_420_888流的處理器。

讓我們看看Camera2/X如何調用extensions-interface來實現上面提到的三個應用流程。

應用流程 1:檢查擴展可用性

BasicExtenderAppFlow1

圖 3. Basic Extender 上的應用流程 1

在此流程中,Camera2/X 直接調用PreviewExtenderImplImageCaptureExtenderImplisExtensionAvailable()方法,而不調用init() 。兩個 Extender 類都必須返回true才能啟用擴展。

這通常是應用程序在啟用擴展程序之前檢查給定相機 ID 是否支持給定擴展程序類型的第一步。這是因為某些擴展僅在某些相機 ID 上受支持。

應用流程二:查詢信息

BasicExtenderAppFlow2

圖 4. Basic Extender 上的應用流程 2

確定擴展是否可用後,應用應在啟用擴展之前查詢以下信息。

  • 仍然捕獲延遲範圍: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange返回捕獲延遲範圍,以供應用評估是否適合為當前場景啟用擴展。

  • 預覽和捕獲表面支持的尺寸: ImageCaptureExtenderImpl.getSupportedResolutionsPreviewExtenderImpl.getSupportedResolutions返回圖像格式列表以及表面格式和尺寸支持的尺寸。

  • 支持的請求和結果鍵: Camera2/X 調用以下方法從您的實現中檢索支持的捕獲請求鍵和結果鍵:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

在查詢更多信息之前,Camera2/X 總是首先在這些 Extender 類上調用init()

應用流程 3:啟用擴展的預覽/仍然捕獲(HAL 實現)

BasicExtenderAppFlow3

圖 5. Basic Extender 上的應用流程 3

上圖說明了啟用預覽並在沒有任何處理器的情況下仍使用擴展進行捕獲的主要流程。這意味著相機 HAL 處理擴展。

在這個流程中,Camera2/X 首先調用init()然後onInit ,它會通知您相機會話即將開始使用指定的擴展。您可以在onInit()中進行繁重的初始化。

在配置CameraCaptureSession時,Camera2/X 會調用onPresetSession來獲取會話參數。捕獲會話配置成功後,Camera2/X 調用onEnableSession返回一個包含捕獲參數的CaptureStageImpl實例。 Camera2/X 立即使用這些捕獲參數發送單個請求以通知 HAL。類似地,在捕獲會話關閉之前,Camera2/X 調用onDisableSession ,然後使用返回的捕獲參數發送單個請求。

Camera2/X 觸發的重複請求包含PreviewExtenderImpl.getCaptureStage()返回的請求參數。此外,靜態捕獲請求包含ImageCaptureExtenderImpl.getCaptureStages()返回的參數。

最後,Camera2/X 在相機會話完成後調用onDeInit() 。您可以在onDeinit()中釋放資源。

預覽處理器

除了相機 HAL,您還可以在處理器中實現擴展。

實現PreviewExtenderImpl.getProcessorType以指定處理器類型,如下所述:

  • PROCESSOR_TYPE_NONE沒有處理器。圖像在相機 HAL 中處理。

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY處理器類型允許您根據最新的TotalCaptureResult使用新的捕獲請求參數更新重複請求。

    PreviewExtenderImpl.getProcessor必須返回一個RequestUpdateProcessorImpl實例,該實例處理TotalCaptureResult實例並返回一個CaptureStageImpl實例以更新重複請求。 PreviewExtenderImpl.getCaptureStage()還應該反映處理的結果並返回最新的CaptureStageImpl

  • PROCESSOR_TYPE_IMAGE_PROCESSOR此類型允許您實現處理器來處理YUV_420_888圖像並將輸出寫入PRIVATE表面。

    您需要在PreviewExtenderImpl.getProcessor中實現並返回一個PreviewImageProcessorImpl實例。處理器負責處理YUV_420_888輸入圖像。它應該將輸出寫入PRIVATE格式的預覽。 Camera2/X 使用YUV_420_888表面而不是PRIVATE來配置CameraCaptureSession進行預覽。

    流程見下圖:

預覽處理器

圖 6.使用PreviewImageProcessorImpl的預覽流程

PreviewImageProcessorImpl接口擴展了ProcessImpl並具有三個重要方法:

  • onOutputSurface(Surface surface, int imageFormat)設置處理器的輸出表面。對於PreviewImageProcessorImplimageFormat是一種像素格式,例如PixelFormat.RGBA_8888

  • onResolutionUpdate(Size size)設置輸入圖像的大小。

  • onImageFormatUpdate(int imageFormat)設置輸入圖像的圖像格式。目前只能是YUV_420_888

圖像捕捉處理器

對於靜態捕獲,您可以通過使用ImageCaptureExtenderImpl.getCaptureProcessor返回CaptureProcessorImpl實例來實現處理器。處理器負責處理捕獲的YUV_420_888圖像列表和TotalCaptureResult實例,並將輸出寫入YUV_420_888表面。

您可以放心地假設在發送靜止捕獲請求之前啟用並運行預覽。

請參見下圖中的流程:

捕獲處理器

圖 7.仍然使用CaptureProcessorImpl捕獲流

  1. Camera2/X 使用YUV_420_888格式的靜態捕獲表面來配置捕獲會話。 Camera2/X 通過調用準備CaptureProcessorImpl

    • CaptureProcessorImpl.onImageFormatUpdate()YUV_420_888
    • CaptureProcessorImpl.onResolutionUpdate()與輸入圖像大小。
    • 帶有輸出YUV_420_888表面的CaptureProcessorImpl.onOutputSurface()
  2. ImageCaptureExtenderImpl.getCaptureStages返回CaptureStageImpl的列表,其中每個元素映射到具有由 Camera2/X 發送的捕獲參數的CaptureRequest實例。例如,如果它返回一個包含三個CaptureStageImpl實例的列表,Camera2/X 會使用captureBurst API 發送三個帶有相應捕獲參數的捕獲請求。

  3. 將接收到的圖像和TotalCaptureResult實例捆綁在一起,發送到CaptureProcessorImpl進行處理。

  4. CaptureProcessorImpl將結果 Image( YUV_420_888格式)寫入由onOutputSurface()調用指定的輸出表面。如有必要,Camera2/X 會將其轉換為 JPEG 圖像。

支持捕獲請求鍵和結果

除了相機預覽和捕捉之外,應用程序還可以設置縮放、閃光燈參數或觸發點擊對焦。這些參數可能與您的擴展實現不兼容。

extensions-interface 1.3.0 中添加了以下方法,以允許您公開實現支持的參數:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys()返回您的實現支持的捕獲請求密鑰。
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys()返回捕獲結果中包含的捕獲結果鍵。

如果相機 HAL 處理擴展,Camera2/X 會在CameraCaptureSession.CaptureCallback中檢索捕獲結果。但是,如果實現了處理器,則 Camera2/X 會在ProcessResultImpl中檢索捕獲結果,該結果將傳遞給PreviewImageProcessorImplCaptureProcessorImpl中的process()方法。您負責通過ProcessResultImpl將捕獲結果報告給 Camera2/X。

下面以CaptureProcessorImpl接口的定義為例。在extensions-interface 1.3.0 或更高版本中,調用第二個process()調用:

Interface CaptureProcessorImpl extends ProcessorImpl {
    // invoked when extensions-interface version < 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
    // invoked when extensions-interface version >= 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
            ProcessResultImpl resultCallback, Executor executor);
}

對於常見的相機操作,如變焦、輕點對焦、閃光燈和曝光補償,我們建議在拍攝請求和拍攝結果時支持以下鍵:

  • 飛漲:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • 點擊對焦:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • 閃光:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • 曝光補償:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

對於實現 1.2.0 或更早版本的 Basic Extender,CameraX Extensions API 明確支持上述所有鍵。對於extensions-interface 1.3.0,CameraX 和 Camera2 都支持返回的列表並僅支持其中包含的鍵。例如,如果您決定在 1.3.0 實現中僅返回CaptureRequest#CONTROL_ZOOM_RATIOCaptureRequest#SCALER_CROP_REGION ,則這意味著應用程序僅支持縮放,而不允許點擊對焦、閃光燈和曝光補償。

高級擴展器

Advanced Extender 是一種基於 Camera2 API 的供應商實現。此擴展器類型是在extensions-interface 1.2.0 中添加的。根據設備製造商的不同,擴展可能會在應用層實現,這取決於以下因素:

  • 自定義流配置:配置自定義流,如 RAW 流或為不同的物理相機 ID 設置多個流。

  • 發送Camera2請求的能力:支持複雜的交互邏輯,可以根據之前請求的結果發送帶參數的抓圖請求。

Advanced Extender 提供包裝器或中間層,因此您可以自定義流配置並按需發送捕獲請求。

要實施的文件

要切換到 Advanced Extender 實現, ExtensionVersionImpl中的isAdvancedExtenderImplemented()方法必須返回true 。對於每種擴展類型,OEM 必須實現相應的擴展器類。 Advanced Extender 實現文件位於高級包中。

要實現的擴展器類
夜晚advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
汽車advanced/AutoAdvancedExtenderImpl.java
散景advanced/BokehAdvancedExtenderImpl.java
面部修飾advanced/BeautyAdvancedExtenderImpl.java

在以下示例中,我們使用AdvancedExtenderImpl作為佔位符。將其替換為您正在實現的擴展的擴展器文件的名稱。

讓我們看看 Camera2/X 如何調用extensions-interface來實現三個應用程序流。

應用流程 1:檢查擴展程序的可用性

高級應用程序流1

圖 8. Advanced Extender 上的應用流程 1

首先,應用程序檢查是否支持給定的擴展。

應用流程二:查詢信息

AdvancedAppFlow2

圖 9. Advanced Extender 上的應用流程 2

調用AdvancedExtenderImpl.init()後,應用可以查詢AdvancedExtenderImpl的以下信息:

  • 估計的仍然捕獲延遲: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange()返回捕獲延遲的範圍,以供應用評估是否適合為當前場景啟用擴展。

  • 支持的預覽和捕捉分辨率:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions()將圖像格式的映射返回到預覽表面格式和尺寸支持的尺寸列表。 OEM 必須至少支持PRIVATE格式。

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions()返回靜止捕獲表面支持的格式和大小。 OEM 必須同時支持JPEGYUV_420_888格式輸出。

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()為圖像分析的額外YUV_420_888流返回支持的大小。如果不支持圖像分析 YUV 表面, getSupportedYuvAnalysisResolutions()應返回null或空列表。

  • 可用的捕獲請求鍵/結果(在extensions-interface 1.3.0 中添加):Camera2/X 調用以下方法從您的實現中檢索支持的捕獲請求鍵和結果鍵:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

有關詳細信息,請參閱支持捕獲請求密鑰和結果

應用流程 3:預覽/仍然捕獲並啟用擴展

AdvancedAppFlow3

圖 10. Advanced Extender 上的應用流程 3

上圖顯示了高級擴展器類型的開始預覽和仍然捕獲的主要流程。讓我們來看看每一步。

  1. SessionProcessorImpl實例

    核心的 Advanced Extender 實現在SessionProcessorImpl中,它負責提供自定義會話配置並發送捕獲請求以啟動預覽並仍然捕獲請求。調用AdvancedExtenderImpl.createSessionProcessor()以返回SessionProcessorImpl實例。

  2. initSession

    SessionProcessorImpl.initSession()為擴展初始化會話。這是您分配資源並返回會話配置以準備CameraCaptureSession的地方。

    對於輸入參數,Camera2/X 指定用於預覽、靜止捕捉和可選 YUV 圖像分析的輸出表面配置。此輸出表面配置 ( OutputSurfaceImpl ) 包含通過AdvancedExtenderImpl中的以下方法檢索的表面、大小和圖像格式:

    • getSupportedPreviewOutputResolutions()
    • getSupportedCaptureOutputResolutions()
    • getSupportedYuvAnalysisResolutions()

    您必須返回一個Camera2SessionConfigImpl實例,該實例由一個Camera2OutputConfigImpl實例列表和用於配置CameraCaptureSession的會話參數組成。您負責將正確的相機圖像輸出到 Camera2/X 傳入的輸出表面。以下是啟用輸出的一些選項:

    • 在相機 HAL 中處理:您可以使用SurfaceOutputConfigImpl實現直接將輸出表面添加到CameraCaptureSession 。這會將提供的輸出表面配置到相機管道,並允許相機 HAL 處理圖像。
    • 處理中間ImageReader表面(RAW、YUV 等):使用ImageReaderOutputConfigImpl實例將中間ImageReader表面添加到CameraCaptureSession

      您需要處理中間圖像並將結果圖像寫入輸出表面。

    • 使用 Camera2 表面共享:通過將任何Camera2OutputConfigImpl實例添加到另一個Camera2OutputConfigImpl實例的getSurfaceSharingOutputConfigs()方法來與另一個表面共享表面。表面格式和尺寸必須相同。

    所有Camera2OutputConfigImpl包括SurfaceOutputConfigImplImageReaderOutputConfigImpl都必須有一個唯一的 ID ( getId() ),用於指定目標表面並從ImageReaderOutputConfigImpl中檢索圖像。

  3. onCaptureSessionStartRequestProcessorImpl

    CameraCaptureSession啟動並且 Camera 框架調用onConfigured()時,Camera2/X 使用 Camera2 請求包裝器RequestProcessImpl調用SessionProcessorImpl.onCaptureSessionStart() 。 Camera2/X 實現RequestProcessImpl ,它使您能夠執行捕獲請求,並在使用ImageReaderOutputConfigImpl檢索圖像

    RequestProcessImpl API 在執行請求方麵類似於 Camera2 CameraCaptureSession API。區別在於:

    • 目標表面由Camera2OutputConfigImpl實例的 ID 指定。
    • 檢索ImageReader的圖像的能力。

    您可以使用指定的Camera2OutputConfigImpl ID 調用RequestProcessorImpl.setImageProcessor()來註冊ImageProcessorImpl實例以接收圖像。

    Camera2/X 調用SessionProcessorImpl.onCaptureSessionEnd()RequestProcessImpl實例失效。

  4. 開始預覽並拍照

    在 Advanced Extender 實現中,您可以通過RequestProcessorImpl接口發送捕獲請求。 Camera2/X 通過分別調用SessionProcessorImpl#startRepeatingSessionProcessorImpl#startCapture通知您開始重複請求以進行預覽或靜止捕獲序列。您應該發送捕獲請求以滿足這些預覽和靜止捕獲請求。

    Camera2/X 還通過SessionProcessorImpl#setParameters捕獲請求參數。您必須在重複請求和單個請求上設置這些請求參數(如果支持參數)。

    您必須至少支持CaptureRequest.JPEG_ORIENTATIONCaptureRequest.JPEG_QUALITYextensions-interface 1.3.0 支持 request 和 result 鍵,它們通過以下方法公開:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys()

    開發者在設置getAvailableCaptureRequestKeys列表中的鍵時,必須啟用參數並確保捕獲結果包含getAvailableCaptureResultKeys列表中的鍵。

  5. startTrigger

    SessionProcessorImpl.startTrigger()被調用來啟動觸發器,例如CaptureRequest.CONTROL_AF_TRIGGERCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER 。您可以忽略任何未在AdvancedExtenderImpl.getAvailableCaptureRequestKeys()中公佈的捕獲請求密鑰。

    extensions-interface 1.3.0 開始支持startTrigger() 。它使應用程序能夠通過擴展實現點擊對焦和閃光。

  6. 清理

    完成捕獲會話時,會在關閉CameraCaptureSession之前調用SessionProcessorImpl.onCaptureSessionEnd() 。捕獲會話關閉後, deInitSession()執行清理。

支持預覽、靜止捕捉和圖像分析

您應該為預覽和仍然捕獲用例應用擴展。但是,如果延遲太高而無法流暢地顯示預覽,您可以僅將效果應用於靜止捕捉。

對於 Basic Extender 類型,無論是否啟用預覽效果,都必須為給定擴展實現ImageCaptureExtenderImplPreviewExtenderImpl 。 Often, an app also uses a YUV stream to analyze the image content such as finding QR codes or text. To better support this use case , you should support the stream combination of preview, still capture, and a YUV_420_888 stream for configuring CameraCaptureSession . This means that if you implement a processor, then you have to support the stream combination of three YUV_420_888 streams.

For Advanced Extender, Camera2/X passes three output surfaces to the SessionProcessorImpl.initSession() call. These output surfaces are for preview , still capture, and image analysis, respectively. You must ensure that preview and still capture output surfaces show the valid output. However, for the image analysis output surface, ensure it's working only when it's non-null. If your implementation can't support the image analysis stream, you can return an empty list in AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . This ensures the image analysis output surface is always null in SessionProcessorImpl.initSession() .

Support video capture

The current Camera Extension architecture supports only the preview and still capture use cases. We don't support enabling the extension on the MediaCodec or MediaRecorder surfaces for recording the video. However, it's possible for apps to record the preview output.

Supporting MediaCodec and MediaRecorder surfaces is under investigation.

Extensions interface version history

The following table shows the Camera Extension interface version history. You should always implement the vendor library with the latest version.

Version Added features
1.0.0
  • Version verification
    • ExtensionVersionImpl
  • Basic Extender
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Library initialization
    • InitializerImpl
  • Expose supported resolutions
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Get estimated capture latency
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Expose supported capture request keys/results keys
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys and getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys and getAvailableCaptureResultKeys
    • New process() call that takes ProcessResultImpl in PreviewImageProcessorImpl and CaptureProcessorImpl
    • Support trigger type request
      • AdvancedExtenderImpl.startTrigger

Reference implementation

For a reference OEM vendor library implementation, see camera-testlib-extensions . Note that this implementation performs passthroughs without actually implementing the effects.

Set up the vendor library on a device

The OEM vendor library isn't built into an app; it's loaded from the device at runtime by Camera2/X. In CameraX, the <uses-library> tag declares that the androidx.camera.extensions.impl library, which is defined in the AndroidManifest.xml file of the camera-extensions library, is a dependency of CameraX and must be loaded at runtime. In Camera2, the framework loads an extensions service that also declares that the <uses-library> loads the same androidx.camera.extensions.impl library at runtime.

This allows third-party apps using extensions to automatically load the OEM vendor library. The OEM library is marked as optional so apps can run on devices that don't have the library on the device. Camera2/X handles this behavior automatically when an app tries to use a camera extension as long as the device manufacturer places the OEM library on the device so that it can be discovered by the app.

To set up the OEM library on a device, do the following:

  1. Add a permission file, which is required by the <uses-library> tag, using the following format: /etc/permissions/ ANY_FILENAME .xml . For example, /etc/permissions/camera_extensions.xml . The files in this directory provide a mapping of the library named in <uses-library> to the actual file path on the device.
  2. Use the example below to add the required information to the file.

    • name must be androidx.camera.extensions.impl as that's the library that CameraX searches for.
    • file is the absolute path of the file that contains the extensions implementation (for example, /system/framework/androidx.camera.extensions.impl.jar ).
    <?xml version="1.0" encoding="utf-8"?>
    <permissions>
        <library name="androidx.camera.extensions.impl"
                 file="OEM_IMPLEMENTED_JAR" />
    </permissions>
    

In Android 12 or higher, devices supporting CameraX extensions must have the ro.camerax.extensions.enabled property set to true , which allows for querying whether a device supports extensions. To do this, add the following line in the device make file:

PRODUCT_VENDOR_PROPERTIES += \
    ro.camerax.extensions.enabled=true \

Validation

To test your implementation of the OEM vendor library during the development stage, use the example app at androidx-main/camera/integration-tests/extensionstestapp/ , which runs through various vendor extensions.

After you complete your implementation, use the Camera Extensions Validation Tool to run automated and manual tests to verify that the vendor library is implemented correctly.

Frequently asked questions (FAQs)

Are there any restrictions on API levels?

Yes. This depends on the Android API feature set that's required by the OEM vendor library implementation. For example, ExtenderStateListener.onPresetSession() uses the SessionConfiguration.setSessionParameters() call to set a baseline set of tags. This call is available only on API level 28 and higher. For details on specific interface methods, see the API reference documentation .