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 del proveedor OEM. Los desarrolladores pueden utilizar la API de extensiones Camera2 y la API de extensiones CameraX para acceder a las extensiones implementadas en la biblioteca del proveedor OEM.

Para obtener una lista de extensiones compatibles, que es la misma en Camera2 y CameraX, consulte API de extensiones de CameraX . Si desea agregar una extensión, presente un error en Issue Tracker .

Esta página describe cómo implementar y habilitar la biblioteca de proveedores OEM en dispositivos.

Arquitectura

El siguiente diagrama describe la arquitectura de la interfaz de Camera Extensions o extensions-interface : Arquitectura

Figura 1. Diagrama de arquitectura de Extensiones de cámara

Como se muestra en el diagrama, para admitir extensiones de cámara, debe implementar la extensions-interface proporcionada por la biblioteca del proveedor OEM. Su biblioteca de proveedores OEM habilita dos API: CameraX Extensions API y Camera2 Extensions API , que utilizan las aplicaciones CameraX y Camera2, respectivamente, para acceder a las extensiones de proveedores.

Implementar la biblioteca de proveedores OEM

Para implementar la biblioteca del proveedor OEM, copie los archivos camera-extensions-stub en un proyecto de biblioteca del sistema. Estos archivos definen la interfaz de Extensiones de cámara.

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

Archivos de interfaz esenciales (no modificar)

  • 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 (agregue su implementación)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Clases de extensión de Bokeh (impleméntelas si se admite la extensión de Bokeh)

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

Clases de extensión nocturna (impleméntelas si se admite la extensión nocturna)

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

Clases de extensión automática (impleméntelas si se admite la extensión automática)

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

Clases de extensión HDR (impleméntelas si se admite la extensión HDR)

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

Clases de extensión de Face Retouch (impleméntelas si la extensión Face Retouch es compatible)

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

Utilidades (opcional, se puede eliminar)

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

No es necesario que proporcione una implementación para cada extensión. Si no implementa una extensión, configure isExtensionAvailable() para devolver false o eliminar las clases Extender correspondientes. Las API de extensiones Camera2 y CameraX informan a la aplicación que la extensión no está disponible.

Veamos cómo las API de extensiones Camera2 y CameraX interactúan con la biblioteca del proveedor para habilitar una extensión. El siguiente diagrama ilustra el flujo de un extremo a otro utilizando la extensión Noche como ejemplo:

Flujo principal

Figura 2. Implementación de extensión nocturna

  1. Verificación de versión:

    Camera2/X llama a ExtensionVersionImpl.checkApiVersion() para garantizar que la versión extensions-interface implementada por OEM sea compatible con las versiones compatibles con Camera2/X.

  2. Inicialización de la biblioteca del proveedor:

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

  3. Crear instancias de clases de extensor:

    Crea una instancia de las clases Extender para la extensión. Hay dos tipos de extensores: extensores básicos y extensores avanzados. Debe implementar un tipo de extensor para todas las extensiones. Para obtener más información, consulte Extensor básico versus Extensor avanzado .

    Camera2/X crea instancias e interactúa con las clases Extender para recuperar 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 realice una inicialización pesada en el constructor o en la llamada init() . Haga el trabajo pesado solo cuando la sesión de la cámara esté a punto de comenzar, como cuando se llama onInit() en Basic Extender o initSession() en Advanced Extender.

    Para la extensión Noche, se crean instancias de las siguientes clases de Extensor para el tipo de Extensor Básico:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    Y para el tipo Advanced Extender:

    • NightAdvancedExtenderImpl.java
  4. Consultar disponibilidad de extensiones:

    Antes de habilitar la extensión, isExtensionAvailable() comprueba si la extensión está disponible en la ID de cámara especificada a través de la instancia de Extender.

  5. Inicialice el extensor con información de la cámara:

    Camera2/X llama init() en la instancia de Extender y le pasa el ID de la cámara y CameraCharacteristics .

  6. Información de consulta:

    Invoca la clase Extender para recuperar información como las resoluciones admitidas, capturar la latencia estimada y capturar claves de solicitud del Extender en preparación para habilitar la extensión.

  7. Habilite la extensión en el extensor:

    La clase Extender proporciona todas las interfaces necesarias para habilitar la clase. Ofrece un mecanismo para conectar la implementación OEM al canal Camera2, como inyectar parámetros de solicitud de captura o habilitar un posprocesador.

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

Las siguientes secciones describen el flujo de extensión con mayor detalle.

Verificación de versión

Al cargar la biblioteca del proveedor OEM desde el dispositivo en tiempo de ejecución, Camera2/X verifica si la biblioteca es compatible con la versión de la extensions-interface . La extensions-interface utiliza versiones semánticas, o MAJOR.MINOR.PATCH, por ejemplo, 1.1.0 o 1.2.0. Sin embargo, sólo se utilizan las versiones principal y secundaria durante la verificación de la versión.

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

