相机扩展程序

设备制造商可以通过原始设备制造商 (OEM) 供应商库提供的相机扩展接口向第三方开发者提供焦外成像、夜间模式和高动态范围 (HDR) 等特效。开发者可以利用 Camera2 Extensions APICameraX Extensions API 启用各种特效,这些特效以 OEM 供应商库中的扩展的形式在设备上实现。

如需查看支持的扩展列表(对于 Camera2 和 CameraX 来说是一样的),请参阅 CameraX Extensions API。如果您想要添加扩展程序,请提交 bug

本文介绍了如何在设备上实现和启用 OEM 供应商库。

架构

下图显示了相机扩展程序接口(即 extensions-interface)的架构: 架构

图 1. 相机扩展程序架构图

如图所示,为了支持相机扩展程序,您需要实现 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

焦外成像扩展器类(如果支持焦外成像扩展程序,请予以实现)

  • 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

脸部照片修复扩展器类(如果支持脸部照片修复扩展程序,请予以实现)

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

实用程序(可选,可以删除)

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

您不需要实现所有扩展程序。如果您不实现某个扩展程序,请将 isExtensionAvailable() 设置为返回 false,或移除相应的扩展器类。Camera2 Extensions API 和 CameraX Extensions API 会向应用报告该扩展程序不可用。

接下来我们了解一下 Camera2 Extensions API 和 CameraX Extensions API 如何与供应商库进行交互,以启用扩展程序。下图以夜间模式扩展程序为例,显示了端到端流程:

主流程

图 2. 夜间模式扩展程序实现

  1. 版本验证

    Camera2/X 会调用 ExtensionVersionImpl.checkApiVersion(),以确保 OEM 实现的 extensions-interface 版本与 Camera2/X 支持的版本兼容。

  2. 供应商库初始化

    InitializerImpl 具有一个 init() 方法,用于初始化供应商库。Camera2/X 会先完成该初始化,然后再访问扩展器类。

  3. 实例化扩展器类

    为扩展程序实例化扩展器类。扩展器分为两种类型:基本扩展器和高级扩展器。您必须为所有扩展程序实现一种扩展器类型。如需了解详情,请参阅基本扩展器与高级扩展器

    Camera2/X 会实例化扩展器类并与之交互,以检索信息并启用扩展程序。对于给定扩展程序,Camera2/X 可以将扩展器类实例化多次。因此,请勿在构造函数或 init() 调用中执行繁重的初始化任务,而是仅在相机会话即将启动时进行,例如在基本扩展器中调用 onInit() 时或在高级扩展器中调用 initSession() 时。

    对于夜间模式扩展程序,Camera2/X 会针对基本扩展器类型实例化以下扩展器类:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    并会针对高级扩展器类型实例化以下扩展器类:

    • NightAdvancedExtenderImpl.java
  4. 检查扩展程序的可用性

    在启用扩展程序之前,isExtensionAvailable() 会通过扩展器实例检查扩展程序对于指定的相机 ID 是否可用。

  5. 使用相机信息初始化扩展器

    Camera2/X 会针对扩展器实例调用 init(),并向其传递相机 ID 和 CameraCharacteristics

  6. 查询信息

    调用扩展器类,以从扩展器检索支持的分辨率、预计静态拍摄延迟时间以及拍摄请求密钥等信息,为启用扩展程序做好准备。

  7. 在扩展器上启用扩展程序

    扩展器类提供启用该类所需的所有接口。它提供一种将 OEM 实现接入 Camera2 管道的机制,例如注入拍摄请求参数或启用后期处理程序。

    对于高级扩展器类型,Camera2/X 会与 SessionProcessorImpl 进行交互,以启用扩展程序。Camera2/X 通过在扩展器上调用 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 和供应商库的“extension-interface”的主要版本不同,系统会将其视为不兼容,并停用相应扩展程序。

向后兼容性

