APIs para gerenciamento de buffer da HAL3 da câmera

O Android 10 introduz opções buffer HAL3 da câmera APIs de gerenciamento de identidade e acesso que permitem para implementar a lógica de gerenciamento de buffer, a fim de obter memória diferente e capturar a latência nas implementações da HAL da câmera.

A HAL da câmera exige N solicitações (em que N é igual ao profundidade do pipeline) enfileirados no pipeline, mas muitas vezes não exige todos os N conjuntos de e de saída ao mesmo tempo.

Por exemplo, a HAL pode ter oito solicitações na fila no pipeline, mas requer apenas buffers de saída para as duas solicitações nos últimos estágios do pipeline. Em dispositivos com o Android 9 e versões anteriores, o framework da câmera aloca quando a solicitação é enfileirada na HAL. Dessa forma, pode haver seis conjuntos de na HAL que não estão em uso. No Android 10, as APIs de gerenciamento de buffer HAL3 da câmera permitem dissociar a saída para liberar os seis conjuntos de buffers. Isso pode levar a centenas de de economia de memória em dispositivos de última geração e também pode ser benéfico para e dispositivos com pouca memória.

A Figura 1 mostra um diagrama da interface HAL da câmera para dispositivos em execução Android 9 e versões anteriores. A Figura 2 mostra a interface HAL da câmera no Android 10 com as APIs de gerenciamento de buffer da HAL3 da câmera implementadas.

Gerenciamento de buffer em nível 9 ou inferior

Figura 1. Interface HAL da câmera no Android 9 e versões anteriores

Gerenciamento de buffer no Android 10

Figura 2. Interface HAL da câmera no Android 10 usando as APIs de gerenciamento de buffer

Implementar as APIs de gerenciamento de buffer

Para implementar as APIs de gerenciamento de buffer, a HAL da câmera precisa:

A HAL da câmera usa requestStreamBuffers e returnStreamBuffers em ICameraDeviceCallback.hal para solicitar e retornar buffers. A HAL também precisa implementar a signalStreamFlush em ICameraDeviceSession.hal para sinalizar que a HAL da câmera retorne buffers.

requestStreamBuffers

Use o requestStreamBuffers para solicitar buffers do framework da câmera. Ao usar a câmera HAL3 APIs de gerenciamento de buffer, solicitações de captura do framework da câmera não contêm buffers de saída, ou seja, o campo bufferId StreamBuffer é 0. Portanto, a HAL da câmera precisa usar requestStreamBuffers para solicitar buffers do framework da câmera.

O método requestStreamBuffers permite que o autor da chamada solicite vários buffers de vários fluxos de saída em uma única chamada, o que permite menos IPCs HIDL chamadas. No entanto, as chamadas levam mais tempo quando mais buffers são solicitados no ao mesmo tempo, o que pode afetar negativamente a latência total de solicitações para resultado. Além disso, como as chamadas para requestStreamBuffers são serializadas na câmera é recomendado que a HAL da câmera use um módulo dedicado para solicitar buffers.

Se uma solicitação de buffer falhar, a HAL da câmera precisará ser capaz de lidar corretamente erros não fatais. A lista a seguir descreve motivos comuns para o armazenamento em buffer as solicitações falham e como elas devem ser tratadas pela HAL da câmera.

  • O app se desconecta do stream de saída: Esse erro não fatal. A HAL da câmera envia ERROR_REQUEST para qualquer solicitação de captura visando um stream desconectado e se preparar para processar solicitações subsequentes normalmente.
  • Tempo limite:pode ocorrer quando um app está ocupado fazendo processamento intensivo, mantendo alguns buffers. A HAL da câmera precisa enviar ERROR_REQUEST para solicitações de captura que não podem ser atendidas devido a uma erro de tempo limite e se prepare para processar as solicitações subsequentes normalmente.
  • O framework da câmera está preparando uma nova configuração de stream: A HAL da câmera precisa aguardar configureStreams a chamada seja concluída antes de chamar requestStreamBuffers novamente.
  • A HAL da câmera atingiu limite de buffer (campo maxBuffers): A HAL da câmera aguarda até retornar pelo menos um buffer do stream antes de chamar requestStreamBuffers de novo.

returnStreamBuffers

Use o returnStreamBuffers para retornar buffers extras ao framework da câmera. A HAL da câmera normalmente retorna buffers para o framework da câmera por meio do processCaptureResult mas só pode considerar as solicitações de captura que foram enviadas ao HAL da câmera. Com o método requestStreamBuffers, é possível implementação da HAL da câmera para reter mais buffers do que o solicitado o framework da câmera. É aqui que o método returnStreamBuffers deve ser usados. Se a implementação da HAL nunca tiver mais buffers do que o solicitado, o A implementação da HAL da câmera não precisa chamar o método returnStreamBuffers .

sinalStreamFlush

A signalStreamFlush é chamado pela estrutura da câmera para notificar a HAL da câmera para retornar todos reservas à mão. Isso normalmente é chamado quando o framework da câmera está prestes a ligar configureStreams e precisam drenar o pipeline de captura da câmera. Semelhante a returnStreamBuffers se uma implementação de HAL da câmera não tiver mais buffers do que solicitado, é possível ter uma implementação vazia desse método.

