Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

API de administración de búfer de cámara HAL3

Android 10 presenta API de administración de búfer HAL3 de cámara opcionales que le permiten implementar la lógica de administración de búfer para lograr diferentes compensaciones de latencia y memoria en las implementaciones de HAL de cámara.

La cámara HAL requiere N solicitudes (donde N es igual a la profundidad de la canalización ) en cola en su canalización, pero a menudo no requiere todos los N conjuntos de búferes de salida al mismo tiempo.

Por ejemplo, la HAL puede tener ocho solicitudes en cola en la canalización, pero solo requiere búferes de salida para las dos solicitudes en las últimas etapas de la canalización. En dispositivos que ejecutan Android 9 y versiones anteriores, el marco de la cámara asigna búferes cuando la solicitud se pone en cola en la HAL, por lo que podría haber seis conjuntos de búferes en la HAL que no estén en uso. En Android 10, las API de administración de búfer de la cámara HAL3 permiten el desacoplamiento de los búferes de salida para liberar los seis conjuntos de búferes. Esto puede generar cientos de megabytes de ahorro de memoria en dispositivos de gama alta y también puede ser beneficioso para dispositivos con poca memoria.

La Figura 1 muestra un diagrama de la interfaz HAL de la cámara para dispositivos con Android 9 y versiones anteriores. La Figura 2 muestra la interfaz HAL de la cámara en Android 10 con las API de administración del búfer HAL3 de la cámara implementadas.

Gestión de búfer en 9 o menos

Figura 1. Interfaz HAL de la cámara en Android 9 y versiones anteriores

Gestión de búfer en Android 10

Figura 2. Interfaz HAL de la cámara en Android 10 usando las API de administración de búfer

Implementación de las API de administración de búfer

Para implementar las API de administración de búfer, la cámara HAL debe:

La cámara HAL usa los métodos requestStreamBuffers y returnStreamBuffers en ICameraDeviceCallback.hal para solicitar y devolver búferes. La HAL también debe implementar el método signalStreamFlush en ICameraDeviceSession.hal para indicar a la cámara HAL que devuelva búferes.

requestStreamBuffers

Utilice el método requestStreamBuffers para solicitar búferes del marco de la cámara. Cuando se utilizan las API de administración de búfer de la cámara HAL3, las solicitudes de captura del marco de la cámara no contienen búfer de salida, es decir, el campo bufferId en StreamBuffer es 0 . Por lo tanto, la cámara HAL debe usar requestStreamBuffers para solicitar búferes del marco de la cámara.

El método requestStreamBuffers permite a la persona que llama solicitar múltiples búferes de múltiples flujos de salida en una sola llamada, lo que permite menos llamadas HIDL IPC. Sin embargo, las llamadas toman más tiempo cuando se solicitan más búferes al mismo tiempo y esto podría afectar negativamente la latencia total de solicitud a resultado. Además, debido a que las llamadas a requestStreamBuffers se serializan en el servicio de la cámara, se recomienda que la cámara HAL utilice un hilo de alta prioridad dedicado para solicitar búferes.

Si falla una solicitud de búfer, la cámara HAL debe poder manejar correctamente los errores no fatales. La siguiente lista describe las razones comunes por las que fallan las solicitudes de búfer y cómo deben ser manejadas por la cámara HAL.

  • La aplicación se desconecta del flujo de salida: este es un error no fatal. La cámara HAL debe enviar ERROR_REQUEST para cualquier solicitud de captura dirigida a una transmisión desconectada y estar lista para procesar las solicitudes posteriores con normalidad.
  • Tiempo de espera: esto puede ocurrir cuando una aplicación está ocupada haciendo un procesamiento intensivo mientras mantiene algunos búferes. La cámara HAL debe enviar ERROR_REQUEST para las solicitudes de captura que no se pueden cumplir debido a un error de tiempo de espera y estar lista para procesar las solicitudes posteriores con normalidad.
  • El marco de la cámara está preparando una nueva configuración de transmisión: la cámara HAL debe esperar hasta que se complete la siguiente llamada configureStreams antes de volver a llamar a requestStreamBuffers .
  • La cámara HAL ha alcanzado su límite de búfer (el campo maxBuffers ): la cámara HAL debe esperar hasta que devuelva al menos un búfer de la secuencia antes de volver a llamar a requestStreamBuffers .

returnStreamBuffers

Utilice el método returnStreamBuffers para devolver búferes adicionales al marco de la cámara. La cámara HAL normalmente devuelve búferes al marco de la cámara a través del método processCaptureResult , pero solo puede tener en cuenta las solicitudes de captura que se han enviado a la cámara HAL. Con el método requestStreamBuffers , es posible que la implementación de HAL de la cámara retenga más búferes de los solicitados por el marco de la cámara. Aquí es cuando se debe utilizar el método returnStreamBuffers . Si la implementación de HAL nunca contiene más búferes de los solicitados, la implementación de HAL de la cámara no necesita llamar al método returnStreamBuffers .

signalStreamFlush

El signalStreamFlush de la cámara llama al método signalStreamFlush para notificar a la cámara HAL que devuelva todos los búferes disponibles. Esto normalmente se llama cuando el marco de la cámara está a punto de llamar a configureStreams y debe drenar la canalización de captura de la cámara. De forma similar al método returnStreamBuffers , si una implementación HAL de cámara no contiene más búferes de los solicitados, es posible tener una implementación vacía de este método.

