Subsistema HAL

Solicitações

O framework do app emite solicitações de resultados capturados para o subsistema de 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 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 andamento ao mesmo tempo, e o envio delas não é bloqueador. 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 de 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. O HAL da câmera fornece interfaces para você implementar suas versões desses componentes. Para manter a compatibilidade entre plataformas de vários fabricantes de dispositivos e fornecedores de processadores de sinal de imagem (ISP, ou sensor 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 ao 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 gatilhos 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, informando sobre eventos como um bloqueio de foco automático ou erros.

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

Figura 2. Pipeline de 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 faz as seguintes premissas:

  • A saída Bayer RAW não passa por nenhum processamento no 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 escalonamento 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 de câmera do Android. Consulte a seção "Sequência de operação esperada e inicialização" para ver uma análise detalhada dessas etapas, incluindo chamadas de API.

  1. Ouve e enumera dispositivos de câmera.
  2. Abra o dispositivo e conecte listeners.
  3. Configure as saídas para o caso de uso de destino (como captura de imagem, gravação etc.).
  4. Crie solicitações para o caso de uso de destino.
  5. Capturar/repetir solicitações e picos.
  6. Receba metadados de resultados e dados de imagem.
  7. Ao mudar de caso de uso, volte à etapa 3.

Resumo da operação da HAL

  • As solicitações assíncronas de capturas vêm do framework.
  • O dispositivo HAL precisa processar as solicitações em ordem. Para cada solicitação, produza metadados de resultado de saída e um ou mais buffers de imagem de saída.
  • FIFO 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. Assim, a estrutura pode corresponder a elas, se necessário.
  • Toda a configuração e o estado de 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 definições de 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 provedores de câmera presentes que implementam a interface ICameraProvider. Se esse ou esses provedores estiverem presentes, a estrutura tentará estabelecer uma conexão.
  2. O framework enumera os dispositivos de câmera usando ICameraProvider::getCameraIdList().
  3. O framework cria uma nova ICameraDevice chamando o ICameraProvider::getCameraDeviceInterface_VX_X() respectivo.
  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 fluxos 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 pelo ICameraDevice::open.
  3. O framework cria e envia a primeira solicitação de captura para a 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. Isso é enviado para a HAL com ICameraDeviceSession::processCaptureRequest(). A HAL precisa bloquear o retorno dessa chamada até que esteja pronta para o envio da próxima solicitação.
  4. O framework continua enviando solicitações e chamadas 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. Essa callback de notificação não precisa ocorrer 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. Depois de um atraso no pipeline, a HAL começa a retornar capturas concluídas para o framework com ICameraDeviceCallback::processCaptureResult(). Elas são retornadas na mesma ordem em que 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 acontecer:

  • 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 fluxos de entrada/saída. Algumas transmissões podem ser reutilizadas da configuração anterior. Em seguida, o framework continua da primeira solicitação de captura para a 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. Essa função pode ser chamada a qualquer momento em que nenhuma outra chamada do framework estiver ativa, embora a chamada possa ser bloqueada até que todas as capturas em andamento sejam concluídas (todos os resultados retornados, todos os buffers preenchidos). Depois que a chamada close() retornar, não serão permitidas mais chamadas para ICameraDeviceCallback da HAL. Quando a chamada close() estiver em andamento, a estrutura não poderá chamar nenhuma outra função do dispositivo HAL.
  • Em caso de erro ou outro evento assíncrono, a HAL precisa chamar ICameraDeviceCallback::notify() com a mensagem de erro/evento adequada. Depois de retornar de uma notificação de erro fatal em todo o dispositivo, a HAL deve agir como se close() tivesse sido chamada nela. No entanto, a 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 vai receber mais callbacks do dispositivo. Métodos diferentes 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 das capacidades deles. Para mais informações, consulte nível de hardware compatível.

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, os parâmetros de tempo de exposição, duração do frame e 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 compatível) android.lens.filterDensity (se compatível)
ON_AUTO_FLASH Tudo está ATIVADO, além de android.flash.firingPower, android.flash.firingTime e android.flash.mode
ON_ALWAYS_FLASH Same as ON_AUTO_FLASH
ON_AUTO_FLASH_RED_EYE Same as 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 Pode 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 individuais de 3A estão desativados.

Os controles no bloco de processamento de imagens na Figura 2 operam com um princípio semelhante, e geralmente cada bloco tem três modos:

  • OFF: este bloco de processamento está desativado. Os blocos de demosaico, correção de cor e ajuste de curva tonal não podem ser desativados.
  • RÁPIDO: nesse modo, o bloco de processamento não pode diminuir a taxa de frames de saída em comparação com o modo DESATIVADO, mas deve produzir a saída da melhor qualidade possível, considerando essa restrição. Normalmente, isso é usado para modos de visualização ou gravação de vídeo ou captura de fotos em sequência. Em alguns dispositivos, isso pode ser equivalente ao modo DESATIVADO (nenhum processamento pode ser feito sem reduzir a taxa de frames). Em outros, pode ser equivalente ao modo HIGH_QUALITY (a melhor qualidade ainda não reduz a taxa de frames).
  • HIGH_QUALITY: nesse modo, o bloco de processamento precisa produzir o resultado da melhor qualidade possível, diminuindo a taxa de frames 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 FAST ou HIGH_QUALITY. Por exemplo, o bloco de correção de cor é compatível com uma matriz de transformação de cor, enquanto o ajuste da curva tonal é compatível com 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 dos fluxos de imagens de saída
  • Disponibilidade de modos de agrupamento/pulo no sensor de imagem
  • A largura de banda da interface do sensor de imagem
  • 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 está sempre configurado para gerar a menor resolução possível, considerando os tamanhos de fluxo de saída solicitados pelo app. A menor resolução é definida como sendo pelo menos tão grande quanto o maior tamanho de fluxo de saída solicitado.
  • Como qualquer solicitação pode usar qualquer ou todos os fluxos de saída configurados no momento, o sensor e o ISP precisam ser configurados para oferecer suporte ao escalonamento de uma única captura para todos os fluxos ao mesmo tempo.
  • Os fluxos JPEG agem como fluxos YUV processados para solicitações em que não estão incluídos. Em solicitações em que são referenciados diretamente, eles agem 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.