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.
Figura 1. Interface HAL da câmera no Android 9 e versões anteriores
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:
- Implementar o HIDL
ICameraDevice@3.5
- Definir a chave de características da câmera
android.info.supportedBufferManagementVersion
paraHIDL_DEVICE_3_5
.
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 chamarrequestStreamBuffers
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 chamarrequestStreamBuffers
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.
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 umconfigureStreams
). 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 ChamadasprocessCaptureRequest
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 pararequestStreamBuffers
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++.