Compatibilidad de versiones principales

Si las versiones principales de la interfaz de extensión son diferentes entre Camera2/X y la biblioteca del proveedor, entonces se considera incompatible y la extensión se desactiva.

Compatibilidad con versiones anteriores

Siempre que la versión principal sea idéntica, Camera2/X garantiza la compatibilidad con bibliotecas de proveedores OEM creadas con versiones anteriores extensions-interface . Por ejemplo, si Camera2/X admite extensions-interface 1.3.0, las bibliotecas del proveedor 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 la biblioteca sea compatible con las próximas versiones extension-interface .

Compatibilidad hacia adelante

La compatibilidad futura con bibliotecas de proveedores de extensions-interface más nuevas depende de usted, el OEM. Si necesita algunas funciones para implementar las extensiones, es posible que desee habilitarlas a partir de una versión determinada. En este caso, puede devolver la versión extensions-interface admitida cuando la versión de la biblioteca Camera2/X cumpla con los requisitos. Si las versiones de Camera2/X no son compatibles, puede devolver una versión incompatible como 99.0.0 para desactivar las extensiones.

Inicialización de la biblioteca del proveedor

Después de verificar la versión extensions-interface implementada por la biblioteca OEM, Camera2/X inicia el proceso de inicialización. El método InitializerImpl.init() indica a la biblioteca OEM que una aplicación está intentando utilizar extensiones.

Camera2/X no realiza otras llamadas a la biblioteca OEM (aparte de la verificación de la versión) hasta que la biblioteca del proveedor OEM llama a OnExtensionsInitializedCallback.onSuccess() para notificar la finalización de la inicialización.

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

Extensor básico versus extensor avanzado

Hay dos tipos de implementación extensions-interface : Basic Extender y Advanced Extender. Advanced Extender ha sido compatible desde extensions-interface 1.2.0.

Implemente Basic Extender para extensiones que procesen imágenes en la cámara HAL o use un postprocesador capaz de procesar transmisiones YUV.

Implemente Advanced Extender para extensiones que necesiten personalizar la configuración de transmisión de Camera2 y enviar solicitudes de captura según sea necesario.

Consulte la siguiente tabla para realizar la comparación:

Extensor básico Extensor avanzado
Configuraciones de transmisión Fijado
Vista previa: PRIVATE o YUV_420_888 (si existe el procesador)
Captura fija: JPEG o YUV_420_888 (si existe el procesador)
Personalizable por OEM.
Enviando solicitud de captura Sólo Camera2/X puede enviar solicitudes de captura. Puede configurar los parámetros para estas solicitudes. Cuando se proporciona el procesador para la captura de imágenes, Camera2/X puede enviar múltiples solicitudes de captura y enviar todas las imágenes y los resultados de la captura al procesador. Se le proporciona una instancia RequestProcessorImpl para ejecutar la solicitud de captura de la cámara2 y obtener resultados e imágenes.

Camera2/X invoca startRepeating y startCapture en SessionProcessorImpl para indicarle al OEM que inicie la solicitud repetida de vista previa e inicie la secuencia de captura fija, respectivamente.

Ganchos en el tubo de la cámara
  • onPresetSession proporciona parámetros de sesión.
  • onEnableSession envía una única solicitud justo después de configurar CameraCaptureSession .
  • onDisableSession envía una única solicitud antes de que se cierre CameraCaptureSession .
  • initSession inicializa y devuelve una configuración de sesión de cámara2 personalizada para crear la sesión de captura.
  • onCaptureSessionStart se invoca justo después de configurar CameraCaptureSession .
  • onCaptureSessionEnd se invoca antes de cerrar CameraCaptureSession .
Adecuado para Extensiones implementadas en la cámara HAL o en un procesador que procesa imágenes YUV.
  • Tiene implementaciones basadas en Camera2 para las extensiones.
  • Necesita una configuración de transmisión personalizada, como transmisión RAW.
  • Necesita secuencia de captura interactiva.
Versión de API compatible Extensiones de Camera2: Android 13 o superior
Extensiones CameraX: camera-extensions 1.1.0 o superior
Extensiones Camera2: Android 12L o superior
Extensiones CameraX: camera-extensions 1.2.0-alpha03 o superior

Flujos de aplicaciones

La siguiente tabla muestra tres tipos de flujos de aplicaciones y sus correspondientes llamadas API de Camera Extensions. Si bien Camera2/X proporciona estas API, debe implementar correctamente la biblioteca del proveedor para admitir estos flujos, que describimos con más detalle en una sección posterior.

