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.
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
:
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:
Figura 2. Implementação da extensão noturna
Verificação da versão:
Camera2/X chama
ExtensionVersionImpl.checkApiVersion()
para garantir que o A versãoextensions-interface
implementada pelo OEM é compatível com a Camera2/X. com suporte.Inicialização da biblioteca de fornecedores:
InitializerImpl
tem um métodoinit()
que inicializa a biblioteca do fornecedor. Camera2/X conclui a inicialização antes de acessar as classes do Extender.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 quandoonInit()
é chamado no Basic Extender ou OinitSession()
é 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
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.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 eCameraCharacteristics
.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.
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ânciaSessionProcessorImpl
chamandocreateSessionProcessor()
na Extensor.
As seções a seguir descrevem o fluxo de extensão em mais detalhes.
Verificação de 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 com bibliotecas de fornecedores OEM criadas com base em 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 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. A
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 |
Ganchos no pipeline da câmera |
|
|
Adequado para | Extensões implementadas na HAL da câmera ou em um processador que processa Imagens YUV. |
|
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
|
val cameraSelector = ExtensionsManager.
getExtensionEnabledCameraSelector
|
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
|
HDR | HdrPreviewExtenderImpl.java
|
Automático | AutoPreviewExtenderImpl.java
|
Bokeh (link em inglês) | BokehPreviewExtenderImpl.java
|
Retoque facial | BeautyPreviewExtenderImpl.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
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
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
ePreviewExtenderImpl.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)
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 HALPROCESSOR_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 noTotalCaptureResult
mais recente.PreviewExtenderImpl.getProcessor
precisa retornar umRequestUpdateProcessorImpl
que processa a instânciaTotalCaptureResult
e retorna uma Instância deCaptureStageImpl
para atualizar a solicitação repetida.PreviewExtenderImpl.getCaptureStage()
também precisa refletir o resultado de o processamento e retornar oCaptureStageImpl
mais recente.PROCESSOR_TYPE_IMAGE_PROCESSOR
:esse tipo permite implementar uma para processarYUV_420_888
imagens e gravar a saída em um PlataformaPRIVATE
.Você precisa implementar e retornar um
PreviewImageProcessorImpl
instância emPreviewExtenderImpl.getProcessor
. O processador é responsável para processarYUV_420_888
imagens de entrada. Ele deve gravar a saída FormatoPRIVATE
de visualização. A Camera2/X usa uma superfícieYUV_420_888
. dePRIVATE
para configurarCameraCaptureSession
para visualização.Confira a ilustração a seguir do fluxo:
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. ParaPreviewImageProcessorImpl
,imageFormat
é um pixel em um formato simples, comoPixelFormat.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 serYUV_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:
Figura 7. Ainda capturar fluxo com CaptureProcessorImpl
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 preparaCaptureProcessorImpl
chamando:CaptureProcessorImpl.onImageFormatUpdate()
comYUV_420_888
.CaptureProcessorImpl.onResolutionUpdate()
pelo tamanho da imagem de entrada.CaptureProcessorImpl.onOutputSurface()
com uma saídaYUV_420_888
superfície
ImageCaptureExtenderImpl.getCaptureStages
retorna uma lista deCaptureStageImpl
, em que cada elemento é mapeado para uma instânciaCaptureRequest
com parâmetros de captura. que são enviadas pela Camera2/X. Por exemplo, se retornar uma lista de trêsCaptureStageImpl
instâncias, a Camera2/X envia três solicitações de captura com parâmetros de captura correspondentes usando ocaptureBurst
API.As imagens recebidas e as instâncias de
TotalCaptureResult
estão agrupadas e enviada paraCaptureProcessorImpl
para processamento.CaptureProcessorImpl
grava a imagem do resultado (formatoYUV_420_888
) na superfície de saída especificada pela chamadaonOutputSurface()
. 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, o
Método isAdvancedExtenderImplemented()
em
ExtensionVersionImpl
precisa retornar true
. Para cada tipo de extensão, os OEMs precisam implementar a
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
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
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 formatoPRIVATE
.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 formatosJPEG
eYUV_420_888
.AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
retorna o tamanhos compatíveis para um stream deYUV_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 retornarnull
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
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 o tipo de extensor avançado. Vamos analisar cada etapa.
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 oSessionProcessorImpl
.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 umaCameraCaptureSession
.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 emAdvancedExtenderImpl
:getSupportedPreviewOutputResolutions()
getSupportedCaptureOutputResolutions()
getSupportedYuvAnalysisResolutions()
Você precisa retornar uma instância
Camera2SessionConfigImpl
, que consiste em uma lista deCamera2OutputConfigImpl
instâncias e os parâmetros de sessão usados para configurarCameraCaptureSession
. 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 umSurfaceOutputConfigImpl
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íciesImageReader
intermediárias para oCameraCaptureSession
com um instânciaImageReaderOutputConfigImpl
.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
aogetSurfaceSharingOutputConfigs()
de outro método instânciaCamera2OutputConfigImpl
. O formato e o tamanho da superfície devem ser idênticos.
Todos os
Camera2OutputConfigImpl
, incluindoSurfaceOutputConfigImpl
eImageReaderOutputConfigImpl
deve ter um ID exclusivo (getId()
), que é usada para especificar a superfície de destino e recuperar a imagemImageReaderOutputConfigImpl
onCaptureSessionStart
eRequestProcessorImpl
Quando
CameraCaptureSession
é iniciado e o framework da câmera invocaonConfigured()
, depois a Camera2/X invocaSessionProcessorImpl.onCaptureSessionStart()
com a solicitação da Camera2 wrapperRequestProcessImpl
. A Camera2/X implementaRequestProcessImpl
, que permite executar as solicitações de captura. recuperar imagens seImageReaderOutputConfigImpl
for usado.As APIs
RequestProcessImpl
são semelhantes às APIs Camera2CameraCaptureSession
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 IDCamera2OutputConfigImpl
para registrar uma instânciaImageProcessorImpl
no receber imagens.A instância
RequestProcessImpl
se torna inválida após chamadas da Camera2/X.SessionProcessorImpl.onCaptureSessionEnd()
.- A superfície de destino é especificada pelo ID do
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 chamandoSessionProcessorImpl#startRepeating
eSessionProcessorImpl#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
eCaptureRequest.JPEG_QUALITY
. Oextensions-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
, é preciso ativar os parâmetros e garantir que a resultado contém as chaves na listagetAvailableCaptureResultKeys
.startTrigger
SessionProcessorImpl.startTrigger()
é invocado para iniciar o gatilho, como comoCaptureRequest.CONTROL_AF_TRIGGER
, eCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER
Você pode desconsiderar qualquer chaves de solicitação de captura que não foram anunciadas noAdvancedExtenderImpl.getAvailableCaptureRequestKeys()
:O
startTrigger()
tem suporte desde oextensions-interface
1.3.0. Ela permite que os aplicativos implementem o toque para focar e atualizar com extensões.Limpeza
Ao terminar uma sessão de captura,
SessionProcessorImpl.onCaptureSessionEnd()
é invocado antes do fechamento.CameraCaptureSession
. Depois que a sessão de captura é encerrada,deInitSession()
executa 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.
No tipo de extensor básico, independentemente de ativar a extensão 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 localização de códigos QR ou texto. Para oferecer melhor suporte a este 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
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 da análise, verifique se ele funciona 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
A
EXTENSION_STRENGTH
Parâmetro de solicitação de captura
controla a intensidade do efeito de pós-processamento da extensão. O evento
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
eNIGHT
: 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
A
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:
- Extensões básicas:
ImageCaptureExtenderImpl.getRealtimeCaptureLatency()
- Extensões avançadas:
SessionProcessorImpl.getRealtimeCaptureLatency
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 :
- Extensões básicas:
ProcessResultImpl.onCaptureProcessProgressed()
- Extensões avançadas:
CaptureCallback.onCaptureProcessProgressed()
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 apresentar aumento da latência de processamento,
e a substituiremos quando a imagem final estiver disponível. Os apps podem configurar
e emita 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 seguintes:
Extensões básicas:
CaptureProcessorImpl.onPostviewOutputSurface
eCaptureProcessorImpl.processWithPostview
Extensões avançadas:
SessionProcessorImpl.startCaptureWithPostview
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 |
|
1.1.0 |
|
1.2.0 |
|
1.3.0 |
|
1.4.0 |
|
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 umaService
. 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 implementaExtensions-Interface
. Isso funciona como uma passagem encaminha chamadas deExtensions-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 retornarfalse
.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 aoExtensions-Interface
. Por exemplo, implementarIAdvancedExtenderImpl.Stub
executa as mesmas operações queAdvancedExtenderImpl
.ImageWrapper
eTotalCaptureResultWrapper
estão necessário para fazer com queImage
eTotalCaptureResult
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:
- 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. Use o exemplo abaixo para adicionar as informações necessárias ao arquivo.
name
precisa serandroidx.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 x extensões de câmera
Para a extensão bokeh, além de expô-la usando extensões de câmera, é possível
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 Bokeh da câmera.
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:
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.