Extensões para câmeras

Os fabricantes de dispositivos podem expor extensões como bokeh, modo noturno e HDR desenvolvedores de terceiros por meio da interface de extensões de câmera fornecida pelo a biblioteca de fornecedor do OEM. Os desenvolvedores podem usar API Camera2 Extensions e a API Extensions do CameraX para acessar as extensões implementadas na biblioteca do fornecedor OEM.

Para conferir uma lista de extensões com suporte, que é igual em toda a Camera2. e CameraX, consulte API CameraX Extensions. Se você quiser adicionar uma extensão, informar um bug com o Issue Tracker (link em inglês).

Esta página descreve como implementar e ativar a biblioteca de fornecedor OEM em dispositivos.

Arquitetura

O diagrama a seguir descreve a arquitetura das extensões de câmera ou extensions-interface: Arquitetura

Figura 1. Diagrama da arquitetura das extensões de câmera

Como mostrado no diagrama, para oferecer suporte a extensões de câmera, você precisa implementar a extensions-interface fornecida pela biblioteca de fornecedores do OEM. Seu A biblioteca de fornecedor OEM permite duas APIs: API Extensions do CameraX e API Camera2 Extensions, que são usados pelos apps CameraX e Camera2, respectivamente, para acessar extensões de fornecedor.

Implementar a biblioteca de fornecedor OEM

Para implementar a biblioteca de fornecedor OEM, copie o camera-extensions-stub em um projeto de biblioteca do sistema. Esses arquivos definem as extensões de câmera interface gráfica do usuário.

O camera-extensions-stub arquivos são divididos nas seguintes categorias:

Arquivos de interface essenciais (não 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

Implementações obrigatórias (adicionar sua implementação)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Classes do extensor bokeh (implemente se a extensão Bokeh for compatível)

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

Classes estendidos à noite (implemente se a extensão Night for compatível)

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

Classes de repetidor automático (implemente se a extensão automática for compatível)

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

Classes de extensor HDR (implemente se a extensão HDR for compatível)

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

Classes do extensor de retoque facial (implemente se essa extensão for compatível)

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

Utilitários (opcional, pode ser excluído)

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

Não é obrigatório fornecer uma implementação para cada extensão. Se você não implemente uma extensão, defina isExtensionAvailable() para retornar false ou remova as classes Extender correspondentes. As extensões Camera2 e CameraX As APIs informam ao app que a extensão não está disponível.

Vamos conferir como as APIs Camera2 e CameraX interagem com o de fornecedor para ativar uma extensão. O diagrama a seguir ilustra Fluxo completo usando a extensão Night como exemplo:

Fluxo principal

Figura 2. Implementação da extensão noturna

  1. Verificação da versão:

    Camera2/X chama ExtensionVersionImpl.checkApiVersion() para garantir que o A versão extensions-interface implementada pelo OEM é compatível com a Camera2/X. com suporte.

  2. Inicialização da biblioteca de fornecedores:

    InitializerImpl tem um método init() que inicializa a biblioteca do fornecedor. Camera2/X conclui a inicialização antes de acessar as classes do Extender.

  3. Instanciar classes Extender:

    Instancia as classes Extender para a extensão. Há dois extensores tipos: Basic Extender e Advanced Extender. É necessário implementar Tipo de extensor para todas as extensões. Para mais informações, consulte Extensor básico vs. repetidor avançado.

    O Camera2/X instancia e interage com as classes Extender para recuperar e ativar a extensão. Para uma determinada extensão, Camera2/X pode instanciar as classes Extender várias vezes. Por isso, não faça inicialização de trabalho pesado no construtor ou na chamada init(). Faça o fazer muito trabalho somente quando a sessão da câmera estiver prestes a inicial, como quando onInit() é chamado no Basic Extender ou O initSession() é chamado no repetidor avançado.

    Para a extensão Night, as seguintes classes Extender são instanciadas para tipo de extensor básico:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    E para o tipo de extensor avançado:

    • NightAdvancedExtenderImpl.java
  4. Verifique a disponibilidade da extensão:

    Antes de ativar a extensão, o isExtensionAvailable() verifica se a estiver disponível no ID de câmera especificado por meio do extensor instância.

  5. Inicialize o extensor com informações da câmera:

    O Camera2/X chama init() na instância do extensor e o transmite para a câmera. ID e CameraCharacteristics.

  6. Informações da consulta:

    Invoca a classe Extender para recuperar informações, como as ainda capturam a latência estimada e as chaves de solicitação o extensor para ativar a extensão.

  7. Ative a extensão no extensor:

    A classe Extender fornece todas as interfaces necessárias para ativar o . Oferece um mecanismo para atrair OEMs. implementação no pipeline da Camera2, como injetando solicitação de captura parâmetros ou ativar um pós-processador.

    Para o tipo avançado, a Camera2/X interage SessionProcessorImpl para ativar a extensão. Camera2/X recupera a instância SessionProcessorImpl chamando createSessionProcessor() na Extensor.

As seções a seguir descrevem o fluxo de extensão em mais detalhes.

Verificação da versão

Ao carregar a biblioteca de fornecedor OEM do dispositivo durante a execução, a Camera2/X verifica se a biblioteca é compatível com a versão extensions-interface. O extensions-interface usa o controle de versões semântico, ou MAJOR.MINOR.PATCH, por exemplo, 1.1.0 ou 1.2.0. No entanto, apenas o principais e secundárias são usadas durante a verificação da versão.

Para verificar a versão, o Camera2/X chama ExtensionVersionImpl.checkApiVersion() com o tipo Versão extensions-interface. Em seguida, a Camera2/X usa a versão relatada pelo Biblioteca OEM para determinar se a extensão pode ser ativada e quais recursos que ele deve invocar.

Compatibilidade da versão principal

Se as versões principais da interface de extensão forem diferentes entre Camera2/X e a biblioteca do fornecedor, ela será considerada incompatível e A extensão está desativada.

Compatibilidade com versões anteriores

Desde que a versão principal seja idêntica, a Camera2/X garante compatibilidade com versões anteriores (link em inglês) com bibliotecas de fornecedores OEM criadas com versões anteriores extensions-interface versão. Por exemplo, se a Camera2/X for compatível extensions-interface 1.3.0, as bibliotecas de fornecedores de OEM que implementaram a 1.0.0; 1.1.0 e 1.2.0 ainda são compatíveis. Isso também significa que, depois de implementar uma versão específica da biblioteca do fornecedor, o Camera2/X garante que a biblioteca é compatível com as próximas versões do extension-interface.

Compatibilidade com versões futuras

Compatibilidade futura com bibliotecas de fornecedores da versão mais recente do extensions-interface depende de você, o OEM. Se você precisar de alguns recursos para implementar as extensões, convém ativar as extensões a partir de uma determinada versão. Neste caso, retorne a versão de extensions-interface com suporte quando o A versão da biblioteca Camera2/X atende aos requisitos. Se as versões da Camera2/X não forem compatíveis, será possível retornar uma versão incompatível, como a 99.0.0, para desativar as extensões.

Inicialização da biblioteca do fornecedor

Depois de verificar a versão do extensions-interface implementada pelo OEM a Camera2/X inicia o processo de inicialização. O O método InitializerImpl.init() indica à biblioteca do OEM que um app está tentando para usar extensões.

O Camera2/X não faz outras chamadas para a biblioteca do OEM (além da verificação de versão) até que a biblioteca do fornecedor OEM chame OnExtensionsInitializedCallback.onSuccess(). para notificar a conclusão da inicialização.

É necessário implementar InitializerImpl a partir da versão extensions-interface 1.1.0. O Camera2/X ignora a inicialização da biblioteca etapa se a biblioteca de fornecedor do OEM implementar extensions-interface 1.0.0.

Extensor básico vs. repetidor avançado

Há dois tipos de implementação de extensions-interface: um repetidor básico e um Extensor avançado. O Advanced Extender tem suporte desde extensions-interface 1.2.0

Implemente um extensor básico para extensões que processam imagens na HAL da câmera ou usar um pós-processador capaz de processar streams YUV.

Implementar o Advanced Extender para extensões que precisam personalizar a Camera2 configuração de stream e enviar solicitações de captura conforme necessário.

Consulte a tabela a seguir para a comparação:

Extensor básico Extensor avançado
Configurações de streaming Fixa
Prévia: PRIVATE ou YUV_420_888 (se o processador existir)
Captura estática: JPEG ou YUV_420_888 (se o processador existir)
Personalizável pelo OEM.
Enviando solicitação de captura Somente a Camera2/X pode enviar solicitações de captura. Você pode definir os parâmetros para essas solicitações. Quando o processador é fornecido para captura de imagem, o Camera2/X pode enviar várias solicitações de captura, enviar todas as imagens e capturar os resultados ao processador. Uma instância RequestProcessorImpl é fornecida a você para execute a solicitação de captura da câmera2 e acesse os resultados e a imagem.

Camera2/X invoca startRepeating e startCapture em SessionProcessorImpl para sinalizar ao OEM que inicie a repetição solicitação de visualização e inicia a sequência de captura estática, respectivamente.

Ganchos no pipeline da câmera
  • onPresetSession fornece parâmetros de sessão.
  • onEnableSession envia uma única solicitação logo depois que CameraCaptureSession é configurado.
  • onDisableSession envia uma única solicitação antes que CameraCaptureSession seja fechado.
  • initSession inicializa e retorna uma câmera2 personalizada. configuração da sessão para criar a sessão de captura.
  • onCaptureSessionStart é invocado logo após a configuração de CameraCaptureSession.
  • onCaptureSessionEnd é invocado antes de CameraCaptureSession ser fechado.
Adequado para Extensões implementadas na HAL da câmera ou em um processador que processa Imagens YUV.
  • Tem implementações baseadas em Camera2 para as extensões.
  • Precisa de uma configuração de stream personalizada, como stream RAW.
  • É necessária uma sequência de captura interativa.
Versão da API compatível Extensões da Camera2: Android 13 ou versões mais recentes
Extensões do CameraX: camera-extensions 1.1.0 ou mais recente
Extensões da Camera2: Android 12L ou mais recente
Extensões do CameraX: camera-extensions 1.2.0-alpha03 ou mais recente

Fluxos de apps

A tabela a seguir mostra três tipos de fluxos de apps e os chamadas da API Camera Extensions correspondentes. Embora a Camera2/X ofereça essas APIs, você deve implementar adequadamente a biblioteca do fornecedor para oferecer suporte a essas que vamos descrever em mais detalhes em uma seção posterior.

Extensões Camera2 Extensões do CameraX
Disponibilidade da extensão de consulta CameraExtensionCharacteristics .getSupportedExtensions ExtensionsManager. isExtensionAvailable
Informações de consulta CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

O CameraX processa o restante das informações na biblioteca.

Visualizar e capturar com a extensão ativada CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector

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

Extensor básico

A interface Basic Extender fornece hooks para vários lugares na câmera. pipeline. Cada tipo de extensão tem classes Extender correspondentes que os OEMs precisam precisam ser implementados.

A tabela a seguir lista as classes de extensão que os OEMS precisam implementar para cada extensão:

Classes estendidas para implementar
Noite NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java

HdrImageCaptureExtenderImpl.java

Automático AutoPreviewExtenderImpl.java

AutoImageCaptureExtenderImpl.java

Bokeh (link em inglês) BokehPreviewExtenderImpl.java

BokehImageCaptureExtenderImpl.java

Retoque facial BeautyPreviewExtenderImpl.java

BeautyImageCaptureExtenderImpl.java

Usamos PreviewExtenderImpl e ImageCaptureExtenderImpl como marcadores de posição. no exemplo a seguir. Substitua-os pelos nomes das imagens que você está implementando.

O repetidor básico tem os seguintes recursos:

  • Injete parâmetros de sessão ao configurar CameraCaptureSession ( onPresetSession).
  • Notificar sobre os eventos de início e encerramento da sessão de captura e enviar um único para notificar a HAL com os parâmetros retornados (onEnableSession, onDisableSession).
  • Injetar parâmetros de captura para a solicitação (PreviewExtenderImpl.getCaptureStage, ImageCaptureExtenderImpl.getCaptureStages).
  • Adicione processadores para visualização e captura com capacidade de processamento Stream YUV_420_888.
.

Vamos conferir como a Camera2/X invoca a extensions-interface para alcançar os três para os fluxos de apps mencionados acima.

Fluxo de apps 1: verificar a disponibilidade da extensão

BasicExtenderAppFlow1

Figura 3. Fluxo 1 do app no repetidor básico

Neste fluxo, a Camera2/X chama diretamente o método isExtensionAvailable() de PreviewExtenderImpl e ImageCaptureExtenderImpl sem chamar init(). As duas classes de extensão precisam retornar true para ativar as extensões.

Geralmente, essa é a primeira etapa para os apps verificarem se a extensão fornecida tem suporte para um determinado ID de câmera antes de ativar a extensão. Isso ocorre porque algumas extensões são compatíveis apenas com determinados IDs de câmera.

Fluxo do app 2: consultar informações

BasicExtenderAppFlow2

Figura 4. Fluxo 2 do app no repetidor básico

Depois de determinar se a extensão está disponível, os apps devem consultar as seguintes informações antes de ativar a extensão.

  • Ainda captura o intervalo de latência: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange retorna o intervalo de a latência de captura para o app avaliar se é apropriado ativar a extensão para o cenário atual.

  • Tamanhos compatíveis com a plataforma de visualização e captura: ImageCaptureExtenderImpl.getSupportedResolutions e PreviewExtenderImpl.getSupportedResolutions retorna uma lista de formatos de imagem e os tamanhos compatíveis com formato e tamanho de superfície.

  • Chaves de solicitação e de resultado compatíveis: O Camera2/X invoca os seguintes métodos para recuperar a captura com suporte chaves de solicitação e de resultado de sua implementação:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

O Camera2/X sempre chama init() primeiro nessas classes do Extender antes de consultar para mais informações.

Fluxo do app 3: visualizar/ainda capturar com a extensão ativada (implementação da HAL)

BasicExtenderAppFlow3

Figura 5. Fluxo 3 do app no repetidor básico

O diagrama acima ilustra o fluxo principal de ativar a visualização e ainda capturar com uma extensão sem qualquer processador. Isso significa que a HAL da câmera processa a extensão.

Nesse fluxo, a Camera2/X chama primeiro init() e depois onInit, que notifica você que uma sessão da câmera está prestes a começar com as extensões especificadas. A inicialização de trabalho pesado pode ser feita em onInit().

Ao configurar CameraCaptureSession, o Camera2/X invoca onPresetSession para receber os parâmetros de sessão. Depois que a sessão de captura configurado corretamente, Camera2/X invoca onEnableSession retornando um CaptureStageImpl que contém os parâmetros de captura. Câmera2/X imediatamente envia uma única solicitação com esses parâmetros de captura para notificar o HAL Da mesma forma, antes do encerramento da sessão de captura, a Camera2/X invoca onDisableSession e, em seguida, envia uma única solicitação com a captura retornada. parâmetros.

A solicitação repetida acionada por Camera2/X contém os parâmetros de solicitação. retornado por PreviewExtenderImpl.getCaptureStage(). Além disso, a capture contém os parâmetros retornados pelo ImageCaptureExtenderImpl.getCaptureStages():

Por fim, Camera2/X invoca onDeInit() após o término da sessão da câmera. É possível liberar recursos em onDeinit().

Processador de visualização

Além da HAL da câmera, também é possível implementar extensões em um processador.

Implementar PreviewExtenderImpl.getProcessorType para especificar o tipo de processador conforme explicado abaixo:

  • PROCESSOR_TYPE_NONE:sem processador. As imagens são processadas na câmera HAL

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY:o tipo de processador permite que você atualize a solicitação recorrente com novos parâmetros de solicitação de captura com base no TotalCaptureResult mais recente.

    PreviewExtenderImpl.getProcessor precisa retornar um RequestUpdateProcessorImpl que processa a instância TotalCaptureResult e retorna uma Instância de CaptureStageImpl para atualizar a solicitação repetida. PreviewExtenderImpl.getCaptureStage() também precisa refletir o resultado de o processamento e retornar o CaptureStageImpl mais recente.

  • PROCESSOR_TYPE_IMAGE_PROCESSOR:esse tipo permite implementar uma para processar YUV_420_888 imagens e gravar a saída em um Plataforma PRIVATE.

    Você precisa implementar e retornar um PreviewImageProcessorImpl instância em PreviewExtenderImpl.getProcessor. O processador é responsável para processar YUV_420_888 imagens de entrada. Ele deve gravar a saída Formato PRIVATE de visualização. A Camera2/X usa uma superfície YUV_420_888. de PRIVATE para configurar CameraCaptureSession para visualização.

    Confira a ilustração a seguir do fluxo:

PreviewProcessor

Figura 6. Visualizar fluxo com PreviewImageProcessorImpl

A interface PreviewImageProcessorImpl estende ProcessImpl e tem três métodos importantes:

  • onOutputSurface(Surface surface, int imageFormat) define a superfície de saída. para o processador. Para PreviewImageProcessorImpl, imageFormat é um pixel em um formato simples, como PixelFormat.RGBA_8888.

  • onResolutionUpdate(Size size) define o tamanho da imagem de entrada.

  • onImageFormatUpdate(int imageFormat) define o formato da imagem da entrada. imagem. No momento, ele só pode ser YUV_420_888.

Processador de captura de imagem

Para a captura estática, você pode implementar um processador retornando uma CaptureProcessorImpl instância usando ImageCaptureExtenderImpl.getCaptureProcessor. O processador é responsável por processar uma lista de YUV_420_888 imagens capturadas e TotalCaptureResult instâncias e gravar a saída em uma superfície YUV_420_888.

Você pode presumir com segurança que a visualização está ativada e em execução antes de enviar o ainda capturar solicitação.

Veja o fluxo no diagrama abaixo:

CaptureProcessor

Figura 7. Ainda capturar fluxo com CaptureProcessorImpl

  1. A Camera2/X usa uma superfície de formato YUV_420_888 para a captura estática para configurar. a sessão de captura. A Camera2/X prepara CaptureProcessorImpl chamando:

    • CaptureProcessorImpl.onImageFormatUpdate() com YUV_420_888.
    • CaptureProcessorImpl.onResolutionUpdate() pelo tamanho da imagem de entrada.
    • CaptureProcessorImpl.onOutputSurface() com uma saída YUV_420_888 superfície
  2. ImageCaptureExtenderImpl.getCaptureStages retorna uma lista de CaptureStageImpl , em que cada elemento é mapeado para uma instância CaptureRequest com parâmetros de captura. que são enviadas pela Camera2/X. Por exemplo, se retornar uma lista de três CaptureStageImpl de instâncias, a Camera2/X envia três solicitações de captura com parâmetros de captura correspondentes usando o captureBurst API.

  3. As imagens recebidas e as instâncias de TotalCaptureResult estão agrupadas e enviada para CaptureProcessorImpl para processamento.

  4. CaptureProcessorImpl grava a imagem do resultado (formato YUV_420_888) na superfície de saída especificada pela chamada onOutputSurface(). A Camera2/X faz a conversão em imagens JPEG, se necessário.

Suporte a chaves e resultados de solicitação de captura

Além da visualização e captura da câmera, os aplicativos podem definir zoom, parâmetros de flash ou acionar um toque para focar. Esses parâmetros podem não ser compatíveis com sua implementação de extensão.

Os métodos a seguir foram adicionados ao extensions-interface 1.3.0 para permitir para expor os parâmetros compatíveis com sua implementação:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() retorna o capturar chaves de solicitação compatíveis com sua implementação.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() retorna o capturar as chaves de resultado contidas no resultado da captura.

Se a HAL da câmera processar a extensão, a Camera2/X vai recuperar a captura resultados em CameraCaptureSession.CaptureCallback. No entanto, se o processador é implementado, a Camera2/X recupera os resultados da captura ProcessResultImpl , que é transmitido à função process(). em PreviewImageProcessorImpl e CaptureProcessorImpl. Você é responsável por denunciar o resultado da captura usando ProcessResultImpl para Camera2/X.

Veja a definição da interface CaptureProcessorImpl abaixo como um exemplo. No extensions-interface 1.3.0 ou versões mais recentes, a segunda chamada process() é invocada:

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 operações comuns da câmera, como zoom, toque para focar, flash e exposição da outra pessoa, é recomendável oferecer suporte às chaves a seguir para resultado da solicitação e da captura:

  • Zoom:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Toque para focar:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Em Flash:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Compensação de exposição:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

Para extensores básicos que implementam a versão 1.2.0 ou anteriores, o CameraX A API Extensions oferece suporte explícito a todas as chaves acima. Para extensions-interface 1.3.0, tanto a CameraX quanto a Camera2 respeitam a lista retornada e aceitam apenas as chaves contidas neles. Por exemplo, se você decidir retornar apenas CaptureRequest#CONTROL_ZOOM_RATIO e CaptureRequest#SCALER_CROP_REGION na implementação da versão 1.3.0, significa que o app só oferece suporte para zoom, enquanto o recurso toque para focar, flash e exposição de pagamento não são permitidas.

Extensor avançado

O Advanced Extender é um tipo de implementação de fornecedor com base na API Camera2. Este tipo de extensor foi adicionado no extensions-interface 1.2.0. Dependendo fabricante do dispositivo, as extensões podem ser implementadas na camada do app, o que depende dos seguintes fatores:

  • Configuração de stream personalizada:configure streams personalizados, como streams RAW. ou ter vários streams para diferentes IDs de câmeras físicas.

  • Capacidade de enviar solicitações da Camera2:suporte a uma interação complicada. lógica que pode enviar solicitações de captura com parâmetros baseados nos resultados do solicitações anteriores.

O repetidor avançado fornece um wrapper, ou uma camada intermediária, para que você possa personalizar a configuração do stream e enviar solicitações de captura sob demanda.

Arquivos para implementar

Para mudar para a implementação do repetidor avançado, a Método isAdvancedExtenderImplemented() em ExtensionVersionImpl precisa retornar true. Para cada tipo de extensão, os OEMs precisam implementar os classes Extender correspondentes. Os arquivos de implementação do Advanced Extender são no pacote advanced.

Classes de extensão para implementar
Noite advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Automático advanced/AutoAdvancedExtenderImpl.java
Bokeh (link em inglês) advanced/BokehAdvancedExtenderImpl.java
Retoque facial advanced/BeautyAdvancedExtenderImpl.java

Usamos AdvancedExtenderImpl como marcador de posição no exemplo a seguir. Substitua-o pelo nome do arquivo do extensor da extensão que você está implementação.

Vamos conferir como a Camera2/X invoca a extensions-interface para alcançar os três fluxos de apps.

Fluxo do app 1: verificar a disponibilidade das extensões

AdvancedAppFlow1

Figura 8. Fluxo 1 do app no repetidor avançado

Primeiro, o app verifica se a extensão é compatível.

Fluxo do app 2: consultar informações

AvançadoAppFlow2

Figura 9. Fluxo 2 do app no repetidor avançado

Depois de chamar AdvancedExtenderImpl.init(), o app pode consultar as seguindo as informações em AdvancedExtenderImpl:

  • Latência estimada de captura estática: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() retorna o intervalo de a latência de captura para o aplicativo avaliar se é apropriado ativar a extensão para o cenário atual.

  • Resoluções compatíveis para visualização e captura:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() retorna um mapa do formato da imagem para a lista de tamanhos compatíveis com o formato de plataforma de visualização e tamanho. Os OEMs precisam ser compatíveis com pelo menos o formato PRIVATE.

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() retorna o formatos e tamanhos compatíveis para a superfície de captura estática. Os OEMs precisam oferecer suporte a ambas Saída dos formatos JPEG e YUV_420_888.

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() retorna o tamanhos compatíveis para um stream de YUV_420_888 extra para análise de imagens. Se o para análise de imagem, a superfície YUV não é compatível. getSupportedYuvAnalysisResolutions() precisa retornar null ou uma lista vazia.

  • Resultados/chaves de solicitação de captura disponíveis (adicionados no extensions-interface 1.3.0): O Camera2/X invoca os seguintes métodos para recuperar a captura com suporte chaves de solicitação e de resultado de sua implementação:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Para mais informações, consulte Suporte a chaves e resultados de solicitação de captura.

Fluxo do app 3: visualizar/ainda capturar com a extensão ativada

AvançadoAppFlow3

Figura 10. Fluxo 3 do app no repetidor avançado

O diagrama acima mostra o fluxo principal para iniciar a visualização e ainda capturar para o tipo de extensor avançado. Vamos analisar cada etapa.

  1. Instância do SessionProcessorImpl

    A implementação principal do Advanced Extender está no SessionProcessorImpl, que é responsável por fornecer uma configuração de sessão personalizada e enviar capture solicitações para iniciar a visualização e capturar a solicitação. AdvancedExtenderImpl.createSessionProcessor() é invocado para retornar o SessionProcessorImpl.

  2. initSession

    SessionProcessorImpl.initSession() inicializa a sessão para a extensão. É aqui que você aloca recursos e retorna uma configuração de sessão para preparando uma CameraCaptureSession.

    Para os parâmetros de entrada, Camera2/X especifica as configurações de superfície de saída. para visualização, captura estática e uma análise de imagem YUV opcional. Esta saída a configuração da superfície (OutputSurfaceImpl) contém a superfície, o tamanho e a imagem que são recuperados pelos seguintes métodos em AdvancedExtenderImpl:

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

    Você precisa retornar uma instância Camera2SessionConfigImpl, que consiste em uma lista de Camera2OutputConfigImpl instâncias e os parâmetros de sessão usados para configurar CameraCaptureSession. Você é responsável produzindo as imagens de câmera corretas para as superfícies de saída transmitidas Camera2/X. Aqui estão algumas opções para ativar a saída:

    • Processamento na HAL da câmera:é possível adicionar diretamente as superfícies de saída. para CameraCaptureSession com um SurfaceOutputConfigImpl implementação. Isso configura a superfície de saída fornecida para a câmera e permite que a HAL da câmera processe a imagem.
    • Processamento da superfície ImageReader intermediária (RAW, YUV etc.): adicione o superfícies ImageReader intermediárias para o CameraCaptureSession com um instância ImageReaderOutputConfigImpl.

      Você precisa processar as imagens intermediárias e gravar a imagem de resultado no na superfície de saída.

    .
    • Usar o compartilhamento de superfície da Camera2:use o compartilhamento de superfície com outra plataforma. adicionando qualquer instância Camera2OutputConfigImpl ao getSurfaceSharingOutputConfigs() de outro método instância Camera2OutputConfigImpl. O formato e o tamanho da superfície devem ser idênticos.

    Todos os Camera2OutputConfigImpl, incluindo SurfaceOutputConfigImpl e ImageReaderOutputConfigImpl deve ter um ID exclusivo (getId()), que é usada para especificar a superfície de destino e recuperar a imagem ImageReaderOutputConfigImpl

  3. onCaptureSessionStart e RequestProcessorImpl

    Quando CameraCaptureSession é iniciado e o framework da câmera invoca onConfigured(), depois a Camera2/X invoca SessionProcessorImpl.onCaptureSessionStart() com a solicitação da Camera2 wrapper RequestProcessImpl. A Camera2/X implementa RequestProcessImpl, que permite executar as solicitações de captura. recuperar imagens se ImageReaderOutputConfigImpl for usado.

    As APIs RequestProcessImpl são semelhantes às APIs Camera2 CameraCaptureSession em termos de execução de solicitações. As diferenças são:

    • A superfície de destino é especificada pelo ID do Camera2OutputConfigImpl.
    • A capacidade de recuperar a imagem do ImageReader.

    Você pode chamar RequestProcessorImpl.setImageProcessor() com uma ID Camera2OutputConfigImpl para registrar uma instância ImageProcessorImpl no receber imagens.

    A instância RequestProcessImpl se torna inválida após chamadas da Camera2/X. SessionProcessorImpl.onCaptureSessionEnd().

  4. Iniciar a visualização e tirar uma foto

    Na implementação do repetidor avançado, é possível enviar solicitações de captura pela interface RequestProcessorImpl. A Camera2/X notifica você para inicie a solicitação repetida de visualização ou a sequência de ainda captura chamando SessionProcessorImpl#startRepeating e SessionProcessorImpl#startCapture, respectivamente. Envie a captura solicitações para satisfazer essas solicitações de visualização e captura.

    Camera2/X também define os parâmetros de solicitação de captura por meio de SessionProcessorImpl#setParameters: É necessário definir esses parâmetros de solicitação (se os parâmetros forem compatíveis) nas solicitações únicas e repetidas.

    É necessário oferecer suporte a pelo menos CaptureRequest.JPEG_ORIENTATION e CaptureRequest.JPEG_QUALITY. O extensions-interface 1.3.0 oferece suporte a solicitações e as chaves de resultado, que são expostas pelos seguintes métodos:

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

    Quando os desenvolvedores definirem as chaves na lista getAvailableCaptureRequestKeys, você precisa ativar os parâmetros e garantir que os resultado contém as chaves na lista getAvailableCaptureResultKeys.

  5. startTrigger

    SessionProcessorImpl.startTrigger() é invocado para iniciar o gatilho, como como CaptureRequest.CONTROL_AF_TRIGGER e CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER Você pode desconsiderar qualquer chaves de solicitação de captura que não foram anunciadas no AdvancedExtenderImpl.getAvailableCaptureRequestKeys():

    O startTrigger() tem suporte desde o extensions-interface 1.3.0. Ela permite que os aplicativos implementem o recurso de toque para focar e flash com extensões.

  6. Limpeza

    Ao terminar uma sessão de captura, SessionProcessorImpl.onCaptureSessionEnd() é invocado antes do fechamento. CameraCaptureSession. Depois que a sessão de captura é encerrada, deInitSession() realiza a limpeza.

Suporte a visualização, captura estática e análise de imagens

Aplique a extensão para os casos de uso de visualização e captura. No entanto, se a latência for muito alta para exibir a visualização sem problemas, será possível aplicar a extensão apenas para captura estática.

Para o tipo básico de extensor, mesmo que a extensão seja ativada para visualização, implemente ImageCaptureExtenderImpl e PreviewExtenderImpl. para uma determinada extensão. Muitas vezes, um app também usa um fluxo YUV para analisar conteúdo de imagem, como QR codes ou texto. Para oferecer melhor suporte a esse caso de uso, , você deve oferecer suporte à combinação de fluxo de visualização, captura estática e uma Stream YUV_420_888 para configurar CameraCaptureSession. Isso significa que, se implementar um processador, você precisa oferecer suporte ao stream combinação de três streams de YUV_420_888.

Para o repetidor avançado, a Camera2/X transmite três superfícies de saída para o SessionProcessorImpl.initSession(). Estas superfícies de saída são para visualização , captura estática e análise de imagem, respectivamente. É necessário garantir que a visualização e ainda capturar superfícies de saída mostram a saída válida. No entanto, para a imagem de saída de análise, certifique-se de que funcione somente quando não for nulo. Se as não oferecer suporte ao fluxo de análise da imagem, será possível retornar uma lista em AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions(). Isso garante que a superfície de saída da análise da imagem seja sempre nula SessionProcessorImpl.initSession():

Suporte à captura de vídeo

A arquitetura atual de extensão de câmera oferece suporte somente à visualização capturar casos de uso. Não é possível ativar a extensão no MediaCodec ou MediaRecorder para gravar o vídeo. No entanto, é possível para que os apps gravem a saída da visualização.

O suporte às plataformas MediaCodec e MediaRecorder está sendo investigado.

Metadados específicos da extensão

No Android 14 e versões mais recentes, metadados específicos da extensão permite que os clientes da extensão de câmera definam e recebam capturas específicas da extensão configurações e resultados da solicitação. Especificamente, a extensão da câmera os clientes podem usar o parâmetro de solicitação de captura EXTENSION_STRENGTH para controlar a força da extensão e o resultado da captura EXTENSION_CURRENT_TYPE para indicar o tipo de extensão ativada.

Capturar solicitações

O EXTENSION_STRENGTH Parâmetro de solicitação de captura controla a intensidade do efeito de pós-processamento da extensão. O modelo O resultado da captura vai incluir o valor de força padrão se esse parâmetro não estiver definido explicitamente pelo cliente. Esse parâmetro pode ser aplicado da seguinte forma para esses tipos de extensão:

  • BOKEH: controla a quantidade de desfoque.
  • HDR e NIGHT: controlam a quantidade de imagens fundidas e o brilho do a imagem final.
  • FACE_RETOUCH: controla a quantidade de melhorias estéticas e da pele. suavização.

O intervalo aceito para o parâmetro EXTENSION_STRENGTH está entre 0 e 100, com 0 indicando que não há processamento de extensão ou passagem simples e 100: indica a intensidade máxima da extensão do efeito de processamento.

Para adicionar suporte a EXTENSION_STRENGTH, use o fornecedor APIs de parâmetros específicos introduzidas na versão 1.3.0 da biblioteca de extensões interface gráfica do usuário. Para mais informações, consulte getAvailableCaptureRequestKeys():

Capturar resultados

O EXTENSION_CURRENT_TYPE o resultado da captura permite que as implementações de extensão notifiquem os clientes sobre a tipo de extensão.

Como as extensões que usam o tipo AUTO alternam dinamicamente entre as extensões como HDR e NIGHT, dependendo das condições da cena, câmera extensões de aplicativo podem usar EXTENSION_CURRENT_TYPE para exibir informações sobre a extensão atual selecionada pela extensão AUTO.

Estimativa de latência de captura em tempo real

No Android 14 e versões mais recentes, os clientes de extensão de câmera consulta em tempo real e ainda captura estimativas de latência com base na cena e as condições do ambiente usando getRealtimeStillCaptureLatency() Isso fornece estimativas mais precisas do que o método estático getEstimatedCaptureLatencyRangeMillis() . Com base na estimativa de latência, os apps podem decidir pular a extensão. processamento nem para exibir uma indicação para notificar os usuários sobre um operação em execução.

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 dar suporte a estimativas de latência de captura em tempo real, implemente o seguinte:

Capturar callbacks do progresso do processamento

No Android 14 e versões mais recentes, os clientes de extensão de câmera pode receber callbacks para o progresso do processamento de captura de longa duração. as operações. Os apps podem mostrar o progresso aos usuários para melhorar a experiência geral do usuário.

Os apps podem usar o seguinte código para integrar esse recurso:

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 oferecer suporte a callbacks de progresso do processamento de captura, o fornecedor da extensão implementação deve chamar os seguintes callbacks com o progresso atual :

Captura estática de pós-visualização

No Android 14 e versões mais recentes, as extensões de câmera podem fornecer uma pós-visualização (imagem de visualização) usando setPostviewOutputConfiguration Para melhorar a experiência do usuário, os aplicativos podem exibir uma imagem de pós-visualização como um quando uma extensão estiver com latência de processamento aumentada, e a substituiremos quando a imagem final estiver disponível. Os apps podem configurar e emitir solicitações de captura de pós-visualização com o seguinte código de referência:

{
…
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 oferecer suporte à captura de postview, a implementação do fornecedor precisa implementar a seguinte:

Suporte à saída SurfaceView

No Android 14 e versões mais recentes, os clientes de extensão de câmera pode usar caminhos de renderização de visualização otimizados para desempenho e potência, registrando uma SurfaceView instância para saída de visualização de solicitações repetidas.

Para oferecer suporte à saída SurfaceView, a implementação da extensão do fornecedor precisa ser capaz de transmitir e gerar visualizações para SurfaceView instâncias. Para Verifique se há suporte para isso, execute o comando SurfaceViewExtensionPreviewTest.java módulo do CTS.

Tipos de sessão específicos do fornecedor

O recurso permite que as implementações de extensão do fornecedor selecionem um tipo de sessão específico do fornecedor que será definido na sessão interna de captura da câmera, em vez do valor padrão.

O recurso funciona inteiramente dentro da pilha do framework e do fornecedor e não tem impacto na API visível para o cliente/público.

Para selecionar um tipo de sessão específico do fornecedor, implemente o seguinte nas suas bibliotecas de extensões: * ExtenderStateListener.onSessionType() para extensões básicas * Camera2SessionConfigImpl.getSessionType() para extensões avançadas

Histórico de versões da interface de extensões

A tabela a seguir mostra o histórico de versões da interface da extensão da câmera. Você deve sempre implementar a biblioteca do fornecedor com a versão mais recente.

Versão Recursos adicionados
1.0.0
  • Verificação de versão
    • ExtensionVersionImpl
  • Extensor básico
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Inicialização da biblioteca
    • InitializerImpl
  • Expor resoluções com suporte
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • Extensor avançado
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Conseguir latência de captura estimada
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Expor chaves de solicitação de captura/chaves de resultados com suporte
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys e getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys e getAvailableCaptureResultKeys
    • Nova chamada process() que leva ProcessResultImpl em PreviewImageProcessorImpl e CaptureProcessorImpl
    • Solicitação de tipo de acionador de suporte
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Metadados específicos da extensão
  • Estimativas de latência de captura dinâmica estática
  • Capturar callbacks do progresso do processamento
  • Captura estática de pós-visualização
  • Suporte para saída SurfaceView
  • Tipos de sessão específicos do fornecedor

Implementação de referência

As seguintes implementações da biblioteca de fornecedores OEM de referência estão disponíveis em frameworks/ex

  • advancedSample: uma implementação básica do Advanced Extender.

  • sample: uma implementação básica do repetidor básico.

  • service_based_sample: uma implementação que demonstra como hospedar Extensões de câmera em uma Service. Essa implementação contém os seguintes componentes:

    • oem_library: Uma biblioteca OEM de extensões de câmera para APIs de extensões da Camera2 e do CameraX. que implementa Extensions-Interface. Isso funciona como uma passagem encaminha chamadas de Extensions-Interface para o serviço. Esta biblioteca também fornece arquivos AIDL e classes de wrapper para comunicação com o serviço.

      O repetidor avançado é ativado por padrão. Para ativar o repetidor básico, mude ExtensionsVersionImpl#isAdvancedExtenderImplemented para retornar false.

    • extensions_service: Um exemplo de implementação do serviço de extensões. Adicionar sua implementação aqui. A interface a ser implementada no serviço é semelhante para o Extensions-Interface. Por exemplo, implementar IAdvancedExtenderImpl.Stub executa as mesmas operações que AdvancedExtenderImpl. ImageWrapper e TotalCaptureResultWrapper estão necessário para fazer com que Image e TotalCaptureResult sejam parcelados.

Configurar a biblioteca do fornecedor em um dispositivo

A biblioteca de fornecedor OEM não está integrada a um app. é carregado do dispositivo durante a execução pela Camera2/X. No CameraX, a tag <uses-library> declara que a biblioteca androidx.camera.extensions.impl, que é definida na AndroidManifest.xml da biblioteca camera-extensions, é uma dependência da CameraX e precisa ser carregados em tempo de execução. Em Camera2, o framework carrega um serviço de extensões que também declara que o <uses-library> carrega o mesmo biblioteca androidx.camera.extensions.impl durante a execução.

Isso permite que apps de terceiros que usam extensões carreguem automaticamente o OEM biblioteca de fornecedor. A biblioteca do OEM está marcada como opcional para que os apps possam ser executados em dispositivos que não têm a biblioteca no dispositivo. Camera2/X processa esse comportamento automaticamente quando um app tenta usar uma câmera. desde que o fabricante do dispositivo coloque a biblioteca do OEM na dispositivo para que ele possa ser descoberto pelo app.

Para configurar a biblioteca do OEM em um dispositivo, faça o seguinte:

  1. Adicione um arquivo de permissão, exigido pela tag <uses-library>. usando o seguinte formato: /etc/permissions/ANY_FILENAME.xml. Para exemplo: /etc/permissions/camera_extensions.xml. Os arquivos neste diretório, fornecem um mapeamento da biblioteca nomeada em <uses-library> para o do caminho real do arquivo no dispositivo.
  2. Use o exemplo abaixo para adicionar as informações necessárias ao arquivo.

    • name precisa ser androidx.camera.extensions.impl, já que é a biblioteca que o CameraX pesquisa.
    • file é o caminho absoluto do arquivo que contém o implementação de extensões (por exemplo, /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>
    

No Android 12 ou versões mais recentes, os dispositivos com suporte ao CameraX as extensões precisam ter a propriedade ro.camerax.extensions.enabled definida como true, que permite consultar se um dispositivo oferece suporte a extensões. Para fazer isso, adicione a seguinte linha ao arquivo do make do dispositivo:

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

Validação

Para testar sua implementação da biblioteca de fornecedor OEM durante a etapa de desenvolvimento, use o aplicativo de exemplo androidx-main/camera/integration-tests/extensionstestapp/, que é executado por várias extensões de fornecedor.

Depois de concluir a implementação, use o Ferramenta de validação de extensões de câmera para executar testes automatizados e manuais para verificar se a biblioteca do fornecedor está implementados corretamente.

Modo de cena estendido versus extensões de câmera

Para a extensão bokeh, além de expô-la usando extensões de câmera, você pode pode expor a extensão usando o modo de cena estendida, que é ativado por as CONTROL_EXTENDED_SCENE_MODE de dados. Para ver mais detalhes de implementação, consulte Camera Bokeh.

O modo de cena estendido tem menos restrições em comparação com as extensões de câmera para apps Camera2. Por exemplo, você pode ativar o modo de cena estendido em uma instância CameraCaptureSession normal compatível com streaming flexível e capturar parâmetros de solicitação. Por outro lado, as extensões de câmera oferecem suporte a apenas um conjunto fixo de tipos de stream e suporte limitado para captura parâmetros de solicitação.

Uma desvantagem do modo de cena estendido é que você só pode implementá-lo no HAL da câmera, o que significa que ela deve ser verificada para funcionar em todos controles ortogonais disponíveis para desenvolvedores de apps.

Recomendamos expor o bokeh usando o modo de cena estendido e a Câmera Extensões, porque os apps podem preferir usar uma API específica para ativar o bokeh. Recomendamos usar primeiro o modo de cena estendido, porque ele é o mais recomendado maneira flexível para que os apps ativem a extensão bokeh. Em seguida, é possível implementar interface de extensões da câmera com base no modo de cena estendido. Se estiver implementando o bokeh na HAL da câmera é difícil, por exemplo, porque requer uma postagem em execução na camada do app para processar imagens, recomendamos implementar a extensão bokeh usando a interface de extensões da câmera.

Perguntas frequentes

Há restrições nos níveis da API?

Sim. Isso depende do conjunto de recursos da API do Android exigido pelo OEM implementação da biblioteca do fornecedor. Por exemplo: O ExtenderStateListener.onPresetSession() usa o SessionConfiguration.setSessionParameters() para definir um conjunto de tags de referência. Esta chamada está disponível somente no nível da API 28 e superior. Para obter detalhes sobre métodos de interface específicos, consulte a documentação de referência da API.