Extensiones de cámara2 Extensiones de cámaraX
Disponibilidad de extensión de consulta CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
Consultar información CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

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

Vista previa y captura fija con la extensión habilitada CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector bindToLifecycle(lifecycleOwner, cameraSelector, vista previa, ...)

Extensor básico

La interfaz del extensor básico proporciona conexiones en varios lugares del canal de la cámara. Cada tipo de extensión tiene clases de extensor correspondientes que los OEM deben implementar.

La siguiente tabla enumera las clases de extensión que los OEM deben implementar para cada extensión:

Clases extendidas para implementar
Noche NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java HdrImageCaptureExtenderImpl.java
Auto AutoPreviewExtenderImpl.java AutoImageCaptureExtenderImpl.java
bokeh BokehPreviewExtenderImpl.java BokehImageCaptureExtenderImpl.java
retoque facial BeautyPreviewExtenderImpl.java BeautyImageCaptureExtenderImpl.java

Usamos PreviewExtenderImpl e ImageCaptureExtenderImpl como marcadores de posición en el siguiente ejemplo. Reemplácelos con los nombres de los archivos reales que está implementando.

Basic Extender tiene las siguientes capacidades:

  • Inyecte parámetros de sesión al configurar CameraCaptureSession ( onPresetSession ).
  • Notificarle sobre los eventos de inicio y cierre de la sesión de captura y enviar una única solicitud para notificar al HAL con los parámetros devueltos ( onEnableSession , onDisableSession ).
  • Inyecte parámetros de captura para la solicitud ( PreviewExtenderImpl.getCaptureStage , ImageCaptureExtenderImpl.getCaptureStages ).
  • Agregue procesadores para obtener una vista previa y captura fija que sean capaces de procesar la transmisión YUV_420_888 .

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

Flujo de aplicación 1: comprobar la disponibilidad de la extensión

BasicExtenderAppFlow1

Figura 3. Flujo de aplicación 1 en Basic Extender

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

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

Flujo de aplicación 2: consultar información

BasicExtenderAppFlow2

Figura 4. Flujo de aplicación 2 en Basic Extender

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

  • Rango de latencia de captura fija: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange devuelve el rango de latencia de captura para que la aplicación evalúe si es apropiado habilitar la extensión para el escenario actual.

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

  • Claves de solicitud y resultados admitidas: Camera2/X invoca los siguientes métodos para recuperar las claves de solicitud de captura y de resultados admitidas de su implementación:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X siempre llama init() primero en estas clases de Extender antes de solicitar más información.

Flujo de aplicación 3: vista previa/captura fija con la extensión habilitada (implementación HAL)

BasicExtenderAppFlow3

Figura 5. Flujo de aplicación 3 en Basic Extender

El diagrama anterior ilustra el flujo principal para habilitar la vista previa y la captura fija con una extensión sin ningún procesador. Esto significa que la cámara HAL procesa la extensión.

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

Al configurar CameraCaptureSession , Camera2/X invoca onPresetSession para obtener los parámetros de la sesión. Una vez que la sesión de captura se configura correctamente, Camera2/X invoca onEnableSession y devuelve una instancia CaptureStageImpl que contiene los parámetros de captura. Camera2/X envía inmediatamente una única solicitud con estos parámetros de captura para notificar a HAL. De manera similar, antes de que se cierre la sesión de captura, Camera2/X invoca onDisableSession y luego envía una única solicitud con los parámetros de captura devueltos.

La solicitud repetida activada por Camera2/X contiene los parámetros de solicitud devueltos por PreviewExtenderImpl.getCaptureStage() . Además, la solicitud de captura fija contiene los parámetros devueltos por ImageCaptureExtenderImpl.getCaptureStages() .

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

Procesador de vista previa

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

Implemente 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 le permite actualizar la solicitud repetida con nuevos parámetros de solicitud de captura basados ​​en el último TotalCaptureResult .

    PreviewExtenderImpl.getProcessor debe devolver una instancia RequestUpdateProcessorImpl que procesa la instancia TotalCaptureResult y devuelve una instancia CaptureStageImpl para actualizar la solicitud repetida. PreviewExtenderImpl.getCaptureStage() también debería reflejar el resultado del procesamiento y devolver el último CaptureStageImpl .

  • PROCESSOR_TYPE_IMAGE_PROCESSOR : este tipo le permite implementar un procesador para procesar imágenes YUV_420_888 y escribir la salida en una superficie PRIVATE .

    Debe implementar y devolver una instancia PreviewImageProcessorImpl en PreviewExtenderImpl.getProcessor . El procesador es responsable de procesar las imágenes de entrada YUV_420_888 . Debería escribir la salida en el formato PRIVATE de vista previa. Camera2/X utiliza una superficie YUV_420_888 en lugar de PRIVATE para configurar CameraCaptureSession para la vista previa.

    Vea la siguiente ilustración para el flujo:

