Solicitações
O framework do app emite solicitações de resultados capturados para o subsistema da câmera. Uma solicitação corresponde a um conjunto de resultados. Uma solicitação encapsula todas as informações de configuração sobre a captura e o processamento desses resultados. Isso inclui coisas como resolução e formato de pixel; controle manual de sensor, lente e flash; modos de operação 3A; controle de processamento RAW para YUV; e geração de estatísticas. Isso permite muito mais controle sobre a saída e o processamento dos resultados. Várias solicitações podem estar em trânsito ao mesmo tempo, e o envio de solicitações não é bloqueado. E as solicitações são sempre processadas na ordem em que são recebidas.

Figura 1. Modelo da câmera
HAL e subsistema da câmera
O subsistema da câmera inclui as implementações dos componentes no pipeline da câmera, como o algoritmo 3A e os controles de processamento. A HAL da câmera oferece interfaces para você implementar suas versões desses componentes. Para manter a compatibilidade entre plataformas entre vários fabricantes de dispositivos e fornecedores de processadores de sinal de imagem (ISP, ou sensores de câmera), o modelo de pipeline da câmera é virtual e não corresponde diretamente a nenhum ISP real. No entanto, ele é semelhante o suficiente aos pipelines de processamento reais para que você possa mapeá-lo para o hardware de maneira eficiente. Além disso, ele é abstrato o suficiente para permitir vários algoritmos e ordens de operação diferentes sem comprometer a qualidade, a eficiência ou a compatibilidade entre dispositivos.
O pipeline da câmera também oferece suporte a acionadores que o framework do app pode iniciar para ativar recursos como o foco automático. Ele também envia notificações de volta para o framework do app, notificando os apps sobre eventos como bloqueio de foco automático ou erros.

Figura 2. Pipeline da câmera
Alguns blocos de processamento de imagens mostrados no diagrama acima não estão bem definidos na versão inicial. O pipeline da câmera parte das seguintes premissas:
- A saída RAW Bayer não passa por nenhum processamento dentro do ISP.
- As estatísticas são geradas com base nos dados brutos do sensor.
- Os vários blocos de processamento que convertem dados brutos do sensor em YUV estão em uma ordem arbitrária.
- Embora várias unidades de escala e corte sejam mostradas, todas as unidades de escalonamento compartilham os controles de região de saída (zoom digital). No entanto, cada unidade pode ter uma resolução de saída e um formato de pixel diferentes.
Resumo do uso da API
Este é um breve resumo das etapas para usar a API Camera do Android. Consulte a
seção "Início e sequência de operação esperada" para conferir um detalhamento dessas etapas, incluindo chamadas de API.
- Detectar e enumerar dispositivos de câmera.
- Abra o dispositivo e conecte os listeners.
- Configure as saídas para o caso de uso de destino (como captura de fotos, gravação etc.).
- Crie solicitações para o caso de uso de destino.
- Capture/repita solicitações e bursts.
- Receber metadados de resultados e dados de imagem.
- Ao mudar de caso de uso, volte para a etapa 3.
Resumo da operação do HAL
- As solicitações assíncronas de capturas vêm do framework.
- O dispositivo HAL precisa processar as solicitações em ordem. E, para cada solicitação, produza metadados de saída e um ou mais buffers de imagem de saída.
- Primeiro a entrar, primeiro a sair para solicitações e resultados, e para streams referenciados por solicitações subsequentes.
- Os carimbos de data/hora precisam ser idênticos para todas as saídas de uma determinada solicitação para que o framework possa fazer a correspondência, se necessário.
- Toda a configuração e o estado da captura (exceto as rotinas 3A) são encapsulados nas solicitações e nos resultados.

