Extensiones de cámara

Los fabricantes de dispositivos pueden exponer extensiones como bokeh, modo nocturno y HDR a desarrolladores externos a través de la interfaz de extensiones de cámara proporcionada por la biblioteca de proveedores OEM. Los desarrolladores pueden usar el API de Extensions para Camera2 y la API de Extensions para CameraX para acceder a las extensiones implementadas en la biblioteca de proveedores del OEM.

Para obtener una lista de las extensiones compatibles, que es la misma en Camera2 y CameraX, consulta API de Extensions para CameraX Si deseas agregar una extensión, informar un error con el Herramienta de seguimiento de errores.

En esta página, se describe cómo implementar y habilitar la biblioteca de proveedores de OEM en dispositivos.

Arquitectura

En el siguiente diagrama, se describe la arquitectura de las extensiones de cámara interfaz o extensions-interface: Arquitectura

Figura 1: Diagrama de arquitectura de las extensiones de cámara

Como se muestra en el diagrama, para admitir extensiones de cámara, debes hacer lo siguiente: Implementa el extensions-interface que proporciona la biblioteca de proveedores del OEM. Tu La biblioteca de proveedores de OEM permite dos APIs: API de CameraX Extensions y API de Extensions para Camera2, que usan las apps de CameraX y Camera2, respectivamente, para acceder extensiones de proveedores.

Cómo implementar la biblioteca de proveedores del OEM

Para implementar la biblioteca de proveedores del OEM, copia el camera-extensions-stub archivos en un proyecto de biblioteca del sistema. Estos archivos definen las extensiones de cámara interfaz de usuario.

La camera-extensions-stub archivos se dividen en las siguientes categorías:

Archivos esenciales de la interfaz (no modificarlos)

  • 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

Implementaciones obligatorias (agrega tu implementación)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Clases de amplificadores de Bokeh (implementaremos la extensión si se admite la extensión Bokeh)

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

Clases de amplificadores nocturnos (implementarla si se admite la extensión Night)

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

Clases de amplificadores automáticos (implementarlo si se admite la extensión automática)

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

Clases de extensor HDR (implementarlo si la extensión HDR es compatible)

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

Clases de amplificador de Retoque facial (implementarlo si se admite la extensión de Retoque facial)

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

Utilidades (opcional, se pueden borrar)

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

No es necesario que proporciones una implementación para cada extensión. Si no implementas una extensión, configura isExtensionAvailable() para que muestre false. quita las clases de amplificadores correspondientes. Las extensiones de Camera2 y CameraX Las APIs informan a la app que la extensión no está disponible.

Analicemos cómo interactúan las APIs de Extensions y Camera2 y CameraX con el la biblioteca del proveedor para habilitar una extensión. En el siguiente diagrama, se ilustra el de extremo a extremo con la extensión Night como ejemplo:

Flujo principal

Figura 2: Implementación de extensión nocturna

  1. Verificación de la versión:

    Camera2/X llama a ExtensionVersionImpl.checkApiVersion() para garantizar que el elemento La versión de extensions-interface implementada por el OEM es compatible con Camera2/X versiones compatibles.

  2. Inicialización de la biblioteca de proveedores:

    InitializerImpl tiene un método init() que inicializa la biblioteca del proveedor. Camera2/X completa la inicialización antes de acceder a las clases del amplificador.

  3. Crea instancias de clases de Extender:

    Crea una instancia de las clases de amplificador para la extensión. Hay dos amplificadores tipos: Amplificador básico y Amplificador avanzado. Debes implementar uno Tipo de amplificador para todas las extensiones. Para obtener más información, consulta Comparación entre el amplificador básico y el avanzado

    Camera2/X crea instancias de las clases del amplificador e interactúa con ellas para recuperarlas. información y habilitar la extensión. Para una extensión determinada, Camera2/X puede crear instancias de las clases Extender varias veces. Como resultado, no hagas una inicialización pesada en el constructor o la llamada a init(). Haz lo siguiente: levantar peso pesado solo cuando la sesión de la cámara está a punto de inicial, como cuando se llama a onInit() en el amplificador básico o Se llama a initSession() en el amplificador avanzado.

    En el caso de la extensión Night, se crean instancias de las siguientes clases de amplificadores para el tipo de amplificador básico:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    Y para el tipo de amplificador avanzado:

    • NightAdvancedExtenderImpl.java
  4. Verifica la disponibilidad de las extensiones:

    Antes de habilitar la extensión, isExtensionAvailable() verifica si el elemento está disponible en el ID de cámara especificado a través del amplificador. instancia.

  5. Inicializa el amplificador con la información de la cámara:

    Camera2/X llama a init() en la instancia del amplificador y le pasa la cámara a la cámara. ID y CameraCharacteristics.

  6. Información de la consulta:

    Invoca la clase Extender para recuperar información como los de estado, capturar la latencia estimada y capturar claves de solicitud de el amplificador a fin de prepararlo para habilitar la extensión.

  7. Sigue estos pasos para habilitar la extensión en el amplificador:

    La clase Extender proporciona todas las interfaces necesarias para habilitar la clase. Ofrece un mecanismo para atraer al OEM en la canalización de Camera2, como la inserción de solicitudes de captura de entrada o la habilitación de un procesador posterior.

    Para el tipo de amplificador avanzado, Camera2/X interactúa con SessionProcessorImpl para habilitar la extensión. Camera2/X recupera el SessionProcessorImpl llamando a createSessionProcessor() en el Amplificador.

En las siguientes secciones, se describe el flujo de extensión con más detalle.

Verificación de la versión

Cuando se carga la biblioteca del proveedor OEM desde el dispositivo durante el tiempo de ejecución, Camera2/X verifica si la biblioteca es compatible con la versión extensions-interface. extensions-interface usa el control de versiones semántico. MAJOR.MINOR.PATCH, por ejemplo, 1.1.0 o 1.2.0. Sin embargo, solo los principales y secundarias durante la verificación de la versión.