Procesador de vista previa

Figura 6. Flujo de vista previa 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 formato de píxeles 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 imagen de entrada. Actualmente, solo puede ser YUV_420_888 .

Procesador de captura de imágenes

Para la captura fija, puede implementar un procesador devolviendo una instancia CaptureProcessorImpl usando ImageCaptureExtenderImpl.getCaptureProcessor . El procesador es responsable de procesar una lista de imágenes YUV_420_888 capturadas e instancias TotalCaptureResult y escribir la salida en una superficie YUV_420_888 .

Puede asumir con seguridad que la vista previa está habilitada y ejecutándose antes de enviar la solicitud de captura de imágenes fijas.

Vea el flujo en el siguiente diagrama:

Procesador de captura

Figura 7. Todavía captura el flujo con CaptureProcessorImpl

  1. Camera2/X utiliza una superficie de formato YUV_420_888 para la captura fija para configurar la sesión de captura. Camera2/X prepara CaptureProcessorImpl llamando a:

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

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

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

Admite claves y resultados de solicitudes de captura

Además de la vista previa y la captura de la cámara, las aplicaciones pueden configurar el zoom, los parámetros del flash o activar un toque para enfocar. Es posible que estos parámetros no sean compatibles con la implementación de su extensión.

Los siguientes métodos se han agregado a extensions-interface 1.3.0 para permitirle exponer los parámetros que admite su implementación:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() devuelve las claves de solicitud de captura admitidas por su implementación.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() devuelve las claves de resultados de captura contenidas en el resultado de captura.

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

Consulte la definición de la interfaz CaptureProcessorImpl a continuación como ejemplo. En extensions-interface 1.3.0 o superior, se invoca la segunda llamada al 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, toque para enfocar, flash y compensación de exposición, recomendamos admitir las siguientes teclas tanto para la solicitud de captura como para el resultado de la captura:

  • Zoom:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Tocar para enfocar:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Destello:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Compensación de exposición:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

Para Basic Extenders que implementan 1.2.0 o versiones anteriores, la API de CameraX Extensions admite explícitamente todas las claves anteriores. Para extensions-interface 1.3.0, tanto CameraX como Camera2 respetan la lista devuelta y admiten solo las claves contenidas en ella. Por ejemplo, si decide devolver solo CaptureRequest#CONTROL_ZOOM_RATIO y CaptureRequest#SCALER_CROP_REGION en la implementación 1.3.0, eso significa que solo se admite el zoom para la aplicación, mientras que no se permiten tocar para enfocar, flash ni compensación de exposición.

Extensor avanzado

Advanced Extender es un tipo de implementación de proveedor basada en la API de Camera2. Este tipo de extensor se agregó en extensions-interface 1.2.0. Dependiendo del fabricante del dispositivo, es posible que se implementen extensiones en la capa de aplicación, lo que depende de los siguientes factores:

  • Configuración de transmisión personalizada: configure transmisiones personalizadas como transmisión RAW o tenga múltiples transmisiones para diferentes ID de cámara física.

  • Capacidad para enviar solicitudes de Camera2: admite una lógica de interacción complicada que puede enviar solicitudes de captura con parámetros basados ​​en los resultados de solicitudes anteriores.

Advanced Extender proporciona un contenedor o una capa intermedia, para que pueda personalizar la configuración de la transmisión y enviar solicitudes de captura a pedido.

Archivos para implementar

Para cambiar a la implementación de Advanced Extender, el método isAdvancedExtenderImplemented() en ExtensionVersionImpl debe devolver true . Para cada tipo de extensión, los OEM deben implementar las clases de extensor correspondientes. Los archivos de implementación de Advanced Extender se encuentran en el paquete avanzado .

Clases extendidas para implementar
Noche advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Auto advanced/AutoAdvancedExtenderImpl.java
bokeh advanced/BokehAdvancedExtenderImpl.java
Retoque facial advanced/BeautyAdvancedExtenderImpl.java

Usamos AdvancedExtenderImpl como marcador de posición en el siguiente ejemplo. Reemplácelo con el nombre del archivo Extender para la extensión que está implementando.

Veamos cómo Camera2/X invoca la extensions-interface para lograr los tres flujos de aplicaciones.

Flujo de aplicación 1: comprobar la disponibilidad de extensiones

AvanzadoAppFlow1

Figura 8. Flujo de aplicación 1 en Advanced Extender

Primero, la aplicación verifica si la extensión dada es compatible.

Flujo de aplicación 2: consultar información

