CameraX 供應商擴展

設備製造商可以實現 CameraX OEM 供應商庫,以通過 CameraX 擴展接口向第三方開發人員公開設備特定的效果。 CameraX 為在運行時加載的供應商實現的類定義了 CameraX 擴展接口。本頁介紹如何實現 OEM 供應商庫並在設備上啟用它。

在實施供應商庫之前,請確保您了解 CameraX Jetpack 支持庫的工作原理。要了解有關 CameraX 的更多信息,請參閱CameraX 概述。有關供應商擴展的更多信息,請參閱供應商擴展

建築學

建築學

圖 1.供應商擴展架構圖

此圖描述了 CameraX 供應商擴展的體系結構。第三方應用程序可以針對 CameraX 擴展庫 ( camera-extensions ) 構建,並使用相機擴展公共 API ( camera-extensions API )。相機擴展 API 由 CameraX 定義,並在相機擴展庫的新版本發佈時更新。相機擴展公共 API 和相機擴展庫的版本控制是相同的。

從 Android 12 開始,可以針對 Camera2 擴展 API 構建第三方應用程序。要啟用支持的擴展模式,應用可以使用CameraDevice#createExtensionSession()創建相機捕獲會話 ( CameraExtensionSession )。

CameraX 定義的擴展接口 ( extensions-interface ) 允許 CameraX 相機擴展庫和 Camera2 擴展 API 與 OEM 供應商庫 ( camera-extensions-stub ) 進行通信。這意味著實現 CameraX OEM 供應商庫的設備也將支持 Camera2 擴展 API。

實施 OEM 供應商庫

這些實現說明使用散景(人像)供應商擴展作為示例,但您可以將它們應用於其他擴展,例如 HDR、面部修飾和夜間模式擴展。為此,請複制並粘貼用於散景擴展的代碼,並將擴展名替換為所需的擴展名(例如,將BokehImageCaptureExtenderImpl替換為HdrImageCaptureExtenderImpl )。

您不需要為每個效果提供實現。沒有供應商實現的效果默認為 CameraX 實現。如果某個效果不可用,則默認實現不會啟用該效果,並向第三方開發者報告該效果不可用。

版本驗證

加載 OEM 庫時,CameraX 會驗證 OEM 庫是否包含與擴展接口版本兼容的版本(在本文檔中稱為extension-version )。為了確定版本兼容性,CameraX 僅檢查主要和次要版本(例如 1.0),但不檢查補丁版本,因為它僅用於錯誤修復,而不是接口更改。本文檔中註明了特定 API 所需的擴展版本。沒有指定擴展版本的 API 與擴展版本 1.0 兼容。

為了驗證版本,CameraX 查詢ExtensionVersionImpl接口。然後,CameraX 使用 OEM 庫報告的版本來確定可以調用的功能。

初始化

CameraX 在確定 OEM 庫實現的擴展接口的版本後開始初始化過程。 InitializerImpl.init方法向 OEM 庫發出應用程序想要使用擴展的信號。在成功狀態調用OnExtensionsInitializedCallback之前,不會對 OEM 庫進行其他調用(除了版本檢查)。

此方法必須從擴展版本 1.1 開始實施。有關詳細信息,請參閱InitializerImpl的源代碼。

ExtenderStateListener 接口

CameraX 在其管道中的多個位置提供掛鉤,以允許 OEM 庫設置相關的SessionParametersCaptureRequest值。要允許 OEM 庫在指定時間設置這些值,請實現ExtenderStateListener接口。此接口必須作為任何擴展器的一部分來實現,無論是預覽、圖像捕獲、散景還是 HDR 擴展器。

圖像捕捉

要支持圖像捕獲的擴展,請實現相應的ImageCaptureExtender接口(例如BokehImageCaptureExtenderHdrImageCaptureExtender )。

ImageCaptureExtender包括與圖像捕獲相關的擴展所需的接口。