Depois que o framework da câmera chama signalStreamFlush, o framework interrompe o envio de novas solicitações de captura à HAL da câmera até que todos foram retornados ao framework da câmera. Quando todos os buffers retornado, as chamadas do método requestStreamBuffers vão falhar, e a câmera e o framework possa continuar funcionando em um estado limpo. Em seguida, o framework da câmera chama o método configureStreams ou processCaptureRequest . Se o framework da câmera chamar o método configureStreams, a câmera A HAL pode começar a solicitar buffers novamente após o retorno da chamada configureStreams. com sucesso. Se o framework da câmera chamar o método processCaptureRequest, a HAL da câmera pode começar a solicitar buffers durante o processCaptureRequest a chamada.

A semântica é diferente para o método signalStreamFlush e as flush . Quando o método flush é chamado, a HAL pode cancelar a captura pendente com ERROR_REQUEST para drenar o pipeline o mais rápido possível. Quando o método signalStreamFlush for chamado, a HAL precisará concluir todos os processos capture as solicitações normalmente e retorne todos os buffers ao framework da câmera.

Outra diferença entre o método signalStreamFlush e outros é signalStreamFlush é um método HIDL unidirecional, o que significa que a câmera o framework pode chamar outras APIs de bloqueio antes que a HAL receba a signalStreamFlush. Isso significa que o método signalStreamFlush e outros métodos (especificamente o método configureStreams) pode chegar à HAL da câmera em uma ordem diferente do que a ordem em que foram chamadas no framework da câmera. Para resolver isso, problema de asynchrony, o campo streamConfigCounter foi adicionado a StreamConfiguration e adicionado como um argumento ao signalStreamFlush . A implementação da HAL da câmera precisa usar o streamConfigCounter. para determinar se uma chamada signalStreamFlush chega depois do chamada configureStreams correspondente. Veja um exemplo na Figura 3.

Lidar com chamadas que chegam atrasadas

Figura 3. Como a HAL da câmera precisa detectar e processar chamadas StreamFlush com sinal que chegam atrasadas

Mudanças de comportamento ao implementar as APIs de gerenciamento de buffer

Ao usar as APIs de gerenciamento de buffer para implementar a lógica correspondente, considere as seguintes mudanças de comportamento na câmera e implementação de HAL da câmera:

  • Solicitações de captura chegam à HAL da câmera com mais rapidez e muito mais com frequência:sem APIs de gerenciamento de buffer, o framework da câmera solicita de saída para cada solicitação de captura antes de enviar uma solicitação de captura ao a HAL da câmera. Ao usar as APIs de gerenciamento de buffer, o framework da câmera não precisa mais esperar por buffers e, portanto, pode enviar solicitações de captura para a HAL da câmera antes.

    Além disso, sem APIs de gerenciamento de buffer, o framework da câmera para enviar solicitações de captura se um dos fluxos de saída da captura solicitação atingiu o número máximo de buffers que a HAL pode conter uma vez (esse valor é designado pela HAL da câmera no Campo HalStream::maxBuffers no valor de retorno de um configureStreams ). Com as APIs de gerenciamento de buffer, esse comportamento de limitação não existe e a implementação da HAL da câmera não pode aceitar Chamadas processCaptureRequest quando a HAL tem muitas solicitações de captura na fila.

  • A latência das chamadas requestStreamBuffers varia significativamente: há vários motivos pelos quais uma chamada para requestStreamBuffers pode demorar mais do que média. Exemplo:

    • Para os primeiros buffers de um stream recém-criado, as chamadas pode demorar mais porque o dispositivo precisa alocar memória.
    • A latência esperada aumenta em proporção ao número de solicitações em cada chamada.
    • O app está armazenando buffers e está ocupado em processamento. Isso podem causar lentidão nas solicitações de buffer ou atingir um tempo limite devido a uma devido à falta de buffers ou a uma CPU ocupada.

Estratégias de gerenciamento de buffer

As APIs de gerenciamento de buffer permitem diferentes tipos de gerenciamento de buffer estratégias a serem implementadas. Por exemplo:

  • Compatível com versões anteriores:a HAL solicita buffers para uma solicitação de captura. durante a chamada processCaptureRequest. Essa estratégia não fornece nenhuma economia de memória, mas pode servir como a primeira implementação do buffer gerenciamento de APIs, exigindo poucas alterações de código na HAL da câmera existente.
  • Economia de memória maximizada:a HAL da câmera solicita apenas buffers de saída. imediatamente antes de precisar ser preenchido. Essa estratégia permite mais economia de memória. A desvantagem potencial é mais pipeline de câmera instabilidade quando as solicitações de buffer levam um tempo excepcionalmente longo para terminar.
  • Em cache:a HAL da câmera armazena alguns buffers em cache para diminuir a probabilidade de ser afetado por uma solicitação ocasional de buffer lento.

A HAL da câmera pode adotar diferentes estratégias para casos de uso específicos, exemplo, usar a estratégia de economia de memória maximizada para casos de uso que usam muito de memória e usar uma estratégia compatível com versões anteriores em outros casos de uso.

Exemplo de implementação na HAL da câmera externa

A HAL de câmera externa foi introduzida no Android 9 e pode ser encontrada árvore de origem em hardware/interfaces/camera/device/3.5/ No Android 10, ele foi atualizado para incluir ExternalCameraDeviceSession.cpp, uma implementação da API de gerenciamento de buffer. Esta HAL de câmera externa implementa a estratégia de economia de memória maximizada mencionada em Gerenciamento de buffer estratégias em algumas centenas de linhas de Código C++.