AvanzadoAppFlow2

Figura 9. Flujo de aplicación 2 en Advanced Extender

Después de llamar AdvancedExtenderImpl.init() , la aplicación puede consultar la siguiente información sobre AdvancedExtenderImpl :

  • Latencia estimada de captura fija: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() devuelve el rango de latencia de captura para que la aplicación evalúe si es apropiado habilitar la extensión para el escenario actual.

  • Resoluciones admitidas para vista previa y captura fija:

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

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() devuelve el formato y los tamaños admitidos para la superficie de captura fija. Los OEM deben admitir salida en formato JPEG y YUV_420_888 .

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() devuelve los tamaños admitidos para una secuencia YUV_420_888 adicional para el análisis de imágenes. Si la superficie YUV de análisis de imágenes no es compatible, getSupportedYuvAnalysisResolutions() debería devolver un 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 las claves de solicitud de captura y las claves de resultados admitidas de su implementación:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Para obtener más información, consulte Claves y resultados de solicitudes de captura de soporte .

Flujo de aplicación 3: vista previa/captura fija con la extensión habilitada

AvanzadoAppFlow3

Figura 10. Flujo de aplicación 3 en Advanced Extender

El diagrama anterior muestra el flujo principal para iniciar la vista previa y capturar imágenes fijas para el tipo de extensor avanzado. Repasemos cada paso.

  1. Instancia SessionProcessorImpl

    La implementación principal de Advanced Extender está en SessionProcessorImpl , que es responsable de proporcionar una configuración de sesión personalizada y enviar solicitudes de captura para iniciar la vista previa y aún así capturar la solicitud. Se invoca AdvancedExtenderImpl.createSessionProcessor() para devolver la instancia SessionProcessorImpl .

  2. initSession

    SessionProcessorImpl.initSession() inicializa la sesión para la extensión. Aquí es donde asigna recursos y devuelve una configuración de sesión para preparar una CameraCaptureSession .

    Para los parámetros de entrada, Camera2/X especifica las configuraciones de la superficie de salida para vista previa, captura de fotografías y un análisis de imagen YUV opcional. Esta configuración de superficie de salida ( OutputSurfaceImpl ) contiene la superficie, el tamaño y el formato de imagen que se recuperan mediante los siguientes métodos en AdvancedExtenderImpl :

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

    Debe devolver una instancia Camera2SessionConfigImpl , que consta de una lista de instancias Camera2OutputConfigImpl y los parámetros de sesión utilizados para configurar CameraCaptureSession . Usted es responsable de enviar las imágenes correctas de la cámara a las superficies de salida pasadas por Camera2/X. Aquí hay algunas opciones para habilitar la salida:

    • Procesamiento en cámara HAL: puede agregar directamente las superficies de salida a CameraCaptureSession con una implementación SurfaceOutputConfigImpl . Esto configura la superficie de salida suministrada a la tubería de la cámara y permite que la cámara HAL procese la imagen.
    • Procesamiento de la superficie intermedia ImageReader (RAW, YUV, etc.): agregue las superficies intermedias ImageReader a CameraCaptureSession con una instancia ImageReaderOutputConfigImpl .

      Debe procesar las imágenes intermedias y escribir la imagen resultante en la superficie de salida.

    • Usar el uso compartido de superficie Camera2: use el uso compartido de superficie con otra superficie agregando cualquier instancia Camera2OutputConfigImpl al método getSurfaceSharingOutputConfigs() de otra instancia de Camera2OutputConfigImpl . El formato y tamaño de la superficie deben ser idénticos.

    Todo Camera2OutputConfigImpl , incluidos SurfaceOutputConfigImpl e ImageReaderOutputConfigImpl , debe tener un ID único ( getId() ), que se utiliza para especificar la superficie de destino y recuperar la imagen de ImageReaderOutputConfigImpl .

  3. onCaptureSessionStart y RequestProcessorImpl

    Cuando se inicia CameraCaptureSession y el marco de la cámara invoca onConfigured() , Camera2/X invoca SessionProcessorImpl.onCaptureSessionStart() con el contenedor de solicitudes Camera2 RequestProcessImpl . Camera2/X implementa RequestProcessImpl , que le permite ejecutar las solicitudes de captura y recuperar imágenes si se utiliza ImageReaderOutputConfigImpl .

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

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

    Puede llamar RequestProcessorImpl.setImageProcessor() con un ID Camera2OutputConfigImpl especificado para registrar una instancia ImageProcessorImpl para recibir imágenes.

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

  4. Inicia la vista previa y toma una foto.

    En la implementación de Advanced Extender, puede enviar solicitudes de captura a través de la interfaz RequestProcessorImpl . Camera2/X le notifica que inicie la solicitud repetida de vista previa o la secuencia de captura fija llamando a SessionProcessorImpl#startRepeating y SessionProcessorImpl#startCapture respectivamente. Debe enviar solicitudes de captura para satisfacer estas solicitudes de vista previa y captura fija.

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

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

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

    Cuando los desarrolladores configuran las claves en la lista getAvailableCaptureRequestKeys , deben habilitar los parámetros y asegurarse de que el resultado de la captura contenga las claves de la lista getAvailableCaptureResultKeys .

  5. startTrigger

    Se invoca SessionProcessorImpl.startTrigger() para iniciar el activador, como CaptureRequest.CONTROL_AF_TRIGGER y CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER . Puede ignorar cualquier clave de solicitud de captura que no se haya anunciado en AdvancedExtenderImpl.getAvailableCaptureRequestKeys() .

    startTrigger() ha sido compatible desde extensions-interface 1.3.0. Permite que las aplicaciones implementen tocar para enfocar y flashear con extensiones.

  6. Limpiar

    Al finalizar una sesión de captura, se invoca SessionProcessorImpl.onCaptureSessionEnd() antes de cerrar CameraCaptureSession . Una vez cerrada la sesión de captura, deInitSession() realiza la limpieza.