Para verificar la versión, Camera2/X llama ExtensionVersionImpl.checkApiVersion() por extensions-interface versión. Luego, Camera2/X usa la versión informada por la biblioteca de OEM para determinar si se puede habilitar la extensión y qué capacidades que debe invocar.

Compatibilidad con versiones principales

Si las versiones principales de extension-interface son diferentes entre Camera2/X y la biblioteca del proveedor, se considera incompatible y la extensión está inhabilitada.

Retrocompatibilidad

Siempre que la versión principal sea idéntica, Camera2/X garantiza retrocompatibilidad con bibliotecas de proveedores OEM compiladas con anterioridad extensions-interface versiones. Por ejemplo, si Camera2/X admite extensions-interface 1.3.0, las bibliotecas de los proveedores OEM que implementaron 1.0.0 1.1.0 y 1.2.0 siguen siendo compatibles. Esto también significa que, después de implementar una versión específica de la biblioteca del proveedor, Camera2/X se asegura de que es retrocompatible con las próximas extension-interface versiones.

Compatibilidad con versiones posteriores

Compatibilidad con versiones futuras de las bibliotecas de proveedores de la versión extensions-interface más reciente depende de ti, el OEM. Si necesita algunas funciones para implementar las extensiones, es posible que quiera habilitar las extensiones a partir de una versión determinada. En este caso, puedes mostrar la versión compatible de extensions-interface cuando la La versión de la biblioteca Camera2/X cumple con los requisitos. Si las versiones de Camera2/X no son compatibles, puedes devolver una versión incompatible, como la 99.0.0, en inhabilitar las extensiones.

Inicialización de la biblioteca de proveedores

Después de verificar la versión de extensions-interface que implementó el OEM , Camera2/X inicia el proceso de inicialización. El El método InitializerImpl.init() le indica a la biblioteca del OEM que prueba una app. para usar extensiones.

Camera2/X no realiza ninguna otra llamada a la biblioteca del OEM (excepto la verificación de versión). hasta que la biblioteca del proveedor del OEM llame a OnExtensionsInitializedCallback.onSuccess() para notificar que se completó la inicialización.

Debes implementar InitializerImpl a partir del extensions-interface 1.1.0. Camera2/X omite la inicialización de la biblioteca. paso si la biblioteca del proveedor del OEM implementa extensions-interface 1.0.0.

Amplificador básico frente a amplificador avanzado

Hay dos tipos de implementación de extensions-interface: amplificador básico y Amplificador avanzado. El amplificador avanzado es compatible desde extensions-interface 1.2.0.

Implementa el amplificador básico para extensiones que procesan imágenes en la HAL de la cámara o usan un postprocesador capaz de procesar transmisiones YUV.

Cómo implementar Advanced Extender para extensiones que necesitan personalizar Camera2 de transmisión continua y enviar solicitudes de captura.

Consulta la siguiente tabla para ver una comparación:

Amplificador básico Amplificador avanzado
Configuraciones de transmisión Fija
Vista previa: PRIVATE o YUV_420_888 (si existe un procesador)
Capturar: JPEG o YUV_420_888 (si existe procesador)
El OEM puede personalizarlo.
Enviando la solicitud de captura Solo Camera2/X puede enviar solicitudes de captura. Puedes configurar los parámetros estas solicitudes. Cuando se proporciona el procesador para la captura de imágenes, Camera2/X puede enviar varias solicitudes de captura, enviar todas las imágenes y capturar los resultados al procesador. Se te proporciona una instancia de RequestProcessorImpl para ejecutar la solicitud de captura de camera2 y obtener resultados y una imagen.

Camera2/X invoca a startRepeating y startCapture en SessionProcessorImpl para indicarle al OEM que inicie la repetición. para la vista previa y comienza la secuencia de captura estática, respectivamente.

Enganches en la canalización de la cámara
  • onPresetSession proporciona parámetros de sesión.
  • onEnableSession envía una sola solicitud inmediatamente después de configurar CameraCaptureSession.
  • onDisableSession envía una sola solicitud antes de que se cierre CameraCaptureSession.
  • initSession inicializa y muestra una camera2 personalizada. de sesión para crear la sesión de captura.
  • onCaptureSessionStart se invoca inmediatamente después de configurar CameraCaptureSession.
  • onCaptureSessionEnd se invoca antes de que se cierre CameraCaptureSession.
Apta para Extensiones implementadas en la HAL de la cámara o en un procesador que procesa Imágenes YUV.
  • Tiene implementaciones basadas en Camera2 para las extensiones.
  • Requiere una configuración de transmisión personalizada, por ejemplo, una transmisión RAW.
  • Requiere secuencia de captura interactiva.
Versión de API compatible Extensiones de Camera2: Android 13 o versiones posteriores
Extensiones de CameraX: camera-extensions 1.1.0 o versiones posteriores
Extensiones de Camera2: Android 12L o versiones posteriores
Extensiones de CameraX: camera-extensions 1.2.0-alpha03 o versiones posteriores

Flujos de aplicaciones

En la siguiente tabla, se muestran tres tipos de flujos de apps y sus llamadas correspondientes a la API de Camera Extensions. Si bien Camera2/X proporciona estas APIs, debes implementar correctamente la biblioteca del proveedor para admitir estas de Terraform, que describiremos con más detalle en una sección posterior.

Extensiones de Camera2 Extensiones de CameraX
Disponibilidad de extensiones de consulta CameraExtensionCharacteristics .getSupportedExtensions ExtensionsManager. isExtensionAvailable
Información de la consulta CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX controla el resto de la información dentro de la biblioteca.

Vista previa y captura estática con la extensión habilitada CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector

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

Amplificador básico

La interfaz del amplificador básico proporciona hooks a varios lugares de la cámara en una canalización de integración continua. Cada tipo de extensión tiene las clases de amplificadores correspondientes que necesitan los OEM para implementarlo.