必須實現CaptureProcessor接口才能在應用層完成後處理。從擴展接口版本 1.1 開始,僅必須支持YUV_420_888輸入圖像格式。如果在相機 HAL 中完成處理,則不需要CaptureProcessor接口。

下圖說明了圖像捕獲處理流程。

圖像採集流程

圖 2.圖像捕獲流程圖

示例:BokehImageCaptureExtenderImpl

要支持圖像捕獲的散景擴展,請實現androidx.camera.extensions.impl包中的BokehImageCaptureExtenderImpl類。

預覽

要支持預覽擴展,請實現相應的PreviewExtender接口(例如BokehPreviewExtenderHdrPreviewExtender )。 PreviewExtender接口包括與預覽相關的擴展所需的接口。

有關詳細信息,請參閱PreviewExtender的源代碼。

預覽擴展的圖像處理可以在相機 HAL 或應用層中執行。這是由PreviewExtenderImpl返回的ProcessorType的值確定的。

如果返回PROCESSOR_TYPE_REQUEST_UPDATE_ONLY類型,則通過CaptureRequest鍵在 HAL 中執行處理。如果返回PROCESSOR_TYPE_IMAGE_PROCESSOR類型,則由PreviewImageProcessorImpl接口在應用層進行處理。此接口對ImageTotalCaptureResult對進行操作。從擴展接口版本 1.1 開始,僅必須支持YUV_420_888輸入圖像格式。

下圖說明了預覽供應商擴展的流程。

預覽流程圖

圖 3.預覽流程圖

示例:BokehPreviewExtenderImpl

要支持散景預覽,請在androidx.camera.extensions.impl包中實現BokehPreviewExtenderImpl類。

參考實現

有關參考 OEM 供應商庫實現,請參閱/platform/frameworks/support/camera/integration-tests/extensionstestlib/ 。請注意,此實現執行直通而不實際實現效果。

在設備上設置供應商庫

OEM 供應商庫未內置到應用程序中,而是由 CameraX 在運行時從設備加載。 <uses-library>標籤聲明了定義在AndroidManifest.xml文件中的androidx.camera.extensions.impl庫是 CameraX 的依賴項,必須在運行時加載。這允許使用供應商擴展的第三方應用程序自動嘗試加載 OEM 供應商庫。 OEM 庫被標記為可選,因此應用可以在沒有該庫的設備上運行。

只要設備製造商將 OEM 庫放置在設備上,以便應用可以發現它,CameraX 就會在應用嘗試使用供應商擴展時自動處理此行為。

要在設備上設置 OEM 庫,請執行以下操作:

  1. 使用以下格式添加<uses-library>標記所需的權限文件: /etc/permissions/ ANY_FILENAME .xml 。例如, /etc/permissions/camera_extensions.xml 。此目錄中的文件提供了在<uses-library>中命名的庫到設備上實際文件路徑的映射。
  2. 使用以下示例將所需信息添加到文件中。

    • name必須是androidx.camera.extensions.impl因為那是 CameraX 搜索的庫。
    • file是包含擴展實現的文件的絕對路徑(例如/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>
    

在 Android 12 或更高版本中,支持 CameraX 擴展的設備必須將ro.camerax.extensions.enabled屬性設置為true ,以便查詢設備是否支持擴展。為此,請在設備 make 文件中添加以下行:

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

驗證

要在開發階段測試 OEM 供應商庫的實現,請使用androidx-main/camera/integration-tests/extensionstestapp/中的示例應用程序,該應用程序運行各種供應商擴展。

完成實施後,使用CameraX 供應商擴展驗證工具運行自動和手動測試,以驗證供應商庫是否正確實施。

常見問題 (FAQ)

API 級別是否有任何限制?

是的。這取決於 OEM 供應商庫實現所需的 Android API 功能集。例如, ExtenderStateListener.onPresetSession()使用SessionConfiguration.setSessionParameters()調用來設置標籤的基線集。此調用僅適用於 API 級別 28 及更高級別。具體接口方法詳見API 參考文檔