Admite vista previa, captura fija y análisis de imágenes

Debe aplicar la extensión tanto para los casos de uso de vista previa como para la captura fija. Sin embargo, si la latencia es demasiado alta para mostrar la vista previa sin problemas, puede aplicar la extensión solo para la captura de imágenes fijas.

Para el tipo de extensor básico, independientemente de habilitar la extensión para la vista previa, debe implementar ImageCaptureExtenderImpl y PreviewExtenderImpl para una extensión determinada. A menudo, una aplicación también utiliza una transmisión YUV para analizar el contenido de la imagen, como buscar códigos QR o texto. Para respaldar mejor este caso de uso, debe admitir la combinación de flujo de vista previa, aún captura y una transmisión YUV_420_888 para configurar CameraCaptureSession . Esto significa que si implementa un procesador, entonces debe admitir la combinación de flujo de tres transmisiones YUV_420_888 .

Para el extensor avanzado, Camera2/X pasa tres superficies de salida a la llamada SessionProcessorImpl.initSession() . Estas superficies de salida son para la vista previa, la captura y el análisis de imágenes, respectivamente. Debe asegurarse de que la vista previa y aún capturar las superficies de salida muestren la salida válida. Sin embargo, para la superficie de salida del análisis de imágenes, asegúrese de que funcione solo cuando no sea nulo. Si su implementación no puede admitir la transmisión de análisis de imágenes, puede devolver una lista vacía en AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . Esto asegura que la superficie de salida del análisis de imágenes siempre sea nula en SessionProcessorImpl.initSession() .

Apoyar la captura de video

La arquitectura de extensión de la cámara actual admite solo la vista previa y aún captura los casos de uso. No admitimos habilitar la extensión en las superficies MediaCodec o MediaRecorder para grabar el video. Sin embargo, es posible que las aplicaciones registren la salida de vista previa.

Apoyo a las superficies MediaCodec y MediaRecorder está bajo investigación.

Metadatos específicos de extensión

Para Android 14 y superior, los metadatos específicos de la extensión permiten que los clientes de extensión de la cámara establezcan y reciban configuraciones y resultados de solicitud de captura específicos de extensión. Específicamente, los clientes de extensión de la cámara pueden usar el parámetro de solicitud de captura EXTENSION_STRENGTH para controlar la fuerza de extensión y el resultado de captura EXTENSION_CURRENT_TYPE para indicar el tipo de extensión habilitado.

Solicitudes de captura

El parámetro de solicitud de captura EXTENSION_STRENGTH controla la resistencia del efecto de postprocesamiento de extensión. El resultado de captura correspondiente incluye el valor de resistencia predeterminado si este parámetro no está configurado explícitamente por el cliente. Este parámetro se puede aplicar de la siguiente manera para estos tipos de extensión:

  • 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 mejora cosmética y suavizado de la piel.

El rango compatible para el parámetro EXTENSION_STRENGTH está entre 0 y 100 , con 0 que no indica un procesamiento de extensión o un paso simple y 100 que indican la máxima resistencia de extensión del efecto de procesamiento.

Para agregar soporte para EXTENSION_STRENGTH , use las API de parámetros específicas del proveedor introducidas en la versión 1.3.0 de la interfaz de la biblioteca de extensión. Para obtener más información, consulte getAvailableCaptureRequestKeys() .

Capturar resultados

El resultado de captura EXTENSION_CURRENT_TYPE permite que las implementaciones de extensión notifiquen a los clientes sobre el tipo de extensión activa.