En la siguiente tabla, se enumeran las clases de amplificadores que los OEMs deben implementar para cada una de ellas. extensión:

Clases de amplificadores para implementar
Noche NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java

HdrImageCaptureExtenderImpl.java

Automático AutoPreviewExtenderImpl.java

AutoImageCaptureExtenderImpl.java

Bokeh BokehPreviewExtenderImpl.java

BokehImageCaptureExtenderImpl.java

Retoque facial BeautyPreviewExtenderImpl.java

BeautyImageCaptureExtenderImpl.java

Usamos PreviewExtenderImpl y ImageCaptureExtenderImpl como marcadores de posición en el siguiente ejemplo. Reemplázalas por los nombres del dominio los archivos que implementes.

El amplificador básico tiene las siguientes funciones:

  • Incorpora parámetros de sesión cuando configures CameraCaptureSession ( onPresetSession).
  • Notificarte sobre los eventos de inicio y cierre de la sesión de captura, y enviar un único para notificar a la HAL con los parámetros mostrados (onEnableSession, onDisableSession).
  • Cómo insertar parámetros de captura para la solicitud (PreviewExtenderImpl.getCaptureStage, ImageCaptureExtenderImpl.getCaptureStages).
  • Agrega procesadores para obtener una vista previa y captura contenido capaz de procesarse. Novedades de YUV_420_888.

Veamos cómo Camera2/X invoca el elemento extensions-interface para lograr estos tres. los flujos de aplicaciones mencionados anteriormente.

Flujo de app 1: Comprueba la disponibilidad de las extensiones

BasicExtenderAppFlow1

Figura 3: Flujo de app 1 en el amplificador básico

En este flujo, Camera2/X llama directamente al método isExtensionAvailable() de PreviewExtenderImpl y ImageCaptureExtenderImpl sin llamar init() Ambas clases de amplificador deben mostrar true para habilitar las extensiones.

Este suele ser el primer paso para que las apps verifiquen si la extensión determinada tipo es compatible con un ID de cámara determinado antes de habilitar la extensión. Esto se debe a que algunas extensiones solo son compatibles con determinados IDs de cámara.

Flujo de la app 2: Información de consulta

BasicExtenderAppFlow2

Figura 4: Flujo de app 2 en el amplificador básico

Después de determinar si la extensión está disponible, las apps deben realizar consultas la siguiente información antes de habilitar la extensión.

  • Captura el rango de latencia: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange devuelve el rango de la latencia de captura para que la app evalúe si es apropiado habilitar la extensión para la situación actual.

  • Tamaños admitidos para la superficie de vista previa y captura: ImageCaptureExtenderImpl.getSupportedResolutions y PreviewExtenderImpl.getSupportedResolutions muestra una lista de formatos de imagen y de los tamaños compatibles para el tamaño y el formato de la superficie.

  • Claves de solicitudes y resultados admitidas: Camera2/X invoca los siguientes métodos para recuperar la captura compatible solicitar claves y claves de resultados de tu implementación:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X siempre llama a init() primero en estas clases de amplificadores antes de realizar consultas. para obtener más información.

Flujo de app 3: Vista previa/captura estática con la extensión habilitada (implementación de HAL)

BasicExtenderAppFlow3

Figura 5: Flujo de app 3 en el amplificador básico

En el diagrama anterior, se ilustra el flujo principal de habilitación de la vista previa y capturar con una extensión sin procesador. Esto significa que la HAL de la cámara procesa la extensión.

En este flujo, Camera2/X primero llama a init() y, luego, a onInit, lo que te notifica que está a punto de comenzar una sesión de cámara con las extensiones especificadas. Puedes realizar una inicialización pesada en onInit().

Cuando configuras CameraCaptureSession, Camera2/X invoca onPresetSession para obtener los parámetros de la sesión. Una vez finalizada la sesión de captura configurado correctamente, Camera2/X invoca a onEnableSession y muestra un CaptureStageImpl que contiene los parámetros de captura. Cámara2/X envía inmediatamente una única solicitud con estos parámetros de captura para notificar al HAL. De manera similar, antes de que se cierre la sesión de captura, Camera2/X invoca onDisableSession y, luego, envía una sola solicitud con la captura que se muestra. parámetros.

La solicitud recurrente activada por Camera2/X contiene los parámetros de la solicitud. que devuelve PreviewExtenderImpl.getCaptureStage(). Además, el ajuste de captura contiene los parámetros que muestra ImageCaptureExtenderImpl.getCaptureStages()

Por último, Camera2/X invoca a onDeInit() una vez finalizada la sesión de la cámara. Puedes liberar recursos en onDeinit().

Procesador de vista previa

Además de la HAL de la cámara, también puedes implementar extensiones en un procesador.

Implementa PreviewExtenderImpl.getProcessorType para especificar el tipo de procesador como se explica a continuación:

  • PROCESSOR_TYPE_NONE: Sin procesador. Las imágenes se procesan en la cámara HAL.

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY: El tipo de procesador te permite actualizar la solicitud recurrente con nuevos parámetros de solicitud de captura basados en el último TotalCaptureResult.

    PreviewExtenderImpl.getProcessor debe mostrar un RequestUpdateProcessorImpl que procesa la instancia TotalCaptureResult y muestra un Instancia CaptureStageImpl para actualizar la solicitud recurrente. PreviewExtenderImpl.getCaptureStage() también debe reflejar el resultado de el procesamiento y muestra la última CaptureStageImpl.

  • PROCESSOR_TYPE_IMAGE_PROCESSOR: Este tipo te permite implementar un para procesar imágenes YUV_420_888 y escribir la salida en una PRIVATE.

    Debes implementar y mostrar un PreviewImageProcessorImpl en PreviewExtenderImpl.getProcessor. El encargado del tratamiento de datos para procesar YUV_420_888 imágenes de entrada. Se debe escribir el resultado en la Formato PRIVATE de la vista previa. En su lugar, Camera2/X usa una superficie YUV_420_888. de PRIVATE para configurar CameraCaptureSession para la vista previa.

    Consulta la siguiente ilustración para ver el flujo:

PreviewProcessor

Figura 6: Obtén una vista previa del flujo con PreviewImageProcessorImpl

La interfaz PreviewImageProcessorImpl extiende ProcessImpl y tiene tres métodos importantes:

  • onOutputSurface(Surface surface, int imageFormat) establece la superficie de salida. para el procesador. Para PreviewImageProcessorImpl, imageFormat es un píxel. formato, como PixelFormat.RGBA_8888.

  • onResolutionUpdate(Size size) establece el tamaño de la imagen de entrada.

  • onImageFormatUpdate(int imageFormat) establece el formato de imagen de la entrada. imagen. Actualmente, solo puede ser YUV_420_888.

Procesador de captura de imágenes

Para la captura estática, puedes implementar un procesador mostrando un CaptureProcessorImpl con ImageCaptureExtenderImpl.getCaptureProcessor. El procesador es responsable de procesar una lista de las imágenes de YUV_420_888 capturadas y TotalCaptureResult y escribe el resultado en una superficie YUV_420_888.

Puedes suponer que la vista previa está habilitada y en ejecución antes de enviar el una solicitud de captura estática.

Observa el flujo en el siguiente diagrama:

Procesador Capture

Figura 7: Capturar el flujo con CaptureProcessorImpl

  1. Para su configuración, Camera2/X usa una superficie de formato YUV_420_888 para la captura estática. la sesión de captura. Camera2/X prepara CaptureProcessorImpl llamando al siguiente:

    • CaptureProcessorImpl.onImageFormatUpdate() con YUV_420_888.
    • CaptureProcessorImpl.onResolutionUpdate() por el tamaño de la imagen de entrada
    • CaptureProcessorImpl.onOutputSurface() con una salida YUV_420_888 de ataque de la nube.
  2. ImageCaptureExtenderImpl.getCaptureStages muestra una lista de CaptureStageImpl , en la que cada elemento se asigna a una instancia de CaptureRequest con parámetros de captura que envía Camera2/X. Por ejemplo, si devuelve una lista de tres CaptureStageImpl instancias, Camera2/X envía tres solicitudes de captura con los parámetros de captura correspondientes captureBurst API de gcloud.

  3. Las imágenes recibidas y las instancias de TotalCaptureResult se agrupan y se envían a CaptureProcessorImpl para su procesamiento.

  4. CaptureProcessorImpl escribe la imagen resultante (en formato YUV_420_888) en la de salida especificada por la llamada onOutputSurface(). Camera2/X lo convierte en imágenes JPEG si es necesario.

Cómo admitir claves de solicitudes de captura y resultados

Además de la vista previa y captura de la cámara, las apps pueden configurar el zoom, parámetros de flash o activar un botón de presionar para enfocar. Es posible que estos parámetros no se compatible con la implementación de extensiones.

Se agregaron los siguientes métodos a extensions-interface 1.3.0 para permitir para exponer los parámetros que admite tu implementación:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() devuelve el capturar claves de solicitud compatibles con tu implementación.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() devuelve el las claves de resultado de captura que se encuentran en el resultado de captura.

Si la HAL de la cámara procesa la extensión, Camera2/X recupera la captura. da como resultado CameraCaptureSession.CaptureCallback. Sin embargo, si se implementa el procesador, Camera2/X recupera los resultados de la captura en ProcessResultImpl , que se pasa a process(). método en PreviewImageProcessorImpl y CaptureProcessorImpl Eres responsable de informar el resultado de la captura a través de ProcessResultImpl a Camera2/X.

Consulta la definición de la interfaz CaptureProcessorImpl a continuación como un ejemplo. En extensions-interface 1.3.0 o versiones posteriores, se invoca la segunda llamada a 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);
}

Para operaciones comunes de la cámara, como zoom, presionar para enfocar, flash y exposición adicional, te recomendamos que admitas las siguientes claves para la captura solicitud y captura del resultado:

  • Zoom:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Presionar para enfocar:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Flash:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Compensación por exposición:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

Para amplificadores básicos que implementan la versión 1.2.0 o versiones anteriores, el CameraX La API de Extensions admite explícitamente todas las claves anteriores. Para extensions-interface 1.3.0, tanto CameraX como Camera2 respetan la lista que se muestra y admitir solo las claves que contiene. Por ejemplo, si decides devolver solo CaptureRequest#CONTROL_ZOOM_RATIO y CaptureRequest#SCALER_CROP_REGION en la implementación de la versión 1.3.0, significa que solo se admite el zoom para la app y la función de presionar para enfocar, flash y exposición remuneración mínima.

Amplificador avanzado

Advanced Extender es un tipo de implementación de proveedor que se basa en la API de Camera2. Este tipo de amplificador se agregó en extensions-interface 1.2.0. Según fabricante del dispositivo, implementar extensiones en la capa de la aplicación que depende de los siguientes factores:

  • Configuración de transmisión personalizada: Configura transmisiones personalizadas, como las RAW. o tener varias transmisiones para diferentes IDs de cámaras físicas.

  • Capacidad para enviar solicitudes de Camera2: Admite una interacción complicada. que pueda enviar solicitudes de captura con parámetros basados en los resultados de de solicitudes anteriores.

El amplificador avanzado proporciona un wrapper o una capa intermedia para que puedas personalizar la configuración de la transmisión y enviar solicitudes de captura a pedido.

Archivos para implementar

Para cambiar a la implementación del amplificador avanzado, Método isAdvancedExtenderImplemented() en ExtensionVersionImpl debe mostrar true. Para cada tipo de extensión, los OEM deben implementar el clases de amplificadores correspondientes. Los archivos de implementación del amplificador avanzado son en el paquete advanced.

Clases de amplificadores para implementar
Noche advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Automático advanced/AutoAdvancedExtenderImpl.java
Bokeh advanced/BokehAdvancedExtenderImpl.java
Retoque facial advanced/BeautyAdvancedExtenderImpl.java