Figura 3. Visão geral da HAL da câmera
Sequência de inicialização e operação esperada
Esta seção contém uma explicação detalhada das etapas esperadas ao usar a API Camera. Consulte platform/hardware/interfaces/camera/ para ver as definições da interface HIDL.
Enumerar, abrir dispositivos de câmera e criar uma sessão ativa
- Após a inicialização, o framework começa a detectar todos os provedores de câmera
presentes que implementam a
interface
ICameraProvider
. Se esse provedor ou provedores estiverem presentes, o framework vai tentar estabelecer uma conexão. - O framework enumera os dispositivos de câmera por meio de
ICameraProvider::getCameraIdList()
. - O framework instancia um novo
ICameraDevice
chamando o respectivoICameraProvider::getCameraDeviceInterface_VX_X()
. - O framework chama
ICameraDevice::open()
para criar uma nova sessão de captura ativa ICameraDeviceSession.
Usar uma sessão de câmera ativa
- O framework chama
ICameraDeviceSession::configureStreams()
com uma lista de streams de entrada/saída para o dispositivo HAL. - O framework solicita configurações padrão para alguns casos de uso com
chamadas para
ICameraDeviceSession::constructDefaultRequestSettings()
. Isso pode ocorrer a qualquer momento depois que oICameraDeviceSession
for criado porICameraDevice::open
. - O framework cria e envia a primeira solicitação de captura para o HAL com
configurações baseadas em um dos conjuntos de configurações padrão e com pelo menos um
fluxo de saída registrado anteriormente pelo framework. Ela é enviada
para o HAL com
ICameraDeviceSession::processCaptureRequest()
. O HAL precisa bloquear o retorno dessa chamada até que ela esteja pronta para enviar a próxima solicitação. - O framework continua a enviar solicitações e chama
ICameraDeviceSession::constructDefaultRequestSettings()
para receber buffers de configurações padrão para outros casos de uso, conforme necessário. - Quando a captura de uma solicitação começa (o sensor começa a expor para a
captura), o HAL chama
ICameraDeviceCallback::notify()
com a mensagem SHUTTER, incluindo o número do frame e o carimbo de data/hora do início da exposição. Esse callback de notificação não precisa acontecer antes da primeira chamada deprocessCaptureResult()
para uma solicitação, mas nenhum resultado é entregue a um app para uma captura até quenotify()
para essa captura seja chamado. - Após algum atraso no pipeline, o HAL começa a retornar capturas concluídas para
a framework com
ICameraDeviceCallback::processCaptureResult()
. Elas são retornadas na mesma ordem em que as solicitações foram enviadas. Várias solicitações podem estar em andamento ao mesmo tempo, dependendo da profundidade do pipeline do dispositivo HAL da câmera.
Depois de algum tempo, uma das seguintes situações vai ocorrer:
- O framework pode parar de enviar novas solicitações, esperar
que as capturas atuais sejam concluídas (todos os buffers preenchidos, todos os resultados
retornados) e chamar
ICameraDeviceSession::configureStreams()
novamente. Isso redefine o hardware e o pipeline da câmera para um novo conjunto de streams de entrada/saída. Algumas transmissões podem ser reutilizadas da configuração anterior. O framework continua da primeira solicitação de captura para o HAL, se pelo menos um fluxo de saída registrado permanecer. Caso contrário,ICameraDeviceSession::configureStreams()
é obrigatório primeiro. - O framework pode chamar
ICameraDeviceSession::close()
para encerrar a sessão da câmera. Ele pode ser chamado a qualquer momento quando nenhuma outra chamada do framework estiver ativa, embora a chamada possa bloquear até que todas as capturas em andamento sejam concluídas (todos os resultados retornados, todos os buffers preenchidos). Depois que a chamadaclose()
retornar, nenhuma outra chamada paraICameraDeviceCallback
será permitida pelo HAL. Depois que a chamadaclose()
estiver em andamento, o framework não poderá chamar nenhuma outra função do dispositivo HAL. - Em caso de erro ou outro evento assíncrono, o HAL precisa chamar
ICameraDeviceCallback::notify()
com a mensagem de erro/evento apropriada. Depois de retornar de uma notificação de erro fatal em todo o dispositivo, o HAL precisa agir como seclose()
tivesse sido chamado. No entanto, o HAL precisa cancelar ou concluir todas as capturas pendentes antes de chamarnotify()
. Assim, quandonotify()
for chamado com um erro fatal, o framework não receberá mais callbacks do dispositivo. Os métodos, além declose()
, precisam retornar -ENODEV ou NULL depois que o métodonotify()
retornar de uma mensagem de erro fatal.