Después de que el marco de la cámara llama a signalStreamFlush , el marco deja de enviar nuevas solicitudes de captura a la cámara HAL hasta que todos los búferes se hayan devuelto al marco de la cámara. Cuando se devuelven todos los búferes, las llamadas al método requestStreamBuffers fallan y el marco de la cámara puede continuar su trabajo en un estado limpio. A continuación, el marco de la cámara llama al método configureStreams o processCaptureRequest . Si el marco de la cámara llama al método configureStreams , la cámara HAL puede comenzar a solicitar búferes nuevamente después de que la llamada configureStreams regrese correctamente. Si el marco de la cámara llama al método processCaptureRequest , la cámara HAL puede comenzar a solicitar búferes durante la llamada processCaptureRequest .

La semántica es diferente para el método signalStreamFlush y el método flush . Cuando se llama al método flush , HAL puede cancelar las solicitudes de captura pendientes con ERROR_REQUEST para drenar la tubería lo antes posible. Cuando se signalStreamFlush método signalStreamFlush , la HAL debe finalizar todas las solicitudes de captura pendientes normalmente y devolver todos los búferes al marco de la cámara.

Otra diferencia entre el signalStreamFlush método y otros métodos es que signalStreamFlush es un método HIDL de una sola vía, lo que significa que el marco cámara pueda poner en otras API de bloqueo antes de la HAL recibe el signalStreamFlush llamada. Esto significa que el método signalStreamFlush y otros métodos (específicamente el método configureStreams ) pueden llegar a la cámara HAL en un orden diferente al orden en el que fueron llamados en el marco de la cámara. Para abordar este problema de asincronía, el campo streamConfigCounter se agregó a StreamConfiguration y se agregó como argumento al método signalStreamFlush . La implementación de la cámara HAL debe usar el argumento streamConfigCounter para determinar si una llamada signalStreamFlush llega más tarde que su llamada configureStreams correspondiente. Consulte la Figura 3 para ver un ejemplo.

Manejo de llamadas que llegan tarde

Figura 3. Cómo la cámara HAL debe detectar y manejar las llamadas signalStreamFlush que llegan tarde

Cambios de comportamiento al implementar las API de administración de búfer

Al usar las API de administración de búfer para implementar la lógica de administración de búfer, considere los siguientes posibles cambios de comportamiento en la implementación de cámara y HAL de cámara:

  • Las solicitudes de captura llegan a la cámara HAL más rápido y con mayor frecuencia: sin API de administración de búfer, el marco de la cámara solicita búferes de salida para cada solicitud de captura antes de enviar una solicitud de captura a la cámara HAL. Cuando se utilizan las API de administración de búfer, el marco de la cámara ya no necesita esperar a los búferes y, por lo tanto, puede enviar solicitudes de captura a la cámara HAL antes.

    Además, sin las API de administración de búfer, el marco de la cámara deja de enviar solicitudes de captura si uno de los flujos de salida de la solicitud de captura ha alcanzado el número máximo de búferes que la HAL puede contener a la vez (este valor lo designa la HAL de la cámara en el HalStream::maxBuffers en el valor de retorno de una llamada configureStreams ). Con las API de administración de búfer, este comportamiento de limitación ya no existe y la implementación de la cámara HAL no debe aceptar llamadas a processCaptureRequest cuando la HAL tiene demasiadas solicitudes de captura en cola.

  • requestStreamBuffers latencia de la llamada requestStreamBuffers varía significativamente: hay muchas razones por las que una llamada requestStreamBuffers puede tardar más que el promedio. Por ejemplo:

    • Para los primeros búferes de una secuencia recién creada, las llamadas pueden demorar más porque el dispositivo necesita asignar memoria.
    • La latencia esperada aumenta en proporción a la cantidad de búferes solicitados en cada llamada.
    • La aplicación contiene búferes y está ocupada procesando. Esto puede hacer que las solicitudes de búfer se ralenticen o se agote el tiempo de espera debido a la falta de búferes o una CPU ocupada.

Estrategias de gestión de búfer

Las API de administración de búfer permiten implementar diferentes tipos de estrategias de administración de búfer. Algunos ejemplos son:

  • Compatible con versiones anteriores: HAL solicita búferes para una solicitud de captura durante la llamada processCaptureRequest . Esta estrategia no proporciona ningún ahorro de memoria, pero puede servir como la primera implementación de las API de administración de búfer, lo que requiere muy pocos cambios de código en la cámara HAL existente.
  • Ahorro de memoria maximizado: la cámara HAL solo solicita búferes de salida inmediatamente antes de que sea necesario llenar uno. Esta estrategia permite maximizar el ahorro de memoria. La desventaja potencial es que hay más interrupciones en la canalización de la cámara cuando las solicitudes de búfer tardan un tiempo inusualmente largo en finalizar.
  • En caché: la cámara HAL almacena en caché algunos búferes para que sea menos probable que se vea afectado por una solicitud de búfer lenta ocasional.

La cámara HAL puede adoptar diferentes estrategias para casos de uso particulares, por ejemplo, usando la estrategia de ahorro de memoria maximizada para casos de uso que usan mucha memoria y usando la estrategia compatible con versiones anteriores para otros casos de uso.

Implementación de muestra en la cámara externa HAL

La cámara externa HAL se introdujo en Android 9 y se puede encontrar en el árbol de fuentes en hardware/interfaces/camera/device/3.5/ . En Android 10, se actualizó para incluir ExternalCameraDeviceSession.cpp , una implementación de la API de administración de búfer. Esta cámara externa HAL implementa la estrategia de ahorro de memoria maximizada mencionada en Estrategias de administración de búfer en unos pocos cientos de líneas de código C ++.