En el siguiente ejemplo, usamos AdvancedExtenderImpl como marcador de posición. Reemplázalo con el nombre del archivo del amplificador de la extensión para implementarlos.

Veamos cómo Camera2/X invoca el elemento extensions-interface para lograr estos tres. en los flujos de la app.

Flujo de aplicación 1: Comprueba la disponibilidad de las extensiones

Flujo de aplicación avanzado1

Figura 8: Flujo de app 1 en el amplificador avanzado

Primero, la app comprueba si la extensión en cuestión es compatible.

Flujo de la app 2: Información de consulta

Flujo de aplicación avanzado2

Figura 9: Flujo de app 2 en el amplificador avanzado

Después de llamar a AdvancedExtenderImpl.init(), la app puede consultar siguiendo la información sobre AdvancedExtenderImpl:

  • Latencia estimada de las capturas estáticas: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() devuelve el rango de la latencia de captura para que la app evalúe si es apropiado habilitar la extensión para la situación actual.

  • Resoluciones admitidas para la vista previa y la captura estática:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() devuelve un mapa. de formato de imagen a la lista de tamaños compatibles con el formato de superficie de vista previa y tamaño. Los OEM deben admitir al menos el formato PRIVATE.

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() devuelve el y tamaños admitidos para la superficie de captura estática. Los OEM deben admitir Resultado en formato JPEG y YUV_420_888.

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() devuelve el tamaños admitidos para una transmisión de YUV_420_888 adicional para el análisis de imágenes. Si el botón no se admite la superficie YUV del análisis de imágenes, getSupportedYuvAnalysisResolutions() debe mostrar null o una lista vacía.

  • Claves/resultados de solicitud de captura disponibles (agregados en extensions-interface 1.3.0): Camera2/X invoca los siguientes métodos para recuperar la captura compatible solicitar claves y claves de resultados de tu implementación:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Para obtener más información, consulta Compatibilidad con claves de solicitud de captura y resultados.

Flujo de app 3: Vista previa o captura estática con la extensión habilitada

Flujo de aplicación avanzado3

Figura 10: Flujo de app 3 en el amplificador avanzado

En el diagrama anterior, se muestra el flujo principal para iniciar la vista previa y capturar aún más el tipo de amplificador avanzado. Revisemos cada paso.

  1. Instancia SessionProcessorImpl

    La implementación principal del amplificador avanzado se encuentra en SessionProcessorImpl, que es responsable de proporcionar una configuración de sesión personalizada y enviar capturar solicitudes para iniciar la vista previa y continuar la solicitud de captura. Se invoca AdvancedExtenderImpl.createSessionProcessor() para mostrar el Instancia SessionProcessorImpl.

  2. initSession

    SessionProcessorImpl.initSession() inicializa la sesión para la extensión. Aquí es donde se asignan los recursos y se muestra una configuración de sesión para preparar un CameraCaptureSession.

    Para los parámetros de entrada, Camera2/X especifica las configuraciones de la superficie de salida para obtener una vista previa, capturar imágenes y un análisis opcional de imágenes YUV. Este resultado la configuración de la superficie (OutputSurfaceImpl) contiene la superficie, el tamaño y la imagen que se recuperan mediante los siguientes métodos en AdvancedExtenderImpl:

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

    Debes mostrar una instancia Camera2SessionConfigImpl, que consta de un lista de instancias de Camera2OutputConfigImpl y los parámetros de sesión usados para configurar CameraCaptureSession. Es responsable de generar las imágenes de cámara correctas a las superficies de salida que pasan Cámara 2/X. Estas son algunas opciones para habilitar el resultado:

    • Procesamiento en la HAL de la cámara: Puedes agregar directamente las superficies de salida. a CameraCaptureSession con un SurfaceOutputConfigImpl para implementarlos. De esta manera, se configura la superficie de salida proporcionada a la cámara. y permite que la HAL de la cámara procese la imagen.
    • Procesamiento de la superficie ImageReader intermedia (RAW, YUV, etc.): Agrega el Las plataformas ImageReader intermedias se muestran a CameraCaptureSession con un Instancia ImageReaderOutputConfigImpl.

      Debes procesar las imágenes intermedias y escribir la imagen de resultado en la superficie de salida.

    • Usa el uso compartido de superficies de Camera2: Usa el uso compartido de superficies con otra plataforma. si agregas cualquier instancia de Camera2OutputConfigImpl al El método getSurfaceSharingOutputConfigs() de otro Instancia Camera2OutputConfigImpl. El formato y tamaño de la superficie deben ser idénticos.

    Todos los Camera2OutputConfigImpl, incluidos SurfaceOutputConfigImpl y ImageReaderOutputConfigImpl debe tener un ID único (getId()), que es que se usa para especificar la superficie de destino y recuperar la imagen de ImageReaderOutputConfigImpl

  3. onCaptureSessionStart y RequestProcessorImpl

    Cuando se inicia CameraCaptureSession e invoca el framework de la cámara onConfigured(), Camera2/X invoca SessionProcessorImpl.onCaptureSessionStart() con la solicitud Camera2 el wrapper RequestProcessImpl. Camera2/X implementa RequestProcessImpl, que te permite ejecutar las solicitudes de captura y recuperar imágenes si se usa ImageReaderOutputConfigImpl

    Las APIs de RequestProcessImpl son similares a Camera2 CameraCaptureSession en términos de ejecución de solicitudes. Las diferencias son las siguientes:

    • La superficie de destino se especifica mediante el ID del Instancia Camera2OutputConfigImpl.
    • La capacidad de recuperar la imagen de ImageReader

    Puedes llamar a RequestProcessorImpl.setImageProcessor() con un valor ID de Camera2OutputConfigImpl para registrar una instancia ImageProcessorImpl pueden recibir imágenes.

    La instancia RequestProcessImpl deja de ser válida después de las llamadas de Camera2/X SessionProcessorImpl.onCaptureSessionEnd()

  4. Iniciar la vista previa y tomar una foto

    En la implementación del amplificador avanzado, puedes enviar solicitudes de captura a través de la interfaz RequestProcessorImpl. Camera2/X te notifica iniciar la solicitud recurrente de vista previa o la secuencia de captura estática llamando a SessionProcessorImpl#startRepeating y SessionProcessorImpl#startCapture respectivamente. Deberías enviar la captura para satisfacer estas solicitudes de vista previa y de captura fija.

    Camera2/X también establece los parámetros de la solicitud de captura a través de SessionProcessorImpl#setParameters Debes establecer estos parámetros de solicitud (si se admiten parámetros) tanto en solicitudes recurrentes como únicas.

    Debes admitir al menos CaptureRequest.JPEG_ORIENTATION y CaptureRequest.JPEG_QUALITY extensions-interface 1.3.0 admite solicitudes y las claves de resultado, que se exponen mediante los siguientes métodos:

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

    Cuando los desarrolladores establecen las claves en la lista getAvailableCaptureRequestKeys, debes habilitar los parámetros y asegurarte de que la captura El resultado contiene las claves de la lista getAvailableCaptureResultKeys.

  5. startTrigger

    Se invoca SessionProcessorImpl.startTrigger() para iniciar el activador, como como CaptureRequest.CONTROL_AF_TRIGGER y CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER Puedes ignorar cualquier de solicitudes de captura que no se anunciaron AdvancedExtenderImpl.getAvailableCaptureRequestKeys()

    startTrigger() es compatible desde la versión 1.3.0 de extensions-interface. Integra permite que las apps implementen la función de presionar para enfocar y escribir en la memoria flash con extensiones.

  6. Realiza una limpieza

    Al terminar una sesión de captura, Se invoca SessionProcessorImpl.onCaptureSessionEnd() antes del cierre CameraCaptureSession Una vez finalizada la sesión de captura, deInitSession() realiza la limpieza.