Figura 4. Fluxo operacional da câmera
Níveis de hardware
Os dispositivos de câmera podem implementar vários níveis de hardware, dependendo dos recursos. Para mais informações, consulte nível de hardware com suporte.
Interação entre a solicitação de captura do app, o controle 3A e o pipeline de processamento
Dependendo das configurações no bloco de controle 3A, o pipeline da câmera ignora alguns dos parâmetros na solicitação de captura do app e usa os valores fornecidos pelas rotinas de controle 3A. Por exemplo, quando a exposição automática está ativa, o tempo de exposição, a duração do frame e os parâmetros de sensibilidade do sensor são controlados pelo algoritmo 3A da plataforma, e todos os valores especificados pelo app são ignorados. Os valores escolhidos para o frame pelas rotinas 3A precisam ser informados nos metadados de saída. A tabela a seguir descreve os diferentes modos do bloco de controle 3A e as propriedades controladas por esses modos. Consulte o arquivo platform/system/media/camera/docs/docs.html para ver as definições dessas propriedades.
Parâmetro | Estado | Propriedades controladas |
---|---|---|
android.control.aeMode | DESATIVADAS | Nenhum |
ATIVADAS | android.sensor.exposureTime android.sensor.frameDuration android.sensor.sensitivity android.lens.aperture (se houver suporte) android.lens.filterDensity (se houver suporte) | |
ON_AUTO_FLASH | Tudo está ATIVADO, além de android.flash.firingPower, android.flash.firingTime e android.flash.mode | |
ON_ALWAYS_FLASH | Igual a ON_AUTO_FLASH | |
ON_AUTO_FLASH_RED_EYE | Igual a ON_AUTO_FLASH | |
android.control.awbMode | DESATIVADAS | Nenhum |
WHITE_BALANCE_* | android.colorCorrection.transform. Ajustes específicos da plataforma se android.colorCorrection.mode for FAST ou HIGH_QUALITY. | |
android.control.afMode | DESATIVADAS | Nenhum |
FOCUS_MODE_* | android.lens.focusDistance | |
android.control.videoStabilization | DESATIVADAS | Nenhum |
ATIVADAS | É possível ajustar android.scaler.cropRegion para implementar a estabilização de vídeo. | |
android.control.mode | DESATIVADAS | AE, AWB e AF estão desativados |
AUTO | As configurações individuais de AE, AWB e AF são usadas | |
SCENE_MODE_* | Pode substituir todos os parâmetros listados acima. Os controles 3A individuais estão desativados. |
Os controles no bloco "Processamento de imagem" na Figura 2 operam de maneira semelhante, e geralmente cada bloco tem três modos:
- DESLIGADO: esse bloco de processamento está desativado. Os blocos de demosaização, correção de cor e ajuste da curva de tom não podem ser desativados.
- RÁPIDO: nesse modo, o bloco de processamento pode não diminuir a taxa de frames de saída em comparação com o modo DESLIGADO, mas deve produzir a melhor saída possível, considerando essa restrição. Normalmente, isso é usado para modos de visualização ou gravação de vídeo ou captura em série para imagens estáticas. Em alguns dispositivos, isso pode ser equivalente ao modo OFF (nenhum processamento pode ser feito sem desacelerar a taxa de frames) e, em alguns dispositivos, pode ser equivalente ao modo HIGH_QUALITY (a melhor qualidade ainda não diminui a taxa de frames).
- HIGH_QUALITY: nesse modo, o bloco de processamento precisa produzir o melhor resultado de qualidade possível, diminuindo a frame rate de saída conforme necessário. Normalmente, isso é usado para captura de imagens estáticas de alta qualidade. Alguns blocos incluem um controle manual que pode ser selecionado opcionalmente em vez de RÁPIDO ou HIGH_QUALITY. Por exemplo, o bloco de correção de cor oferece suporte a uma matriz de transformação de cor, enquanto o ajuste da curva de tom oferece suporte a uma curva de mapeamento de tom global arbitrária.
A taxa de frames máxima que pode ser aceita por um subsistema de câmera é uma função de muitos fatores:
- Resoluções solicitadas de streams de imagens de saída
- Disponibilidade de modos de agrupamento/ignoração no imager
- A largura de banda da interface do imager
- A largura de banda dos vários blocos de processamento do ISP
Como esses fatores podem variar muito entre diferentes ISPs e sensores, a interface HAL da câmera tenta abstrair as restrições de largura de banda em um modelo o mais simples possível. O modelo apresentado tem as seguintes características:
- O sensor de imagem é sempre configurado para gerar a menor resolução possível, considerando os tamanhos de stream de saída solicitados pelo app. A resolução menor é definida como pelo menos o tamanho do fluxo de saída solicitado.
- Como qualquer solicitação pode usar qualquer um ou todos os streams de saída configurados no momento, o sensor e o ISP precisam ser configurados para oferecer suporte à escala de uma única captura para todos os streams ao mesmo tempo.
- Os fluxos JPEG funcionam como fluxos YUV processados para solicitações em que não estão incluídas. Em solicitações em que são referenciadas diretamente, elas funcionam como fluxos JPEG.
- O processador JPEG pode ser executado simultaneamente ao restante do pipeline da câmera, mas não pode processar mais de uma captura por vez.