Debido a que las extensiones que usan el tipo AUTO cambian dinámicamente entre tipos de extensión como HDR y NIGHT dependiendo de las condiciones de la escena, las aplicaciones de extensiones de cámara pueden usar EXTENSION_CURRENT_TYPE para mostrar información sobre la extensión actual seleccionada por la extensión AUTO .

Estimación de latencia de captura en tiempo real

Para Android 14 y superior, los clientes de extensión de la cámara pueden consultar en tiempo real aún capturar estimaciones de latencia basadas en la escena y las condiciones del entorno utilizando getRealtimeStillCaptureLatency() . Este método proporciona estimaciones más precisas que el método estático getEstimatedCaptureLatencyRangeMillis() . Según la estimación de latencia, las aplicaciones pueden decidir omitir el procesamiento de extensión o mostrar una indicación para notificar a los usuarios sobre una operación de larga duració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 apoyar las estimaciones de latencia en tiempo real, implementa lo siguiente:

Capturar las devoluciones de llamada de progreso del procesamiento

Para Android 14 y superior, los clientes de Extension de la cámara pueden recibir devoluciones de llamada para el progreso de las operaciones de procesamiento de captura de larga duración. Las aplicaciones pueden mostrar el progreso actual a los usuarios para mejorar la experiencia general del usuario.

Las aplicaciones 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 de progreso del procesamiento de captura, la implementación de su proveedor de extensión debe llamar a las siguientes devoluciones de llamada con el valor de progreso actual:

Postview todavía captura

Para Android 14 y superior, las extensiones de la cámara pueden suministrar una vista posterior (imagen de vista previa) utilizando setPostviewOutputConfiguration . Para mejorar la experiencia del usuario, las aplicaciones pueden mostrar una imagen posterior a la vista como marcador de posición cuando una extensión está experimentando una mayor latencia de procesamiento y reemplazar la imagen cuando la imagen final está disponible. Las aplicaciones pueden configurar y emitir solicitudes de captura Postview utilizando 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 Postview Still Capture, la implementación de su proveedor debe implementar lo siguiente:

Soporte de salida SurfaceView

Para Android 14 y superior, los clientes de Extension de la cámara pueden usar rutas de renderizado de vista previa optimizada de potencia y rendimiento registrando una instancia SurfaceView para la salida de vista previa para repetir solicitudes.

Para admitir la salida SurfaceView , la implementación de la extensión de su proveedor debe ser capaz de transmitir y emitir una vista previa a las instancias SurfaceView . Para verificar que esto sea compatible, ejecute SurfaceViewExtensionPreviewTest.java CTS Module.

Tipos de sesión específicos del proveedor

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

La característica funciona completamente dentro del marco y la pila de proveedores y no tiene un impacto de API visible para el cliente/público.

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

Historial de versiones de la interfaz de extensiones

La siguiente tabla muestra el historial de versiones de la interfaz de extensión de la cámara. Siempre debe implementar la biblioteca de proveedores con la última versión.

Versión Funciones añadidas
1.0.0
  • Verificación de la versión
    • ExtensionVersionImpl
  • Extensor básico
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Inicialización de la biblioteca
    • InitializerImpl
  • Exponer las resoluciones compatibles
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Obtenga la latencia de captura estimada
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Exponer claves de solicitud de captura compatibles/claves de resultados
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys y getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys y getAvailableCaptureResultKeys
    • Nueva process() Llama que toma ProcessResultImpl en PreviewImageProcessorImpl y CaptureProcessorImpl
    • Solicitud de tipo de activación de soporte
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Metadatos específicos de extensión
  • Dynamic Still Capture Latency Estimaciones
  • Capturar las devoluciones de llamada de progreso del procesamiento
  • Postview todavía captura
  • Soporte para la salida SurfaceView
  • Tipos de sesión específicos del proveedor

Implementación de referencia

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

  • advancedSample : una implementación básica de Advanced Extender.

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

  • service_based_sample : una implementación que demuestra cómo alojar las extensiones de la cámara en un Service . Esta implementación contiene los siguientes componentes:

    • oem_library : una biblioteca OEM de extensiones de cámara para API Camera2 y CamerAx Extensions que implementa Extensions-Interface . Esto actúa como un paso que reenvía las llamadas de Extensions-Interface al servicio. Esta biblioteca también proporciona archivos AIDL y clases de envoltura para comunicarse con el servicio.

      Advanced Extender está habilitado de forma predeterminada. Para habilitar el extensor básico, cambie ExtensionsVersionImpl#isAdvancedExtenderImplemented para devolver false .

    • extensions_service : una implementación de muestra del servicio de extensiones. Agregue su implementación aquí. La interfaz para implementar en el servicio es similar a la Extensions-Interface . Por ejemplo, la implementación de IAdvancedExtenderImpl.Stub realiza las mismas operaciones que AdvancedExtenderImpl . ImageWrapper y TotalCaptureResultWrapper son necesarios para que Image y TotalCaptureResult parcelable.