Compatibilidad con la vista previa, la captura estática y el análisis de imágenes

Deberías aplicar la extensión tanto para la vista previa como para la captura de casos de uso. Sin embargo, si la latencia es demasiado alta para mostrar sin problemas la vista previa, puedes aplica la extensión solo para la captura estática.

Para el tipo de amplificador básico, independientemente de habilitar la extensión para la vista previa, debes implementar ImageCaptureExtenderImpl y PreviewExtenderImpl para una extensión determinada. A menudo, una app también usa una transmisión YUV para analizar la contenido de imágenes, como la búsqueda de códigos QR o de texto. Para admitir mejor este caso de uso , debes admitir la combinación de transmisión de vista previa, la captura estática y un Transmisión de YUV_420_888 para configurar CameraCaptureSession. Esto significa que, si implementas un procesador, deberás admitir la transmisión combinación de tres transmisiones YUV_420_888.

Para el amplificador avanzado, Camera2/X pasa tres superficies de salida al SessionProcessorImpl.initSession() llamada. Estas plataformas de salida son para la vista previa , la captura estática y el análisis de imágenes, respectivamente. Asegúrate de que la vista previa y las superficies de salida de capturas estáticas muestran el resultado válido. Sin embargo, para la imagen análisis de salida, asegúrate de que funcione solo cuando no sea nulo. Si el implementación no admite el flujo de análisis de imágenes, puedes mostrar un lista en AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions(). Esta garantiza que la superficie de salida del análisis de imágenes siempre sea nula en SessionProcessorImpl.initSession()

Compatibilidad con captura de video

La arquitectura actual de la extensión de cámara solo admite la vista previa y para capturar casos de uso. No se admite habilitar la extensión en MediaCodec o MediaRecorder para grabar el video. Sin embargo, es posible para que las apps graben el resultado de la vista previa.

Se está investigando la compatibilidad con las plataformas MediaCodec y MediaRecorder.

Metadatos específicos de la extensión

En el caso de Android 14 y versiones posteriores, metadatos específicos de la extensión Permite a los clientes de extensiones de cámara establecer y recibir capturas específicas de la extensión. la configuración y los resultados de las solicitudes. Específicamente, extensión de la cámara los clientes pueden usar el parámetro de solicitud de captura EXTENSION_STRENGTH para controlar la intensidad de la extensión y el resultado de captura de EXTENSION_CURRENT_TYPE para indicar el tipo de extensión habilitada.

Solicitudes de captura

El EXTENSION_STRENGTH Parámetro de solicitud de captura controla la intensidad del efecto de procesamiento posterior de la extensión. El modelo de Si no se establece este parámetro, el resultado de la captura incluye el valor de intensidad predeterminado explícitamente por el cliente. Este parámetro se puede aplicar de la siguiente manera para estas tipos de extensiones:

  • BOKEH: Controla la cantidad de desenfoque.
  • HDR y NIGHT: Controla la cantidad de imágenes fusionadas y el brillo de la imagen final.
  • FACE_RETOUCH: Controla la cantidad de mejoras estéticas y de la piel. suavizado de forma manual.

El rango admitido para el parámetro EXTENSION_STRENGTH está entre 0 y 100, en el que 0 indica que no se procesó ninguna extensión ni se realizó una transferencia simple. 100: Indica la intensidad máxima de la extensión del efecto de procesamiento.

Para agregar compatibilidad con EXTENSION_STRENGTH, usa el proveedor. APIs de parámetros específicos que se introdujeron en la versión 1.3.0 de la biblioteca de extensiones interfaz de usuario. Para obtener más información, consulta getAvailableCaptureRequestKeys().

Captura los resultados

El EXTENSION_CURRENT_TYPE capturado permite que las implementaciones de extensiones notifiquen a los clientes sobre la actividad tipo de extensión.

Porque las extensiones que usan el tipo AUTO cambian de manera dinámica entre las extensiones tipos, como HDR y NIGHT, según las condiciones de la escena, la cámara extensiones las apps pueden usar EXTENSION_CURRENT_TYPE para mostrar información sobre la extensión actual que seleccionó la extensión AUTO.