只要主要版本相同,Camera2/X 即可确保向后兼容使用之前的 extensions-interface 版本构建的 OEM 供应商库。例如,如果 Camera2/X 支持 extensions-interface 1.3.0,则实现 1.0.0、1.1.0 和 1.2.0 的 OEM 供应商库仍然兼容。这也意味着,您实现特定版本的供应商库后,可确保该库向后兼容支持即将推出的 extension-interface 版本的 Camera2/X。

向前兼容性

是否与实现较新的 extensions-interface 版本的供应商库向前兼容取决于您(即 OEM)。如果您需要某些功能来实现扩展程序,则可能需要支持自特定版本以来的扩展程序。在这种情况下,您可以在 Camera2/X 库版本符合相关要求时,返回支持的 extensions-interface 版本。如果 Camera2/X 版本不受支持,您可以返回不兼容的版本(例如 99.0.0),以停用扩展程序。

供应商库初始化

验证 OEM 库实现的 extensions-interface 版本后,Camera2/X 会启动初始化流程。InitializerImpl.init() 方法会向 OEM 库发出信号,表明应用正在尝试使用扩展程序。

在 OEM 供应商库调用 OnExtensionsInitializedCallback.onSuccess() 以通知初始化完成之前,Camera2/X 不会对 OEM 库进行任何其他调用(版本检查除外)。

extensions-interface 1.1.0 开始,您必须实现 InitializerImpl。如果 OEM 供应商库实现 extensions-interface 1.0.0,Camera2/X 会跳过库初始化步骤。

基本扩展器与高级扩展器

extensions-interface 实现分为两种类型:基本扩展器和高级扩展器。高级扩展器从 extensions-interface 1.2.0 开始受支持。

针对在相机 HAL 中处理图片或使用能够处理 YUV 数据流的后期处理程序的扩展程序,实现基本扩展器。

针对需要自定义 Camera2 数据流配置和根据需要发送拍摄请求的扩展程序,实现高级扩展器。

如需进行比较,请参阅下表:

基本扩展器 高级扩展器
数据流配置 固定
预览:PRIVATEYUV_420_888(如果有处理器)
静态拍摄:JPEGYUV_420_888(如果有处理器)
可由 OEM 自定义。
发送拍摄请求 只有 Camera2/X 可以发送拍摄请求。您可以为这些请求设置参数。为图片拍摄提供处理器时,Camera2/X 可以发送多个拍摄请求,并将所有图片和拍摄结果发送给处理器。 系统为您提供了一个 RequestProcessorImpl 实例,可用于执行 Camera2 拍摄请求并获取结果和图片。

Camera2/X 会针对 SessionProcessorImpl 调用 startRepeatingstartCapture,以分别指示 OEM 发起重复预览请求或启动静态拍摄序列。

相机管道中的钩子
  • onPresetSession 用于提供会话参数。
  • onEnableSession 用于在 CameraCaptureSession 配置完成后立即发送单个请求。
  • onDisableSession 用于在 CameraCaptureSession 关闭之前发送单个请求。
  • initSession 用于初始化并返回自定义的 Camera2 会话配置,以创建拍摄会话。
  • 系统会在 CameraCaptureSession 配置完成后立即调用 onCaptureSessionStart
  • 系统会在 CameraCaptureSession 关闭之前调用 onCaptureSessionEnd
适用情形 在相机 HAL 或处理 YUV 图片的处理器中实现的扩展程序。
  • 对于特效,采用基于 Camera2 的实现。
  • 需要自定义数据流配置,例如 RAW 数据流。
  • 需要交互式拍摄序列。
支持的 API 版本 Camera2 扩展程序:Android 13 或更高版本
CameraX 扩展程序:camera-extensions 1.1.0 或更高版本
Camera2 扩展:Android 12L 或更高版本
CameraX 扩展:camera-extensions 1.2.0-alpha03 或更高版本

应用流程

下表显示了 3 种类型的应用流程及其对应的 Camera Extensions 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, ...)

基本扩展器

基本扩展器接口在相机管道中的多个位置提供钩子。每种扩展程序类型都有相应的扩展器类,OEM 需要实现这些类。

下表列出了 OEM 需要为每个扩展程序实现的扩展器类:

需要实现的扩展器类
夜间模式 NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java