Configure la biblioteca de proveedores en un dispositivo

La biblioteca de proveedores OEM no está integrada en una aplicación; Se carga desde el dispositivo en tiempo de ejecución por Camera2/X. En CamerAx, la etiqueta <uses-library> declara que la biblioteca androidx.camera.extensions.impl , que se define en el archivo AndroidManifest.xml de la biblioteca camera-extensions , es una dependencia de CamerAx y debe cargarse en tiempo de ejecución. En Camera2, el marco carga un servicio de extensiones que también declara que <uses-library> carga la misma biblioteca androidx.camera.extensions.impl en tiempo de ejecución.

Esto permite que las aplicaciones de terceros usen extensiones cargar automáticamente la biblioteca de proveedores OEM. La biblioteca OEM está marcada como opcional para que las aplicaciones puedan ejecutarse en dispositivos que no tienen la biblioteca en el dispositivo. Camera2/X maneja este comportamiento automáticamente cuando una aplicación intenta usar una extensión de la cámara siempre que el fabricante del dispositivo coloque la biblioteca OEM en el dispositivo para que la aplicación pueda descubrirla.

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

  1. Agregue un archivo de permiso, que requiere la etiqueta <uses-library> , utilizando el siguiente formato: /etc/permissions/ ANY_FILENAME .xml . Por ejemplo, /etc/permissions/camera_extensions.xml . Los archivos en este directorio proporcionan una asignación de la biblioteca nombrada en <uses-library> a la ruta de archivo real en el dispositivo.
  2. Use el ejemplo a continuación para agregar la información requerida al archivo.

    • name debe ser androidx.camera.extensions.impl , ya que esa es la biblioteca que busca Camerax.
    • file es la ruta absoluta del archivo que contiene la 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 superior, los dispositivos que soportan las extensiones de CamerAx deben tener la propiedad ro.camerax.extensions.enabled establecida en true , lo que permite consultar si un dispositivo admite extensiones. Para hacer esto, agregue la siguiente línea en el dispositivo.

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

Validación

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

Después de completar su implementación, use la herramienta de validación de extensiones de cámara para ejecutar pruebas automatizadas y manuales para verificar que la biblioteca de proveedores se implementa correctamente.

Modo de escena extendido versus extensiones de cámara

Para la extensión de Bokeh, además de exponerla con las extensiones de la cámara, puede exponer la extensión utilizando el modo de escena extendida, que está habilitado a través de la tecla CONTROL_EXTENDED_SCENE_MODE . Para obtener más detalles de implementación, consulte Camera Bokeh .

El modo de escena extendido tiene menos restricciones en comparación con las extensiones de la cámara para las aplicaciones de Camera2. Por ejemplo, puede habilitar el modo de escena extendido en una instancia regular CameraCaptureSession que admite combinaciones de flujo flexibles y capturar parámetros de solicitud. Por el contrario, las extensiones de la cámara solo admiten un conjunto fijo de tipos de transmisión y tienen un soporte limitado para los parámetros de solicitud de captura.

Una desventaja del modo de escena extendido es que solo puede implementarlo en la cámara HAL, lo que significa que debe verificarse para funcionar en todos los controles ortogonales disponibles para los desarrolladores de aplicaciones.

Recomendamos exponer a Bokeh usando tanto el modo de escena extendido como las extensiones de la cámara porque las aplicaciones pueden preferir usar una API particular para habilitar Bokeh. Recomendamos primero usar el modo de escena extendida porque esta es la forma más flexible para que las aplicaciones habiliten la extensión Bokeh. Luego puede implementar la interfaz de extensiones de cámara en función del modo de escena extendida. Si implementar bokeh en la cámara hal es difícil, por ejemplo, porque requiere un procesador posterior que se ejecuta en la capa de la aplicación para procesar imágenes, recomendamos implementar la extensión de Bokeh utilizando la interfaz de extensiones de la cámara.

Preguntas frecuentes (FAQ)

¿Hay alguna restricción a los niveles de API?

Sí. Esto depende del conjunto de características de la API de Android requerida por la implementación de la biblioteca de proveedores OEM. Por ejemplo, ExtenderStateListener.onPresetSession() usa la llamada SessionConfiguration.setSessionParameters() para establecer un conjunto de etiquetas de línea de base. Esta llamada está disponible solo en el nivel API 28 y superior. Para obtener detalles sobre métodos de interfaz específicos, consulte la documentación de referencia de la API .