Estimación de latencia de capturas estáticas en tiempo real

Para Android 14 y versiones posteriores, los clientes de extensiones de cámara puede consultar en tiempo real, de todos modos, capturar estimaciones de latencia según la escena y las condiciones del entorno getRealtimeStillCaptureLatency() Esta proporciona estimaciones más precisas que la estática getEstimatedCaptureLatencyRangeMillis() . Según la estimación de latencia, las apps pueden decidir omitir la extensión procesamiento ni mostrar una indicación para notificar a los usuarios sobre la larga operación en ejecución.

CameraExtensionSession.StillCaptureLatency latency;

latency = extensionSession.getRealtimeStillCaptureLatency();

// The capture latency from ExtensionCaptureCallback#onCaptureStarted() until ExtensionCaptureCallback#onCaptureProcessStarted().

latency.getCaptureLatency();

// The processing latency from  ExtensionCaptureCallback#onCaptureProcessStarted() until  the processed frame returns to the client.

latency.getProcessingLatency();

Para admitir estimaciones de latencia de capturas estáticas en tiempo real, implementa lo siguiente:

Devoluciones de llamada del progreso de procesamiento de la captura

Para Android 14 y versiones posteriores, los clientes de extensiones de cámara Puede recibir devoluciones de llamada sobre el progreso del procesamiento de captura fija de larga duración. las operaciones. Las apps pueden mostrar el progreso actual a los usuarios para mejorar la experiencia general del usuario.

Las apps pueden usar el siguiente código para integrar esta función:

import android.hardware.camera2.CameraExtensionSession.
ExtensionCaptureCallback;

{
…
  class AppCallbackImpl extends ExtensionCaptureCallback {
…
    @Override
    public void onCaptureProcessProgressed(
      @NonNull CameraExtensionSession session,
      @NonNull CaptureRequest request,
      @IntRange(from = 0, to = 100) int progress) {
      // Update app UI with current progress
    }
  }
…
}

Para admitir las devoluciones de llamada del progreso del procesamiento de la captura, el proveedor de la extensión implementación debe llamar a las siguientes devoluciones de llamada con el progreso actual valor:

Captura estática de la vista previa

En Android 14 y versiones posteriores, las extensiones de cámara pueden suministrar una vista previa (imagen de vista previa) con setPostviewOutputConfiguration Para mejorar la experiencia del usuario, las apps pueden mostrar una imagen postview como marcador de posición cuando una extensión tiene una mayor latencia de procesamiento y reemplace la imagen cuando esté disponible la imagen final. Las apps pueden configurar y emite solicitudes de captura postview con el siguiente código de referencia:

