Subsistema HAL

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.

Modelo de solicitação de câmera

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.

Camada de abstração de hardware da câmera

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.

  1. Detectar e enumerar dispositivos de câmera.
  2. Abra o dispositivo e conecte os listeners.
  3. Configure as saídas para o caso de uso de destino (como captura de fotos, gravação etc.).
  4. Crie solicitações para o caso de uso de destino.
  5. Capture/repita solicitações e bursts.
  6. Receber metadados de resultados e dados de imagem.
  7. 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.
Visão geral da HAL da câmera

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

  1. 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.
  2. O framework enumera os dispositivos de câmera por meio de ICameraProvider::getCameraIdList().
  3. O framework instancia um novo ICameraDevice chamando o respectivo ICameraProvider::getCameraDeviceInterface_VX_X().
  4. O framework chama ICameraDevice::open() para criar uma nova sessão de captura ativa ICameraDeviceSession.

Usar uma sessão de câmera ativa

  1. O framework chama ICameraDeviceSession::configureStreams() com uma lista de streams de entrada/saída para o dispositivo HAL.
  2. 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 o ICameraDeviceSession for criado por ICameraDevice::open.
  3. 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.
  4. 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.
  5. 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 de processCaptureResult() para uma solicitação, mas nenhum resultado é entregue a um app para uma captura até que notify() para essa captura seja chamado.
  6. 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 chamada close() retornar, nenhuma outra chamada para ICameraDeviceCallback será permitida pelo HAL. Depois que a chamada close() 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 se close() tivesse sido chamado. No entanto, o HAL precisa cancelar ou concluir todas as capturas pendentes antes de chamar notify(). Assim, quando notify() for chamado com um erro fatal, o framework não receberá mais callbacks do dispositivo. Os métodos, além de close(), precisam retornar -ENODEV ou NULL depois que o método notify() retornar de uma mensagem de erro fatal.
Fluxo de operações da câmera

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.