{
…
if (!CameraExtensionCharacteristics.isPostviewAvailable()) {
    continue;
}
…
ExtensionSessionConfiguration extensionConfiguration = new
        ExtensionSessionConfiguration(
                CameraExtensionCharacteristics.EXTENSION_NIGHT,
                outputConfig,
                backgroundExecutor,
                extensionSessionStateCallback
    );

extensionConfiguration.setPostviewOutputConfiguration(
    postviewImageOutput);
…
CaptureRequest.Builder captureRequestBuilder =
    cameraDevice.createCaptureRequest(
        CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(stillImageReader.getSurface());
captureRequestBuilder.addTarget(postviewImageSurface);

CaptureRequest captureRequest = captureRequestBuilder.build();
…
}

Para admitir la captura estática de la vista previa, la implementación de tu proveedor debe implementar el lo siguiente:

Compatibilidad con el resultado de SurfaceView

Para Android 14 y versiones posteriores, los clientes de extensiones de cámara puede usar rutas de renderización de vista previa optimizadas para la potencia y el rendimiento registrando un SurfaceView para obtener una vista previa del resultado de las solicitudes recurrentes.

Para admitir el resultado de SurfaceView, la implementación de la extensión de tu proveedor debe ser Es capaz de transmitir y generar vistas previas a SurfaceView instancias. Para verifica que sea compatible, ejecuta SurfaceViewExtensionPreviewTest.java Módulo de CTS

Tipos de sesiones específicos de proveedores

La función permite que las implementaciones de extensiones de proveedores seleccionen un tipo de sesión específico del proveedor que se configurará en la sesión de captura de cámara interna en lugar del valor predeterminado.

La función funciona completamente dentro del framework y la pila de proveedores, y no tiene un impacto visible en la API entre el cliente o el público.

Para seleccionar un tipo de sesión específico del proveedor, implementa lo siguiente en tus bibliotecas de extensiones: * ExtenderStateListener.onSessionType() para extensiones básicas * Camera2SessionConfigImpl.getSessionType() para extensiones avanzadas

Historial de versiones de la interfaz de extensiones

En la siguiente tabla, se muestra el historial de versiones de la interfaz de extensión de cámara. Tú siempre debes implementar la biblioteca del proveedor con la versión más reciente.

Versión Funciones agregadas
1.0.0
  • Verificación de la versión
    • ExtensionVersionImpl
  • Amplificador básico
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Inicialización de la biblioteca
    • InitializerImpl
  • Exponer las resoluciones admitidas
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Obtener una latencia de captura estimada
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Exponer claves de resultados/claves de solicitud de captura admitidas
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys y getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys y getAvailableCaptureResultKeys
    • Nueva llamada a process() que toma ProcessResultImpl en PreviewImageProcessorImpl y CaptureProcessorImpl
    • Compatibilidad con la solicitud de tipo de activador
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Metadatos específicos de la extensión
  • Estimaciones dinámicas de latencia de capturas estáticas
  • Devoluciones de llamada del progreso de procesamiento de la captura
  • Captura estática de la vista previa
  • Compatibilidad con la salida SurfaceView
  • Tipos de sesiones específicos de proveedores

Implementación de referencia

Las siguientes implementaciones de bibliotecas de proveedores OEM de referencia están disponibles en frameworks/ex

  • advancedSample: Es una implementación básica del amplificador avanzado.

  • sample: Es una implementación básica del amplificador básico.

  • service_based_sample: Es una implementación que demuestra cómo alojar. Extensiones de cámara Service Esta implementación contiene los siguientes componentes:

    • oem_library Una biblioteca de OEM de extensiones de cámara para las APIs de extensiones de Camera2 y CameraX que implementa Extensions-Interface. Esto actúa como una transferencia que desvía llamadas de Extensions-Interface al servicio. Esta biblioteca también proporciona archivos AIDL y clases de wrapper para comunicarse con el servicio.

      El amplificador avanzado está habilitado de forma predeterminada. Para habilitar el amplificador básico, haz lo siguiente: cambia ExtensionsVersionImpl#isAdvancedExtenderImplemented para mostrar false

    • extensions_service Este es un ejemplo de implementación del servicio de extensiones. Agrega tu implementación aquí. La interfaz que se implementará en el servicio es similar a Extensions-Interface. Por ejemplo, implementar el IAdvancedExtenderImpl.Stub realiza las mismas operaciones que AdvancedExtenderImpl ImageWrapper y TotalCaptureResultWrapper son se requiere para hacer que Image y TotalCaptureResult sean parcelables.

Configura la biblioteca del proveedor en un dispositivo

La biblioteca del proveedor OEM no está integrada en una app. se carga desde el dispositivo durante el tiempo de ejecución. En CameraX, la etiqueta <uses-library> declara que la biblioteca androidx.camera.extensions.impl, que se define en el AndroidManifest.xml de la biblioteca camera-extensions, es una dependencia de CameraX y se debe se cargan en el tiempo de ejecución. En Camera2, el framework carga un servicio de extensiones que también declara que <uses-library> carga la misma androidx.camera.extensions.impl durante el tiempo de ejecución.

Esto permite que las apps de terceros que usan extensiones carguen automáticamente el OEM biblioteca de proveedores. La biblioteca del OEM se marca como opcional para que las apps puedan ejecutarse en dispositivos que no tienen la biblioteca en el dispositivo. Camera2/X controla este comportamiento automáticamente cuando una app intenta usar la cámara siempre y cuando el fabricante del dispositivo coloque la biblioteca OEM en el para que la app pueda detectarlo.

Para configurar la biblioteca del OEM en un dispositivo, haz lo siguiente:

  1. Agrega un archivo de permisos, requerido por la etiqueta <uses-library>. con el siguiente formato: /etc/permissions/ANY_FILENAME.xml Para por ejemplo, /etc/permissions/camera_extensions.xml. Los archivos de esta proporcionan una asignación de la biblioteca denominada en <uses-library> al ruta de acceso real del archivo en el dispositivo.
  2. Usa el siguiente ejemplo para agregar la información requerida al archivo.

    • name debe ser androidx.camera.extensions.impl, ya que es la biblioteca que busca CameraX.
    • file es la ruta de acceso absoluta del archivo que contiene el implementación de extensiones (por ejemplo, /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>
    

En Android 12 o versiones posteriores, los dispositivos compatibles con CameraX Las extensiones deben tener la propiedad ro.camerax.extensions.enabled establecida en true, que permite consultar si un dispositivo admite extensiones. Para ello, agrega la siguiente línea en el archivo de marca del dispositivo:

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

Validación

Para probar tu implementación de la biblioteca de proveedores de OEM durante la en la etapa de desarrollo, usa la app de ejemplo androidx-main/camera/integration-tests/extensionstestapp/, que se ejecuta a través de varias extensiones de proveedores.

Después de completar la implementación, usa el Herramienta de validación de extensiones de la cámara para ejecutar pruebas automatizadas y manuales para verificar que la biblioteca del proveedor esté se implementaron correctamente.

Modo panorámico extendido frente a extensiones de cámara

En el caso de la extensión bokeh, además de exponerla con las extensiones de la cámara, también puedes puede exponer la extensión con el modo panorámico extendido, que se habilita mediante el CONTROL_EXTENDED_SCENE_MODE . Para obtener más detalles sobre la implementación, consulta Bokeh de la cámara.

El modo panorámico extendido tiene menos restricciones en comparación con las extensiones de la cámara para de la app de camera2. Por ejemplo, puedes habilitar el modo panorámico extendido en una instancia CameraCaptureSession normal que admite transmisión flexible y captura los parámetros de solicitud. En cambio, las extensiones de la cámara admiten solo un conjunto fijo de tipos de transmisión y tienen compatibilidad limitada con la captura los parámetros de solicitud.

Una desventaja del modo panorámico extendido es que solo puedes implementarlo en HAL de la cámara, lo que significa que se debe verificar que funcione en todos y controles ortogonales disponibles para los desarrolladores de apps.

Te recomendamos que expongas el bokeh con el modo de escena extendido y la Cámara Extensiones porque las apps podrían preferir usar una API en particular para habilitar el bokeh. Recomendamos usar primero el modo de escena extendido porque es el más y flexible para que las apps habiliten la extensión bokeh. Luego, puedes implementar interfaz de extensiones de la cámara basada en el modo panorámico extendido. Si implementas bokeh en la HAL de la cámara es difícil, por ejemplo, porque requiere una publicación procesador que se ejecuta en la capa de la app para procesar imágenes, recomendamos implementar la extensión bokeh con la interfaz de extensiones de la cámara.

Preguntas frecuentes

¿Existen restricciones para los niveles de API?

Sí. Depende del conjunto de funciones de la API de Android que requiera el OEM. implementación de la biblioteca de proveedores. Por ejemplo: ExtenderStateListener.onPresetSession() usa el SessionConfiguration.setSessionParameters() para establecer un conjunto de etiquetas de referencia. Esta llamada solo está disponible en el nivel de API 28 y versiones posteriores Para obtener detalles sobre métodos de interfaz específicos, consulta la Documentación de referencia de la API.